xecs/
world.rs

1use crate::component::{Component, ComponentRead, ComponentStorage, ComponentWrite, StorageRead, StorageWrite};
2use crate::entity::{Entity, EntityId, EntityManager, Entities};
3use crate::group::Group;
4use crate::query::{QueryIterator, Queryable};
5use crate::resource::{Resource, ResourceRead, ResourceWrite};
6use crate::sparse_set::SparseSet;
7use std::any::TypeId;
8use std::collections::HashMap;
9use std::fmt::{Debug, Formatter};
10use parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard};
11
12/// World is the core of XECS.It manages all components and entities
13pub struct World {
14    entity_manager: RwLock<EntityManager>,
15    // Box<SparseSet<EntityId,Component>>
16    components: HashMap<TypeId,RwLock<Box<dyn ComponentStorage>>>,
17    groups: Vec<RwLock<Group>>,
18    resources : HashMap<TypeId,RwLock<Box<dyn Resource>>>
19}
20
21impl World {
22    /// Create a empty world.
23    pub fn new() -> World {
24        World {
25            entity_manager: RwLock::new(EntityManager::new()),
26            components: Default::default(),
27            groups: Default::default(),
28            resources : Default::default()
29        }
30    }
31
32    /// Register resource in world 
33    pub fn register_resource<R : Resource>(&mut self,resource : R) {
34        let type_id = TypeId::of::<R>();
35        self.resources.insert(type_id,RwLock::new(Box::new(resource)));
36    }
37
38    /// Get a read guard of resource
39    pub fn resource_read<R : Resource>(&self) -> Option<ResourceRead<'_,R>> {
40        let type_id = TypeId::of::<R>();
41        let lock = self.resources.get(&type_id)?
42            .read();
43        Some(ResourceRead::new(lock))
44    }
45
46    /// Get a write guard of resource
47    pub fn resource_write<R : Resource>(&self) -> Option<ResourceWrite<'_,R>> {
48        let type_id = TypeId::of::<R>();
49        let lock = self.resources.get(&type_id)?
50            .write();
51        Some(ResourceWrite::new(lock))
52    }
53
54    /// Register a component.
55    /// # Panics
56    /// Panic if component is registered.
57    pub fn register<T: Component>(&mut self) -> &mut Self {
58        assert!(!self.has_registered::<T>(),
59                "World:Cannot register a component twice");
60        let type_id = TypeId::of::<T>();
61        self.components.insert(
62            type_id,
63            RwLock::new(Box::new(SparseSet::<EntityId, T>::new())),
64        );
65        self
66    }
67
68    /// Check if component is registered.
69    pub fn has_registered<T: Component>(&self) -> bool {
70        let type_id = TypeId::of::<T>();
71        self.components.contains_key(&type_id)
72    }
73
74    /// Create an entity without any component in World,
75    ///  return an [Entity](crate::entity::Entity).
76    pub fn create_entity(&self) -> Entity<'_> {
77        let id = {
78            let mut entity_manager = self.entity_manager.write();
79            entity_manager.allocate()
80        };
81        self.entity(id).unwrap()
82    }
83
84    /// Create count of entities
85    /// # Details
86    /// This funtionn ensures tbe entity id is continuous.
87    pub fn create_entities(&self,count: usize) -> Entities<'_> {
88        let ids = {
89            let mut entity_manager = self.entity_manager.write();
90            entity_manager.allocate_n(count)
91        };
92        let entity_manager = self.entity_manager.read();
93        Entities::new(self,ids,entity_manager)
94    }
95
96    /// Remove entity and its components.
97    pub fn remove_entity(&self, entity_id: EntityId) {
98        assert!(self.exist(entity_id),
99                "World:Cannot remove a non-exists entity");
100        // find all groups need remove 
101        let mut groups = vec![];
102        for group in &self.groups {
103            let need_remove = {
104                let group = group.read();
105                let (type_a,type_b) = group.types();
106                let comp_a = self.raw_storage_read(type_a).unwrap();
107                let comp_b = self.raw_storage_read(type_b).unwrap();
108                group.in_group(entity_id, &comp_a, &comp_b)
109            };
110            if need_remove {
111                groups.push(group.write());
112            };
113        }
114        // remove entity in group and its storages
115        for mut group in groups {
116            match &mut *group{
117                Group::FullOwning(data) => {
118                    let (type_a,type_b) = data.types();
119                    let mut comp_a = self.raw_storage_write(type_a).unwrap();
120                    let mut comp_b = self.raw_storage_write(type_b).unwrap();
121                    data.remove(entity_id,&mut comp_a,&mut comp_b);
122                    comp_a.remove(entity_id);
123                    comp_b.remove(entity_id);
124                },
125                Group::PartialOwning(data) => {
126                    let (type_a,type_b) = data.types();
127                    let mut comp_a = self.raw_storage_write(type_a).unwrap();
128                    let comp_b = self.raw_storage_read(type_b).unwrap();
129                    data.remove(entity_id,&mut comp_a,&comp_b);
130                    comp_a.remove(entity_id);
131                }
132                Group::NonOwning(data) => {
133                    let (type_a,type_b) = data.types();
134                    let comp_a = self.raw_storage_read(type_a).unwrap();
135                    let comp_b = self.raw_storage_read(type_b).unwrap();
136                    data.remove(entity_id,&comp_a,&comp_b);
137                },
138            }
139        }
140        // remove entity in other storages
141        let mut storages = vec![];
142        for storage in self.components.values() {
143            let need_remove = {
144                let storage = storage.read();
145                storage.has(entity_id)
146            };
147            if need_remove {
148                storages.push(storage.write());
149            }
150        }
151        for mut storage in storages {
152            storage.remove(entity_id);
153        }
154        // remove entity from manager
155        {
156            let mut entity_manager = self.entity_manager.write();
157            entity_manager.remove(entity_id);
158        }
159    }
160
161    /// Get lock guard of raw component storage,
162    /// return None if component is not registered.
163    pub(in crate) fn raw_storage_read(&self,id : TypeId) 
164        -> Option<RwLockReadGuard<'_,Box<dyn ComponentStorage>>> {
165        self.components
166            .get(&id)
167            .map(|rwlock|rwlock.read())
168    }
169
170    /// Get lock guard of raw component storage,
171    /// return None if component is not registered.
172    pub(in crate) fn raw_storage_write(&self,id : TypeId) 
173        -> Option<RwLockWriteGuard<'_,Box<dyn ComponentStorage>>> {
174        self.components
175            .get(&id)
176            .map(|rwlock|rwlock.write())
177    }
178
179    /// Attach a component to an entity.  
180    /// # Panics
181    /// * Panic if ```T``` is not registered.
182    /// * Panic if ```entity_id``` not exist.
183    pub fn attach_component<T: Component>(&self, entity_id: EntityId,component: T) {
184        self.entity(entity_id)
185            .expect("World: Cannot attach component to a non-existence entity")
186            .attach(component);
187    }
188
189    /// Detach a component from an entity.
190    /// # Details
191    /// Return ```None``` if entity doesn't have this component,  
192    /// otherwise return ```Some(component)```
193    /// # Panics
194    /// * Panic if ```T``` is not registered.
195    /// * Panic if ```entity_id``` not exist.
196    pub fn detach_component<T: Component>(&self, entity_id: EntityId) -> Option<T> {
197        self.entity(entity_id)
198            .expect("World: Cannot detach component to a non-existence entity")
199            .detach::<T>()
200    }
201
202    /// Check if ```entity_id``` exists in World.
203    pub fn exist(&self, entity_id: EntityId) -> bool {
204        let entity_manager = self.entity_manager.read();
205        entity_manager.has(entity_id)
206    }
207
208    /// Get the component storage's read guard
209    pub fn components_read<T : Component>(&self) -> Option<StorageRead<'_,T>> {
210        let type_id = TypeId::of::<T>();
211        let lock = self.raw_storage_read(type_id)?;
212        Some(StorageRead::from_lock(lock))
213    }
214
215    /// Get the component storage's write guard
216    pub fn components_write<T : Component>(&self) -> Option<StorageWrite<'_,T>> {
217        let type_id = TypeId::of::<T>();
218        let lock = self.raw_storage_write(type_id)?;
219        Some(StorageWrite::from_lock(lock))
220    }
221
222    /// Get the read guard of component of an entity
223    pub fn entity_component_read<T : Component>(&self,id : EntityId) -> Option<ComponentRead<'_,T>> {
224        let lock = self.components_read::<T>()?;
225        if lock.exist(id) {
226            Some(unsafe {
227                ComponentRead::new(id,lock)
228            })
229        } else {
230            None
231        }
232    }
233
234    /// Get the write guard of component of an entity
235    pub fn entity_component_write<T : Component>(&self,id : EntityId) -> Option<ComponentWrite<'_,T>> {
236        let lock = self.components_write::<T>()?;
237        if lock.exist(id) {
238            Some(unsafe {
239                ComponentWrite::new(id,lock)
240            })
241        } else {
242            None
243        }
244    }
245
246    /// Get an [Entity](crate::entity::Entity) from an entity id
247    pub fn entity(&self,id : EntityId) -> Option<Entity<'_>> {
248        let lock = self.entity_manager.read();
249        if lock.has(id) {
250            Some(Entity::new(&self, lock, id))
251        } else {
252            None
253        }
254    }
255
256    /// Make a [group](crate::group) to accelerate the iteration.
257    /// ## Panics
258    /// * Panic if ```group``` is the same as another group in [World](crate::world::World).
259    /// * Panic if component is owned by another group.
260    pub fn make_group<G : Into<Group> + 'static + Copy>(&mut self, group: G) {
261        assert!(!self.has_group(group),
262                "World: Cannot make group because world has a same group");
263        let group = group.into();
264        assert!(
265            {
266                let mut ok = true;
267                'outer: for world_group in &self.groups {
268                    let world_group = world_group.read();
269                    for owning_type in world_group.owning() {
270                        if group.owned(owning_type) {
271                            ok = false;
272                            break 'outer;
273                        }
274                    }
275                }
276                ok
277            },
278            "World: Cannot make group because component was owned by another group"
279        );
280
281        self.groups.push(RwLock::new(group));
282        let group = self.groups.last().unwrap();
283        let mut group = group.write();
284        match &mut *group{
285            Group::FullOwning(data) => {
286                let (type_a,type_b) = data.types();
287                let mut comp_a = self.raw_storage_write(type_a).unwrap();
288                let mut comp_b = self.raw_storage_write(type_b).unwrap();
289                data.make(&mut comp_a,&mut comp_b);
290            },
291            Group::PartialOwning(data) => {
292                let (type_a,type_b) = data.types();
293                let mut comp_a = self.raw_storage_write(type_a).unwrap();
294                let comp_b = self.raw_storage_read(type_b).unwrap();
295                data.make(&mut comp_a,&comp_b);
296            },
297            Group::NonOwning(data) => {
298                let (type_a,type_b) = data.types();
299                let comp_a = self.raw_storage_read(type_a).unwrap();
300                let comp_b = self.raw_storage_read(type_b).unwrap();
301                data.make(&comp_a,&comp_b);
302            },
303        }
304    }
305
306    /// Check if (group)[crate::group] exists in [World](crate::world::World).
307    /// Return true if group is same as another group in World.
308    pub(in crate) fn has_group<G : Into<Group> + 'static>(&self, group: G) -> bool {
309        let group = group.into();
310        for world_group in &self.groups {
311            let world_group = world_group.read();
312            if world_group.eq(&group) {
313                return true;
314            }
315        }
316        false
317    }
318
319    pub(in crate) fn group<G : Into<Group> + 'static>(&self, group: G) -> RwLockReadGuard<Group> {
320        let group = group.into();
321        self.groups
322            .iter()
323            .find(|world_group| {
324                let world_group = world_group.read();
325                world_group.eq(&group)
326            })
327            // unwrap here
328            // existence will be ensured by an outside function
329            .unwrap()
330            .read()
331    }
332
333    pub(in crate) fn groups(&self,type_id : TypeId) -> Vec<RwLockWriteGuard<'_,Group>> {
334        let mut groups = vec![];
335        for group in &self.groups {
336            let need_add = {
337                let group = group.read();
338                let (type_id_a,type_id_b) = group.types();
339                type_id_a == type_id || type_id_b == type_id
340            };
341            if need_add {
342                groups.push(group.write())
343            }
344        }
345        groups
346    }
347
348    /// [Query](crate::query) entities with conditions
349    pub fn query<'a, T: Queryable<'a>>(
350        &'a self,
351    ) -> Box<dyn QueryIterator<Item = <T as Queryable>::Item> + 'a> {
352        <T as Queryable<'a>>::query(self)
353    }
354
355}
356
357impl Debug for World {
358    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
359        f.debug_struct("World")
360            .field("entities", &self.entity_manager)
361            .field(
362                "components",
363                &self.components.keys().cloned().collect::<Vec<TypeId>>(),
364            )
365            .finish()
366    }
367}
368
369#[cfg(test)]
370mod tests {
371    use std::fmt::Debug;
372    use crate::component::Component;
373    use crate::entity::EntityId;
374    use crate::group::{full_owning, non_owning, partial_owning};
375    use crate::query::WithId;
376    use crate::world::World;
377
378    #[test]
379    fn component_test() {
380        let mut world = World::new();
381
382        world.register::<char>();
383
384        let id1 = world.create_entity().into_id();
385        let id2 = world.create_entity().into_id();
386        let _id3 = world.create_entity().into_id();
387
388        world.attach_component(id1,'c');
389        world.attach_component(id2,'a');
390
391        {
392            let components = world.components_read::<char>().unwrap();
393            let components = components.data();
394            assert_eq!(components,&['c','a'])
395        }
396        world.remove_entity(id1);
397
398        {
399            let components = world.components_read::<char>().unwrap();
400            let components = components.data();
401            assert_eq!(components,&['a'])
402        }
403    }
404
405    #[test]
406    fn group_test() {
407        let mut world = World::new();
408
409        world.register::<u32>();
410        world.register::<char>();
411        world.register::<()>();
412
413        fn print<T>(world : &World,msg : &str)
414        where T: Component + Clone + Debug {
415            let v = world.query::<&T>()
416                .with_id()
417                .map(|(id,data)|(id,data.clone()))
418                .collect::<Vec<_>>();
419            println!("{}:{:?}",msg,&v);
420        }
421
422        world.create_entity().attach(1_u32).attach(());
423        let id2 = world.create_entity().attach(2_u32).into_id();
424        let id3 = world
425            .create_entity()
426            .attach(3_u32)
427            .attach('a')
428            .attach(())
429            .into_id();
430        world.create_entity().attach(4_u32).attach('b');
431        world.create_entity().attach(5_u32).attach('c');
432        world.create_entity().attach(6_u32);
433        let id7 = world.create_entity().attach('d').attach(()).into_id();
434        println!("#initial");
435        print::<u32>(&world, "u32 :");
436        print::<char>(&world, "char:");
437        print::<()>(&world, "()  :");
438        println!();
439
440        dbg!("Here");
441        world.make_group(full_owning::<u32, char>());
442        dbg!("Here");
443        world.make_group(non_owning::<u32, char>());
444        dbg!("Here");
445        world.make_group(partial_owning::<(), u32>());
446        dbg!("Here");
447        println!("#Made group full/non<u32,char> partial_owning<(),u32>");
448        print::<u32>(&world, "u32 :");
449        print::<char>(&world, "char:");
450        print::<()>(&world, "()  :");
451        println!();
452
453        world.attach_component(id2,'b');
454        println!("#attach component char b for id=2");
455        print::<u32>(&world, "u32 :");
456        print::<char>(&world, "char:");
457        print::<()>(&world, "()  :");
458        println!();
459
460        world.attach_component(id7,2_u32);
461        println!("#attach component u32=2 for id=7");
462        print::<u32>(&world, "u32 :");
463        print::<char>(&world, "char:");
464        print::<()>(&world, "()  :");
465        println!();
466
467        world.detach_component::<u32>(id3);
468        println!("#detach component u32 for id=3");
469        print::<u32>(&world, "u32 :");
470        print::<char>(&world, "char:");
471        print::<()>(&world, "()  :");
472        println!();
473    }
474
475    #[test]
476    fn debug_trait_test() {
477        let mut world = World::new();
478
479        world.register::<char>();
480        world.register::<u32>();
481
482        world.create_entity().attach('c').attach(12_u32);
483        world.create_entity().attach('a');
484
485        world.make_group(full_owning::<char, u32>());
486
487        world.create_entity().attach('c').attach(12_u32);
488        world.create_entity().attach('a');
489
490        println!("{:?}", world);
491    }
492
493    #[test]
494    fn resource_test() {
495        let mut world = World::new();
496        #[derive(Debug)]
497        struct Test {
498            name : String,
499            age : u32
500        }
501        
502        world.register_resource(Test{
503            name : "affff".to_string(),
504            age : 12
505        });
506
507        assert!(world.resource_read::<Test>().is_some());
508        assert_eq!(world.resource_read::<Test>().unwrap().age,12);
509
510        world.resource_write::<Test>().unwrap().age = 13;
511
512        assert_eq!(world.resource_read::<Test>().unwrap().age,13);
513        assert_eq!(&world.resource_read::<Test>().unwrap().name,"affff");
514    }
515
516    #[test]
517    fn entity_component_test() {
518        let mut world = World::new();
519
520        world.register::<u32>();
521
522        world.create_entity().attach(5_u32);
523        let id = world.create_entity().attach(7_u32).into_id();
524        world.create_entity().attach(2_u32);
525
526        {
527            let v = world.entity_component_read::<u32>(id).unwrap();
528            assert_eq!(*v,7);
529        }
530
531        {
532            let mut v = world.entity_component_write::<u32>(id).unwrap();
533            *v = 3;
534        }
535
536        {
537            let v = world.entity_component_read::<u32>(id).unwrap();
538            assert_eq!(*v,3);
539        }
540    }
541
542    #[test]
543    fn entity_test() {
544        let mut world = World::new();
545
546        world.register::<u32>();
547
548        world.create_entity().attach(5_u32);
549        let id = world.create_entity().attach(7_u32).into_id();
550        world.create_entity().attach(2_u32);
551
552        let entity = world.entity(id).unwrap();
553
554        {
555            let v = entity.component_read::<u32>().unwrap();
556            assert_eq!(*v,7);
557        }
558
559        {
560            let mut v = entity.component_write::<u32>().unwrap();
561            *v = 3;
562        }
563
564        {
565            let v = entity.component_read::<u32>().unwrap();
566            assert_eq!(*v,3);
567        }
568    }
569
570    #[test]
571    fn enitites_test() {
572        let mut world = World::new();
573
574        world.register::<u32>();
575        world.register::<char>();
576
577        world.create_entity()
578            .attach(2_u32)
579            .attach('a');
580
581        let ids = world.create_entities(5)
582            .attach([1_u32,2,3,4,5].as_slice())
583            .attach(['a','b','c','d','e'].as_slice())
584            .into_ids();
585        
586        println!("{:?}",ids);
587        
588        {
589            let num = world.components_read::<u32>().unwrap();
590            let chr = world.components_read::<char>().unwrap();
591            assert_eq!(num.data(),&[2,1_u32,2,3,4,5]);
592            assert_eq!(chr.data(),&['a','a','b','c','d','e']);
593        }
594
595        // remove one id in ids
596        world.remove_entity(EntityId::new(4).unwrap());
597
598        // craete a new one 
599        let id = world.create_entity().into_id();
600
601        // check if id is reused
602        assert_eq!(id,EntityId::new(4).unwrap());
603    }
604}