entity_table/
lib.rs

1#[cfg(feature = "serialize")]
2pub use serde; // Re-export serde so it can be referenced in macro body
3#[cfg(feature = "serialize")]
4use serde::{Deserialize, Serialize};
5use std::{iter, mem, slice};
6
7type Id = u32;
8type Index = u32;
9
10#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
11#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
12pub struct Entity {
13    id: Id,
14    index: Index,
15}
16
17#[derive(Clone, Debug, Default)]
18struct IndexToId {
19    vec: Vec<Option<Id>>,
20}
21
22impl IndexToId {
23    fn new_with_capacity(capacity: usize) -> Self {
24        let mut vec = Vec::with_capacity(capacity);
25        vec.resize(capacity, None);
26        Self { vec }
27    }
28    fn insert(&mut self, Entity { id, index }: Entity) {
29        if index as usize >= self.vec.len() {
30            self.vec.resize(index as usize + 1, None);
31        }
32        self.vec[index as usize] = Some(id);
33    }
34    fn remove(&mut self, index: Index) {
35        if let Some(entry) = self.vec.get_mut(index as usize) {
36            *entry = None;
37        }
38    }
39    fn clear(&mut self) {
40        self.vec.clear();
41    }
42    fn contains(&self, entity: Entity) -> bool {
43        self.vec.get(entity.index as usize) == Some(&Some(entity.id))
44    }
45    fn entities(&self) -> Entities {
46        Entities {
47            iter: self.vec.iter().enumerate(),
48        }
49    }
50}
51
52pub struct Entities<'a> {
53    iter: iter::Enumerate<slice::Iter<'a, Option<Id>>>,
54}
55
56impl<'a> Iterator for Entities<'a> {
57    type Item = Entity;
58
59    fn next(&mut self) -> Option<Self::Item> {
60        loop {
61            if let Some((index, maybe_id)) = self.iter.next() {
62                if let Some(id) = maybe_id {
63                    return Some(Entity {
64                        index: index as u32,
65                        id: *id,
66                    });
67                }
68            } else {
69                return None;
70            }
71        }
72    }
73}
74
75#[cfg(feature = "serialize")]
76#[derive(Serialize, Deserialize)]
77struct IndexToIdSerialize {
78    entities: Vec<Entity>,
79    // In the typical use case there will be a large number of entities whose id and index fields
80    // will match, beginning with the entity whose id and index are 0. This is because in most
81    // games there is a large amount of static entities which make up the level that get allocated
82    // before dynamic entities.
83    num_matching_entities: u32,
84}
85
86#[cfg(feature = "serialize")]
87impl IndexToId {
88    fn to_serialize(&self) -> IndexToIdSerialize {
89        let entities = self
90            .vec
91            .iter()
92            .enumerate()
93            .skip_while(|&(index, maybe_id)| maybe_id.map(|id| id == index as u32).unwrap_or(false))
94            .filter_map(|(index, maybe_id)| {
95                maybe_id.map(|id| Entity {
96                    id,
97                    index: index as u32,
98                })
99            })
100            .collect();
101        let num_matching_entities = self
102            .vec
103            .iter()
104            .enumerate()
105            .take_while(|&(index, maybe_id)| maybe_id.map(|id| id == index as u32).unwrap_or(false))
106            .count() as u32;
107        IndexToIdSerialize {
108            entities,
109            num_matching_entities,
110        }
111    }
112    fn from_serialize(
113        IndexToIdSerialize {
114            entities,
115            num_matching_entities,
116        }: IndexToIdSerialize,
117    ) -> Self {
118        let vec = if let Some(max_index) = entities
119            .iter()
120            .map(|e| e.index)
121            .max()
122            .or(num_matching_entities.checked_sub(1))
123        {
124            let mut vec = vec![None; max_index as usize + 1];
125            for id_and_index in 0..num_matching_entities {
126                vec[id_and_index as usize] = Some(id_and_index);
127            }
128            for entity in entities {
129                vec[entity.index as usize] = Some(entity.id);
130            }
131            vec
132        } else {
133            Vec::new()
134        };
135        Self { vec }
136    }
137}
138
139#[cfg(feature = "serialize")]
140impl Serialize for IndexToId {
141    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
142        self.to_serialize().serialize(s)
143    }
144}
145
146#[cfg(feature = "serialize")]
147impl<'a> Deserialize<'a> for IndexToId {
148    fn deserialize<D: serde::Deserializer<'a>>(d: D) -> Result<Self, D::Error> {
149        Deserialize::deserialize(d).map(Self::from_serialize)
150    }
151}
152
153#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
154#[derive(Debug, Default)]
155pub struct EntityAllocator {
156    next_id: Id,
157    next_index: Index,
158    index_to_id: IndexToId,
159    free_indices: Vec<Index>,
160}
161
162impl EntityAllocator {
163    pub fn alloc(&mut self) -> Entity {
164        let id = self.next_id;
165        self.next_id += 1;
166        let index = self.free_indices.pop().unwrap_or_else(|| {
167            let index = self.next_index;
168            self.next_index += 1;
169            index
170        });
171        let entity = Entity { id, index };
172        self.index_to_id.insert(entity);
173        Entity { id, index }
174    }
175    pub fn exists(&self, entity: Entity) -> bool {
176        self.index_to_id.vec[entity.index as usize] == Some(entity.id)
177    }
178    pub fn free(&mut self, entity: Entity) {
179        if self.exists(entity) {
180            self.index_to_id.remove(entity.index);
181            self.free_indices.push(entity.index);
182        }
183    }
184    pub fn clear(&mut self) {
185        self.next_id = 0;
186        self.next_index = 0;
187        self.index_to_id.vec.clear();
188        self.free_indices.clear();
189    }
190}
191
192#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
193#[derive(Debug, Clone)]
194pub struct ComponentTableEntry<T> {
195    data: T,
196    entity: Entity,
197}
198
199#[cfg_attr(feature = "serialize", derive(Serialize, Deserialize))]
200#[derive(Debug, Clone)]
201pub struct ComponentTableEntries<T> {
202    vec: Vec<ComponentTableEntry<T>>,
203}
204
205impl<T> Default for ComponentTableEntries<T> {
206    fn default() -> Self {
207        Self {
208            vec: Default::default(),
209        }
210    }
211}
212
213impl<T> ComponentTableEntries<T> {
214    fn entity_index_tables(&self) -> (Vec<Option<Index>>, IndexToId) {
215        if let Some(max_index) = self.vec.iter().map(|entry| entry.entity.index).max() {
216            let mut vec = Vec::with_capacity(max_index as usize + 1);
217            vec.resize(max_index as usize + 1, None);
218            let mut entity_index_to_entity_id =
219                IndexToId::new_with_capacity(max_index as usize + 1);
220            for (index, entry) in self.vec.iter().enumerate() {
221                vec[entry.entity.index as usize] = Some(index as u32);
222                entity_index_to_entity_id.insert(entry.entity);
223            }
224            (vec, entity_index_to_entity_id)
225        } else {
226            (Vec::new(), Default::default())
227        }
228    }
229    pub fn into_component_table(self) -> ComponentTable<T> {
230        let (entity_index_to_entry_index, entity_index_to_entity_id) = self.entity_index_tables();
231        ComponentTable {
232            entries: self,
233            entity_index_to_entry_index,
234            entity_index_to_entity_id,
235        }
236    }
237    pub fn clear(&mut self) {
238        self.vec.clear();
239    }
240}
241
242#[derive(Debug, Clone)]
243pub struct ComponentTable<T> {
244    entries: ComponentTableEntries<T>,
245    entity_index_to_entry_index: Vec<Option<Index>>,
246    entity_index_to_entity_id: IndexToId,
247}
248
249impl<T> Default for ComponentTable<T> {
250    fn default() -> Self {
251        ComponentTableEntries::default().into_component_table()
252    }
253}
254
255#[cfg(feature = "serialize")]
256impl<T: Serialize> Serialize for ComponentTable<T> {
257    fn serialize<S: serde::Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
258        self.entries.serialize(s)
259    }
260}
261
262#[cfg(feature = "serialize")]
263impl<'a, T: Deserialize<'a>> Deserialize<'a> for ComponentTable<T> {
264    fn deserialize<D: serde::Deserializer<'a>>(d: D) -> Result<Self, D::Error> {
265        Deserialize::deserialize(d).map(ComponentTableEntries::into_component_table)
266    }
267}
268
269impl<T> ComponentTable<T> {
270    pub fn clear(&mut self) {
271        self.entries.clear();
272        self.entity_index_to_entry_index.clear();
273        self.entity_index_to_entity_id.clear();
274    }
275    pub fn is_empty(&self) -> bool {
276        self.entries.vec.is_empty()
277    }
278    pub fn len(&self) -> usize {
279        self.entries.vec.len()
280    }
281    pub fn entries(&self) -> &ComponentTableEntries<T> {
282        &self.entries
283    }
284    pub fn insert(&mut self, entity: Entity, data: T) -> Option<T> {
285        if let Some(maybe_entry_index) = self
286            .entity_index_to_entry_index
287            .get_mut(entity.index as usize)
288        {
289            if let Some(entry_index) = maybe_entry_index {
290                debug_assert!((*entry_index as usize) < self.entries.vec.len());
291                let entry = &mut self.entries.vec[*entry_index as usize];
292                if entry.entity == entity {
293                    debug_assert!(self.entity_index_to_entity_id.contains(entity));
294                    // This entity already has a component in this table, so we return the previous
295                    // value associated with it and store the new value.
296                    Some(mem::replace(&mut entry.data, data))
297                } else {
298                    // This entity doesn't have a component in this table, but there is a stale
299                    // entry from a previous entity with the same index, which will be overwritten.
300                    entry.entity.id = entity.id;
301                    entry.data = data;
302                    self.entity_index_to_entity_id.insert(entity);
303                    None
304                }
305            } else {
306                // This entity doesn't have a component in this table, but there is an entry in
307                // `self.entity_index_to_entry_index` for the entity, so push a new component and
308                // update `self.entity_index_to_entry_index` to point to the new component.
309                *maybe_entry_index = Some(self.entries.vec.len() as u32);
310                self.entries.vec.push(ComponentTableEntry { data, entity });
311                self.entity_index_to_entity_id.insert(entity);
312                None
313            }
314        } else {
315            // There is no corresponding entry in `self.entity_index_to_entry_index`. Push the
316            // component and add an entry in `self.entity_index_to_entry_index` that points to the
317            // new component.
318            self.entity_index_to_entry_index
319                .resize(entity.index as usize, None);
320            self.entity_index_to_entry_index
321                .push(Some(self.entries.vec.len() as u32));
322            self.entries.vec.push(ComponentTableEntry { data, entity });
323            self.entity_index_to_entity_id.insert(entity);
324            None
325        }
326    }
327    pub fn contains(&self, entity: Entity) -> bool {
328        if let Some(Some(entry_index)) = self.entity_index_to_entry_index.get(entity.index as usize)
329        {
330            debug_assert!((*entry_index as usize) < self.entries.vec.len());
331            self.entries.vec[*entry_index as usize].entity.id == entity.id
332        } else {
333            false
334        }
335    }
336    pub fn remove(&mut self, entity: Entity) -> Option<T> {
337        if let Some(maybe_entry_index) = self
338            .entity_index_to_entry_index
339            .get_mut(entity.index as usize)
340        {
341            self.entity_index_to_entity_id.remove(entity.index);
342            if let Some(entry_index) = maybe_entry_index.take() {
343                debug_assert!((entry_index as usize) < self.entries.vec.len());
344                if entry_index as usize == self.entries.vec.len() - 1 {
345                    // Optimization when the component is the final one in the table, just pop it
346                    // and return it.
347                    self.entries.vec.pop().map(|entry| entry.data)
348                } else {
349                    // Move the final entry in the table over the entry to remove, and then update
350                    // the index in `self.entity_index_to_entry_index` for the moved entity.
351                    let entry = self.entries.vec.swap_remove(entry_index as usize);
352                    let moved_index = self.entries.vec[entry_index as usize].entity.index;
353                    self.entity_index_to_entry_index[moved_index as usize] = Some(entry_index);
354                    Some(entry.data)
355                }
356            } else {
357                None
358            }
359        } else {
360            debug_assert!(!self.entity_index_to_entity_id.contains(entity));
361            None
362        }
363    }
364    pub fn get(&self, entity: Entity) -> Option<&T> {
365        if let Some(Some(entry_index)) = self.entity_index_to_entry_index.get(entity.index as usize)
366        {
367            debug_assert!((*entry_index as usize) < self.entries.vec.len());
368            let entry = &self.entries.vec[*entry_index as usize];
369            if entry.entity.id == entity.id {
370                Some(&entry.data)
371            } else {
372                None
373            }
374        } else {
375            None
376        }
377    }
378    pub fn get_mut(&mut self, entity: Entity) -> Option<&mut T> {
379        if let Some(Some(entry_index)) = self.entity_index_to_entry_index.get(entity.index as usize)
380        {
381            debug_assert!((*entry_index as usize) < self.entries.vec.len());
382            let entry = &mut self.entries.vec[*entry_index as usize];
383            if entry.entity.id == entity.id {
384                Some(&mut entry.data)
385            } else {
386                None
387            }
388        } else {
389            None
390        }
391    }
392    pub fn iter(&self) -> ComponentTableIter<T> {
393        ComponentTableIter {
394            iter: self.entries.vec.iter(),
395        }
396    }
397    pub fn iter_mut(&mut self) -> ComponentTableIterMut<T> {
398        ComponentTableIterMut {
399            iter: self.entries.vec.iter_mut(),
400        }
401    }
402    pub fn entities(&self) -> Entities {
403        self.entity_index_to_entity_id.entities()
404    }
405}
406
407pub struct ComponentTableIter<'a, T> {
408    iter: slice::Iter<'a, ComponentTableEntry<T>>,
409}
410
411pub struct ComponentTableIterMut<'a, T> {
412    iter: slice::IterMut<'a, ComponentTableEntry<T>>,
413}
414
415impl<'a, T> Iterator for ComponentTableIter<'a, T> {
416    type Item = (Entity, &'a T);
417    fn next(&mut self) -> Option<Self::Item> {
418        self.iter.next().map(|entry| (entry.entity, &entry.data))
419    }
420}
421
422impl<'a, T> Iterator for ComponentTableIterMut<'a, T> {
423    type Item = (Entity, &'a mut T);
424    fn next(&mut self) -> Option<Self::Item> {
425        self.iter
426            .next()
427            .map(|entry| (entry.entity, &mut entry.data))
428    }
429}
430
431#[cfg(not(feature = "serialize"))]
432#[macro_export]
433macro_rules! declare_entity_module_types {
434    { $($component_name:ident: $component_type:ty,)* } => {
435
436        #[derive(Debug, Clone)]
437        pub struct Components {
438            $(pub $component_name: $crate::ComponentTable<$component_type>,)*
439        }
440
441        #[derive(Debug, Clone)]
442        pub struct EntityData {
443            $(pub $component_name: Option<$component_type>,)*
444        }
445
446        #[derive(Debug, Clone)]
447        pub struct EntityUpdate {
448            $(pub $component_name: Option<Option<$component_type>>,)*
449        }
450    }
451}
452
453#[cfg(feature = "serialize")]
454#[macro_export]
455macro_rules! declare_entity_module_types {
456    { $($component_name:ident: $component_type:ty,)* } => {
457
458        #[derive(Debug, Clone, $crate::serde::Serialize, $crate::serde::Deserialize)]
459        pub struct Components {
460            $(pub $component_name: $crate::ComponentTable<$component_type>,)*
461        }
462
463        #[derive(Debug, Clone, $crate::serde::Serialize, $crate::serde::Deserialize)]
464        pub struct EntityData {
465            $(pub $component_name: Option<$component_type>,)*
466        }
467
468        #[derive(Debug, Clone, $crate::serde::Serialize, $crate::serde::Deserialize)]
469        pub struct EntityUpdate {
470            $(pub $component_name: Option<Option<$component_type>>,)*
471        }
472    }
473}
474
475#[macro_export]
476macro_rules! entity_data_field_pun {
477    { $field:ident : $value:expr } => { Some($value) };
478    { $field:ident } => { Some($field) };
479}
480
481#[macro_export]
482macro_rules! entity_data {
483    { $($field:ident $(: $value:expr)?,)* .. $default:expr } => {
484        EntityData {
485            $($field : $crate::entity_data_field_pun!($field $(: $value)?),)*
486            ..$default
487        }
488    };
489    { $($field:ident $(: $value:expr)?),* $(,)? } => {
490        $crate::entity_data! {
491            $($field $(: $value)?,)*
492            ..Default::default()
493        }
494    }
495}
496
497#[macro_export]
498macro_rules! entity_update_field_pun {
499    { $field:ident : $value:expr } => { Some($value) };
500    { $field:ident } => { Some($field) };
501}
502
503#[macro_export]
504macro_rules! entity_update {
505    { $($field:ident $(: $value:expr)?,)* .. $default:expr } => {
506        EntityUpdate {
507            $($field : $crate::entity_update_field_pun!($field $(: $value)?),)*
508            ..$default
509        }
510    };
511    { $($field:ident $(: $value:expr)?),* $(,)? } => {
512        $crate::entity_update! {
513            $($field $(: $value)?,)*
514            ..Default::default()
515        }
516    }
517}
518
519#[macro_export]
520macro_rules! declare_entity_module {
521    { $module_name:ident { $($component_name:ident: $component_type:ty,)* } } => {
522        mod $module_name {
523
524            #[allow(unused_imports)]
525            use super::*;
526
527            $crate::declare_entity_module_types! {
528                $($component_name: $component_type,)*
529            }
530
531            impl Default for Components {
532                fn default() -> Self {
533                    Self {
534                        $($component_name: Default::default(),)*
535                    }
536                }
537            }
538
539            impl Default for EntityData {
540                fn default() -> Self {
541                    Self {
542                        $($component_name: None,)*
543                    }
544                }
545            }
546
547            impl Default for EntityUpdate {
548                fn default() -> Self {
549                    Self {
550                        $($component_name: None,)*
551                    }
552                }
553            }
554
555            impl Components {
556                #[allow(unused)]
557                pub fn clear(&mut self) {
558                    $(self.$component_name.clear();)*
559                }
560                #[allow(unused)]
561                pub fn remove_entity(&mut self, entity: $crate::Entity) {
562                    $(self.$component_name.remove(entity);)*
563                }
564                #[allow(unused)]
565                pub fn clone_entity_data(&self, entity: $crate::Entity) -> EntityData {
566                    EntityData {
567                        $($component_name: self.$component_name.get(entity).cloned(),)*
568                    }
569                }
570                #[allow(unused)]
571                pub fn remove_entity_data(&mut self, entity: $crate::Entity) -> EntityData {
572                    EntityData {
573                        $($component_name: self.$component_name.remove(entity),)*
574                    }
575                }
576                #[allow(unused)]
577                pub fn insert_entity_data(&mut self, entity: $crate::Entity, entity_data: EntityData) {
578                    $(if let Some(field) = entity_data.$component_name {
579                        self.$component_name.insert(entity, field);
580                    })*
581                }
582                #[allow(unused)]
583                pub fn update_entity_data(&mut self, entity: $crate::Entity, entity_data: EntityData) {
584                    $(if let Some(field) = entity_data.$component_name {
585                        self.$component_name.insert(entity, field);
586                    } else {
587                        self.$component_name.remove(entity);
588                    })*
589                }
590                #[allow(unused)]
591                pub fn apply_entity_update(&mut self, entity: $crate::Entity, entity_update: EntityUpdate) {
592                    $(match entity_update.$component_name {
593                        Some(Some(value)) => { self.$component_name.insert(entity, value); }
594                        Some(None) => { self.$component_name.remove(entity); }
595                        None => (),
596                    })*
597                }
598            }
599        }
600    }
601}
602
603#[cfg(test)]
604mod test {
605    use super::*;
606
607    #[test]
608    fn entity_alloc_remove() {
609        let mut a = EntityAllocator::default();
610        let e0 = a.alloc();
611        let e1 = a.alloc();
612        let e2 = a.alloc();
613        a.free(e1);
614        a.free(e1); // second free should be redundant
615        let e3 = a.alloc();
616        let e4 = a.alloc();
617        assert_eq!([e0.id, e1.id, e2.id, e3.id, e4.id], [0, 1, 2, 3, 4]);
618        assert_eq!(
619            [e0.index, e1.index, e2.index, e3.index, e4.index],
620            [0, 1, 2, 1, 3]
621        );
622    }
623
624    #[test]
625    fn component_table_insert_remove() {
626        let mut a = EntityAllocator::default();
627        let e0 = a.alloc();
628        let e1 = a.alloc();
629        let e2 = a.alloc();
630        let mut c = ComponentTable::default();
631        c.insert(e0, "zero".to_string());
632        c.insert(e1, "one".to_string());
633        c.insert(e2, "two".to_string());
634        assert_eq!(c.get(e0).unwrap(), "zero");
635        assert_eq!(c.get(e1).unwrap(), "one");
636        assert_eq!(c.get(e2).unwrap(), "two");
637        c.remove(e0);
638        assert_eq!(c.get(e0), None);
639        assert_eq!(c.get(e1).unwrap(), "one");
640        assert_eq!(c.get(e2).unwrap(), "two");
641        c.insert(e0, "zero again".to_string());
642        assert_eq!(c.get(e0).unwrap(), "zero again");
643        assert_eq!(c.get(e1).unwrap(), "one");
644        assert_eq!(c.get(e2).unwrap(), "two");
645        c.insert(e1, "one again".to_string());
646        *c.get_mut(e2).unwrap() = "two again".to_string();
647        assert_eq!(c.get(e0).unwrap(), "zero again");
648        assert_eq!(c.get(e1).unwrap(), "one again");
649        assert_eq!(c.get(e2).unwrap(), "two again");
650        a.free(e0);
651        let raw_entries = c
652            .entries
653            .vec
654            .iter()
655            .map(|e| e.data.clone())
656            .collect::<Vec<_>>();
657        assert_eq!(raw_entries, ["two again", "one again", "zero again"]);
658        assert_eq!(c.entity_index_to_entry_index, [Some(2), Some(1), Some(0)]);
659        let e3 = a.alloc();
660        assert_eq!(e3.index, 0);
661        assert_eq!(c.get(e3), None);
662        c.insert(e3, "three".to_string());
663        assert_eq!(c.get(e3).unwrap(), "three");
664        let raw_entries = c
665            .entries
666            .vec
667            .iter()
668            .map(|e| e.data.clone())
669            .collect::<Vec<_>>();
670        assert_eq!(raw_entries, ["two again", "one again", "three"]);
671        assert_eq!(c.entity_index_to_entry_index, [Some(2), Some(1), Some(0)]);
672    }
673
674    #[test]
675    fn declare_entity_module_macro() {
676        declare_entity_module! {
677            components {
678                coord: (i32, i32),
679                name: String,
680                health: i32,
681            }
682        }
683        use components::Components;
684        let mut entity_allocator = EntityAllocator::default();
685        let mut components = Components::default();
686        let e0 = entity_allocator.alloc();
687        let e1 = entity_allocator.alloc();
688        components.coord.insert(e0, (12, 19));
689        components.name.insert(e0, "Foo".to_string());
690        components.health.insert(e0, 42);
691        components.coord.insert(e1, (0, 0));
692        components.remove_entity(e1);
693        entity_allocator.free(e1);
694        assert!(!components.coord.contains(e1));
695        let e0_data = components.remove_entity_data(e0);
696        let e2 = entity_allocator.alloc();
697        components.insert_entity_data(e2, e0_data);
698        assert_eq!(components.name.get(e2).unwrap(), "Foo");
699    }
700
701    #[cfg(feature = "serialize")]
702    #[test]
703    fn serde() {
704        declare_entity_module! {
705            components {
706                coord: (i32, i32),
707                name: String,
708            }
709        }
710        use components::{Components, EntityData};
711        let mut entity_allocator = EntityAllocator::default();
712        let mut components = Components::default();
713        let e0 = entity_allocator.alloc();
714        components.insert_entity_data(
715            e0,
716            EntityData {
717                coord: Some((21, 42)),
718                name: Some("foo".to_string()),
719            },
720        );
721        let e1 = entity_allocator.alloc();
722        components.insert_entity_data(
723            e1,
724            EntityData {
725                coord: None,
726                name: Some("bar".to_string()),
727            },
728        );
729        let e2 = entity_allocator.alloc();
730        components.insert_entity_data(
731            e2,
732            EntityData {
733                coord: Some((2, 3)),
734                name: Some("baz".to_string()),
735            },
736        );
737        entity_allocator.free(e1);
738        components.remove_entity(e1);
739        let e3 = entity_allocator.alloc();
740        components.insert_entity_data(
741            e3,
742            EntityData {
743                coord: Some((11, 12)),
744                name: Some("qux".to_string()),
745            },
746        );
747        entity_allocator.free(e0);
748        components.remove_entity(e0);
749        let json = serde_json::to_string(&components).unwrap();
750        let deserialized: Components = serde_json::from_str(&json).unwrap();
751        assert_eq!(
752            components.coord.get(e2).unwrap(),
753            deserialized.coord.get(e2).unwrap()
754        );
755        assert_eq!(
756            components.coord.get(e3).unwrap(),
757            deserialized.coord.get(e3).unwrap()
758        );
759        assert_eq!(
760            components.name.get(e2).unwrap(),
761            deserialized.name.get(e2).unwrap()
762        );
763        assert_eq!(
764            components.name.get(e3).unwrap(),
765            deserialized.name.get(e3).unwrap()
766        );
767        assert!(!entity_allocator.exists(e0));
768        assert!(!entity_allocator.exists(e1));
769    }
770
771    #[test]
772    fn entity_data() {
773        declare_entity_module! {
774            components {
775                coord: (i32, i32),
776                name: String,
777            }
778        }
779        use components::EntityData;
780        let coord = (12, 1);
781        let no_default = entity_data! { coord };
782        let with_default = entity_data! { coord, ..Default::default() };
783        let non_punned = entity_data! { coord: (12, 1) };
784        assert_eq!(no_default.coord, with_default.coord);
785        assert_eq!(with_default.coord, non_punned.coord);
786    }
787
788    #[test]
789    fn entity_update() {
790        declare_entity_module! {
791            components {
792                coord: (i32, i32),
793                name: String,
794                solid: (),
795                age: u8,
796            }
797        }
798        use components::{Components, EntityData, EntityUpdate};
799        let mut entity_allocator = EntityAllocator::default();
800        let entity = entity_allocator.alloc();
801        let mut components = Components::default();
802        components.insert_entity_data(
803            entity,
804            entity_data! {
805                coord: (1, 2),
806                name: "bar".to_string(),
807            },
808        );
809        let name = Some("foo".to_string());
810        let update = entity_update! {
811            name,
812            age: Some(30),
813            solid: None,
814        };
815        components.apply_entity_update(entity, update);
816        let data = components.remove_entity_data(entity);
817        assert_eq!(data.name.unwrap(), "foo");
818        assert_eq!(data.age.unwrap(), 30);
819        assert_eq!(data.solid, None);
820        assert_eq!(data.coord.unwrap(), (1, 2));
821    }
822
823    #[test]
824    fn entity_iterator() {
825        fn compare_entity_iterators(x: &ComponentTable<()>) {
826            use std::collections::HashSet;
827            let via_entities = x.entities().collect::<HashSet<_>>();
828            let via_iter = x.iter().map(|(entity, _)| entity).collect::<HashSet<_>>();
829            assert_eq!(via_entities, via_iter);
830        }
831        declare_entity_module! {
832            components {
833                x: (),
834            }
835        }
836        use components::Components;
837        let mut entity_allocator = EntityAllocator::default();
838        let mut components = Components::default();
839        compare_entity_iterators(&components.x);
840        let e0 = entity_allocator.alloc();
841        let e1 = entity_allocator.alloc();
842        let e2 = entity_allocator.alloc();
843        let e3 = entity_allocator.alloc();
844        let e4 = entity_allocator.alloc();
845        components.x.insert(e0, ());
846        components.x.insert(e1, ());
847        components.x.insert(e2, ());
848        components.x.insert(e3, ());
849        components.x.insert(e4, ());
850        compare_entity_iterators(&components.x);
851        components.x.remove(e2);
852        compare_entity_iterators(&components.x);
853        components.x.insert(e2, ());
854        compare_entity_iterators(&components.x);
855        entity_allocator.free(e3);
856        let e5 = entity_allocator.alloc();
857        components.x.insert(e5, ());
858        compare_entity_iterators(&components.x);
859    }
860}