intuicio_framework_ecs/
world.rs

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