conniecs/
world.rs

1//! TODO: Add documentation including describing how the derive macros work
2
3use crate::component::ComponentManager;
4use crate::entity::{
5    BuildData, Entity, EntityBuilder, EntityData, EntityIter, EntityManager, EntityModifier,
6    ModifyData,
7};
8use crate::services::ServiceManager;
9use crate::system::SystemManager;
10
11pub struct World<S>
12where
13    S: SystemManager,
14{
15    pub systems: S,
16    pub data: DataHelper<S::Components, S::Services>,
17}
18
19pub struct DataHelper<C, M>
20where
21    C: ComponentManager,
22    M: ServiceManager,
23{
24    pub components: C,
25    pub services: M,
26    pub(crate) entities: EntityManager<C>,
27}
28
29impl<C, M> DataHelper<C, M>
30where
31    C: ComponentManager,
32    M: ServiceManager,
33{
34    pub fn with_entity_data<F, R>(&mut self, entity: Entity, closure: F) -> Option<R>
35    where
36        F: FnOnce(EntityData<C>, &mut C, &mut M) -> R,
37    {
38        if self.entities.is_valid(entity) {
39            Some(closure(
40                EntityData(self.entities.indexed(entity)),
41                &mut self.components,
42                &mut self.services,
43            ))
44        } else {
45            None
46        }
47    }
48
49    pub fn create_entity<F>(&mut self, builder: F) -> Entity
50    where
51        F: FnOnce(BuildData<C>, &mut C, &mut M),
52    {
53        self.create_entity_with_builder(builder)
54    }
55
56    pub fn create_entity_with_builder<B>(&mut self, builder: B) -> Entity
57    where
58        B: EntityBuilder<C, M>,
59    {
60        self.entities
61            .create_entity(builder, &mut self.components, &mut self.services)
62    }
63
64    pub fn remove_entity(&mut self, entity: Entity) -> bool {
65        self.entities.remove_entity(entity)
66    }
67
68    pub fn entities(&self) -> EntityIter<C> {
69        self.entities.iter()
70    }
71}
72
73impl<S> World<S>
74where
75    S: SystemManager,
76{
77    pub fn new() -> Self
78    where
79        S::Services: Default,
80    {
81        World::with_services(Default::default())
82    }
83
84    pub fn with_services(services: S::Services) -> Self {
85        World {
86            systems: S::build_manager(),
87            data: DataHelper {
88                services,
89                components: S::Components::build_manager(),
90                entities: EntityManager::new(),
91            },
92        }
93    }
94
95    pub fn entities(&self) -> EntityIter<S::Components> {
96        self.data.entities.iter()
97    }
98
99    pub fn modify_entity<F>(&mut self, entity: Entity, modifier: F)
100    where
101        F: FnOnce(ModifyData<S::Components>, &mut S::Components, &mut S::Services),
102    {
103        self.modify_entity_with_modifer(entity, modifier)
104    }
105
106    pub fn modify_entity_with_modifer<M>(&mut self, entity: Entity, modifier: M)
107    where
108        M: EntityModifier<S::Components, S::Services>,
109    {
110        let indexed = self.data.entities.indexed(entity);
111        modifier.modify(
112            ModifyData(indexed),
113            &mut self.data.components,
114            &mut self.data.services,
115        );
116        self.systems.reactivated(
117            EntityData(indexed),
118            &self.data.components,
119            &mut self.data.services,
120        );
121    }
122
123    pub fn refresh(&mut self) {
124        self.flush_queue();
125
126        for entity in self.data.entities.iter() {
127            self.systems
128                .reactivated(entity, &self.data.components, &mut self.data.services);
129        }
130    }
131
132    pub fn flush_queue(&mut self) {
133        self.data.entities.flush_queue(
134            &mut self.data.components,
135            &mut self.data.services,
136            &mut self.systems,
137        );
138    }
139
140    pub fn update(&mut self) {
141        self.flush_queue();
142        self.systems.update(&mut self.data);
143        self.flush_queue();
144    }
145
146    /// Mass delete all entities and their data
147    pub fn wipe(&mut self) {
148        self.flush_queue();
149
150        for entity in self.data.entities.iter() {
151            self.systems
152                .deactivated(entity, &self.data.components, &mut self.data.services);
153        }
154
155        self.data.entities.clear();
156        self.data.components.__wipe_all();
157    }
158}