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 && archetype.has_columns_exact(columns)
388 {
389 return Some(id as u32);
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([])
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 len(&self) -> usize {
485 match &self.connections {
486 RelationConnections::Zero(_) => 0,
487 RelationConnections::One(_) => 1,
488 RelationConnections::More(vec) => vec.len(),
489 }
490 }
491
492 pub fn is_empty(&self) -> bool {
494 match &self.connections {
495 RelationConnections::Zero(_) => true,
496 RelationConnections::One(_) => false,
497 RelationConnections::More(vec) => vec.is_empty(),
498 }
499 }
500
501 pub fn add(&mut self, payload: T, entity: Entity) {
503 self.connections = match std::mem::take(&mut self.connections) {
504 RelationConnections::Zero(_) => RelationConnections::One([(payload, entity)]),
505 RelationConnections::One([a]) => RelationConnections::More(vec![a, (payload, entity)]),
506 RelationConnections::More(mut vec) => {
507 if let Some(index) = vec.iter().position(|item| item.1 == entity) {
508 vec[index].0 = payload;
509 } else {
510 vec.push((payload, entity));
511 }
512 RelationConnections::More(vec)
513 }
514 };
515 }
516
517 pub fn remove(&mut self, entity: Entity) {
519 self.connections = match std::mem::take(&mut self.connections) {
520 RelationConnections::Zero(a) => RelationConnections::Zero(a),
521 RelationConnections::One([a]) => {
522 if a.1 == entity {
523 RelationConnections::Zero([])
524 } else {
525 RelationConnections::One([a])
526 }
527 }
528 RelationConnections::More(mut vec) => {
529 if let Some(index) = vec.iter().position(|a| a.1 == entity) {
530 vec.swap_remove(index);
531 }
532 if vec.len() == 1 {
533 RelationConnections::One([vec.remove(0)])
534 } else if vec.is_empty() {
535 RelationConnections::Zero([])
536 } else {
537 RelationConnections::More(vec)
538 }
539 }
540 }
541 }
542
543 pub fn clear(&mut self) {
545 self.connections = Default::default();
546 }
547
548 pub fn has(&self, entity: Entity) -> bool {
550 match &self.connections {
551 RelationConnections::Zero(_) => false,
552 RelationConnections::One([a]) => a.1 == entity,
553 RelationConnections::More(vec) => vec.iter().any(|(_, e)| *e == entity),
554 }
555 }
556
557 pub fn payload(&self, entity: Entity) -> Option<&T> {
559 match &self.connections {
560 RelationConnections::Zero(_) => None,
561 RelationConnections::One([a]) => {
562 if a.1 == entity {
563 Some(&a.0)
564 } else {
565 None
566 }
567 }
568 RelationConnections::More(vec) => vec
569 .iter()
570 .find_map(|(p, e)| if *e == entity { Some(p) } else { None }),
571 }
572 }
573
574 pub fn payload_mut(&mut self, entity: Entity) -> Option<&mut T> {
576 match &mut self.connections {
577 RelationConnections::Zero(_) => None,
578 RelationConnections::One([a]) => {
579 if a.1 == entity {
580 Some(&mut a.0)
581 } else {
582 None
583 }
584 }
585 RelationConnections::More(vec) => vec
586 .iter_mut()
587 .find_map(|(p, e)| if *e == entity { Some(p) } else { None }),
588 }
589 }
590
591 pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
593 match &self.connections {
594 RelationConnections::Zero(a) => a.iter(),
595 RelationConnections::One(a) => a.iter(),
596 RelationConnections::More(vec) => vec.iter(),
597 }
598 .map(|(_, e)| *e)
599 }
600
601 pub fn iter(&self) -> impl Iterator<Item = (&T, Entity)> {
603 match &self.connections {
604 RelationConnections::Zero(a) => a.iter(),
605 RelationConnections::One(a) => a.iter(),
606 RelationConnections::More(vec) => vec.iter(),
607 }
608 .map(|(p, e)| (p, *e))
609 }
610
611 pub fn iter_mut(&mut self) -> impl Iterator<Item = (&mut T, Entity)> {
613 match &mut self.connections {
614 RelationConnections::Zero(a) => a.iter_mut(),
615 RelationConnections::One(a) => a.iter_mut(),
616 RelationConnections::More(vec) => vec.iter_mut(),
617 }
618 .map(|(p, e)| (p, *e))
619 }
620}
621
622pub struct RelationsTraverseIter<'a, const LOCKING: bool, T: Component> {
624 world: &'a World,
625 incoming: bool,
626 stack: VecDeque<(Option<Entity>, Entity)>,
627 visited: HashSet<Entity>,
628 _phantom: PhantomData<fn() -> T>,
629}
630
631impl<const LOCKING: bool, T: Component> Iterator for RelationsTraverseIter<'_, LOCKING, T> {
632 type Item = (Entity, Entity);
633
634 fn next(&mut self) -> Option<Self::Item> {
635 while let Some((from, to)) = self.stack.pop_front() {
636 if self.visited.contains(&to) {
637 continue;
638 }
639 self.visited.insert(to);
640 if self.incoming {
641 for (from, _, to) in self.world.relations_incomming::<LOCKING, T>(to) {
642 if self.stack.len() == self.stack.capacity() {
643 self.stack.reserve_exact(self.stack.capacity());
644 }
645 self.stack.push_back((Some(from), to));
646 }
647 } else {
648 for (from, _, to) in self.world.relations_outgoing::<LOCKING, T>(to) {
649 if self.stack.len() == self.stack.capacity() {
650 self.stack.reserve_exact(self.stack.capacity());
651 }
652 self.stack.push_back((Some(from), to));
653 }
654 }
655 return Some((from.unwrap_or_default(), to));
656 }
657 None
658 }
659}
660
661#[derive(Default, Clone)]
663pub struct WorldChanges {
664 table: HashMap<Entity, Vec<TypeHash>>,
665}
666
667impl WorldChanges {
668 pub fn clear(&mut self) {
673 self.table.clear();
674 }
675
676 pub fn has_entity(&self, entity: Entity) -> bool {
684 self.table.contains_key(&entity)
685 }
686
687 pub fn has_entity_component<T>(&self, entity: Entity) -> bool {
698 self.has_entity_component_raw(entity, TypeHash::of::<T>())
699 }
700
701 pub fn has_entity_component_raw(&self, entity: Entity, type_hash: TypeHash) -> bool {
710 self.table
711 .get(&entity)
712 .map(|components| components.contains(&type_hash))
713 .unwrap_or_default()
714 }
715
716 pub fn has_component<T>(&self) -> bool {
724 self.has_component_raw(TypeHash::of::<T>())
725 }
726
727 pub fn has_component_raw(&self, type_hash: TypeHash) -> bool {
735 self.table
736 .values()
737 .any(|components| components.contains(&type_hash))
738 }
739
740 pub fn iter(&self) -> impl Iterator<Item = (Entity, &[TypeHash])> {
745 self.table
746 .iter()
747 .map(|(entity, components)| (*entity, components.as_slice()))
748 }
749
750 pub fn iter_of<T>(&self) -> impl Iterator<Item = Entity> + '_ {
758 self.iter_of_raw(TypeHash::of::<T>())
759 }
760
761 pub fn iter_of_raw(&self, type_hash: TypeHash) -> impl Iterator<Item = Entity> + '_ {
769 self.table
770 .iter()
771 .filter(move |(_, components)| components.contains(&type_hash))
772 .map(|(entity, _)| *entity)
773 }
774}
775
776pub struct World {
779 pub new_archetype_capacity: usize,
782 entities: EntityMap,
783 archetypes: ArchetypeMap,
784 added: WorldChanges,
785 removed: WorldChanges,
786 updated: Arc<RwLock<WorldChanges>>,
787}
788
789impl Default for World {
790 fn default() -> Self {
791 World {
792 new_archetype_capacity: 128,
793 entities: Default::default(),
794 archetypes: Default::default(),
795 added: Default::default(),
796 removed: Default::default(),
797 updated: Default::default(),
798 }
799 }
800}
801
802impl World {
803 #[inline]
804 pub fn with_new_archetype_capacity(mut self, value: usize) -> Self {
805 self.new_archetype_capacity = value.max(1);
806 self
807 }
808
809 #[inline]
810 pub fn is_empty(&self) -> bool {
811 self.entities.is_empty()
812 }
813
814 #[inline]
815 pub fn len(&self) -> usize {
816 self.entities.len()
817 }
818
819 #[inline]
820 pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
821 self.entities.iter()
822 }
823
824 #[inline]
825 pub fn entity_by_index(&self, mut index: usize) -> Option<Entity> {
826 for archetype in self.archetypes() {
827 if index >= archetype.len() {
828 index -= archetype.len();
829 continue;
830 }
831 return archetype.entities().get(index);
832 }
833 None
834 }
835
836 #[inline]
837 pub(crate) fn entity_archetype_id(&self, entity: Entity) -> Result<u32, WorldError> {
838 self.entities.get(entity)
839 }
840
841 #[inline]
842 pub fn archetypes(&self) -> impl Iterator<Item = &Archetype> {
843 self.archetypes.iter()
844 }
845
846 #[inline]
847 pub fn archetypes_mut(&mut self) -> impl Iterator<Item = &mut Archetype> {
848 self.archetypes.iter_mut()
849 }
850
851 #[inline]
852 pub(crate) fn archetype_by_id(&self, id: u32) -> Result<&Archetype, WorldError> {
853 self.archetypes.get(id)
854 }
855
856 pub fn added(&self) -> &WorldChanges {
857 &self.added
858 }
859
860 pub fn removed(&self) -> &WorldChanges {
861 &self.removed
862 }
863
864 pub fn updated(&'_ self) -> Option<RwLockReadGuard<'_, WorldChanges>> {
865 self.updated.try_read().ok()
866 }
867
868 pub fn entity_did_changed(&self, entity: Entity) -> bool {
869 self.added.has_entity(entity)
870 || self.removed.has_entity(entity)
871 || self
872 .updated
873 .try_read()
874 .ok()
875 .map(|updated| updated.has_entity(entity))
876 .unwrap_or_default()
877 }
878
879 pub fn component_did_changed<T>(&self) -> bool {
880 self.component_did_changed_raw(TypeHash::of::<T>())
881 }
882
883 pub fn component_did_changed_raw(&self, type_hash: TypeHash) -> bool {
884 self.added.has_component_raw(type_hash)
885 || self.removed.has_component_raw(type_hash)
886 || self
887 .updated
888 .try_read()
889 .ok()
890 .map(|updated| updated.has_component_raw(type_hash))
891 .unwrap_or_default()
892 }
893
894 pub fn entity_component_did_changed<T>(&self, entity: Entity) -> bool {
895 self.entity_component_did_changed_raw(entity, TypeHash::of::<T>())
896 }
897
898 pub fn entity_component_did_changed_raw(&self, entity: Entity, type_hash: TypeHash) -> bool {
899 self.added.has_entity_component_raw(entity, type_hash)
900 || self.removed.has_entity_component_raw(entity, type_hash)
901 || self
902 .updated
903 .try_read()
904 .ok()
905 .map(|updated| updated.has_entity_component_raw(entity, type_hash))
906 .unwrap_or_default()
907 }
908
909 pub fn update<T>(&self, entity: Entity) {
910 self.update_raw(entity, TypeHash::of::<T>());
911 }
912
913 pub fn update_raw(&self, entity: Entity, type_hash: TypeHash) {
914 if let Ok(mut updated) = self.updated.try_write() {
915 let components = updated.table.entry(entity).or_default();
916 if !components.contains(&type_hash) {
917 components.push(type_hash);
918 }
919 }
920 }
921
922 pub fn validate_sdir(&self) -> Result<(), ArchetypeError> {
923 for archetype in self.archetypes.iter() {
924 archetype.validate_sdir()?;
925 }
926 Ok(())
927 }
928
929 pub fn is_column_sdir_locked_raw(&self, type_hash: TypeHash) -> bool {
930 self.archetypes
931 .iter()
932 .any(|archetype| archetype.is_column_sdir_locked_raw(type_hash))
933 }
934
935 pub fn is_column_sdir_locked<T: Component>(&self) -> bool {
936 self.is_column_sdir_locked_raw(TypeHash::of::<T>())
937 }
938
939 pub fn clear_changes(&mut self) {
940 self.added.clear();
941 self.removed.clear();
942 if let Ok(mut updated) = self.updated.try_write() {
943 updated.clear();
944 }
945 }
946
947 #[inline]
948 pub fn clear(&mut self) {
949 self.clear_changes();
950 self.despawn_all();
951 }
952
953 pub fn spawn(&mut self, bundle: impl Bundle) -> Result<Entity, WorldError> {
954 let bundle_columns = bundle.columns();
955 if bundle_columns.is_empty() {
956 return Err(WorldError::EmptyColumnSet);
957 }
958 let bundle_types = bundle_columns
959 .iter()
960 .map(|column| column.type_hash())
961 .collect::<Vec<_>>();
962 let (entity, id) = self.entities.acquire()?;
963 let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&bundle_columns)
964 {
965 *id = Some(archetype_id);
966 archetype_id
967 } else {
968 let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
969 Ok(result) => result,
970 Err(error) => {
971 self.entities.release(entity)?;
972 return Err(error);
973 }
974 };
975 let archetype = match Archetype::new(bundle_columns, self.new_archetype_capacity) {
976 Ok(result) => result,
977 Err(error) => {
978 self.entities.release(entity)?;
979 return Err(error.into());
980 }
981 };
982 *archetype_slot = Some(archetype);
983 *id = Some(archetype_id);
984 archetype_id
985 };
986 let archetype = match self.archetypes.get_mut(id) {
987 Ok(result) => result,
988 Err(error) => {
989 self.entities.release(entity)?;
990 return Err(error);
991 }
992 };
993 match archetype.insert(entity, bundle) {
994 Ok(_) => {
995 self.added
996 .table
997 .entry(entity)
998 .or_default()
999 .extend(bundle_types);
1000 Ok(entity)
1001 }
1002 Err(error) => {
1003 self.entities.release(entity)?;
1004 Err(error.into())
1005 }
1006 }
1007 }
1008
1009 pub unsafe fn spawn_uninitialized<T: BundleColumns>(
1011 &'_ mut self,
1012 ) -> Result<(Entity, ArchetypeEntityRowAccess<'_>), WorldError> {
1013 unsafe { self.spawn_uninitialized_raw(T::columns_static()) }
1014 }
1015
1016 pub unsafe fn spawn_uninitialized_raw(
1018 &'_ mut self,
1019 columns: Vec<ArchetypeColumnInfo>,
1020 ) -> Result<(Entity, ArchetypeEntityRowAccess<'_>), WorldError> {
1021 if columns.is_empty() {
1022 return Err(WorldError::EmptyColumnSet);
1023 }
1024 let bundle_types = columns
1025 .iter()
1026 .map(|column| column.type_hash())
1027 .collect::<Vec<_>>();
1028 let (entity, id) = self.entities.acquire()?;
1029 let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1030 *id = Some(archetype_id);
1031 archetype_id
1032 } else {
1033 let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
1034 Ok(result) => result,
1035 Err(error) => {
1036 self.entities.release(entity)?;
1037 return Err(error);
1038 }
1039 };
1040 let archetype = match Archetype::new(columns, self.new_archetype_capacity) {
1041 Ok(result) => result,
1042 Err(error) => {
1043 self.entities.release(entity)?;
1044 return Err(error.into());
1045 }
1046 };
1047 *archetype_slot = Some(archetype);
1048 *id = Some(archetype_id);
1049 archetype_id
1050 };
1051 let archetype = match self.archetypes.get_mut(id) {
1052 Ok(result) => result,
1053 Err(error) => {
1054 self.entities.release(entity)?;
1055 return Err(error);
1056 }
1057 };
1058 match archetype.add(entity) {
1059 Ok(result) => {
1060 self.added
1061 .table
1062 .entry(entity)
1063 .or_default()
1064 .extend(bundle_types);
1065 Ok((entity, result))
1066 }
1067 Err(error) => {
1068 self.entities.release(entity)?;
1069 Err(error.into())
1070 }
1071 }
1072 }
1073
1074 pub fn despawn(&mut self, entity: Entity) -> Result<(), WorldError> {
1075 let id = self.entities.release(entity)?;
1076 let archetype = self.archetypes.get_mut(id).unwrap();
1077 match archetype.remove(entity) {
1078 Ok(_) => {
1079 self.removed
1080 .table
1081 .entry(entity)
1082 .or_default()
1083 .extend(archetype.columns().map(|column| column.type_hash()));
1084 Ok(())
1085 }
1086 Err(error) => {
1087 self.entities.acquire()?;
1088 Err(error.into())
1089 }
1090 }
1091 }
1092
1093 pub unsafe fn despawn_uninitialized(&mut self, entity: Entity) -> Result<(), WorldError> {
1095 let id = self.entities.release(entity)?;
1096 let archetype = self.archetypes.get_mut(id).unwrap();
1097 match unsafe { archetype.remove_uninitialized(entity) } {
1098 Ok(_) => {
1099 self.removed
1100 .table
1101 .entry(entity)
1102 .or_default()
1103 .extend(archetype.columns().map(|column| column.type_hash()));
1104 Ok(())
1105 }
1106 Err(error) => {
1107 self.entities.acquire()?;
1108 Err(error.into())
1109 }
1110 }
1111 }
1112
1113 #[inline]
1114 pub fn despawn_all(&mut self) {
1115 self.archetypes.clear();
1116 self.entities.clear();
1117 }
1118
1119 pub fn insert(&mut self, entity: Entity, bundle: impl Bundle) -> Result<(), WorldError> {
1120 let bundle_columns = bundle.columns();
1121 if bundle_columns.is_empty() {
1122 return Err(WorldError::EmptyColumnSet);
1123 }
1124 let bundle_types = bundle_columns
1125 .iter()
1126 .map(|column| column.type_hash())
1127 .collect::<Vec<_>>();
1128 let old_id = self.entities.get(entity)?;
1129 let mut new_columns = self
1130 .archetypes
1131 .get_mut(old_id)?
1132 .columns()
1133 .cloned()
1134 .collect::<Vec<_>>();
1135 for column in bundle_columns {
1136 if !new_columns
1137 .iter()
1138 .any(|c| c.type_hash() == column.type_hash())
1139 {
1140 new_columns.push(column);
1141 }
1142 }
1143 if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
1144 if new_id == old_id {
1145 return Ok(());
1146 }
1147 let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
1148 let access = old_archetype.transfer(new_archetype, entity)?;
1149 bundle.initialize_into(&access);
1150 self.entities.set(entity, new_id)?;
1151 } else {
1152 let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1153 let access = self
1154 .archetypes
1155 .get_mut(old_id)
1156 .unwrap()
1157 .transfer(&mut archetype, entity)?;
1158 bundle.initialize_into(&access);
1159 drop(access);
1160 let (new_id, archetype_slot) = self.archetypes.acquire()?;
1161 *archetype_slot = Some(archetype);
1162 self.entities.set(entity, new_id)?;
1163 }
1164 self.added
1165 .table
1166 .entry(entity)
1167 .or_default()
1168 .extend(bundle_types);
1169 Ok(())
1170 }
1171
1172 pub fn remove<T: BundleColumns>(&mut self, entity: Entity) -> Result<(), WorldError> {
1173 self.remove_raw(entity, T::columns_static())
1174 }
1175
1176 pub fn remove_raw(
1177 &mut self,
1178 entity: Entity,
1179 columns: Vec<ArchetypeColumnInfo>,
1180 ) -> Result<(), WorldError> {
1181 if columns.is_empty() {
1182 return Err(WorldError::EmptyColumnSet);
1183 }
1184 let bundle_types = columns
1185 .iter()
1186 .map(|column| column.type_hash())
1187 .collect::<Vec<_>>();
1188 let old_id = self.entities.get(entity)?;
1189 let mut new_columns = self
1190 .archetypes
1191 .get_mut(old_id)?
1192 .columns()
1193 .cloned()
1194 .collect::<Vec<_>>();
1195 let despawn = new_columns.is_empty();
1196 for column in columns {
1197 if let Some(index) = new_columns
1198 .iter()
1199 .position(|c| c.type_hash() == column.type_hash())
1200 {
1201 new_columns.swap_remove(index);
1202 }
1203 }
1204 if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
1205 if new_id == old_id {
1206 return Ok(());
1207 }
1208 let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
1209 old_archetype.transfer(new_archetype, entity)?;
1210 self.entities.set(entity, new_id)?;
1211 } else {
1212 let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1213 self.archetypes
1214 .get_mut(old_id)
1215 .unwrap()
1216 .transfer(&mut archetype, entity)?;
1217 let (new_id, archetype_slot) = self.archetypes.acquire()?;
1218 *archetype_slot = Some(archetype);
1219 self.entities.set(entity, new_id)?;
1220 }
1221 if despawn {
1222 let _ = self.entities.release(entity);
1223 }
1224 self.removed
1225 .table
1226 .entry(entity)
1227 .or_default()
1228 .extend(bundle_types);
1229 Ok(())
1230 }
1231
1232 pub fn merge<const LOCKING: bool>(
1233 &mut self,
1234 mut other: Self,
1235 processor: &WorldProcessor,
1236 ) -> Result<(), WorldError> {
1237 let mut mappings = HashMap::<_, _>::with_capacity(other.len());
1238 let mut archetype_offsets = Vec::with_capacity(other.archetypes().count());
1239 for archetype_from in other.archetypes_mut() {
1240 let columns = archetype_from.columns().cloned().collect::<Vec<_>>();
1241 let archetype_id =
1242 if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1243 archetype_id
1244 } else {
1245 let (archetype_id, archetype_slot) = self.archetypes.acquire()?;
1246 let archetype = Archetype::new(columns.clone(), self.new_archetype_capacity)?;
1247 *archetype_slot = Some(archetype);
1248 archetype_id
1249 };
1250 let archetype = self.archetypes.get_mut(archetype_id)?;
1251 let offset = archetype.len();
1252 let entities_from = archetype_from.entities().iter().collect::<Vec<_>>();
1253 for entity_from in entities_from {
1254 let (entity, access) = unsafe { self.spawn_uninitialized_raw(columns.clone())? };
1255 let access_from = match archetype_from.row::<LOCKING>(entity_from) {
1256 Ok(access_from) => access_from,
1257 Err(error) => {
1258 drop(access);
1259 unsafe { self.despawn_uninitialized(entity)? };
1260 return Err(error.into());
1261 }
1262 };
1263 for column in &columns {
1264 unsafe {
1265 let data = access.data(column.type_hash()).unwrap();
1266 let data_from = access_from.data(column.type_hash()).unwrap();
1267 data.copy_from(data_from, column.layout().size());
1268 }
1269 }
1270 mappings.insert(entity_from, entity);
1271 }
1272 archetype_offsets.push((columns, offset));
1273 unsafe { archetype_from.clear_uninitialized() };
1274 }
1275 for (columns, offset) in archetype_offsets {
1276 if let Some(id) = self.archetypes.find_by_columns_exact(&columns) {
1277 let archetype = self.archetype_by_id(id)?;
1278 for column in archetype.columns() {
1279 let access = archetype.dynamic_column::<LOCKING>(column.type_hash(), true)?;
1280 for index in offset..archetype.len() {
1281 unsafe {
1282 processor.remap_entities_raw(
1283 column.type_hash(),
1284 access.data(index)?,
1285 WorldProcessorEntityMapping::new(&mappings),
1286 );
1287 }
1288 }
1289 }
1290 }
1291 }
1292 Ok(())
1293 }
1294
1295 pub fn has_entity(&self, entity: Entity) -> bool {
1296 self.entities.get(entity).is_ok()
1297 }
1298
1299 pub fn has_entity_component<T: Component>(&self, entity: Entity) -> bool {
1300 self.has_entity_component_raw(entity, TypeHash::of::<T>())
1301 }
1302
1303 pub fn has_entity_component_raw(&self, entity: Entity, component: TypeHash) -> bool {
1304 self.entities
1305 .get(entity)
1306 .and_then(|index| self.archetypes.get(index))
1307 .map(|archetype| archetype.has_type(component))
1308 .unwrap_or_default()
1309 }
1310
1311 pub fn has_component<T: Component>(&self) -> bool {
1312 self.has_component_raw(TypeHash::of::<T>())
1313 }
1314
1315 pub fn has_component_raw(&self, component: TypeHash) -> bool {
1316 self.archetypes
1317 .iter()
1318 .any(|archetype| archetype.has_type(component) && !archetype.is_empty())
1319 }
1320
1321 pub fn find_by<const LOCKING: bool, T: Component + PartialEq>(
1322 &self,
1323 data: &T,
1324 ) -> Option<Entity> {
1325 for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1326 if component == data {
1327 return Some(entity);
1328 }
1329 }
1330 None
1331 }
1332
1333 pub fn find_with<const LOCKING: bool, T: Component>(
1334 &self,
1335 f: impl Fn(&T) -> bool,
1336 ) -> Option<Entity> {
1337 for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1338 if f(component) {
1339 return Some(entity);
1340 }
1341 }
1342 None
1343 }
1344
1345 pub fn component<const LOCKING: bool, T: Component>(
1346 &'_ self,
1347 entity: Entity,
1348 ) -> Result<ComponentRef<'_, LOCKING, T>, WorldError> {
1349 Ok(ComponentRef {
1350 inner: self.get::<LOCKING, T>(entity, false)?,
1351 })
1352 }
1353
1354 pub fn component_mut<const LOCKING: bool, T: Component>(
1355 &'_ self,
1356 entity: Entity,
1357 ) -> Result<ComponentRefMut<'_, LOCKING, T>, WorldError> {
1358 Ok(ComponentRefMut {
1359 inner: self.get::<LOCKING, T>(entity, true)?,
1360 })
1361 }
1362
1363 pub fn get<const LOCKING: bool, T: Component>(
1364 &'_ self,
1365 entity: Entity,
1366 unique: bool,
1367 ) -> Result<ArchetypeEntityColumnAccess<'_, LOCKING, T>, WorldError> {
1368 Ok(self
1369 .archetypes
1370 .get(self.entities.get(entity)?)?
1371 .entity::<LOCKING, T>(entity, unique)?)
1372 }
1373
1374 pub fn dynamic_get<const LOCKING: bool>(
1375 &'_ self,
1376 type_hash: TypeHash,
1377 entity: Entity,
1378 unique: bool,
1379 ) -> Result<ArchetypeDynamicEntityColumnAccess<'_, LOCKING>, WorldError> {
1380 Ok(self
1381 .archetypes
1382 .get(self.entities.get(entity)?)?
1383 .dynamic_entity::<LOCKING>(type_hash, entity, unique)?)
1384 }
1385
1386 pub fn row<const LOCKING: bool>(
1387 &'_ self,
1388 entity: Entity,
1389 ) -> Result<ArchetypeEntityRowAccess<'_>, WorldError> {
1390 Ok(self
1391 .archetypes
1392 .get(self.entities.get(entity)?)?
1393 .row::<LOCKING>(entity)?)
1394 }
1395
1396 pub fn entity<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1397 &'a self,
1398 entity: Entity,
1399 ) -> Option<Fetch::Value> {
1400 self.lookup_access::<LOCKING, Fetch>().access(entity)
1403 }
1404
1405 pub fn query<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>>(
1406 &'a self,
1407 ) -> TypedQueryIter<'a, LOCKING, Fetch> {
1408 TypedQueryIter::new(self)
1409 }
1410
1411 pub fn dynamic_query<'a, const LOCKING: bool>(
1412 &'a self,
1413 filter: &DynamicQueryFilter,
1414 ) -> DynamicQueryIter<'a, LOCKING> {
1415 DynamicQueryIter::new(filter, self)
1416 }
1417
1418 pub fn lookup<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1419 &'a self,
1420 entities: impl IntoIterator<Item = Entity> + 'a,
1421 ) -> TypedLookupIter<'a, LOCKING, Fetch> {
1422 TypedLookupIter::new(self, entities)
1423 }
1424
1425 pub fn lookup_access<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1426 &'a self,
1427 ) -> TypedLookupAccess<'a, LOCKING, Fetch> {
1428 TypedLookupAccess::new(self)
1429 }
1430
1431 pub fn lookup_one<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1432 &'a self,
1433 entity: Entity,
1434 ) -> Option<Fetch::ValueOne> {
1435 Fetch::fetch_one(self, entity)
1436 }
1437
1438 pub fn dynamic_lookup<'a, const LOCKING: bool>(
1439 &'a self,
1440 filter: &DynamicQueryFilter,
1441 entities: impl IntoIterator<Item = Entity> + 'a,
1442 ) -> DynamicLookupIter<'a, LOCKING> {
1443 DynamicLookupIter::new(filter, self, entities)
1444 }
1445
1446 pub fn dynamic_lookup_access<'a, const LOCKING: bool>(
1447 &'a self,
1448 filter: &DynamicQueryFilter,
1449 ) -> DynamicLookupAccess<'a, LOCKING> {
1450 DynamicLookupAccess::new(filter, self)
1451 }
1452
1453 pub fn relate<const LOCKING: bool, T: Component>(
1454 &mut self,
1455 payload: T,
1456 from: Entity,
1457 to: Entity,
1458 ) -> Result<(), WorldError> {
1459 if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1460 if let Some(relation) = relation.write() {
1461 relation.add(payload, to);
1462 }
1463 return Ok(());
1464 }
1465 self.insert(from, (Relation::<T>::new(payload, to),))
1466 }
1467
1468 pub fn relate_one<const LOCKING: bool, T: Component>(
1469 &mut self,
1470 payload: T,
1471 from: Entity,
1472 to: Entity,
1473 ) -> Result<(), WorldError> {
1474 if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1475 if let Some(relation) = relation.write() {
1476 relation.clear();
1477 relation.add(payload, to);
1478 }
1479 return Ok(());
1480 }
1481 self.insert(from, (Relation::<T>::new(payload, to),))
1482 }
1483
1484 pub fn relate_pair<const LOCKING: bool, I: Component, O: Component>(
1485 &mut self,
1486 payload_incoming: I,
1487 payload_outgoing: O,
1488 from: Entity,
1489 to: Entity,
1490 ) -> Result<(), WorldError> {
1491 self.relate::<LOCKING, _>(payload_outgoing, from, to)?;
1492 self.relate::<LOCKING, _>(payload_incoming, to, from)?;
1493 Ok(())
1494 }
1495
1496 pub fn unrelate<const LOCKING: bool, T: Component>(
1497 &mut self,
1498 from: Entity,
1499 to: Entity,
1500 ) -> Result<(), WorldError> {
1501 let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1502 if let Some(relation) = relation.write() {
1503 relation.remove(to);
1504 relation.is_empty()
1505 } else {
1506 false
1507 }
1508 } else {
1509 false
1510 };
1511 if remove {
1512 self.remove::<(Relation<T>,)>(from)?;
1513 }
1514 Ok(())
1515 }
1516
1517 pub fn unrelate_pair<const LOCKING: bool, I: Component, O: Component>(
1518 &mut self,
1519 from: Entity,
1520 to: Entity,
1521 ) -> Result<(), WorldError> {
1522 self.unrelate::<LOCKING, O>(from, to)?;
1523 self.unrelate::<LOCKING, I>(to, from)?;
1524 Ok(())
1525 }
1526
1527 pub fn unrelate_any<const LOCKING: bool, T: Component>(
1528 &mut self,
1529 entity: Entity,
1530 ) -> Result<(), WorldError> {
1531 let to_remove = self
1532 .query::<LOCKING, (Entity, &mut Relation<T>)>()
1533 .filter_map(|(e, relation)| {
1534 relation.remove(entity);
1535 if relation.is_empty() { Some(e) } else { None }
1536 })
1537 .collect::<Vec<_>>();
1538 for entity in to_remove {
1539 self.remove::<(Relation<T>,)>(entity)?;
1540 }
1541 Ok(())
1542 }
1543
1544 pub fn unrelate_all<const LOCKING: bool, T: Component>(
1545 &mut self,
1546 entity: Entity,
1547 ) -> Result<(), WorldError> {
1548 let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(entity, true) {
1549 if let Some(relation) = relation.write() {
1550 relation.clear();
1551 relation.is_empty()
1552 } else {
1553 false
1554 }
1555 } else {
1556 false
1557 };
1558 if remove {
1559 self.remove::<(Relation<T>,)>(entity)?;
1560 }
1561 Ok(())
1562 }
1563
1564 pub fn has_relation<const LOCKING: bool, T: Component>(
1565 &self,
1566 from: Entity,
1567 to: Entity,
1568 ) -> bool {
1569 self.get::<LOCKING, Relation<T>>(from, false)
1570 .ok()
1571 .and_then(|relation| Some(relation.read()?.has(to)))
1572 .unwrap_or_default()
1573 }
1574
1575 pub fn relations<const LOCKING: bool, T: Component>(
1576 &self,
1577 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1578 self.query::<LOCKING, (Entity, &Relation<T>)>()
1579 .flat_map(|(from, relation)| {
1580 relation
1581 .iter()
1582 .map(move |(payload, to)| (from, payload, to))
1583 })
1584 }
1585
1586 pub fn relations_mut<const LOCKING: bool, T: Component>(
1587 &self,
1588 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1589 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1590 .flat_map(|(from, relation)| {
1591 relation
1592 .iter_mut()
1593 .map(move |(payload, to)| (from, payload, to))
1594 })
1595 }
1596
1597 pub fn relations_outgoing<const LOCKING: bool, T: Component>(
1598 &self,
1599 from: Entity,
1600 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1601 self.query::<LOCKING, (Entity, &Relation<T>)>()
1602 .filter(move |(entity, _)| *entity == from)
1603 .flat_map(|(from, relation)| {
1604 relation
1605 .iter()
1606 .map(move |(payload, to)| (from, payload, to))
1607 })
1608 }
1609
1610 pub fn relations_outgoing_mut<const LOCKING: bool, T: Component>(
1611 &self,
1612 from: Entity,
1613 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1614 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1615 .filter(move |(entity, _)| *entity == from)
1616 .flat_map(|(from, relation)| {
1617 relation
1618 .iter_mut()
1619 .map(move |(payload, to)| (from, payload, to))
1620 })
1621 }
1622
1623 pub fn relations_incomming<const LOCKING: bool, T: Component>(
1624 &self,
1625 to: Entity,
1626 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1627 self.query::<LOCKING, (Entity, &Relation<T>)>()
1628 .flat_map(move |(from, relation)| {
1629 relation
1630 .iter()
1631 .filter(move |(_, entity)| *entity == to)
1632 .map(move |(payload, to)| (from, payload, to))
1633 })
1634 }
1635
1636 pub fn relations_incomming_mut<const LOCKING: bool, T: Component>(
1637 &self,
1638 to: Entity,
1639 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1640 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1641 .flat_map(move |(from, relation)| {
1642 relation
1643 .iter_mut()
1644 .filter(move |(_, entity)| *entity == to)
1645 .map(move |(payload, to)| (from, payload, to))
1646 })
1647 }
1648
1649 pub fn traverse_outgoing<const LOCKING: bool, T: Component>(
1650 &'_ self,
1651 entities: impl IntoIterator<Item = Entity>,
1652 ) -> RelationsTraverseIter<'_, LOCKING, T> {
1653 RelationsTraverseIter {
1654 world: self,
1655 incoming: false,
1656 stack: entities.into_iter().map(|entity| (None, entity)).collect(),
1657 visited: Default::default(),
1658 _phantom: Default::default(),
1659 }
1660 }
1661
1662 pub fn traverse_incoming<const LOCKING: bool, T: Component>(
1663 &'_ self,
1664 entities: impl IntoIterator<Item = Entity>,
1665 ) -> RelationsTraverseIter<'_, LOCKING, T> {
1666 RelationsTraverseIter {
1667 world: self,
1668 incoming: true,
1669 stack: entities.into_iter().map(|entity| (None, entity)).collect(),
1670 visited: Default::default(),
1671 _phantom: Default::default(),
1672 }
1673 }
1674
1675 pub fn relation_lookup<'a, const LOCKING: bool, Fetch: TypedRelationLookupFetch<'a>>(
1676 &'a self,
1677 entity: Entity,
1678 ) -> TypedRelationLookupIter<'a, Fetch> {
1679 TypedRelationLookupIter::new(self, entity)
1680 }
1681}
1682
1683#[cfg(test)]
1684mod tests {
1685 use super::*;
1686 use crate::{
1687 commands::{CommandBuffer, DespawnCommand},
1688 query::{Exclude, Include, Update},
1689 };
1690 use std::{
1691 sync::{Arc, RwLock},
1692 thread::spawn,
1693 time::{Duration, Instant},
1694 };
1695
1696 #[test]
1697 fn test_world_changes() {
1698 let mut world = World::default();
1699 assert!(world.is_empty());
1700 assert!(world.spawn(()).is_err());
1701
1702 let (entity, row) = unsafe { world.spawn_uninitialized::<(u8, u16, u32)>().unwrap() };
1703 assert_eq!(entity, Entity::new(0, 0).unwrap());
1704 unsafe { row.initialize(1u8).unwrap() };
1705 unsafe { row.initialize(2u16).unwrap() };
1706 unsafe { row.initialize(3u32).unwrap() };
1707 assert_eq!(*row.read::<u8>().unwrap(), 1);
1708 assert_eq!(*row.read::<u16>().unwrap(), 2);
1709 assert_eq!(*row.read::<u32>().unwrap(), 3);
1710 drop(row);
1711 world.despawn(entity).unwrap();
1712 assert!(world.is_empty());
1713
1714 let entity = world.spawn((1u8, 2u16, 3u32)).unwrap();
1715 assert_eq!(entity, Entity::new(0, 1).unwrap());
1716 assert_eq!(
1717 *world
1718 .get::<true, u8>(entity, false)
1719 .unwrap()
1720 .read()
1721 .unwrap(),
1722 1
1723 );
1724 assert_eq!(
1725 *world
1726 .get::<true, u16>(entity, false)
1727 .unwrap()
1728 .read()
1729 .unwrap(),
1730 2
1731 );
1732 assert_eq!(
1733 *world
1734 .get::<true, u32>(entity, false)
1735 .unwrap()
1736 .read()
1737 .unwrap(),
1738 3
1739 );
1740 assert!(world.get::<true, u64>(entity, false).is_err());
1741 assert_eq!(world.len(), 1);
1742
1743 world.insert(entity, (4u64,)).unwrap();
1744 assert_eq!(
1745 *world
1746 .get::<true, u8>(entity, false)
1747 .unwrap()
1748 .read()
1749 .unwrap(),
1750 1
1751 );
1752 assert_eq!(
1753 *world
1754 .get::<true, u16>(entity, false)
1755 .unwrap()
1756 .read()
1757 .unwrap(),
1758 2
1759 );
1760 assert_eq!(
1761 *world
1762 .get::<true, u32>(entity, false)
1763 .unwrap()
1764 .read()
1765 .unwrap(),
1766 3
1767 );
1768 assert_eq!(
1769 *world
1770 .get::<true, u64>(entity, false)
1771 .unwrap()
1772 .read()
1773 .unwrap(),
1774 4
1775 );
1776
1777 world.remove::<(u8,)>(entity).unwrap();
1778 assert!(world.get::<true, u8>(entity, false).is_err());
1779 assert_eq!(
1780 *world
1781 .get::<true, u16>(entity, false)
1782 .unwrap()
1783 .read()
1784 .unwrap(),
1785 2
1786 );
1787 assert_eq!(
1788 *world
1789 .get::<true, u32>(entity, false)
1790 .unwrap()
1791 .read()
1792 .unwrap(),
1793 3
1794 );
1795 assert_eq!(
1796 *world
1797 .get::<true, u64>(entity, false)
1798 .unwrap()
1799 .read()
1800 .unwrap(),
1801 4
1802 );
1803
1804 world.clear();
1805 assert!(world.is_empty());
1806 }
1807
1808 #[test]
1809 fn test_world_query() {
1810 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1811
1812 let mut world = World::default().with_new_archetype_capacity(N);
1813
1814 for index in 0..N {
1815 world.spawn((index as u8,)).unwrap();
1816 }
1817 for index in N..(N * 2) {
1818 world.spawn((index as u8, index as u16)).unwrap();
1819 }
1820 for index in (N * 2)..(N * 3) {
1821 world.spawn((index as u16,)).unwrap();
1822 }
1823
1824 for (index, v) in world.query::<true, &u8>().enumerate() {
1825 assert_eq!(*v, index as u8);
1826 }
1827
1828 for (index, item) in world
1829 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>())
1830 .enumerate()
1831 {
1832 let v = item.read::<u8>().unwrap().read::<u8>().unwrap();
1833 assert_eq!(*v, index as u8);
1834 }
1835
1836 for (index, v) in world.query::<true, &u16>().enumerate() {
1837 assert_eq!(*v, (index + N) as u16);
1838 }
1839
1840 for (index, item) in world
1841 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u16>())
1842 .enumerate()
1843 {
1844 let v = item.read::<u16>().unwrap().read::<u16>().unwrap();
1845 assert_eq!(*v, (index + N) as u16);
1846 }
1847
1848 for (index, (entity, a, b)) in world.query::<true, (Entity, &u8, &u16)>().enumerate() {
1849 assert!(entity.is_valid());
1850 assert_eq!(*a, (index + N) as u8);
1851 assert_eq!(*b, (index + N) as u16);
1852 }
1853
1854 for (index, item) in world
1855 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().read::<u16>())
1856 .enumerate()
1857 {
1858 let a = item.read::<u8>().unwrap().read::<u8>().unwrap();
1859 let b = item.read::<u16>().unwrap().read::<u16>().unwrap();
1860 assert!(item.entity().is_valid());
1861 assert_eq!(*a, (index + N) as u8);
1862 assert_eq!(*b, (index + N) as u16);
1863 }
1864
1865 for (index, (a, b)) in world.query::<true, (&u8, Option<&u16>)>().enumerate() {
1866 assert_eq!(*a, index as u8);
1867 if let Some(b) = b {
1868 assert_eq!(*b, index as u16);
1869 }
1870 }
1871
1872 for (entity, _, _) in world.query::<true, (Entity, &u8, Include<u16>)>() {
1873 assert!((entity.id() as usize) >= N);
1874 assert!((entity.id() as usize) < N * 2);
1875 }
1876
1877 for item in world
1878 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().include::<u16>())
1879 {
1880 assert!((item.entity().id() as usize) >= N);
1881 assert!((item.entity().id() as usize) < N * 2);
1882 }
1883
1884 for (entity, _, _) in world.query::<true, (Entity, &u8, Exclude<u16>)>() {
1885 assert!((entity.id() as usize) < N);
1886 }
1887
1888 for item in world
1889 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().exclude::<u16>())
1890 {
1891 assert!((item.entity().id() as usize) < N);
1892 }
1893 }
1894
1895 #[test]
1896 fn test_world_lookup() {
1897 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1898
1899 let mut world = World::default().with_new_archetype_capacity(N);
1900
1901 let mut entities = vec![];
1902 for index in 0..N {
1903 let entity = world.spawn((index as u8,)).unwrap();
1904 if index % 2 == 0 {
1905 entities.push(entity);
1906 }
1907 }
1908 assert_eq!(entities.len(), N / 2);
1909
1910 let compare_entities = world
1911 .lookup::<true, (Entity, &u8)>(entities.iter().copied())
1912 .map(|(entity, _)| entity)
1913 .collect::<Vec<_>>();
1914 assert_eq!(compare_entities, entities);
1915
1916 let mut lookup = world.lookup_access::<true, Exclude<f32>>();
1917 for entity in entities.iter().copied() {
1918 assert!(lookup.access(entity).is_some());
1919 }
1920 drop(lookup);
1921
1922 let mut lookup = world.lookup_access::<true, (Entity, &u8)>();
1923 for entity in entities.iter().copied() {
1924 assert_eq!(lookup.access(entity).unwrap().0, entity);
1925 }
1926 drop(lookup);
1927
1928 let compare_entities = world
1929 .dynamic_lookup::<true>(
1930 &DynamicQueryFilter::default().read::<u8>(),
1931 entities.iter().copied(),
1932 )
1933 .map(|item| item.entity())
1934 .collect::<Vec<_>>();
1935 assert_eq!(compare_entities, entities);
1936
1937 let lookup =
1938 world.dynamic_lookup_access::<true>(&DynamicQueryFilter::default().read::<u8>());
1939 for entity in entities.iter().copied() {
1940 let item = lookup.access(entity).unwrap();
1941 assert_eq!(item.entity(), entity);
1942 }
1943 drop(lookup);
1944
1945 let entity = world.spawn((1u8, 2.0f32, "3")).unwrap();
1946 let (a, b) = world.entity::<true, (&u8, &mut f32)>(entity).unwrap();
1947 assert_eq!(*a, 1);
1948 assert_eq!(*b, 2.0);
1949 }
1950
1951 #[test]
1952 fn test_change_detection() {
1953 let mut world = World::default();
1954
1955 for index in 0..10usize {
1956 world.spawn((index,)).unwrap();
1957 }
1958 let mut list = world.added().iter_of::<usize>().collect::<Vec<_>>();
1959 list.sort();
1960 assert_eq!(
1961 list,
1962 (0..10)
1963 .map(|index| Entity::new(index, 0).unwrap())
1964 .collect::<Vec<_>>()
1965 );
1966
1967 for mut v in world.query::<true, Update<usize>>() {
1968 *v.write_notified(&world) *= 2;
1969 }
1970 for (entity, v) in world.query::<true, (Entity, &usize)>() {
1971 assert_eq!(entity.id() as usize * 2, *v);
1972 }
1973 let mut list = world
1974 .updated()
1975 .unwrap()
1976 .iter_of::<usize>()
1977 .collect::<Vec<_>>();
1978 list.sort();
1979 assert_eq!(
1980 list,
1981 (0..10)
1982 .map(|index| Entity::new(index, 0).unwrap())
1983 .collect::<Vec<_>>()
1984 );
1985
1986 let mut commands = CommandBuffer::default();
1987 for entity in world.entities() {
1988 commands.command(DespawnCommand::new(entity));
1989 }
1990 commands.execute(&mut world);
1991 let mut list = world.removed().iter_of::<usize>().collect::<Vec<_>>();
1992 list.sort();
1993 assert_eq!(
1994 list,
1995 (0..10)
1996 .map(|index| Entity::new(index, 0).unwrap())
1997 .collect::<Vec<_>>()
1998 );
1999 }
2000
2001 #[test]
2002 fn test_zst_components() {
2003 #[derive(Debug, PartialEq, Eq)]
2004 struct Foo;
2005
2006 #[derive(Debug, PartialEq, Eq)]
2007 struct Bar(bool);
2008
2009 let mut world = World::default();
2010 world.spawn((Foo,)).unwrap();
2011 assert_eq!(world.query::<true, &Foo>().count(), 1);
2012 for v in world.query::<true, &Foo>() {
2013 assert_eq!(v, &Foo);
2014 }
2015 world.spawn((Bar(true),)).unwrap();
2016 assert_eq!(world.query::<true, &Bar>().count(), 1);
2017 for v in world.query::<true, &Bar>() {
2018 assert_eq!(v, &Bar(true));
2019 }
2020 world.spawn((Foo, Bar(false))).unwrap();
2021 assert_eq!(world.query::<true, &Foo>().count(), 2);
2022 assert_eq!(world.query::<true, &Bar>().count(), 2);
2023 assert_eq!(world.query::<true, (&Bar, &Foo)>().count(), 1);
2024 for (a, b) in world.query::<true, (&Bar, &Foo)>() {
2025 assert_eq!(a, &Bar(false));
2026 assert_eq!(b, &Foo);
2027 }
2028 }
2029
2030 #[test]
2031 fn test_world_relations() {
2032 struct Parent;
2033 struct Child;
2034 struct Root;
2035
2036 let mut world = World::default();
2037 let a = world.spawn((0u8, false, Root)).unwrap();
2038 let b = world.spawn((1u8, false)).unwrap();
2039 let c = world.spawn((2u8, false)).unwrap();
2040 let d = world.spawn((3u8, false)).unwrap();
2041 world
2042 .relate_pair::<true, _, _>(Parent, Child, a, b)
2043 .unwrap();
2044 world
2045 .relate_pair::<true, _, _>(Parent, Child, a, c)
2046 .unwrap();
2047 world
2048 .relate_pair::<true, _, _>(Parent, Child, c, d)
2049 .unwrap();
2050
2051 assert_eq!(
2052 world
2053 .relations_incomming::<true, Parent>(a)
2054 .map(|(entity, _, _)| entity)
2055 .collect::<Vec<_>>(),
2056 vec![b, c]
2057 );
2058 assert_eq!(
2059 world
2060 .relations_incomming::<true, Parent>(b)
2061 .map(|(entity, _, _)| entity)
2062 .collect::<Vec<_>>(),
2063 vec![]
2064 );
2065 assert_eq!(
2066 world
2067 .relations_incomming::<true, Parent>(c)
2068 .map(|(entity, _, _)| entity)
2069 .collect::<Vec<_>>(),
2070 vec![d]
2071 );
2072 assert_eq!(
2073 world
2074 .relations_incomming::<true, Parent>(d)
2075 .map(|(entity, _, _)| entity)
2076 .collect::<Vec<_>>(),
2077 vec![]
2078 );
2079
2080 assert_eq!(
2081 world
2082 .relations_outgoing::<true, Parent>(a)
2083 .map(|(_, _, entity)| entity)
2084 .collect::<Vec<_>>(),
2085 vec![]
2086 );
2087 assert_eq!(
2088 world
2089 .relations_outgoing::<true, Parent>(b)
2090 .map(|(_, _, entity)| entity)
2091 .collect::<Vec<_>>(),
2092 vec![a]
2093 );
2094 assert_eq!(
2095 world
2096 .relations_outgoing::<true, Parent>(c)
2097 .map(|(_, _, entity)| entity)
2098 .collect::<Vec<_>>(),
2099 vec![a]
2100 );
2101 assert_eq!(
2102 world
2103 .relations_outgoing::<true, Parent>(d)
2104 .map(|(_, _, entity)| entity)
2105 .collect::<Vec<_>>(),
2106 vec![c]
2107 );
2108
2109 assert_eq!(
2110 world
2111 .traverse_outgoing::<true, Child>([a])
2112 .collect::<Vec<_>>(),
2113 vec![(Entity::INVALID, a), (a, b), (a, c), (c, d)]
2114 );
2115
2116 for (entity, _) in world.query::<true, (Entity, Include<Root>)>() {
2117 for (other, _, _) in world.relations_incomming::<true, Parent>(entity) {
2118 let mut v = world.get::<true, bool>(other, true).unwrap();
2119 let v = v.write().unwrap();
2120 *v = !*v;
2121 }
2122 }
2123
2124 assert!(!*world.get::<true, bool>(a, false).unwrap().read().unwrap());
2125 assert!(*world.get::<true, bool>(b, false).unwrap().read().unwrap());
2126 assert!(*world.get::<true, bool>(c, false).unwrap().read().unwrap());
2127 assert!(!*world.get::<true, bool>(d, false).unwrap().read().unwrap());
2128
2129 world.unrelate::<true, Parent>(b, a).unwrap();
2130 world.unrelate::<true, Parent>(c, a).unwrap();
2131 world.unrelate::<true, Parent>(d, c).unwrap();
2132 assert!(world.query::<true, &Relation<Parent>>().count() == 0);
2133 }
2134
2135 #[test]
2136 fn test_world_async() {
2137 const N: usize = if cfg!(miri) { 10 } else { 1000 };
2138
2139 fn is_async<T: Send + Sync>() {}
2140
2141 is_async::<World>();
2142
2143 let world = Arc::new(RwLock::new(World::default().with_new_archetype_capacity(N)));
2144 let world2 = world.clone();
2145
2146 {
2147 let mut world = world.write().unwrap();
2148 for index in 0..N {
2149 world.spawn((index as u8, index as u16)).unwrap();
2150 }
2151 }
2152
2153 let handle = spawn(move || {
2154 let timer = Instant::now();
2155 while timer.elapsed() < Duration::from_secs(1) {
2156 let world = world2.read().unwrap();
2157 for v in world.query::<true, &mut u16>() {
2158 *v = v.wrapping_add(1);
2159 }
2160 }
2161 });
2162
2163 let timer = Instant::now();
2164 while timer.elapsed() < Duration::from_secs(1) {
2165 let world = world.read().unwrap();
2166 for v in world.query::<true, &mut u8>() {
2167 *v = v.wrapping_add(1);
2168 }
2169 }
2170
2171 let _ = handle.join();
2172 }
2173
2174 #[test]
2175 fn test_add_remove_components() {
2176 struct A(#[allow(dead_code)] f32);
2177 struct B(#[allow(dead_code)] f32);
2178
2179 const N: usize = if cfg!(miri) { 10 } else { 10000 };
2180
2181 let mut world = World::default().with_new_archetype_capacity(1);
2182
2183 let entities = (0..N)
2184 .map(|_| world.spawn((A(0.0),)).unwrap())
2185 .collect::<Vec<_>>();
2186
2187 for entity in &entities {
2188 world.insert(*entity, (B(0.0),)).unwrap();
2189 }
2190
2191 for entity in &entities {
2192 world.remove::<(B,)>(*entity).unwrap();
2193 }
2194 }
2195}