1use crate::{
2 archetype::{
3 Archetype, ArchetypeColumnInfo, ArchetypeDynamicEntityColumnAccess,
4 ArchetypeEntityColumnAccess, ArchetypeEntityRowAccess, ArchetypeError,
5 },
6 bundle::{Bundle, BundleColumns},
7 component::{Component, ComponentRef, ComponentRefMut},
8 entity::Entity,
9 processor::{WorldProcessor, WorldProcessorEntityMapping},
10 query::{
11 DynamicLookupAccess, DynamicLookupIter, DynamicQueryFilter, DynamicQueryIter,
12 TypedLookupAccess, TypedLookupFetch, TypedLookupIter, TypedQueryFetch, TypedQueryIter,
13 TypedRelationLookupFetch, TypedRelationLookupIter,
14 },
15};
16use intuicio_core::{registry::Registry, types::struct_type::NativeStructBuilder};
17use intuicio_data::type_hash::TypeHash;
18use std::{
19 collections::{HashMap, HashSet, VecDeque},
20 error::Error,
21 marker::PhantomData,
22 sync::{Arc, RwLock, RwLockReadGuard},
23};
24
25#[derive(Debug, PartialEq, Eq)]
27pub enum WorldError {
28 Archetype(ArchetypeError),
30 ReachedEntityIdCapacity,
32 ReachedArchetypeIdCapacity,
34 EntityDoesNotExists { entity: Entity },
36 ArchetypeDoesNotExists { id: u32 },
38 DuplicateMutableArchetypeAccess { id: u32 },
40 EmptyColumnSet,
42}
43
44impl WorldError {
45 pub fn allow<T>(
62 input: Result<T, Self>,
63 items: impl IntoIterator<Item = Self>,
64 ok: T,
65 ) -> Result<T, Self> {
66 match input {
67 Err(error) => {
68 if items.into_iter().any(|item| error == item) {
69 Ok(ok)
70 } else {
71 Err(error)
72 }
73 }
74 result => result,
75 }
76 }
77}
78
79impl Error for WorldError {}
80
81impl From<ArchetypeError> for WorldError {
82 fn from(value: ArchetypeError) -> Self {
83 Self::Archetype(value)
84 }
85}
86
87impl std::fmt::Display for WorldError {
88 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
89 match self {
90 Self::Archetype(archetype) => write!(f, "World archetype: {}", archetype),
91 Self::ReachedEntityIdCapacity => write!(f, "Reached entity id capacity"),
92 Self::ReachedArchetypeIdCapacity => write!(f, "Reached archetype id capacity"),
93 Self::EntityDoesNotExists { entity } => {
94 write!(f, "Entity does not exists: {}", entity)
95 }
96 Self::ArchetypeDoesNotExists { id } => {
97 write!(f, "Archetype does not exists: {}", id)
98 }
99 Self::DuplicateMutableArchetypeAccess { id } => {
100 write!(f, "Trying to access mutably same archetype twice: {}", id)
101 }
102 Self::EmptyColumnSet => {
103 write!(f, "Trying to perform change on empty column set")
104 }
105 }
106 }
107}
108
109#[derive(Default)]
112struct EntityMap {
113 id_generator: u32,
114 table: Vec<(u32, Option<u32>)>,
116 reusable: Vec<Entity>,
117 size: usize,
118}
119
120impl EntityMap {
121 fn is_empty(&self) -> bool {
123 self.size == 0
124 }
125
126 fn len(&self) -> usize {
128 self.size
129 }
130
131 fn iter(&self) -> impl Iterator<Item = Entity> + '_ {
133 self.table
134 .iter()
135 .enumerate()
136 .filter_map(|(id, (generation, archetype))| {
137 if archetype.is_some() {
138 Some(unsafe { Entity::new_unchecked(id as u32, *generation) })
139 } else {
140 None
141 }
142 })
143 }
144
145 fn clear(&mut self) {
147 self.id_generator = 0;
148 self.table.clear();
149 self.reusable.clear();
150 self.size = 0;
151 }
152
153 fn acquire(&mut self) -> Result<(Entity, &mut Option<u32>), WorldError> {
160 if let Some(mut entity) = self.reusable.pop() {
161 let (generation, archetype) = &mut self.table[entity.id() as usize];
162 entity = entity.bump_generation();
163 *generation = entity.generation();
164 self.size += 1;
165 return Ok((entity, archetype));
166 }
167 if self.id_generator == u32::MAX {
168 Err(WorldError::ReachedEntityIdCapacity)
169 } else {
170 let id = self.id_generator;
171 self.id_generator += 1;
172 while self.table.len() < self.id_generator as usize {
173 if self.table.len() == self.table.capacity() {
174 self.table.reserve_exact(self.table.capacity());
175 }
176 self.table.push((0, None));
177 }
178 let (_, archetype) = &mut self.table[id as usize];
179 self.size += 1;
180 Ok((Entity::new(id, 0).unwrap(), archetype))
181 }
182 }
183
184 fn release(&mut self, entity: Entity) -> Result<u32, WorldError> {
190 if let Some((generation, archetype)) = self.table.get_mut(entity.id() as usize) {
191 if entity.generation() == *generation {
192 if let Some(archetype) = archetype.take() {
193 self.reusable.push(entity);
194 self.size -= 1;
195 Ok(archetype)
196 } else {
197 Err(WorldError::EntityDoesNotExists { entity })
198 }
199 } else {
200 Err(WorldError::EntityDoesNotExists { entity })
201 }
202 } else {
203 Err(WorldError::EntityDoesNotExists { entity })
204 }
205 }
206
207 fn get(&self, entity: Entity) -> Result<u32, WorldError> {
213 if let Some((generation, archetype)) = self.table.get(entity.id() as usize) {
214 if entity.generation() == *generation {
215 if let Some(archetype) = *archetype {
216 Ok(archetype)
217 } else {
218 Err(WorldError::EntityDoesNotExists { entity })
219 }
220 } else {
221 Err(WorldError::EntityDoesNotExists { entity })
222 }
223 } else {
224 Err(WorldError::EntityDoesNotExists { entity })
225 }
226 }
227
228 fn set(&mut self, entity: Entity, archetype_id: u32) -> Result<(), WorldError> {
234 if let Some((generation, archetype)) = self.table.get_mut(entity.id() as usize) {
235 if entity.generation() == *generation {
236 if let Some(archetype) = archetype.as_mut() {
237 *archetype = archetype_id;
238 Ok(())
239 } else {
240 Err(WorldError::EntityDoesNotExists { entity })
241 }
242 } else {
243 Err(WorldError::EntityDoesNotExists { entity })
244 }
245 } else {
246 Err(WorldError::EntityDoesNotExists { entity })
247 }
248 }
249}
250
251#[derive(Default)]
253struct ArchetypeMap {
254 id_generator: u32,
255 table: Vec<Option<Archetype>>,
257 reusable: Vec<u32>,
258}
259
260impl ArchetypeMap {
261 fn iter(&self) -> impl Iterator<Item = &Archetype> + '_ {
263 self.table.iter().filter_map(|archetype| archetype.as_ref())
264 }
265
266 fn iter_mut(&mut self) -> impl Iterator<Item = &mut Archetype> + '_ {
268 self.table
269 .iter_mut()
270 .filter_map(|archetype| archetype.as_mut())
271 }
272
273 fn clear(&mut self) {
275 self.id_generator = 0;
276 self.table.clear();
277 self.reusable.clear();
278 }
279
280 fn acquire(&mut self) -> Result<(u32, &mut Option<Archetype>), WorldError> {
286 if let Some(id) = self.reusable.pop() {
287 let archetype = &mut self.table[id as usize];
288 return Ok((id, archetype));
289 }
290 if self.id_generator == u32::MAX {
291 Err(WorldError::ReachedArchetypeIdCapacity)
292 } else {
293 let id = self.id_generator;
294 self.id_generator += 1;
295 while self.table.len() < self.id_generator as usize {
296 if self.table.len() == self.table.capacity() {
297 self.table.reserve_exact(self.table.capacity());
298 }
299 self.table.push(None);
300 }
301 let archetype = &mut self.table[id as usize];
302 Ok((id, archetype))
303 }
304 }
305
306 fn get(&self, id: u32) -> Result<&Archetype, WorldError> {
312 if let Some(archetype) = self
313 .table
314 .get(id as usize)
315 .and_then(|archetype| archetype.as_ref())
316 {
317 Ok(archetype)
318 } else {
319 Err(WorldError::ArchetypeDoesNotExists { id })
320 }
321 }
322
323 fn get_mut(&mut self, id: u32) -> Result<&mut Archetype, WorldError> {
329 if let Some(archetype) = self
330 .table
331 .get_mut(id as usize)
332 .and_then(|archetype| archetype.as_mut())
333 {
334 Ok(archetype)
335 } else {
336 Err(WorldError::ArchetypeDoesNotExists { id })
337 }
338 }
339
340 fn get_mut_two(&mut self, [a, b]: [u32; 2]) -> Result<[&mut Archetype; 2], WorldError> {
347 if a == b {
348 return Err(WorldError::DuplicateMutableArchetypeAccess { id: a });
349 }
350 if let Some(archetype) = self.table.get(a as usize) {
351 if archetype.is_none() {
352 return Err(WorldError::ArchetypeDoesNotExists { id: a });
353 }
354 } else {
355 return Err(WorldError::ArchetypeDoesNotExists { id: a });
356 }
357 if let Some(archetype) = self.table.get(b as usize) {
358 if archetype.is_none() {
359 return Err(WorldError::ArchetypeDoesNotExists { id: b });
360 }
361 } else {
362 return Err(WorldError::ArchetypeDoesNotExists { id: b });
363 }
364 if a < b {
365 let (left, right) = self.table.split_at_mut(b as usize);
366 Ok([
367 left[a as usize].as_mut().unwrap(),
368 right[0].as_mut().unwrap(),
369 ])
370 } else {
371 let (right, left) = self.table.split_at_mut(a as usize);
372 Ok([
373 left[0].as_mut().unwrap(),
374 right[b as usize].as_mut().unwrap(),
375 ])
376 }
377 }
378
379 fn find_by_columns_exact(&self, columns: &[ArchetypeColumnInfo]) -> Option<u32> {
385 for (id, archetype) in self.table.iter().enumerate() {
386 if let Some(archetype) = archetype.as_ref() {
387 if archetype.has_columns_exact(columns) {
388 return Some(id as u32);
389 }
390 }
391 }
392 None
393 }
394}
395
396#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
399enum RelationConnections<T: Component> {
400 Zero([(T, Entity); 0]),
401 One([(T, Entity); 1]),
402 More(Vec<(T, Entity)>),
403}
404
405impl<T: Component> Default for RelationConnections<T> {
406 fn default() -> Self {
407 Self::Zero(Default::default())
408 }
409}
410
411#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
413pub struct Relation<T: Component> {
414 connections: RelationConnections<T>,
415}
416
417impl<T: Component> Default for Relation<T> {
418 fn default() -> Self {
419 Self {
420 connections: Default::default(),
421 }
422 }
423}
424
425impl<T: Component> Relation<T> {
426 pub fn install_to_registry(registry: &mut Registry) {
428 registry.add_type(NativeStructBuilder::new::<Self>().build());
429 }
430
431 pub fn register_to_processor(processor: &mut WorldProcessor) {
433 processor.register_entity_remapping::<Self>(|relation, mapping| {
434 let iter = match &mut relation.connections {
435 RelationConnections::Zero(a) => a.iter_mut(),
436 RelationConnections::One(a) => a.iter_mut(),
437 RelationConnections::More(vec) => vec.iter_mut(),
438 };
439 for (_, entity) in iter {
440 *entity = mapping.remap(*entity);
441 }
442 });
443 processor.register_entity_inspector::<Self>(|relation| {
444 relation.iter().map(|(_, entity)| entity).collect()
445 });
446 processor.register_formatter::<Self>(|relation, fmt| {
447 fmt.debug_struct("Relation")
448 .field(
449 "entities",
450 &relation
451 .iter()
452 .map(|(_, entity)| entity)
453 .collect::<Vec<_>>(),
454 )
455 .finish_non_exhaustive()
456 });
457 }
458
459 pub fn register_to_processor_debug(processor: &mut WorldProcessor)
461 where
462 T: std::fmt::Debug,
463 {
464 processor.register_debug_formatter::<Self>();
465 }
466
467 pub fn new(payload: T, entity: Entity) -> Self {
469 Self::default().with(payload, entity)
470 }
471
472 pub fn with(mut self, payload: T, entity: Entity) -> Self {
474 self.add(payload, entity);
475 self
476 }
477
478 pub fn type_hash(&self) -> TypeHash {
480 TypeHash::of::<T>()
481 }
482
483 pub fn is_empty(&self) -> bool {
485 match &self.connections {
486 RelationConnections::Zero(_) => true,
487 RelationConnections::One(_) => false,
488 RelationConnections::More(vec) => vec.is_empty(),
489 }
490 }
491
492 pub fn add(&mut self, payload: T, entity: Entity) {
494 self.connections = match std::mem::take(&mut self.connections) {
495 RelationConnections::Zero(_) => RelationConnections::One([(payload, entity)]),
496 RelationConnections::One([a]) => RelationConnections::More(vec![a, (payload, entity)]),
497 RelationConnections::More(mut vec) => {
498 if let Some(index) = vec.iter().position(|item| item.1 == entity) {
499 vec[index].0 = payload;
500 } else {
501 vec.push((payload, entity));
502 }
503 RelationConnections::More(vec)
504 }
505 };
506 }
507
508 pub fn remove(&mut self, entity: Entity) {
510 self.connections = match std::mem::take(&mut self.connections) {
511 RelationConnections::Zero(a) => RelationConnections::Zero(a),
512 RelationConnections::One([a]) => {
513 if a.1 == entity {
514 RelationConnections::Zero([])
515 } else {
516 RelationConnections::One([a])
517 }
518 }
519 RelationConnections::More(mut vec) => {
520 if let Some(index) = vec.iter().position(|a| a.1 == entity) {
521 vec.swap_remove(index);
522 }
523 if vec.len() == 1 {
524 RelationConnections::One([vec.remove(0)])
525 } else if vec.is_empty() {
526 RelationConnections::Zero([])
527 } else {
528 RelationConnections::More(vec)
529 }
530 }
531 }
532 }
533
534 pub fn clear(&mut self) {
536 self.connections = Default::default();
537 }
538
539 pub fn has(&self, entity: Entity) -> bool {
541 match &self.connections {
542 RelationConnections::Zero(_) => false,
543 RelationConnections::One([a]) => a.1 == entity,
544 RelationConnections::More(vec) => vec.iter().any(|(_, e)| *e == entity),
545 }
546 }
547
548 pub fn payload(&self, entity: Entity) -> Option<&T> {
550 match &self.connections {
551 RelationConnections::Zero(_) => None,
552 RelationConnections::One([a]) => {
553 if a.1 == entity {
554 Some(&a.0)
555 } else {
556 None
557 }
558 }
559 RelationConnections::More(vec) => vec
560 .iter()
561 .find_map(|(p, e)| if *e == entity { Some(p) } else { None }),
562 }
563 }
564
565 pub fn payload_mut(&mut self, entity: Entity) -> Option<&mut T> {
567 match &mut self.connections {
568 RelationConnections::Zero(_) => None,
569 RelationConnections::One([a]) => {
570 if a.1 == entity {
571 Some(&mut a.0)
572 } else {
573 None
574 }
575 }
576 RelationConnections::More(vec) => vec
577 .iter_mut()
578 .find_map(|(p, e)| if *e == entity { Some(p) } else { None }),
579 }
580 }
581
582 pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
584 match &self.connections {
585 RelationConnections::Zero(a) => a.iter(),
586 RelationConnections::One(a) => a.iter(),
587 RelationConnections::More(vec) => vec.iter(),
588 }
589 .map(|(_, e)| *e)
590 }
591
592 pub fn iter(&self) -> impl Iterator<Item = (&T, Entity)> {
594 match &self.connections {
595 RelationConnections::Zero(a) => a.iter(),
596 RelationConnections::One(a) => a.iter(),
597 RelationConnections::More(vec) => vec.iter(),
598 }
599 .map(|(p, e)| (p, *e))
600 }
601
602 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&mut T, Entity)> {
604 match &mut self.connections {
605 RelationConnections::Zero(a) => a.iter_mut(),
606 RelationConnections::One(a) => a.iter_mut(),
607 RelationConnections::More(vec) => vec.iter_mut(),
608 }
609 .map(|(p, e)| (p, *e))
610 }
611}
612
613pub struct RelationsTraverseIter<'a, const LOCKING: bool, T: Component> {
615 world: &'a World,
616 incoming: bool,
617 stack: VecDeque<(Option<Entity>, Entity)>,
618 visited: HashSet<Entity>,
619 _phantom: PhantomData<fn() -> T>,
620}
621
622impl<const LOCKING: bool, T: Component> Iterator for RelationsTraverseIter<'_, LOCKING, T> {
623 type Item = (Entity, Entity);
624
625 fn next(&mut self) -> Option<Self::Item> {
626 while let Some((from, to)) = self.stack.pop_front() {
627 if self.visited.contains(&to) {
628 continue;
629 }
630 self.visited.insert(to);
631 if self.incoming {
632 for (from, _, to) in self.world.relations_incomming::<LOCKING, T>(to) {
633 if self.stack.len() == self.stack.capacity() {
634 self.stack.reserve_exact(self.stack.capacity());
635 }
636 self.stack.push_back((Some(from), to));
637 }
638 } else {
639 for (from, _, to) in self.world.relations_outgoing::<LOCKING, T>(to) {
640 if self.stack.len() == self.stack.capacity() {
641 self.stack.reserve_exact(self.stack.capacity());
642 }
643 self.stack.push_back((Some(from), to));
644 }
645 }
646 return Some((from.unwrap_or_default(), to));
647 }
648 None
649 }
650}
651
652#[derive(Default, Clone)]
654pub struct WorldChanges {
655 table: HashMap<Entity, Vec<TypeHash>>,
656}
657
658impl WorldChanges {
659 pub fn clear(&mut self) {
664 self.table.clear();
665 }
666
667 pub fn has_entity(&self, entity: Entity) -> bool {
675 self.table.contains_key(&entity)
676 }
677
678 pub fn has_entity_component<T>(&self, entity: Entity) -> bool {
689 self.has_entity_component_raw(entity, TypeHash::of::<T>())
690 }
691
692 pub fn has_entity_component_raw(&self, entity: Entity, type_hash: TypeHash) -> bool {
701 self.table
702 .get(&entity)
703 .map(|components| components.contains(&type_hash))
704 .unwrap_or_default()
705 }
706
707 pub fn has_component<T>(&self) -> bool {
715 self.has_component_raw(TypeHash::of::<T>())
716 }
717
718 pub fn has_component_raw(&self, type_hash: TypeHash) -> bool {
726 self.table
727 .values()
728 .any(|components| components.contains(&type_hash))
729 }
730
731 pub fn iter(&self) -> impl Iterator<Item = (Entity, &[TypeHash])> {
736 self.table
737 .iter()
738 .map(|(entity, components)| (*entity, components.as_slice()))
739 }
740
741 pub fn iter_of<T>(&self) -> impl Iterator<Item = Entity> + '_ {
749 self.iter_of_raw(TypeHash::of::<T>())
750 }
751
752 pub fn iter_of_raw(&self, type_hash: TypeHash) -> impl Iterator<Item = Entity> + '_ {
760 self.table
761 .iter()
762 .filter(move |(_, components)| components.contains(&type_hash))
763 .map(|(entity, _)| *entity)
764 }
765}
766
767pub struct World {
770 pub new_archetype_capacity: usize,
773 entities: EntityMap,
774 archetypes: ArchetypeMap,
775 added: WorldChanges,
776 removed: WorldChanges,
777 updated: Arc<RwLock<WorldChanges>>,
778}
779
780impl Default for World {
781 fn default() -> Self {
782 World {
783 new_archetype_capacity: 128,
784 entities: Default::default(),
785 archetypes: Default::default(),
786 added: Default::default(),
787 removed: Default::default(),
788 updated: Default::default(),
789 }
790 }
791}
792
793impl World {
794 #[inline]
795 pub fn with_new_archetype_capacity(mut self, value: usize) -> Self {
796 self.new_archetype_capacity = value;
797 self
798 }
799
800 #[inline]
801 pub fn is_empty(&self) -> bool {
802 self.entities.is_empty()
803 }
804
805 #[inline]
806 pub fn len(&self) -> usize {
807 self.entities.len()
808 }
809
810 #[inline]
811 pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
812 self.entities.iter()
813 }
814
815 #[inline]
816 pub fn entity_by_index(&self, mut index: usize) -> Option<Entity> {
817 for archetype in self.archetypes() {
818 if index >= archetype.len() {
819 index -= archetype.len();
820 continue;
821 }
822 return archetype.entities().get(index);
823 }
824 None
825 }
826
827 #[inline]
828 pub(crate) fn entity_archetype_id(&self, entity: Entity) -> Result<u32, WorldError> {
829 self.entities.get(entity)
830 }
831
832 #[inline]
833 pub fn archetypes(&self) -> impl Iterator<Item = &Archetype> {
834 self.archetypes.iter()
835 }
836
837 #[inline]
838 pub fn archetypes_mut(&mut self) -> impl Iterator<Item = &mut Archetype> {
839 self.archetypes.iter_mut()
840 }
841
842 #[inline]
843 pub(crate) fn archetype_by_id(&self, id: u32) -> Result<&Archetype, WorldError> {
844 self.archetypes.get(id)
845 }
846
847 pub fn added(&self) -> &WorldChanges {
848 &self.added
849 }
850
851 pub fn removed(&self) -> &WorldChanges {
852 &self.removed
853 }
854
855 pub fn updated(&self) -> Option<RwLockReadGuard<WorldChanges>> {
856 self.updated.try_read().ok()
857 }
858
859 pub fn entity_did_changed(&self, entity: Entity) -> bool {
860 self.added.has_entity(entity)
861 || self.removed.has_entity(entity)
862 || self
863 .updated
864 .try_read()
865 .ok()
866 .map(|updated| updated.has_entity(entity))
867 .unwrap_or_default()
868 }
869
870 pub fn component_did_changed<T>(&self) -> bool {
871 self.component_did_changed_raw(TypeHash::of::<T>())
872 }
873
874 pub fn component_did_changed_raw(&self, type_hash: TypeHash) -> bool {
875 self.added.has_component_raw(type_hash)
876 || self.removed.has_component_raw(type_hash)
877 || self
878 .updated
879 .try_read()
880 .ok()
881 .map(|updated| updated.has_component_raw(type_hash))
882 .unwrap_or_default()
883 }
884
885 pub fn entity_component_did_changed<T>(&self, entity: Entity) -> bool {
886 self.entity_component_did_changed_raw(entity, TypeHash::of::<T>())
887 }
888
889 pub fn entity_component_did_changed_raw(&self, entity: Entity, type_hash: TypeHash) -> bool {
890 self.added.has_entity_component_raw(entity, type_hash)
891 || self.removed.has_entity_component_raw(entity, type_hash)
892 || self
893 .updated
894 .try_read()
895 .ok()
896 .map(|updated| updated.has_entity_component_raw(entity, type_hash))
897 .unwrap_or_default()
898 }
899
900 pub fn update<T>(&self, entity: Entity) {
901 self.update_raw(entity, TypeHash::of::<T>());
902 }
903
904 pub fn update_raw(&self, entity: Entity, type_hash: TypeHash) {
905 if let Ok(mut updated) = self.updated.try_write() {
906 let components = updated.table.entry(entity).or_default();
907 if !components.contains(&type_hash) {
908 components.push(type_hash);
909 }
910 }
911 }
912
913 pub fn clear_changes(&mut self) {
914 self.added.clear();
915 self.removed.clear();
916 if let Ok(mut updated) = self.updated.try_write() {
917 updated.clear();
918 }
919 }
920
921 #[inline]
922 pub fn clear(&mut self) {
923 self.clear_changes();
924 self.archetypes.clear();
925 self.entities.clear();
926 }
927
928 pub fn spawn(&mut self, bundle: impl Bundle) -> Result<Entity, WorldError> {
929 let bundle_columns = bundle.columns();
930 if bundle_columns.is_empty() {
931 return Err(WorldError::EmptyColumnSet);
932 }
933 let bundle_types = bundle_columns
934 .iter()
935 .map(|column| column.type_hash())
936 .collect::<Vec<_>>();
937 let (entity, id) = self.entities.acquire()?;
938 let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&bundle_columns)
939 {
940 *id = Some(archetype_id);
941 archetype_id
942 } else {
943 let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
944 Ok(result) => result,
945 Err(error) => {
946 self.entities.release(entity)?;
947 return Err(error);
948 }
949 };
950 let archetype = match Archetype::new(bundle_columns, self.new_archetype_capacity) {
951 Ok(result) => result,
952 Err(error) => {
953 self.entities.release(entity)?;
954 return Err(error.into());
955 }
956 };
957 *archetype_slot = Some(archetype);
958 *id = Some(archetype_id);
959 archetype_id
960 };
961 let archetype = match self.archetypes.get_mut(id) {
962 Ok(result) => result,
963 Err(error) => {
964 self.entities.release(entity)?;
965 return Err(error);
966 }
967 };
968 match archetype.insert(entity, bundle) {
969 Ok(_) => {
970 self.added
971 .table
972 .entry(entity)
973 .or_default()
974 .extend(bundle_types);
975 Ok(entity)
976 }
977 Err(error) => {
978 self.entities.release(entity)?;
979 Err(error.into())
980 }
981 }
982 }
983
984 pub unsafe fn spawn_uninitialized<T: BundleColumns>(
986 &mut self,
987 ) -> Result<(Entity, ArchetypeEntityRowAccess), WorldError> {
988 unsafe { self.spawn_uninitialized_raw(T::columns_static()) }
989 }
990
991 pub unsafe fn spawn_uninitialized_raw(
993 &mut self,
994 columns: Vec<ArchetypeColumnInfo>,
995 ) -> Result<(Entity, ArchetypeEntityRowAccess), WorldError> {
996 if columns.is_empty() {
997 return Err(WorldError::EmptyColumnSet);
998 }
999 let bundle_types = columns
1000 .iter()
1001 .map(|column| column.type_hash())
1002 .collect::<Vec<_>>();
1003 let (entity, id) = self.entities.acquire()?;
1004 let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1005 *id = Some(archetype_id);
1006 archetype_id
1007 } else {
1008 let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
1009 Ok(result) => result,
1010 Err(error) => {
1011 self.entities.release(entity)?;
1012 return Err(error);
1013 }
1014 };
1015 let archetype = match Archetype::new(columns, self.new_archetype_capacity) {
1016 Ok(result) => result,
1017 Err(error) => {
1018 self.entities.release(entity)?;
1019 return Err(error.into());
1020 }
1021 };
1022 *archetype_slot = Some(archetype);
1023 *id = Some(archetype_id);
1024 archetype_id
1025 };
1026 let archetype = match self.archetypes.get_mut(id) {
1027 Ok(result) => result,
1028 Err(error) => {
1029 self.entities.release(entity)?;
1030 return Err(error);
1031 }
1032 };
1033 match archetype.add(entity) {
1034 Ok(result) => {
1035 self.added
1036 .table
1037 .entry(entity)
1038 .or_default()
1039 .extend(bundle_types);
1040 Ok((entity, result))
1041 }
1042 Err(error) => {
1043 self.entities.release(entity)?;
1044 Err(error.into())
1045 }
1046 }
1047 }
1048
1049 pub fn despawn(&mut self, entity: Entity) -> Result<(), WorldError> {
1050 let id = self.entities.release(entity)?;
1051 let archetype = self.archetypes.get_mut(id).unwrap();
1052 match archetype.remove(entity) {
1053 Ok(_) => {
1054 self.removed
1055 .table
1056 .entry(entity)
1057 .or_default()
1058 .extend(archetype.columns().map(|column| column.type_hash()));
1059 Ok(())
1060 }
1061 Err(error) => {
1062 self.entities.acquire()?;
1063 Err(error.into())
1064 }
1065 }
1066 }
1067
1068 pub unsafe fn despawn_uninitialized(&mut self, entity: Entity) -> Result<(), WorldError> {
1070 let id = self.entities.release(entity)?;
1071 let archetype = self.archetypes.get_mut(id).unwrap();
1072 match unsafe { archetype.remove_uninitialized(entity) } {
1073 Ok(_) => {
1074 self.removed
1075 .table
1076 .entry(entity)
1077 .or_default()
1078 .extend(archetype.columns().map(|column| column.type_hash()));
1079 Ok(())
1080 }
1081 Err(error) => {
1082 self.entities.acquire()?;
1083 Err(error.into())
1084 }
1085 }
1086 }
1087
1088 pub fn insert(&mut self, entity: Entity, bundle: impl Bundle) -> Result<(), WorldError> {
1089 let bundle_columns = bundle.columns();
1090 if bundle_columns.is_empty() {
1091 return Err(WorldError::EmptyColumnSet);
1092 }
1093 let bundle_types = bundle_columns
1094 .iter()
1095 .map(|column| column.type_hash())
1096 .collect::<Vec<_>>();
1097 let old_id = self.entities.get(entity)?;
1098 let mut new_columns = self
1099 .archetypes
1100 .get_mut(old_id)?
1101 .columns()
1102 .cloned()
1103 .collect::<Vec<_>>();
1104 for column in bundle_columns {
1105 if !new_columns
1106 .iter()
1107 .any(|c| c.type_hash() == column.type_hash())
1108 {
1109 new_columns.push(column);
1110 }
1111 }
1112 if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
1113 if new_id == old_id {
1114 return Ok(());
1115 }
1116 let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
1117 let access = old_archetype.transfer(new_archetype, entity)?;
1118 bundle.initialize_into(&access);
1119 self.entities.set(entity, new_id)?;
1120 } else {
1121 let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1122 let access = self
1123 .archetypes
1124 .get_mut(old_id)
1125 .unwrap()
1126 .transfer(&mut archetype, entity)?;
1127 bundle.initialize_into(&access);
1128 drop(access);
1129 let (new_id, archetype_slot) = self.archetypes.acquire()?;
1130 *archetype_slot = Some(archetype);
1131 self.entities.set(entity, new_id)?;
1132 }
1133 self.added
1134 .table
1135 .entry(entity)
1136 .or_default()
1137 .extend(bundle_types);
1138 Ok(())
1139 }
1140
1141 pub fn remove<T: BundleColumns>(&mut self, entity: Entity) -> Result<(), WorldError> {
1142 self.remove_raw(entity, T::columns_static())
1143 }
1144
1145 pub fn remove_raw(
1146 &mut self,
1147 entity: Entity,
1148 columns: Vec<ArchetypeColumnInfo>,
1149 ) -> Result<(), WorldError> {
1150 if columns.is_empty() {
1151 return Err(WorldError::EmptyColumnSet);
1152 }
1153 let bundle_types = columns
1154 .iter()
1155 .map(|column| column.type_hash())
1156 .collect::<Vec<_>>();
1157 let old_id = self.entities.get(entity)?;
1158 let mut new_columns = self
1159 .archetypes
1160 .get_mut(old_id)?
1161 .columns()
1162 .cloned()
1163 .collect::<Vec<_>>();
1164 let despawn = new_columns.is_empty();
1165 for column in columns {
1166 if let Some(index) = new_columns
1167 .iter()
1168 .position(|c| c.type_hash() == column.type_hash())
1169 {
1170 new_columns.swap_remove(index);
1171 }
1172 }
1173 if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
1174 if new_id == old_id {
1175 return Ok(());
1176 }
1177 let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
1178 old_archetype.transfer(new_archetype, entity)?;
1179 self.entities.set(entity, new_id)?;
1180 } else {
1181 let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1182 self.archetypes
1183 .get_mut(old_id)
1184 .unwrap()
1185 .transfer(&mut archetype, entity)?;
1186 let (new_id, archetype_slot) = self.archetypes.acquire()?;
1187 *archetype_slot = Some(archetype);
1188 self.entities.set(entity, new_id)?;
1189 }
1190 if despawn {
1191 let _ = self.entities.release(entity);
1192 }
1193 self.removed
1194 .table
1195 .entry(entity)
1196 .or_default()
1197 .extend(bundle_types);
1198 Ok(())
1199 }
1200
1201 pub fn merge<const LOCKING: bool>(
1202 &mut self,
1203 mut other: Self,
1204 processor: &WorldProcessor,
1205 ) -> Result<(), WorldError> {
1206 let mut mappings = HashMap::<_, _>::with_capacity(other.len());
1207 let mut archetype_offsets = Vec::with_capacity(other.archetypes().count());
1208 for archetype_from in other.archetypes_mut() {
1209 let columns = archetype_from.columns().cloned().collect::<Vec<_>>();
1210 let archetype_id =
1211 if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1212 archetype_id
1213 } else {
1214 let (archetype_id, archetype_slot) = self.archetypes.acquire()?;
1215 let archetype = Archetype::new(columns.clone(), self.new_archetype_capacity)?;
1216 *archetype_slot = Some(archetype);
1217 archetype_id
1218 };
1219 let archetype = self.archetypes.get_mut(archetype_id)?;
1220 let offset = archetype.len();
1221 let entities_from = archetype_from.entities().iter().collect::<Vec<_>>();
1222 for entity_from in entities_from {
1223 let (entity, access) = unsafe { self.spawn_uninitialized_raw(columns.clone())? };
1224 let access_from = match archetype_from.row::<LOCKING>(entity_from) {
1225 Ok(access_from) => access_from,
1226 Err(error) => {
1227 drop(access);
1228 unsafe { self.despawn_uninitialized(entity)? };
1229 return Err(error.into());
1230 }
1231 };
1232 for column in &columns {
1233 unsafe {
1234 let data = access.data(column.type_hash()).unwrap();
1235 let data_from = access_from.data(column.type_hash()).unwrap();
1236 data.copy_from(data_from, column.layout().size());
1237 }
1238 }
1239 mappings.insert(entity_from, entity);
1240 }
1241 archetype_offsets.push((columns, offset));
1242 unsafe { archetype_from.clear_uninitialized() };
1243 }
1244 for (columns, offset) in archetype_offsets {
1245 if let Some(id) = self.archetypes.find_by_columns_exact(&columns) {
1246 let archetype = self.archetype_by_id(id)?;
1247 for column in archetype.columns() {
1248 let access = archetype.dynamic_column::<LOCKING>(column.type_hash(), true)?;
1249 for index in offset..archetype.len() {
1250 unsafe {
1251 processor.remap_entities_raw(
1252 column.type_hash(),
1253 access.data(index)?,
1254 WorldProcessorEntityMapping::new(&mappings),
1255 );
1256 }
1257 }
1258 }
1259 }
1260 }
1261 Ok(())
1262 }
1263
1264 pub fn has_entity(&self, entity: Entity) -> bool {
1265 self.entities.get(entity).is_ok()
1266 }
1267
1268 pub fn has_entity_component<T: Component>(&self, entity: Entity) -> bool {
1269 self.has_entity_component_raw(entity, TypeHash::of::<T>())
1270 }
1271
1272 pub fn has_entity_component_raw(&self, entity: Entity, component: TypeHash) -> bool {
1273 self.entities
1274 .get(entity)
1275 .and_then(|index| self.archetypes.get(index))
1276 .map(|archetype| archetype.has_type(component))
1277 .unwrap_or_default()
1278 }
1279
1280 pub fn has_component<T: Component>(&self) -> bool {
1281 self.has_component_raw(TypeHash::of::<T>())
1282 }
1283
1284 pub fn has_component_raw(&self, component: TypeHash) -> bool {
1285 self.archetypes
1286 .iter()
1287 .any(|archetype| archetype.has_type(component) && !archetype.is_empty())
1288 }
1289
1290 pub fn find_by<const LOCKING: bool, T: Component + PartialEq>(
1291 &self,
1292 data: &T,
1293 ) -> Option<Entity> {
1294 for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1295 if component == data {
1296 return Some(entity);
1297 }
1298 }
1299 None
1300 }
1301
1302 pub fn find_with<const LOCKING: bool, T: Component>(
1303 &self,
1304 f: impl Fn(&T) -> bool,
1305 ) -> Option<Entity> {
1306 for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1307 if f(component) {
1308 return Some(entity);
1309 }
1310 }
1311 None
1312 }
1313
1314 pub fn component<const LOCKING: bool, T: Component>(
1315 &self,
1316 entity: Entity,
1317 ) -> Result<ComponentRef<LOCKING, T>, WorldError> {
1318 Ok(ComponentRef {
1319 inner: self.get::<LOCKING, T>(entity, false)?,
1320 })
1321 }
1322
1323 pub fn component_mut<const LOCKING: bool, T: Component>(
1324 &self,
1325 entity: Entity,
1326 ) -> Result<ComponentRefMut<LOCKING, T>, WorldError> {
1327 Ok(ComponentRefMut {
1328 inner: self.get::<LOCKING, T>(entity, true)?,
1329 })
1330 }
1331
1332 pub fn get<const LOCKING: bool, T: Component>(
1333 &self,
1334 entity: Entity,
1335 unique: bool,
1336 ) -> Result<ArchetypeEntityColumnAccess<LOCKING, T>, WorldError> {
1337 Ok(self
1338 .archetypes
1339 .get(self.entities.get(entity)?)?
1340 .entity::<LOCKING, T>(entity, unique)?)
1341 }
1342
1343 pub fn dynamic_get<const LOCKING: bool>(
1344 &self,
1345 type_hash: TypeHash,
1346 entity: Entity,
1347 unique: bool,
1348 ) -> Result<ArchetypeDynamicEntityColumnAccess<LOCKING>, WorldError> {
1349 Ok(self
1350 .archetypes
1351 .get(self.entities.get(entity)?)?
1352 .dynamic_entity::<LOCKING>(type_hash, entity, unique)?)
1353 }
1354
1355 pub fn row<const LOCKING: bool>(
1356 &self,
1357 entity: Entity,
1358 ) -> Result<ArchetypeEntityRowAccess, WorldError> {
1359 Ok(self
1360 .archetypes
1361 .get(self.entities.get(entity)?)?
1362 .row::<LOCKING>(entity)?)
1363 }
1364
1365 pub fn entity<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1366 &'a self,
1367 entity: Entity,
1368 ) -> Option<Fetch::Value> {
1369 self.lookup_access::<LOCKING, Fetch>().access(entity)
1372 }
1373
1374 pub fn query<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>>(
1375 &'a self,
1376 ) -> TypedQueryIter<'a, LOCKING, Fetch> {
1377 TypedQueryIter::new(self)
1378 }
1379
1380 pub fn dynamic_query<'a, const LOCKING: bool>(
1381 &'a self,
1382 filter: &DynamicQueryFilter,
1383 ) -> DynamicQueryIter<'a, LOCKING> {
1384 DynamicQueryIter::new(filter, self)
1385 }
1386
1387 pub fn lookup<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1388 &'a self,
1389 entities: impl IntoIterator<Item = Entity> + 'a,
1390 ) -> TypedLookupIter<'a, LOCKING, Fetch> {
1391 TypedLookupIter::new(self, entities)
1392 }
1393
1394 pub fn lookup_access<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1395 &'a self,
1396 ) -> TypedLookupAccess<'a, LOCKING, Fetch> {
1397 TypedLookupAccess::new(self)
1398 }
1399
1400 pub fn lookup_one<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1401 &'a self,
1402 entity: Entity,
1403 ) -> Option<Fetch::ValueOne> {
1404 Fetch::fetch_one(self, entity)
1405 }
1406
1407 pub fn dynamic_lookup<'a, const LOCKING: bool>(
1408 &'a self,
1409 filter: &DynamicQueryFilter,
1410 entities: impl IntoIterator<Item = Entity> + 'a,
1411 ) -> DynamicLookupIter<'a, LOCKING> {
1412 DynamicLookupIter::new(filter, self, entities)
1413 }
1414
1415 pub fn dynamic_lookup_access<'a, const LOCKING: bool>(
1416 &'a self,
1417 filter: &DynamicQueryFilter,
1418 ) -> DynamicLookupAccess<'a, LOCKING> {
1419 DynamicLookupAccess::new(filter, self)
1420 }
1421
1422 pub fn relate<const LOCKING: bool, T: Component>(
1423 &mut self,
1424 payload: T,
1425 from: Entity,
1426 to: Entity,
1427 ) -> Result<(), WorldError> {
1428 if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1429 if let Some(relation) = relation.write() {
1430 relation.add(payload, to);
1431 }
1432 return Ok(());
1433 }
1434 self.insert(from, (Relation::<T>::new(payload, to),))
1435 }
1436
1437 pub fn relate_one<const LOCKING: bool, T: Component>(
1438 &mut self,
1439 payload: T,
1440 from: Entity,
1441 to: Entity,
1442 ) -> Result<(), WorldError> {
1443 if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1444 if let Some(relation) = relation.write() {
1445 relation.clear();
1446 relation.add(payload, to);
1447 }
1448 return Ok(());
1449 }
1450 self.insert(from, (Relation::<T>::new(payload, to),))
1451 }
1452
1453 pub fn relate_pair<const LOCKING: bool, I: Component, O: Component>(
1454 &mut self,
1455 payload_incoming: I,
1456 payload_outgoing: O,
1457 from: Entity,
1458 to: Entity,
1459 ) -> Result<(), WorldError> {
1460 self.relate::<LOCKING, _>(payload_outgoing, from, to)?;
1461 self.relate::<LOCKING, _>(payload_incoming, to, from)?;
1462 Ok(())
1463 }
1464
1465 pub fn unrelate<const LOCKING: bool, T: Component>(
1466 &mut self,
1467 from: Entity,
1468 to: Entity,
1469 ) -> Result<(), WorldError> {
1470 let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1471 if let Some(relation) = relation.write() {
1472 relation.remove(to);
1473 relation.is_empty()
1474 } else {
1475 false
1476 }
1477 } else {
1478 false
1479 };
1480 if remove {
1481 self.remove::<(Relation<T>,)>(from)?;
1482 }
1483 Ok(())
1484 }
1485
1486 pub fn unrelate_pair<const LOCKING: bool, I: Component, O: Component>(
1487 &mut self,
1488 from: Entity,
1489 to: Entity,
1490 ) -> Result<(), WorldError> {
1491 self.unrelate::<LOCKING, O>(from, to)?;
1492 self.unrelate::<LOCKING, I>(to, from)?;
1493 Ok(())
1494 }
1495
1496 pub fn unrelate_any<const LOCKING: bool, T: Component>(
1497 &mut self,
1498 entity: Entity,
1499 ) -> Result<(), WorldError> {
1500 let to_remove = self
1501 .query::<LOCKING, (Entity, &mut Relation<T>)>()
1502 .filter_map(|(e, relation)| {
1503 relation.remove(entity);
1504 if relation.is_empty() { Some(e) } else { None }
1505 })
1506 .collect::<Vec<_>>();
1507 for entity in to_remove {
1508 self.remove::<(Relation<T>,)>(entity)?;
1509 }
1510 Ok(())
1511 }
1512
1513 pub fn unrelate_all<const LOCKING: bool, T: Component>(
1514 &mut self,
1515 entity: Entity,
1516 ) -> Result<(), WorldError> {
1517 let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(entity, true) {
1518 if let Some(relation) = relation.write() {
1519 relation.clear();
1520 relation.is_empty()
1521 } else {
1522 false
1523 }
1524 } else {
1525 false
1526 };
1527 if remove {
1528 self.remove::<(Relation<T>,)>(entity)?;
1529 }
1530 Ok(())
1531 }
1532
1533 pub fn has_relation<const LOCKING: bool, T: Component>(
1534 &self,
1535 from: Entity,
1536 to: Entity,
1537 ) -> bool {
1538 self.get::<LOCKING, Relation<T>>(from, false)
1539 .ok()
1540 .and_then(|relation| Some(relation.read()?.has(to)))
1541 .unwrap_or_default()
1542 }
1543
1544 pub fn relations<const LOCKING: bool, T: Component>(
1545 &self,
1546 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1547 self.query::<LOCKING, (Entity, &Relation<T>)>()
1548 .flat_map(|(from, relation)| {
1549 relation
1550 .iter()
1551 .map(move |(payload, to)| (from, payload, to))
1552 })
1553 }
1554
1555 pub fn relations_mut<const LOCKING: bool, T: Component>(
1556 &self,
1557 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1558 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1559 .flat_map(|(from, relation)| {
1560 relation
1561 .iter_mut()
1562 .map(move |(payload, to)| (from, payload, to))
1563 })
1564 }
1565
1566 pub fn relations_outgoing<const LOCKING: bool, T: Component>(
1567 &self,
1568 from: Entity,
1569 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1570 self.query::<LOCKING, (Entity, &Relation<T>)>()
1571 .filter(move |(entity, _)| *entity == from)
1572 .flat_map(|(from, relation)| {
1573 relation
1574 .iter()
1575 .map(move |(payload, to)| (from, payload, to))
1576 })
1577 }
1578
1579 pub fn relations_outgoing_mut<const LOCKING: bool, T: Component>(
1580 &self,
1581 from: Entity,
1582 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1583 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1584 .filter(move |(entity, _)| *entity == from)
1585 .flat_map(|(from, relation)| {
1586 relation
1587 .iter_mut()
1588 .map(move |(payload, to)| (from, payload, to))
1589 })
1590 }
1591
1592 pub fn relations_incomming<const LOCKING: bool, T: Component>(
1593 &self,
1594 to: Entity,
1595 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1596 self.query::<LOCKING, (Entity, &Relation<T>)>()
1597 .flat_map(move |(from, relation)| {
1598 relation
1599 .iter()
1600 .filter(move |(_, entity)| *entity == to)
1601 .map(move |(payload, to)| (from, payload, to))
1602 })
1603 }
1604
1605 pub fn relations_incomming_mut<const LOCKING: bool, T: Component>(
1606 &self,
1607 to: Entity,
1608 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1609 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1610 .flat_map(move |(from, relation)| {
1611 relation
1612 .iter_mut()
1613 .filter(move |(_, entity)| *entity == to)
1614 .map(move |(payload, to)| (from, payload, to))
1615 })
1616 }
1617
1618 pub fn traverse_outgoing<const LOCKING: bool, T: Component>(
1619 &self,
1620 entities: impl IntoIterator<Item = Entity>,
1621 ) -> RelationsTraverseIter<LOCKING, T> {
1622 RelationsTraverseIter {
1623 world: self,
1624 incoming: false,
1625 stack: entities.into_iter().map(|entity| (None, entity)).collect(),
1626 visited: Default::default(),
1627 _phantom: Default::default(),
1628 }
1629 }
1630
1631 pub fn traverse_incoming<const LOCKING: bool, T: Component>(
1632 &self,
1633 entities: impl IntoIterator<Item = Entity>,
1634 ) -> RelationsTraverseIter<LOCKING, T> {
1635 RelationsTraverseIter {
1636 world: self,
1637 incoming: true,
1638 stack: entities.into_iter().map(|entity| (None, entity)).collect(),
1639 visited: Default::default(),
1640 _phantom: Default::default(),
1641 }
1642 }
1643
1644 pub fn relation_lookup<'a, const LOCKING: bool, Fetch: TypedRelationLookupFetch<'a>>(
1645 &'a self,
1646 entity: Entity,
1647 ) -> TypedRelationLookupIter<'a, Fetch> {
1648 TypedRelationLookupIter::new(self, entity)
1649 }
1650}
1651
1652#[cfg(test)]
1653mod tests {
1654 use super::*;
1655 use crate::{
1656 commands::{CommandBuffer, DespawnCommand},
1657 query::{Exclude, Include, Update},
1658 };
1659 use std::{
1660 sync::{Arc, RwLock},
1661 thread::spawn,
1662 time::{Duration, Instant},
1663 };
1664
1665 #[test]
1666 fn test_world_changes() {
1667 let mut world = World::default();
1668 assert!(world.is_empty());
1669 assert!(world.spawn(()).is_err());
1670
1671 let (entity, row) = unsafe { world.spawn_uninitialized::<(u8, u16, u32)>().unwrap() };
1672 assert_eq!(entity, Entity::new(0, 0).unwrap());
1673 unsafe { row.initialize(1u8).unwrap() };
1674 unsafe { row.initialize(2u16).unwrap() };
1675 unsafe { row.initialize(3u32).unwrap() };
1676 assert_eq!(*row.read::<u8>().unwrap(), 1);
1677 assert_eq!(*row.read::<u16>().unwrap(), 2);
1678 assert_eq!(*row.read::<u32>().unwrap(), 3);
1679 drop(row);
1680 world.despawn(entity).unwrap();
1681 assert!(world.is_empty());
1682
1683 let entity = world.spawn((1u8, 2u16, 3u32)).unwrap();
1684 assert_eq!(entity, Entity::new(0, 1).unwrap());
1685 assert_eq!(
1686 *world
1687 .get::<true, u8>(entity, false)
1688 .unwrap()
1689 .read()
1690 .unwrap(),
1691 1
1692 );
1693 assert_eq!(
1694 *world
1695 .get::<true, u16>(entity, false)
1696 .unwrap()
1697 .read()
1698 .unwrap(),
1699 2
1700 );
1701 assert_eq!(
1702 *world
1703 .get::<true, u32>(entity, false)
1704 .unwrap()
1705 .read()
1706 .unwrap(),
1707 3
1708 );
1709 assert!(world.get::<true, u64>(entity, false).is_err());
1710 assert_eq!(world.len(), 1);
1711
1712 world.insert(entity, (4u64,)).unwrap();
1713 assert_eq!(
1714 *world
1715 .get::<true, u8>(entity, false)
1716 .unwrap()
1717 .read()
1718 .unwrap(),
1719 1
1720 );
1721 assert_eq!(
1722 *world
1723 .get::<true, u16>(entity, false)
1724 .unwrap()
1725 .read()
1726 .unwrap(),
1727 2
1728 );
1729 assert_eq!(
1730 *world
1731 .get::<true, u32>(entity, false)
1732 .unwrap()
1733 .read()
1734 .unwrap(),
1735 3
1736 );
1737 assert_eq!(
1738 *world
1739 .get::<true, u64>(entity, false)
1740 .unwrap()
1741 .read()
1742 .unwrap(),
1743 4
1744 );
1745
1746 world.remove::<(u8,)>(entity).unwrap();
1747 assert!(world.get::<true, u8>(entity, false).is_err());
1748 assert_eq!(
1749 *world
1750 .get::<true, u16>(entity, false)
1751 .unwrap()
1752 .read()
1753 .unwrap(),
1754 2
1755 );
1756 assert_eq!(
1757 *world
1758 .get::<true, u32>(entity, false)
1759 .unwrap()
1760 .read()
1761 .unwrap(),
1762 3
1763 );
1764 assert_eq!(
1765 *world
1766 .get::<true, u64>(entity, false)
1767 .unwrap()
1768 .read()
1769 .unwrap(),
1770 4
1771 );
1772
1773 world.clear();
1774 assert!(world.is_empty());
1775 }
1776
1777 #[test]
1778 fn test_world_query() {
1779 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1780
1781 let mut world = World::default().with_new_archetype_capacity(N);
1782
1783 for index in 0..N {
1784 world.spawn((index as u8,)).unwrap();
1785 }
1786 for index in N..(N * 2) {
1787 world.spawn((index as u8, index as u16)).unwrap();
1788 }
1789 for index in (N * 2)..(N * 3) {
1790 world.spawn((index as u16,)).unwrap();
1791 }
1792
1793 for (index, v) in world.query::<true, &u8>().enumerate() {
1794 assert_eq!(*v, index as u8);
1795 }
1796
1797 for (index, item) in world
1798 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>())
1799 .enumerate()
1800 {
1801 let v = item.read::<u8>().unwrap().read::<u8>().unwrap();
1802 assert_eq!(*v, index as u8);
1803 }
1804
1805 for (index, v) in world.query::<true, &u16>().enumerate() {
1806 assert_eq!(*v, (index + N) as u16);
1807 }
1808
1809 for (index, item) in world
1810 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u16>())
1811 .enumerate()
1812 {
1813 let v = item.read::<u16>().unwrap().read::<u16>().unwrap();
1814 assert_eq!(*v, (index + N) as u16);
1815 }
1816
1817 for (index, (entity, a, b)) in world.query::<true, (Entity, &u8, &u16)>().enumerate() {
1818 assert!(entity.is_valid());
1819 assert_eq!(*a, (index + N) as u8);
1820 assert_eq!(*b, (index + N) as u16);
1821 }
1822
1823 for (index, item) in world
1824 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().read::<u16>())
1825 .enumerate()
1826 {
1827 let a = item.read::<u8>().unwrap().read::<u8>().unwrap();
1828 let b = item.read::<u16>().unwrap().read::<u16>().unwrap();
1829 assert!(item.entity().is_valid());
1830 assert_eq!(*a, (index + N) as u8);
1831 assert_eq!(*b, (index + N) as u16);
1832 }
1833
1834 for (index, (a, b)) in world.query::<true, (&u8, Option<&u16>)>().enumerate() {
1835 assert_eq!(*a, index as u8);
1836 if let Some(b) = b {
1837 assert_eq!(*b, index as u16);
1838 }
1839 }
1840
1841 for (entity, _, _) in world.query::<true, (Entity, &u8, Include<u16>)>() {
1842 assert!((entity.id() as usize) >= N);
1843 assert!((entity.id() as usize) < N * 2);
1844 }
1845
1846 for item in world
1847 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().include::<u16>())
1848 {
1849 assert!((item.entity().id() as usize) >= N);
1850 assert!((item.entity().id() as usize) < N * 2);
1851 }
1852
1853 for (entity, _, _) in world.query::<true, (Entity, &u8, Exclude<u16>)>() {
1854 assert!((entity.id() as usize) < N);
1855 }
1856
1857 for item in world
1858 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().exclude::<u16>())
1859 {
1860 assert!((item.entity().id() as usize) < N);
1861 }
1862 }
1863
1864 #[test]
1865 fn test_world_lookup() {
1866 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1867
1868 let mut world = World::default().with_new_archetype_capacity(N);
1869
1870 let mut entities = vec![];
1871 for index in 0..N {
1872 let entity = world.spawn((index as u8,)).unwrap();
1873 if index % 2 == 0 {
1874 entities.push(entity);
1875 }
1876 }
1877
1878 let compare_entities = world
1879 .lookup::<true, (Entity, &u8)>(entities.iter().copied())
1880 .map(|(entity, _)| entity)
1881 .collect::<Vec<_>>();
1882 assert_eq!(compare_entities, entities);
1883
1884 let mut lookup = world.lookup_access::<true, (Entity, &u8)>();
1885 for entity in entities.iter().copied() {
1886 assert_eq!(lookup.access(entity).unwrap().0, entity);
1887 }
1888 drop(lookup);
1889
1890 let compare_entities = world
1891 .dynamic_lookup::<true>(
1892 &DynamicQueryFilter::default().read::<u8>(),
1893 entities.iter().copied(),
1894 )
1895 .map(|item| item.entity())
1896 .collect::<Vec<_>>();
1897 assert_eq!(compare_entities, entities);
1898
1899 let lookup =
1900 world.dynamic_lookup_access::<true>(&DynamicQueryFilter::default().read::<u8>());
1901 for entity in entities.iter().copied() {
1902 let item = lookup.access(entity).unwrap();
1903 assert_eq!(item.entity(), entity);
1904 }
1905 drop(lookup);
1906
1907 let entity = world.spawn((1u8, 2.0f32, "3")).unwrap();
1908 let (a, b) = world.entity::<true, (&u8, &mut f32)>(entity).unwrap();
1909 assert_eq!(*a, 1);
1910 assert_eq!(*b, 2.0);
1911 }
1912
1913 #[test]
1914 fn test_change_detection() {
1915 let mut world = World::default();
1916
1917 for index in 0..10usize {
1918 world.spawn((index,)).unwrap();
1919 }
1920 let mut list = world.added().iter_of::<usize>().collect::<Vec<_>>();
1921 list.sort();
1922 assert_eq!(
1923 list,
1924 (0..10)
1925 .map(|index| Entity::new(index, 0).unwrap())
1926 .collect::<Vec<_>>()
1927 );
1928
1929 for mut v in world.query::<true, Update<usize>>() {
1930 *v.write_notified(&world) *= 2;
1931 }
1932 for (entity, v) in world.query::<true, (Entity, &usize)>() {
1933 assert_eq!(entity.id() as usize * 2, *v);
1934 }
1935 let mut list = world
1936 .updated()
1937 .unwrap()
1938 .iter_of::<usize>()
1939 .collect::<Vec<_>>();
1940 list.sort();
1941 assert_eq!(
1942 list,
1943 (0..10)
1944 .map(|index| Entity::new(index, 0).unwrap())
1945 .collect::<Vec<_>>()
1946 );
1947
1948 let mut commands = CommandBuffer::default();
1949 for entity in world.entities() {
1950 commands.command(DespawnCommand::new(entity));
1951 }
1952 commands.execute(&mut world);
1953 let mut list = world.removed().iter_of::<usize>().collect::<Vec<_>>();
1954 list.sort();
1955 assert_eq!(
1956 list,
1957 (0..10)
1958 .map(|index| Entity::new(index, 0).unwrap())
1959 .collect::<Vec<_>>()
1960 );
1961 }
1962
1963 #[test]
1964 fn test_zst_components() {
1965 #[derive(Debug, PartialEq, Eq)]
1966 struct Foo;
1967
1968 #[derive(Debug, PartialEq, Eq)]
1969 struct Bar(bool);
1970
1971 let mut world = World::default();
1972 world.spawn((Foo,)).unwrap();
1973 assert_eq!(world.query::<true, &Foo>().count(), 1);
1974 for v in world.query::<true, &Foo>() {
1975 assert_eq!(v, &Foo);
1976 }
1977 world.spawn((Bar(true),)).unwrap();
1978 assert_eq!(world.query::<true, &Bar>().count(), 1);
1979 for v in world.query::<true, &Bar>() {
1980 assert_eq!(v, &Bar(true));
1981 }
1982 world.spawn((Foo, Bar(false))).unwrap();
1983 assert_eq!(world.query::<true, &Foo>().count(), 2);
1984 assert_eq!(world.query::<true, &Bar>().count(), 2);
1985 assert_eq!(world.query::<true, (&Bar, &Foo)>().count(), 1);
1986 for (a, b) in world.query::<true, (&Bar, &Foo)>() {
1987 assert_eq!(a, &Bar(false));
1988 assert_eq!(b, &Foo);
1989 }
1990 }
1991
1992 #[test]
1993 fn test_world_relations() {
1994 struct Parent;
1995 struct Child;
1996 struct Root;
1997
1998 let mut world = World::default();
1999 let a = world.spawn((0u8, false, Root)).unwrap();
2000 let b = world.spawn((1u8, false)).unwrap();
2001 let c = world.spawn((2u8, false)).unwrap();
2002 let d = world.spawn((3u8, false)).unwrap();
2003 world
2004 .relate_pair::<true, _, _>(Parent, Child, a, b)
2005 .unwrap();
2006 world
2007 .relate_pair::<true, _, _>(Parent, Child, a, c)
2008 .unwrap();
2009 world
2010 .relate_pair::<true, _, _>(Parent, Child, c, d)
2011 .unwrap();
2012
2013 assert_eq!(
2014 world
2015 .relations_incomming::<true, Parent>(a)
2016 .map(|(entity, _, _)| entity)
2017 .collect::<Vec<_>>(),
2018 vec![b, c]
2019 );
2020 assert_eq!(
2021 world
2022 .relations_incomming::<true, Parent>(b)
2023 .map(|(entity, _, _)| entity)
2024 .collect::<Vec<_>>(),
2025 vec![]
2026 );
2027 assert_eq!(
2028 world
2029 .relations_incomming::<true, Parent>(c)
2030 .map(|(entity, _, _)| entity)
2031 .collect::<Vec<_>>(),
2032 vec![d]
2033 );
2034 assert_eq!(
2035 world
2036 .relations_incomming::<true, Parent>(d)
2037 .map(|(entity, _, _)| entity)
2038 .collect::<Vec<_>>(),
2039 vec![]
2040 );
2041
2042 assert_eq!(
2043 world
2044 .relations_outgoing::<true, Parent>(a)
2045 .map(|(_, _, entity)| entity)
2046 .collect::<Vec<_>>(),
2047 vec![]
2048 );
2049 assert_eq!(
2050 world
2051 .relations_outgoing::<true, Parent>(b)
2052 .map(|(_, _, entity)| entity)
2053 .collect::<Vec<_>>(),
2054 vec![a]
2055 );
2056 assert_eq!(
2057 world
2058 .relations_outgoing::<true, Parent>(c)
2059 .map(|(_, _, entity)| entity)
2060 .collect::<Vec<_>>(),
2061 vec![a]
2062 );
2063 assert_eq!(
2064 world
2065 .relations_outgoing::<true, Parent>(d)
2066 .map(|(_, _, entity)| entity)
2067 .collect::<Vec<_>>(),
2068 vec![c]
2069 );
2070
2071 assert_eq!(
2072 world
2073 .traverse_outgoing::<true, Child>([a])
2074 .collect::<Vec<_>>(),
2075 vec![(Entity::INVALID, a), (a, b), (a, c), (c, d)]
2076 );
2077
2078 for (entity, _) in world.query::<true, (Entity, Include<Root>)>() {
2079 for (other, _, _) in world.relations_incomming::<true, Parent>(entity) {
2080 let mut v = world.get::<true, bool>(other, true).unwrap();
2081 let v = v.write().unwrap();
2082 *v = !*v;
2083 }
2084 }
2085
2086 assert!(!*world.get::<true, bool>(a, false).unwrap().read().unwrap());
2087 assert!(*world.get::<true, bool>(b, false).unwrap().read().unwrap());
2088 assert!(*world.get::<true, bool>(c, false).unwrap().read().unwrap());
2089 assert!(!*world.get::<true, bool>(d, false).unwrap().read().unwrap());
2090
2091 world.unrelate::<true, Parent>(b, a).unwrap();
2092 world.unrelate::<true, Parent>(c, a).unwrap();
2093 world.unrelate::<true, Parent>(d, c).unwrap();
2094 assert!(world.query::<true, &Relation<Parent>>().count() == 0);
2095 }
2096
2097 #[test]
2098 fn test_world_async() {
2099 const N: usize = if cfg!(miri) { 10 } else { 1000 };
2100
2101 fn is_async<T: Send + Sync>() {}
2102
2103 is_async::<World>();
2104
2105 let world = Arc::new(RwLock::new(World::default().with_new_archetype_capacity(N)));
2106 let world2 = world.clone();
2107
2108 {
2109 let mut world = world.write().unwrap();
2110 for index in 0..N {
2111 world.spawn((index as u8, index as u16)).unwrap();
2112 }
2113 }
2114
2115 let handle = spawn(move || {
2116 let timer = Instant::now();
2117 while timer.elapsed() < Duration::from_secs(1) {
2118 let world = world2.read().unwrap();
2119 for v in world.query::<true, &mut u16>() {
2120 *v = v.wrapping_add(1);
2121 }
2122 }
2123 });
2124
2125 let timer = Instant::now();
2126 while timer.elapsed() < Duration::from_secs(1) {
2127 let world = world.read().unwrap();
2128 for v in world.query::<true, &mut u8>() {
2129 *v = v.wrapping_add(1);
2130 }
2131 }
2132
2133 let _ = handle.join();
2134 }
2135}