1#[cfg(feature = "serialize")]
2pub use serde; #[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 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 Some(mem::replace(&mut entry.data, data))
297 } else {
298 entry.entity.id = entity.id;
301 entry.data = data;
302 self.entity_index_to_entity_id.insert(entity);
303 None
304 }
305 } else {
306 *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 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 self.entries.vec.pop().map(|entry| entry.data)
348 } else {
349 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); 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}