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 #[cfg(feature = "tracing")]
996 #[cfg(feature = "trace-changes")]
997 tracing::event!(
998 name: "Entity spawned",
999 target: "anput::world",
1000 tracing::Level::INFO,
1001 entity = entity.to_string(),
1002 archetype_id = id,
1003 bundle_types = format!("{:?}", bundle_types),
1004 thread_id = format!("{:?}", std::thread::current().id()),
1005 backtrace = format!("{}", std::backtrace::Backtrace::capture()),
1006 );
1007 self.added
1008 .table
1009 .entry(entity)
1010 .or_default()
1011 .extend(bundle_types);
1012 Ok(entity)
1013 }
1014 Err(error) => {
1015 self.entities.release(entity)?;
1016 Err(error.into())
1017 }
1018 }
1019 }
1020
1021 pub unsafe fn spawn_uninitialized<T: BundleColumns>(
1023 &'_ mut self,
1024 ) -> Result<(Entity, ArchetypeEntityRowAccess<'_>), WorldError> {
1025 unsafe { self.spawn_uninitialized_raw(T::columns_static()) }
1026 }
1027
1028 pub unsafe fn spawn_uninitialized_raw(
1030 &'_ mut self,
1031 columns: Vec<ArchetypeColumnInfo>,
1032 ) -> Result<(Entity, ArchetypeEntityRowAccess<'_>), WorldError> {
1033 if columns.is_empty() {
1034 return Err(WorldError::EmptyColumnSet);
1035 }
1036 let bundle_types = columns
1037 .iter()
1038 .map(|column| column.type_hash())
1039 .collect::<Vec<_>>();
1040 let (entity, id) = self.entities.acquire()?;
1041 let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1042 *id = Some(archetype_id);
1043 archetype_id
1044 } else {
1045 let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
1046 Ok(result) => result,
1047 Err(error) => {
1048 self.entities.release(entity)?;
1049 return Err(error);
1050 }
1051 };
1052 let archetype = match Archetype::new(columns, self.new_archetype_capacity) {
1053 Ok(result) => result,
1054 Err(error) => {
1055 self.entities.release(entity)?;
1056 return Err(error.into());
1057 }
1058 };
1059 *archetype_slot = Some(archetype);
1060 *id = Some(archetype_id);
1061 archetype_id
1062 };
1063 let archetype = match self.archetypes.get_mut(id) {
1064 Ok(result) => result,
1065 Err(error) => {
1066 self.entities.release(entity)?;
1067 return Err(error);
1068 }
1069 };
1070 match archetype.add(entity) {
1071 Ok(result) => {
1072 #[cfg(feature = "tracing")]
1073 #[cfg(feature = "trace-changes")]
1074 tracing::event!(
1075 name: "Entity spawned uninitialized",
1076 target: "anput::world",
1077 tracing::Level::INFO,
1078 entity = entity.to_string(),
1079 archetype_id = id,
1080 bundle_types = format!("{:?}", bundle_types),
1081 thread_id = format!("{:?}", std::thread::current().id()),
1082 backtrace = format!("{}", std::backtrace::Backtrace::capture()),
1083 );
1084 self.added
1085 .table
1086 .entry(entity)
1087 .or_default()
1088 .extend(bundle_types);
1089 Ok((entity, result))
1090 }
1091 Err(error) => {
1092 self.entities.release(entity)?;
1093 Err(error.into())
1094 }
1095 }
1096 }
1097
1098 pub fn despawn(&mut self, entity: Entity) -> Result<(), WorldError> {
1099 let id = self.entities.release(entity)?;
1100 let archetype = self.archetypes.get_mut(id).unwrap();
1101 match archetype.remove(entity) {
1102 Ok(_) => {
1103 #[cfg(feature = "tracing")]
1104 #[cfg(feature = "trace-changes")]
1105 tracing::event!(
1106 name: "Entity despawned",
1107 target: "anput::world",
1108 tracing::Level::INFO,
1109 entity = entity.to_string(),
1110 archetype_id = id,
1111 bundle_types = format!("{:?}", archetype.columns().map(|column| column.type_hash()).collect::<Vec<_>>()),
1112 thread_id = format!("{:?}", std::thread::current().id()),
1113 backtrace = format!("{}", std::backtrace::Backtrace::capture()),
1114 );
1115 self.removed
1116 .table
1117 .entry(entity)
1118 .or_default()
1119 .extend(archetype.columns().map(|column| column.type_hash()));
1120 Ok(())
1121 }
1122 Err(error) => {
1123 self.entities.acquire()?;
1124 Err(error.into())
1125 }
1126 }
1127 }
1128
1129 pub unsafe fn despawn_uninitialized(&mut self, entity: Entity) -> Result<(), WorldError> {
1131 let id = self.entities.release(entity)?;
1132 let archetype = self.archetypes.get_mut(id).unwrap();
1133 match unsafe { archetype.remove_uninitialized(entity) } {
1134 Ok(_) => {
1135 #[cfg(feature = "tracing")]
1136 #[cfg(feature = "trace-changes")]
1137 tracing::event!(
1138 name: "Entity despawned uninitialized",
1139 target: "anput::world",
1140 tracing::Level::INFO,
1141 entity = entity.to_string(),
1142 archetype_id = id,
1143 bundle_types = format!("{:?}", archetype.columns().map(|column| column.type_hash()).collect::<Vec<_>>()),
1144 thread_id = format!("{:?}", std::thread::current().id()),
1145 backtrace = format!("{}", std::backtrace::Backtrace::capture()),
1146 );
1147 self.removed
1148 .table
1149 .entry(entity)
1150 .or_default()
1151 .extend(archetype.columns().map(|column| column.type_hash()));
1152 Ok(())
1153 }
1154 Err(error) => {
1155 self.entities.acquire()?;
1156 Err(error.into())
1157 }
1158 }
1159 }
1160
1161 #[inline]
1162 pub fn despawn_all(&mut self) {
1163 #[cfg(feature = "tracing")]
1164 #[cfg(feature = "trace-changes")]
1165 tracing::event!(
1166 name: "Despawned all entities",
1167 target: "anput::world",
1168 tracing::Level::INFO,
1169 thread_id = format!("{:?}", std::thread::current().id()),
1170 backtrace = format!("{}", std::backtrace::Backtrace::capture()),
1171 );
1172 self.archetypes.clear();
1173 self.entities.clear();
1174 }
1175
1176 pub fn insert(&mut self, entity: Entity, bundle: impl Bundle) -> Result<(), WorldError> {
1177 let bundle_columns = bundle.columns();
1178 if bundle_columns.is_empty() {
1179 return Err(WorldError::EmptyColumnSet);
1180 }
1181 let bundle_types = bundle_columns
1182 .iter()
1183 .map(|column| column.type_hash())
1184 .collect::<Vec<_>>();
1185 let old_id = self.entities.get(entity)?;
1186 let mut new_columns = self
1187 .archetypes
1188 .get_mut(old_id)?
1189 .columns()
1190 .cloned()
1191 .collect::<Vec<_>>();
1192 for column in bundle_columns {
1193 if !new_columns
1194 .iter()
1195 .any(|c| c.type_hash() == column.type_hash())
1196 {
1197 new_columns.push(column);
1198 }
1199 }
1200 let _new_id = if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
1201 if new_id == old_id {
1202 return Ok(());
1203 }
1204 let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
1205 let access = old_archetype.transfer(new_archetype, entity)?;
1206 bundle.initialize_into(&access);
1207 self.entities.set(entity, new_id)?;
1208 new_id
1209 } else {
1210 let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1211 let access = self
1212 .archetypes
1213 .get_mut(old_id)
1214 .unwrap()
1215 .transfer(&mut archetype, entity)?;
1216 bundle.initialize_into(&access);
1217 drop(access);
1218 let (new_id, archetype_slot) = self.archetypes.acquire()?;
1219 *archetype_slot = Some(archetype);
1220 self.entities.set(entity, new_id)?;
1221 new_id
1222 };
1223 #[cfg(feature = "tracing")]
1224 #[cfg(feature = "trace-changes")]
1225 tracing::event!(
1226 name: "Inserted components to entity",
1227 target: "anput::world",
1228 tracing::Level::INFO,
1229 entity = entity.to_string(),
1230 old_archetype_id = old_id,
1231 new_archetype_id = _new_id,
1232 bundle_types = format!("{:?}", bundle_types),
1233 thread_id = format!("{:?}", std::thread::current().id()),
1234 backtrace = format!("{}", std::backtrace::Backtrace::capture()),
1235 );
1236 self.added
1237 .table
1238 .entry(entity)
1239 .or_default()
1240 .extend(bundle_types);
1241 Ok(())
1242 }
1243
1244 pub fn remove<T: BundleColumns>(&mut self, entity: Entity) -> Result<(), WorldError> {
1245 self.remove_raw(entity, T::columns_static())
1246 }
1247
1248 pub fn remove_raw(
1249 &mut self,
1250 entity: Entity,
1251 columns: Vec<ArchetypeColumnInfo>,
1252 ) -> Result<(), WorldError> {
1253 if columns.is_empty() {
1254 return Err(WorldError::EmptyColumnSet);
1255 }
1256 let bundle_types = columns
1257 .iter()
1258 .map(|column| column.type_hash())
1259 .collect::<Vec<_>>();
1260 let old_id = self.entities.get(entity)?;
1261 let mut new_columns = self
1262 .archetypes
1263 .get_mut(old_id)?
1264 .columns()
1265 .cloned()
1266 .collect::<Vec<_>>();
1267 let despawn = new_columns.is_empty();
1268 for column in columns {
1269 if let Some(index) = new_columns
1270 .iter()
1271 .position(|c| c.type_hash() == column.type_hash())
1272 {
1273 new_columns.swap_remove(index);
1274 }
1275 }
1276 let _new_id = if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
1277 if new_id == old_id {
1278 return Ok(());
1279 }
1280 let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
1281 old_archetype.transfer(new_archetype, entity)?;
1282 self.entities.set(entity, new_id)?;
1283 new_id
1284 } else {
1285 let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1286 self.archetypes
1287 .get_mut(old_id)
1288 .unwrap()
1289 .transfer(&mut archetype, entity)?;
1290 let (new_id, archetype_slot) = self.archetypes.acquire()?;
1291 *archetype_slot = Some(archetype);
1292 self.entities.set(entity, new_id)?;
1293 new_id
1294 };
1295 if despawn {
1296 let _ = self.entities.release(entity);
1297 }
1298 #[cfg(feature = "tracing")]
1299 #[cfg(feature = "trace-changes")]
1300 tracing::event!(
1301 name: "Removed components from entity",
1302 target: "anput::world",
1303 tracing::Level::INFO,
1304 entity = entity.to_string(),
1305 old_archetype_id = old_id,
1306 new_archetype_id = _new_id,
1307 bundle_types = format!("{:?}", bundle_types),
1308 thread_id = format!("{:?}", std::thread::current().id()),
1309 backtrace = format!("{}", std::backtrace::Backtrace::capture()),
1310 );
1311 self.removed
1312 .table
1313 .entry(entity)
1314 .or_default()
1315 .extend(bundle_types);
1316 Ok(())
1317 }
1318
1319 pub fn merge<const LOCKING: bool>(
1320 &mut self,
1321 mut other: Self,
1322 processor: &WorldProcessor,
1323 ) -> Result<(), WorldError> {
1324 let mut mappings = HashMap::<_, _>::with_capacity(other.len());
1325 let mut archetype_offsets = Vec::with_capacity(other.archetypes().count());
1326 for archetype_from in other.archetypes_mut() {
1327 let columns = archetype_from.columns().cloned().collect::<Vec<_>>();
1328 let archetype_id =
1329 if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1330 archetype_id
1331 } else {
1332 let (archetype_id, archetype_slot) = self.archetypes.acquire()?;
1333 let archetype = Archetype::new(columns.clone(), self.new_archetype_capacity)?;
1334 *archetype_slot = Some(archetype);
1335 archetype_id
1336 };
1337 let archetype = self.archetypes.get_mut(archetype_id)?;
1338 let offset = archetype.len();
1339 let entities_from = archetype_from.entities().iter().collect::<Vec<_>>();
1340 for entity_from in entities_from {
1341 let (entity, access) = unsafe { self.spawn_uninitialized_raw(columns.clone())? };
1342 let access_from = match archetype_from.row::<LOCKING>(entity_from) {
1343 Ok(access_from) => access_from,
1344 Err(error) => {
1345 drop(access);
1346 unsafe { self.despawn_uninitialized(entity)? };
1347 return Err(error.into());
1348 }
1349 };
1350 for column in &columns {
1351 unsafe {
1352 let data = access.data(column.type_hash()).unwrap();
1353 let data_from = access_from.data(column.type_hash()).unwrap();
1354 data.copy_from(data_from, column.layout().size());
1355 }
1356 }
1357 mappings.insert(entity_from, entity);
1358 }
1359 archetype_offsets.push((columns, offset));
1360 unsafe { archetype_from.clear_uninitialized() };
1361 }
1362 for (columns, offset) in archetype_offsets {
1363 if let Some(id) = self.archetypes.find_by_columns_exact(&columns) {
1364 let archetype = self.archetype_by_id(id)?;
1365 for column in archetype.columns() {
1366 let access = archetype.dynamic_column::<LOCKING>(column.type_hash(), true)?;
1367 for index in offset..archetype.len() {
1368 unsafe {
1369 processor.remap_entities_raw(
1370 column.type_hash(),
1371 access.data(index)?,
1372 WorldProcessorEntityMapping::new(&mappings),
1373 );
1374 }
1375 }
1376 }
1377 }
1378 }
1379 Ok(())
1380 }
1381
1382 pub fn has_entity(&self, entity: Entity) -> bool {
1383 self.entities.get(entity).is_ok()
1384 }
1385
1386 pub fn has_entity_component<T: Component>(&self, entity: Entity) -> bool {
1387 self.has_entity_component_raw(entity, TypeHash::of::<T>())
1388 }
1389
1390 pub fn has_entity_component_raw(&self, entity: Entity, component: TypeHash) -> bool {
1391 self.entities
1392 .get(entity)
1393 .and_then(|index| self.archetypes.get(index))
1394 .map(|archetype| archetype.has_type(component))
1395 .unwrap_or_default()
1396 }
1397
1398 pub fn has_component<T: Component>(&self) -> bool {
1399 self.has_component_raw(TypeHash::of::<T>())
1400 }
1401
1402 pub fn has_component_raw(&self, component: TypeHash) -> bool {
1403 self.archetypes
1404 .iter()
1405 .any(|archetype| archetype.has_type(component) && !archetype.is_empty())
1406 }
1407
1408 pub fn find_by<const LOCKING: bool, T: Component + PartialEq>(
1409 &self,
1410 data: &T,
1411 ) -> Option<Entity> {
1412 for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1413 if component == data {
1414 return Some(entity);
1415 }
1416 }
1417 None
1418 }
1419
1420 pub fn find_with<const LOCKING: bool, T: Component>(
1421 &self,
1422 f: impl Fn(&T) -> bool,
1423 ) -> Option<Entity> {
1424 for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1425 if f(component) {
1426 return Some(entity);
1427 }
1428 }
1429 None
1430 }
1431
1432 pub fn component<const LOCKING: bool, T: Component>(
1433 &'_ self,
1434 entity: Entity,
1435 ) -> Result<ComponentRef<'_, LOCKING, T>, WorldError> {
1436 Ok(ComponentRef {
1437 inner: self.get::<LOCKING, T>(entity, false)?,
1438 })
1439 }
1440
1441 pub fn component_mut<const LOCKING: bool, T: Component>(
1442 &'_ self,
1443 entity: Entity,
1444 ) -> Result<ComponentRefMut<'_, LOCKING, T>, WorldError> {
1445 Ok(ComponentRefMut {
1446 inner: self.get::<LOCKING, T>(entity, true)?,
1447 })
1448 }
1449
1450 pub fn get<const LOCKING: bool, T: Component>(
1451 &'_ self,
1452 entity: Entity,
1453 unique: bool,
1454 ) -> Result<ArchetypeEntityColumnAccess<'_, LOCKING, T>, WorldError> {
1455 Ok(self
1456 .archetypes
1457 .get(self.entities.get(entity)?)?
1458 .entity::<LOCKING, T>(entity, unique)?)
1459 }
1460
1461 pub fn dynamic_get<const LOCKING: bool>(
1462 &'_ self,
1463 type_hash: TypeHash,
1464 entity: Entity,
1465 unique: bool,
1466 ) -> Result<ArchetypeDynamicEntityColumnAccess<'_, LOCKING>, WorldError> {
1467 Ok(self
1468 .archetypes
1469 .get(self.entities.get(entity)?)?
1470 .dynamic_entity::<LOCKING>(type_hash, entity, unique)?)
1471 }
1472
1473 pub fn row<const LOCKING: bool>(
1474 &'_ self,
1475 entity: Entity,
1476 ) -> Result<ArchetypeEntityRowAccess<'_>, WorldError> {
1477 Ok(self
1478 .archetypes
1479 .get(self.entities.get(entity)?)?
1480 .row::<LOCKING>(entity)?)
1481 }
1482
1483 pub fn entity<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1484 &'a self,
1485 entity: Entity,
1486 ) -> Option<Fetch::Value> {
1487 self.lookup_access::<LOCKING, Fetch>().access(entity)
1490 }
1491
1492 pub fn query<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>>(
1493 &'a self,
1494 ) -> TypedQueryIter<'a, LOCKING, Fetch> {
1495 TypedQueryIter::new(self)
1496 }
1497
1498 pub fn dynamic_query<'a, const LOCKING: bool>(
1499 &'a self,
1500 filter: &DynamicQueryFilter,
1501 ) -> DynamicQueryIter<'a, LOCKING> {
1502 DynamicQueryIter::new(filter, self)
1503 }
1504
1505 pub fn lookup<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1506 &'a self,
1507 entities: impl IntoIterator<Item = Entity> + 'a,
1508 ) -> TypedLookupIter<'a, LOCKING, Fetch> {
1509 TypedLookupIter::new(self, entities)
1510 }
1511
1512 pub fn lookup_access<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1513 &'a self,
1514 ) -> TypedLookupAccess<'a, LOCKING, Fetch> {
1515 TypedLookupAccess::new(self)
1516 }
1517
1518 pub fn lookup_one<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1519 &'a self,
1520 entity: Entity,
1521 ) -> Option<Fetch::ValueOne> {
1522 Fetch::fetch_one(self, entity)
1523 }
1524
1525 pub fn dynamic_lookup<'a, const LOCKING: bool>(
1526 &'a self,
1527 filter: &DynamicQueryFilter,
1528 entities: impl IntoIterator<Item = Entity> + 'a,
1529 ) -> DynamicLookupIter<'a, LOCKING> {
1530 DynamicLookupIter::new(filter, self, entities)
1531 }
1532
1533 pub fn dynamic_lookup_access<'a, const LOCKING: bool>(
1534 &'a self,
1535 filter: &DynamicQueryFilter,
1536 ) -> DynamicLookupAccess<'a, LOCKING> {
1537 DynamicLookupAccess::new(filter, self)
1538 }
1539
1540 pub fn relate<const LOCKING: bool, T: Component>(
1541 &mut self,
1542 payload: T,
1543 from: Entity,
1544 to: Entity,
1545 ) -> Result<(), WorldError> {
1546 if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1547 if let Some(relation) = relation.write() {
1548 relation.add(payload, to);
1549 }
1550 return Ok(());
1551 }
1552 self.insert(from, (Relation::<T>::new(payload, to),))
1553 }
1554
1555 pub fn relate_one<const LOCKING: bool, T: Component>(
1556 &mut self,
1557 payload: T,
1558 from: Entity,
1559 to: Entity,
1560 ) -> Result<(), WorldError> {
1561 if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1562 if let Some(relation) = relation.write() {
1563 relation.clear();
1564 relation.add(payload, to);
1565 }
1566 return Ok(());
1567 }
1568 self.insert(from, (Relation::<T>::new(payload, to),))
1569 }
1570
1571 pub fn relate_pair<const LOCKING: bool, I: Component, O: Component>(
1572 &mut self,
1573 payload_incoming: I,
1574 payload_outgoing: O,
1575 from: Entity,
1576 to: Entity,
1577 ) -> Result<(), WorldError> {
1578 self.relate::<LOCKING, _>(payload_outgoing, from, to)?;
1579 self.relate::<LOCKING, _>(payload_incoming, to, from)?;
1580 Ok(())
1581 }
1582
1583 pub fn unrelate<const LOCKING: bool, T: Component>(
1584 &mut self,
1585 from: Entity,
1586 to: Entity,
1587 ) -> Result<(), WorldError> {
1588 let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1589 if let Some(relation) = relation.write() {
1590 relation.remove(to);
1591 relation.is_empty()
1592 } else {
1593 false
1594 }
1595 } else {
1596 false
1597 };
1598 if remove {
1599 self.remove::<(Relation<T>,)>(from)?;
1600 }
1601 Ok(())
1602 }
1603
1604 pub fn unrelate_pair<const LOCKING: bool, I: Component, O: Component>(
1605 &mut self,
1606 from: Entity,
1607 to: Entity,
1608 ) -> Result<(), WorldError> {
1609 self.unrelate::<LOCKING, O>(from, to)?;
1610 self.unrelate::<LOCKING, I>(to, from)?;
1611 Ok(())
1612 }
1613
1614 pub fn unrelate_any<const LOCKING: bool, T: Component>(
1615 &mut self,
1616 entity: Entity,
1617 ) -> Result<(), WorldError> {
1618 let to_remove = self
1619 .query::<LOCKING, (Entity, &mut Relation<T>)>()
1620 .filter_map(|(e, relation)| {
1621 relation.remove(entity);
1622 if relation.is_empty() { Some(e) } else { None }
1623 })
1624 .collect::<Vec<_>>();
1625 for entity in to_remove {
1626 self.remove::<(Relation<T>,)>(entity)?;
1627 }
1628 Ok(())
1629 }
1630
1631 pub fn unrelate_all<const LOCKING: bool, T: Component>(
1632 &mut self,
1633 entity: Entity,
1634 ) -> Result<(), WorldError> {
1635 let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(entity, true) {
1636 if let Some(relation) = relation.write() {
1637 relation.clear();
1638 relation.is_empty()
1639 } else {
1640 false
1641 }
1642 } else {
1643 false
1644 };
1645 if remove {
1646 self.remove::<(Relation<T>,)>(entity)?;
1647 }
1648 Ok(())
1649 }
1650
1651 pub fn has_relation<const LOCKING: bool, T: Component>(
1652 &self,
1653 from: Entity,
1654 to: Entity,
1655 ) -> bool {
1656 self.get::<LOCKING, Relation<T>>(from, false)
1657 .ok()
1658 .and_then(|relation| Some(relation.read()?.has(to)))
1659 .unwrap_or_default()
1660 }
1661
1662 pub fn relations<const LOCKING: bool, T: Component>(
1663 &self,
1664 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1665 self.query::<LOCKING, (Entity, &Relation<T>)>()
1666 .flat_map(|(from, relation)| {
1667 relation
1668 .iter()
1669 .map(move |(payload, to)| (from, payload, to))
1670 })
1671 }
1672
1673 pub fn relations_mut<const LOCKING: bool, T: Component>(
1674 &self,
1675 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1676 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1677 .flat_map(|(from, relation)| {
1678 relation
1679 .iter_mut()
1680 .map(move |(payload, to)| (from, payload, to))
1681 })
1682 }
1683
1684 pub fn relations_outgoing<const LOCKING: bool, T: Component>(
1685 &self,
1686 from: Entity,
1687 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1688 self.query::<LOCKING, (Entity, &Relation<T>)>()
1689 .filter(move |(entity, _)| *entity == from)
1690 .flat_map(|(from, relation)| {
1691 relation
1692 .iter()
1693 .map(move |(payload, to)| (from, payload, to))
1694 })
1695 }
1696
1697 pub fn relations_outgoing_mut<const LOCKING: bool, T: Component>(
1698 &self,
1699 from: Entity,
1700 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1701 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1702 .filter(move |(entity, _)| *entity == from)
1703 .flat_map(|(from, relation)| {
1704 relation
1705 .iter_mut()
1706 .map(move |(payload, to)| (from, payload, to))
1707 })
1708 }
1709
1710 pub fn relations_incomming<const LOCKING: bool, T: Component>(
1711 &self,
1712 to: Entity,
1713 ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1714 self.query::<LOCKING, (Entity, &Relation<T>)>()
1715 .flat_map(move |(from, relation)| {
1716 relation
1717 .iter()
1718 .filter(move |(_, entity)| *entity == to)
1719 .map(move |(payload, to)| (from, payload, to))
1720 })
1721 }
1722
1723 pub fn relations_incomming_mut<const LOCKING: bool, T: Component>(
1724 &self,
1725 to: Entity,
1726 ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1727 self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1728 .flat_map(move |(from, relation)| {
1729 relation
1730 .iter_mut()
1731 .filter(move |(_, entity)| *entity == to)
1732 .map(move |(payload, to)| (from, payload, to))
1733 })
1734 }
1735
1736 pub fn traverse_outgoing<const LOCKING: bool, T: Component>(
1737 &'_ self,
1738 entities: impl IntoIterator<Item = Entity>,
1739 ) -> RelationsTraverseIter<'_, LOCKING, T> {
1740 RelationsTraverseIter {
1741 world: self,
1742 incoming: false,
1743 stack: entities.into_iter().map(|entity| (None, entity)).collect(),
1744 visited: Default::default(),
1745 _phantom: Default::default(),
1746 }
1747 }
1748
1749 pub fn traverse_incoming<const LOCKING: bool, T: Component>(
1750 &'_ self,
1751 entities: impl IntoIterator<Item = Entity>,
1752 ) -> RelationsTraverseIter<'_, LOCKING, T> {
1753 RelationsTraverseIter {
1754 world: self,
1755 incoming: true,
1756 stack: entities.into_iter().map(|entity| (None, entity)).collect(),
1757 visited: Default::default(),
1758 _phantom: Default::default(),
1759 }
1760 }
1761
1762 pub fn relation_lookup<'a, const LOCKING: bool, Fetch: TypedRelationLookupFetch<'a>>(
1763 &'a self,
1764 entity: Entity,
1765 ) -> TypedRelationLookupIter<'a, Fetch> {
1766 TypedRelationLookupIter::new(self, entity)
1767 }
1768}
1769
1770#[cfg(test)]
1771mod tests {
1772 use super::*;
1773 use crate::{
1774 commands::{CommandBuffer, DespawnCommand},
1775 query::{Exclude, Include, Update},
1776 };
1777 use std::{
1778 sync::{Arc, RwLock},
1779 thread::spawn,
1780 time::{Duration, Instant},
1781 };
1782
1783 #[test]
1784 fn test_world_changes() {
1785 let mut world = World::default();
1786 assert!(world.is_empty());
1787 assert!(world.spawn(()).is_err());
1788
1789 let (entity, row) = unsafe { world.spawn_uninitialized::<(u8, u16, u32)>().unwrap() };
1790 assert_eq!(entity, Entity::new(0, 0).unwrap());
1791 unsafe { row.initialize(1u8).unwrap() };
1792 unsafe { row.initialize(2u16).unwrap() };
1793 unsafe { row.initialize(3u32).unwrap() };
1794 assert_eq!(*row.read::<u8>().unwrap(), 1);
1795 assert_eq!(*row.read::<u16>().unwrap(), 2);
1796 assert_eq!(*row.read::<u32>().unwrap(), 3);
1797 drop(row);
1798 world.despawn(entity).unwrap();
1799 assert!(world.is_empty());
1800
1801 let entity = world.spawn((1u8, 2u16, 3u32)).unwrap();
1802 assert_eq!(entity, Entity::new(0, 1).unwrap());
1803 assert_eq!(
1804 *world
1805 .get::<true, u8>(entity, false)
1806 .unwrap()
1807 .read()
1808 .unwrap(),
1809 1
1810 );
1811 assert_eq!(
1812 *world
1813 .get::<true, u16>(entity, false)
1814 .unwrap()
1815 .read()
1816 .unwrap(),
1817 2
1818 );
1819 assert_eq!(
1820 *world
1821 .get::<true, u32>(entity, false)
1822 .unwrap()
1823 .read()
1824 .unwrap(),
1825 3
1826 );
1827 assert!(world.get::<true, u64>(entity, false).is_err());
1828 assert_eq!(world.len(), 1);
1829
1830 world.insert(entity, (4u64,)).unwrap();
1831 assert_eq!(
1832 *world
1833 .get::<true, u8>(entity, false)
1834 .unwrap()
1835 .read()
1836 .unwrap(),
1837 1
1838 );
1839 assert_eq!(
1840 *world
1841 .get::<true, u16>(entity, false)
1842 .unwrap()
1843 .read()
1844 .unwrap(),
1845 2
1846 );
1847 assert_eq!(
1848 *world
1849 .get::<true, u32>(entity, false)
1850 .unwrap()
1851 .read()
1852 .unwrap(),
1853 3
1854 );
1855 assert_eq!(
1856 *world
1857 .get::<true, u64>(entity, false)
1858 .unwrap()
1859 .read()
1860 .unwrap(),
1861 4
1862 );
1863
1864 world.remove::<(u8,)>(entity).unwrap();
1865 assert!(world.get::<true, u8>(entity, false).is_err());
1866 assert_eq!(
1867 *world
1868 .get::<true, u16>(entity, false)
1869 .unwrap()
1870 .read()
1871 .unwrap(),
1872 2
1873 );
1874 assert_eq!(
1875 *world
1876 .get::<true, u32>(entity, false)
1877 .unwrap()
1878 .read()
1879 .unwrap(),
1880 3
1881 );
1882 assert_eq!(
1883 *world
1884 .get::<true, u64>(entity, false)
1885 .unwrap()
1886 .read()
1887 .unwrap(),
1888 4
1889 );
1890
1891 world.clear();
1892 assert!(world.is_empty());
1893 }
1894
1895 #[test]
1896 fn test_world_query() {
1897 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1898
1899 let mut world = World::default().with_new_archetype_capacity(N);
1900
1901 for index in 0..N {
1902 world.spawn((index as u8,)).unwrap();
1903 }
1904 for index in N..(N * 2) {
1905 world.spawn((index as u8, index as u16)).unwrap();
1906 }
1907 for index in (N * 2)..(N * 3) {
1908 world.spawn((index as u16,)).unwrap();
1909 }
1910
1911 for (index, v) in world.query::<true, &u8>().enumerate() {
1912 assert_eq!(*v, index as u8);
1913 }
1914
1915 for (index, item) in world
1916 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>())
1917 .enumerate()
1918 {
1919 let v = item.read::<u8>().unwrap().read::<u8>().unwrap();
1920 assert_eq!(*v, index as u8);
1921 }
1922
1923 for (index, v) in world.query::<true, &u16>().enumerate() {
1924 assert_eq!(*v, (index + N) as u16);
1925 }
1926
1927 for (index, item) in world
1928 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u16>())
1929 .enumerate()
1930 {
1931 let v = item.read::<u16>().unwrap().read::<u16>().unwrap();
1932 assert_eq!(*v, (index + N) as u16);
1933 }
1934
1935 for (index, (entity, a, b)) in world.query::<true, (Entity, &u8, &u16)>().enumerate() {
1936 assert!(entity.is_valid());
1937 assert_eq!(*a, (index + N) as u8);
1938 assert_eq!(*b, (index + N) as u16);
1939 }
1940
1941 for (index, item) in world
1942 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().read::<u16>())
1943 .enumerate()
1944 {
1945 let a = item.read::<u8>().unwrap().read::<u8>().unwrap();
1946 let b = item.read::<u16>().unwrap().read::<u16>().unwrap();
1947 assert!(item.entity().is_valid());
1948 assert_eq!(*a, (index + N) as u8);
1949 assert_eq!(*b, (index + N) as u16);
1950 }
1951
1952 for (index, (a, b)) in world.query::<true, (&u8, Option<&u16>)>().enumerate() {
1953 assert_eq!(*a, index as u8);
1954 if let Some(b) = b {
1955 assert_eq!(*b, index as u16);
1956 }
1957 }
1958
1959 for (entity, _, _) in world.query::<true, (Entity, &u8, Include<u16>)>() {
1960 assert!((entity.id() as usize) >= N);
1961 assert!((entity.id() as usize) < N * 2);
1962 }
1963
1964 for item in world
1965 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().include::<u16>())
1966 {
1967 assert!((item.entity().id() as usize) >= N);
1968 assert!((item.entity().id() as usize) < N * 2);
1969 }
1970
1971 for (entity, _, _) in world.query::<true, (Entity, &u8, Exclude<u16>)>() {
1972 assert!((entity.id() as usize) < N);
1973 }
1974
1975 for item in world
1976 .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().exclude::<u16>())
1977 {
1978 assert!((item.entity().id() as usize) < N);
1979 }
1980 }
1981
1982 #[test]
1983 fn test_world_lookup() {
1984 const N: usize = if cfg!(miri) { 10 } else { 1000 };
1985
1986 let mut world = World::default().with_new_archetype_capacity(N);
1987
1988 let mut entities = vec![];
1989 for index in 0..N {
1990 let entity = world.spawn((index as u8,)).unwrap();
1991 if index % 2 == 0 {
1992 entities.push(entity);
1993 }
1994 }
1995 assert_eq!(entities.len(), N / 2);
1996
1997 let compare_entities = world
1998 .lookup::<true, (Entity, &u8)>(entities.iter().copied())
1999 .map(|(entity, _)| entity)
2000 .collect::<Vec<_>>();
2001 assert_eq!(compare_entities, entities);
2002
2003 let mut lookup = world.lookup_access::<true, Exclude<f32>>();
2004 for entity in entities.iter().copied() {
2005 assert!(lookup.access(entity).is_some());
2006 }
2007 drop(lookup);
2008
2009 let mut lookup = world.lookup_access::<true, (Entity, &u8)>();
2010 for entity in entities.iter().copied() {
2011 assert_eq!(lookup.access(entity).unwrap().0, entity);
2012 }
2013 drop(lookup);
2014
2015 let compare_entities = world
2016 .dynamic_lookup::<true>(
2017 &DynamicQueryFilter::default().read::<u8>(),
2018 entities.iter().copied(),
2019 )
2020 .map(|item| item.entity())
2021 .collect::<Vec<_>>();
2022 assert_eq!(compare_entities, entities);
2023
2024 let lookup =
2025 world.dynamic_lookup_access::<true>(&DynamicQueryFilter::default().read::<u8>());
2026 for entity in entities.iter().copied() {
2027 let item = lookup.access(entity).unwrap();
2028 assert_eq!(item.entity(), entity);
2029 }
2030 drop(lookup);
2031
2032 let entity = world.spawn((1u8, 2.0f32, "3")).unwrap();
2033 let (a, b) = world.entity::<true, (&u8, &mut f32)>(entity).unwrap();
2034 assert_eq!(*a, 1);
2035 assert_eq!(*b, 2.0);
2036 }
2037
2038 #[test]
2039 fn test_change_detection() {
2040 let mut world = World::default();
2041
2042 for index in 0..10usize {
2043 world.spawn((index,)).unwrap();
2044 }
2045 let mut list = world.added().iter_of::<usize>().collect::<Vec<_>>();
2046 list.sort();
2047 assert_eq!(
2048 list,
2049 (0..10)
2050 .map(|index| Entity::new(index, 0).unwrap())
2051 .collect::<Vec<_>>()
2052 );
2053
2054 for mut v in world.query::<true, Update<usize>>() {
2055 *v.write_notified(&world) *= 2;
2056 }
2057 for (entity, v) in world.query::<true, (Entity, &usize)>() {
2058 assert_eq!(entity.id() as usize * 2, *v);
2059 }
2060 let mut list = world
2061 .updated()
2062 .unwrap()
2063 .iter_of::<usize>()
2064 .collect::<Vec<_>>();
2065 list.sort();
2066 assert_eq!(
2067 list,
2068 (0..10)
2069 .map(|index| Entity::new(index, 0).unwrap())
2070 .collect::<Vec<_>>()
2071 );
2072
2073 let mut commands = CommandBuffer::default();
2074 for entity in world.entities() {
2075 commands.command(DespawnCommand::new(entity));
2076 }
2077 commands.execute(&mut world);
2078 let mut list = world.removed().iter_of::<usize>().collect::<Vec<_>>();
2079 list.sort();
2080 assert_eq!(
2081 list,
2082 (0..10)
2083 .map(|index| Entity::new(index, 0).unwrap())
2084 .collect::<Vec<_>>()
2085 );
2086 }
2087
2088 #[test]
2089 fn test_zst_components() {
2090 #[derive(Debug, PartialEq, Eq)]
2091 struct Foo;
2092
2093 #[derive(Debug, PartialEq, Eq)]
2094 struct Bar(bool);
2095
2096 let mut world = World::default();
2097 world.spawn((Foo,)).unwrap();
2098 assert_eq!(world.query::<true, &Foo>().count(), 1);
2099 for v in world.query::<true, &Foo>() {
2100 assert_eq!(v, &Foo);
2101 }
2102 world.spawn((Bar(true),)).unwrap();
2103 assert_eq!(world.query::<true, &Bar>().count(), 1);
2104 for v in world.query::<true, &Bar>() {
2105 assert_eq!(v, &Bar(true));
2106 }
2107 world.spawn((Foo, Bar(false))).unwrap();
2108 assert_eq!(world.query::<true, &Foo>().count(), 2);
2109 assert_eq!(world.query::<true, &Bar>().count(), 2);
2110 assert_eq!(world.query::<true, (&Bar, &Foo)>().count(), 1);
2111 for (a, b) in world.query::<true, (&Bar, &Foo)>() {
2112 assert_eq!(a, &Bar(false));
2113 assert_eq!(b, &Foo);
2114 }
2115 }
2116
2117 #[test]
2118 fn test_world_relations() {
2119 struct Parent;
2120 struct Child;
2121 struct Root;
2122
2123 let mut world = World::default();
2124 let a = world.spawn((0u8, false, Root)).unwrap();
2125 let b = world.spawn((1u8, false)).unwrap();
2126 let c = world.spawn((2u8, false)).unwrap();
2127 let d = world.spawn((3u8, false)).unwrap();
2128 world
2129 .relate_pair::<true, _, _>(Parent, Child, a, b)
2130 .unwrap();
2131 world
2132 .relate_pair::<true, _, _>(Parent, Child, a, c)
2133 .unwrap();
2134 world
2135 .relate_pair::<true, _, _>(Parent, Child, c, d)
2136 .unwrap();
2137
2138 assert_eq!(
2139 world
2140 .relations_incomming::<true, Parent>(a)
2141 .map(|(entity, _, _)| entity)
2142 .collect::<Vec<_>>(),
2143 vec![b, c]
2144 );
2145 assert_eq!(
2146 world
2147 .relations_incomming::<true, Parent>(b)
2148 .map(|(entity, _, _)| entity)
2149 .collect::<Vec<_>>(),
2150 vec![]
2151 );
2152 assert_eq!(
2153 world
2154 .relations_incomming::<true, Parent>(c)
2155 .map(|(entity, _, _)| entity)
2156 .collect::<Vec<_>>(),
2157 vec![d]
2158 );
2159 assert_eq!(
2160 world
2161 .relations_incomming::<true, Parent>(d)
2162 .map(|(entity, _, _)| entity)
2163 .collect::<Vec<_>>(),
2164 vec![]
2165 );
2166
2167 assert_eq!(
2168 world
2169 .relations_outgoing::<true, Parent>(a)
2170 .map(|(_, _, entity)| entity)
2171 .collect::<Vec<_>>(),
2172 vec![]
2173 );
2174 assert_eq!(
2175 world
2176 .relations_outgoing::<true, Parent>(b)
2177 .map(|(_, _, entity)| entity)
2178 .collect::<Vec<_>>(),
2179 vec![a]
2180 );
2181 assert_eq!(
2182 world
2183 .relations_outgoing::<true, Parent>(c)
2184 .map(|(_, _, entity)| entity)
2185 .collect::<Vec<_>>(),
2186 vec![a]
2187 );
2188 assert_eq!(
2189 world
2190 .relations_outgoing::<true, Parent>(d)
2191 .map(|(_, _, entity)| entity)
2192 .collect::<Vec<_>>(),
2193 vec![c]
2194 );
2195
2196 assert_eq!(
2197 world
2198 .traverse_outgoing::<true, Child>([a])
2199 .collect::<Vec<_>>(),
2200 vec![(Entity::INVALID, a), (a, b), (a, c), (c, d)]
2201 );
2202
2203 for (entity, _) in world.query::<true, (Entity, Include<Root>)>() {
2204 for (other, _, _) in world.relations_incomming::<true, Parent>(entity) {
2205 let mut v = world.get::<true, bool>(other, true).unwrap();
2206 let v = v.write().unwrap();
2207 *v = !*v;
2208 }
2209 }
2210
2211 assert!(!*world.get::<true, bool>(a, false).unwrap().read().unwrap());
2212 assert!(*world.get::<true, bool>(b, false).unwrap().read().unwrap());
2213 assert!(*world.get::<true, bool>(c, false).unwrap().read().unwrap());
2214 assert!(!*world.get::<true, bool>(d, false).unwrap().read().unwrap());
2215
2216 world.unrelate::<true, Parent>(b, a).unwrap();
2217 world.unrelate::<true, Parent>(c, a).unwrap();
2218 world.unrelate::<true, Parent>(d, c).unwrap();
2219 assert!(world.query::<true, &Relation<Parent>>().count() == 0);
2220 }
2221
2222 #[test]
2223 fn test_world_async() {
2224 const N: usize = if cfg!(miri) { 10 } else { 1000 };
2225
2226 fn is_async<T: Send + Sync>() {}
2227
2228 is_async::<World>();
2229
2230 let world = Arc::new(RwLock::new(World::default().with_new_archetype_capacity(N)));
2231 let world2 = world.clone();
2232
2233 {
2234 let mut world = world.write().unwrap();
2235 for index in 0..N {
2236 world.spawn((index as u8, index as u16)).unwrap();
2237 }
2238 }
2239
2240 let handle = spawn(move || {
2241 let timer = Instant::now();
2242 while timer.elapsed() < Duration::from_secs(1) {
2243 let world = world2.read().unwrap();
2244 for v in world.query::<true, &mut u16>() {
2245 *v = v.wrapping_add(1);
2246 }
2247 }
2248 });
2249
2250 let timer = Instant::now();
2251 while timer.elapsed() < Duration::from_secs(1) {
2252 let world = world.read().unwrap();
2253 for v in world.query::<true, &mut u8>() {
2254 *v = v.wrapping_add(1);
2255 }
2256 }
2257
2258 let _ = handle.join();
2259 }
2260
2261 #[test]
2262 fn test_add_remove_components() {
2263 struct A(#[allow(dead_code)] f32);
2264 struct B(#[allow(dead_code)] f32);
2265
2266 const N: usize = if cfg!(miri) { 10 } else { 10000 };
2267
2268 let mut world = World::default().with_new_archetype_capacity(1);
2269
2270 let entities = (0..N)
2271 .map(|_| world.spawn((A(0.0),)).unwrap())
2272 .collect::<Vec<_>>();
2273
2274 for entity in &entities {
2275 world.insert(*entity, (B(0.0),)).unwrap();
2276 }
2277
2278 for entity in &entities {
2279 world.remove::<(B,)>(*entity).unwrap();
2280 }
2281 }
2282}