anput/
world.rs

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/// Represents errors that can occur in the ECS `World`.
26#[derive(Debug, PartialEq, Eq)]
27pub enum WorldError {
28    /// Error related to an archetype operation.
29    Archetype(ArchetypeError),
30    /// Indicates that the system has reached the maximum capacity for entity IDs.
31    ReachedEntityIdCapacity,
32    /// Indicates that the system has reached the maximum capacity for archetype IDs.
33    ReachedArchetypeIdCapacity,
34    /// Indicates that an operation was attempted on an entity that does not exist.
35    EntityDoesNotExists { entity: Entity },
36    /// Indicates that an operation was attempted on an archetype that does not exist.
37    ArchetypeDoesNotExists { id: u32 },
38    /// Indicates an attempt to access the same archetype mutably more than once, which could lead to data race issues.
39    DuplicateMutableArchetypeAccess { id: u32 },
40    /// Indicates that an operation involved an empty column set, which is invalid in the ECS context.
41    EmptyColumnSet,
42}
43
44impl WorldError {
45    /// Allows certain errors to be ignored by providing a fallback value (`ok`).
46    ///
47    /// This method checks whether the error matches any of the allowed error variants
48    /// provided in `items`. If a match is found, the provided fallback value (`ok`) is
49    /// returned instead. Otherwise, the original error is returned.
50    ///
51    /// # Arguments
52    ///
53    /// * `input` - A `Result` that may contain an error to evaluate.
54    /// * `items` - A collection of `WorldError` variants to allow.
55    /// * `ok` - The value to return if the error matches one of the allowed variants.
56    ///
57    /// # Returns
58    ///
59    /// * `Ok(ok)` if the error matches an allowed variant.
60    /// * `Err(error)` if the error does not match any allowed variant.
61    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/// Manages the lifecycle of entities and maps them to archetypes.
110/// Tracks entities using a table and maintains reusable IDs to optimize performance.
111#[derive(Default)]
112struct EntityMap {
113    id_generator: u32,
114    /// index is entity id, value is pair of generation and optional archetype id.
115    table: Vec<(u32, Option<u32>)>,
116    reusable: Vec<Entity>,
117    size: usize,
118}
119
120impl EntityMap {
121    /// Returns `true` if the map contains no active entities.
122    fn is_empty(&self) -> bool {
123        self.size == 0
124    }
125
126    /// Returns the number of active entities in the map.
127    fn len(&self) -> usize {
128        self.size
129    }
130
131    /// Returns an iterator over all active entities.
132    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    /// Clears the map, removing all entities and resetting internal state.
146    fn clear(&mut self) {
147        self.id_generator = 0;
148        self.table.clear();
149        self.reusable.clear();
150        self.size = 0;
151    }
152
153    /// Acquires a new entity. Either reuses an entity ID from the pool or generates a new one.
154    ///
155    /// # Returns
156    /// * `Ok((entity, &mut Option<u32>))` - The newly acquired entity and a mutable reference
157    ///   to its associated archetype.
158    /// * `Err(WorldError::ReachedEntityIdCapacity)` - If the ID generator has reached its maximum capacity.
159    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    /// Releases an entity back into the reusable pool, if it exists.
185    ///
186    /// # Returns
187    /// * `Ok(u32)` - The archetype ID of the released entity.
188    /// * `Err(WorldError::EntityDoesNotExists)` - If the entity does not exist or is already released.
189    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    /// Retrieves the archetype ID for the given entity.
208    ///
209    /// # Returns
210    /// * `Ok(u32)` - The archetype ID associated with the entity.
211    /// * `Err(WorldError::EntityDoesNotExists)` - If the entity does not exist or is invalid.
212    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    /// Sets the archetype ID for the given entity.
229    ///
230    /// # Returns
231    /// * `Ok(())` - If the operation is successful.
232    /// * `Err(WorldError::EntityDoesNotExists)` - If the entity does not exist or is invalid.
233    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/// Manages a collection of archetypes, including the creation, access, and reuse of archetype IDs.
252#[derive(Default)]
253struct ArchetypeMap {
254    id_generator: u32,
255    /// index is archetype id, value is optional archetype.
256    table: Vec<Option<Archetype>>,
257    reusable: Vec<u32>,
258}
259
260impl ArchetypeMap {
261    /// Returns an iterator over all existing archetypes in the map.
262    fn iter(&self) -> impl Iterator<Item = &Archetype> + '_ {
263        self.table.iter().filter_map(|archetype| archetype.as_ref())
264    }
265
266    /// Returns a mutable iterator over all existing archetypes in the map.
267    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    /// Clears all archetypes and resets the internal state of the map.
274    fn clear(&mut self) {
275        self.id_generator = 0;
276        self.table.clear();
277        self.reusable.clear();
278    }
279
280    /// Acquires a new archetype ID, either from the reusable pool or by generating a new one.
281    ///
282    /// # Returns
283    /// * `Ok((u32, &mut Option<Archetype>))` - The ID of the acquired archetype and a mutable reference to it.
284    /// * `Err(WorldError::ReachedArchetypeIdCapacity)` - If the ID generator has reached its maximum capacity.
285    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    /// Retrieves an immutable reference to an archetype by its ID.
307    ///
308    /// # Returns
309    /// * `Ok(&Archetype)` - A reference to the archetype.
310    /// * `Err(WorldError::ArchetypeDoesNotExists)` - If the ID does not correspond to a valid archetype.
311    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    /// Retrieves a mutable reference to an archetype by its ID.
324    ///
325    /// # Returns
326    /// * `Ok(&mut Archetype)` - A mutable reference to the archetype.
327    /// * `Err(WorldError::ArchetypeDoesNotExists)` - If the ID does not correspond to a valid archetype.
328    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    /// Retrieves mutable references to two distinct archetypes by their IDs.
341    ///
342    /// # Returns
343    /// * `Ok([&mut Archetype; 2])` - Mutable references to the requested archetypes.
344    /// * `Err(WorldError::DuplicateMutableArchetypeAccess)` - If the same ID is provided for both archetypes.
345    /// * `Err(WorldError::ArchetypeDoesNotExists)` - If one or both IDs do not correspond to valid archetypes.
346    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    /// Finds an archetype that matches the given set of columns exactly.
380    ///
381    /// # Returns
382    /// * `Some(u32)` - The ID of the matching archetype.
383    /// * `None` - If no archetype matches the provided columns.
384    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/// Represents the connections of a relation between entities.
397/// Can handle zero, one, or multiple connections.
398#[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/// Represents a relationship between entities with associated metadata (payload).
412#[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    /// Installs the relation type into the provided registry for entity processing.
427    pub fn install_to_registry(registry: &mut Registry) {
428        registry.add_type(NativeStructBuilder::new::<Self>().build());
429    }
430
431    /// Registers relation-specific entity remapping and inspection logic with the processor.
432    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    /// Registers debug-specific formatting for this relation in the processor.
460    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    /// Creates a new relation with a single connection.
468    pub fn new(payload: T, entity: Entity) -> Self {
469        Self::default().with(payload, entity)
470    }
471
472    /// Adds a connection to the relation and returns the modified relation.
473    pub fn with(mut self, payload: T, entity: Entity) -> Self {
474        self.add(payload, entity);
475        self
476    }
477
478    /// Returns the hash for the type of the payload.
479    pub fn type_hash(&self) -> TypeHash {
480        TypeHash::of::<T>()
481    }
482
483    /// Returns the number of connections in the relation.
484    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    /// Checks if the relation has no connections.
493    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    /// Adds a connection to the relation, updating or inserting as necessary.
502    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    /// Removes a connection associated with an entity.
518    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    /// Clears all stored relations.
544    pub fn clear(&mut self) {
545        self.connections = Default::default();
546    }
547
548    /// Checks if the relation has a connection with the given entity.
549    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    /// Gets the payload associated with the given entity.
558    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    /// Gets a mutable reference to the payload associated with the given entity.
575    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    /// Returns an iterator over all entities in the relation.
592    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    /// Returns an iterator over all payload-entity pairs in the relation.
602    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    /// Returns a mutable iterator over all payload-entity pairs in the relation.
612    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
622/// An iterator that traverses relations in a graph-like structure, tracking visited entities.
623pub 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/// Represents a record of changes made to entities in the world, tracking their components.
662#[derive(Default, Clone)]
663pub struct WorldChanges {
664    table: HashMap<Entity, Vec<TypeHash>>,
665}
666
667impl WorldChanges {
668    /// Clears all tracked changes.
669    ///
670    /// After calling this, the structure will no longer contain any information about entities
671    /// or their components.
672    pub fn clear(&mut self) {
673        self.table.clear();
674    }
675
676    /// Checks if a specific entity exists in the tracked changes.
677    ///
678    /// # Arguments
679    /// * `entity` - The entity to check for.
680    ///
681    /// # Returns
682    /// `true` if the entity is present in the changes, `false` otherwise.
683    pub fn has_entity(&self, entity: Entity) -> bool {
684        self.table.contains_key(&entity)
685    }
686
687    /// Checks if a specific entity has a component of type `T`.
688    ///
689    /// # Arguments
690    /// * `entity` - The entity to check.
691    ///
692    /// # Type Parameters
693    /// * `T` - The component type to check for.
694    ///
695    /// # Returns
696    /// `true` if the entity has the component, `false` otherwise.
697    pub fn has_entity_component<T>(&self, entity: Entity) -> bool {
698        self.has_entity_component_raw(entity, TypeHash::of::<T>())
699    }
700
701    /// Checks if a specific entity has a component with the given type hash.
702    ///
703    /// # Arguments
704    /// * `entity` - The entity to check.
705    /// * `type_hash` - The type hash of the component.
706    ///
707    /// # Returns
708    /// `true` if the entity has the component, `false` otherwise.
709    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    /// Checks if any entity in the world has a component of type `T`.
717    ///
718    /// # Type Parameters
719    /// * `T` - The component type to check for.
720    ///
721    /// # Returns
722    /// `true` if any entity has the component, `false` otherwise.
723    pub fn has_component<T>(&self) -> bool {
724        self.has_component_raw(TypeHash::of::<T>())
725    }
726
727    /// Checks if any entity in the world has a component with the given type hash.
728    ///
729    /// # Arguments
730    /// * `type_hash` - The type hash of the component.
731    ///
732    /// # Returns
733    /// `true` if any entity has the component, `false` otherwise.
734    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    /// Iterates over all entities and their associated component type hashes.
741    ///
742    /// # Returns
743    /// An iterator of tuples `(Entity, &[TypeHash])`.
744    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    /// Iterates over all entities that have a component of type `T`.
751    ///
752    /// # Type Parameters
753    /// * `T` - The component type to filter by.
754    ///
755    /// # Returns
756    /// An iterator over entities that have the specified component.
757    pub fn iter_of<T>(&self) -> impl Iterator<Item = Entity> + '_ {
758        self.iter_of_raw(TypeHash::of::<T>())
759    }
760
761    /// Iterates over all entities that have a component with the given type hash.
762    ///
763    /// # Arguments
764    /// * `type_hash` - The type hash of the component to filter by.
765    ///
766    /// # Returns
767    /// An iterator over entities that have the specified component.
768    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
776/// Represents the main data structure of the ECS (Entity-Component System),
777/// managing entities, components, and their organizational structure.
778pub struct World {
779    /// The initial capacity for new archetypes. Determines the number of archetypes that can be
780    /// allocated before resizing.
781    pub new_archetype_capacity: usize,
782    entities: EntityMap,
783    archetypes: ArchetypeMap,
784    added: WorldChanges,
785    removed: WorldChanges,
786    updated: Arc<RwLock<WorldChanges>>,
787}
788
789impl Default for World {
790    fn default() -> Self {
791        World {
792            new_archetype_capacity: 128,
793            entities: Default::default(),
794            archetypes: Default::default(),
795            added: Default::default(),
796            removed: Default::default(),
797            updated: Default::default(),
798        }
799    }
800}
801
802impl World {
803    #[inline]
804    pub fn with_new_archetype_capacity(mut self, value: usize) -> Self {
805        self.new_archetype_capacity = value.max(1);
806        self
807    }
808
809    #[inline]
810    pub fn is_empty(&self) -> bool {
811        self.entities.is_empty()
812    }
813
814    #[inline]
815    pub fn len(&self) -> usize {
816        self.entities.len()
817    }
818
819    #[inline]
820    pub fn entities(&self) -> impl Iterator<Item = Entity> + '_ {
821        self.entities.iter()
822    }
823
824    #[inline]
825    pub fn entity_by_index(&self, mut index: usize) -> Option<Entity> {
826        for archetype in self.archetypes() {
827            if index >= archetype.len() {
828                index -= archetype.len();
829                continue;
830            }
831            return archetype.entities().get(index);
832        }
833        None
834    }
835
836    #[inline]
837    pub(crate) fn entity_archetype_id(&self, entity: Entity) -> Result<u32, WorldError> {
838        self.entities.get(entity)
839    }
840
841    #[inline]
842    pub fn archetypes(&self) -> impl Iterator<Item = &Archetype> {
843        self.archetypes.iter()
844    }
845
846    #[inline]
847    pub fn archetypes_mut(&mut self) -> impl Iterator<Item = &mut Archetype> {
848        self.archetypes.iter_mut()
849    }
850
851    #[inline]
852    pub(crate) fn archetype_by_id(&self, id: u32) -> Result<&Archetype, WorldError> {
853        self.archetypes.get(id)
854    }
855
856    pub fn added(&self) -> &WorldChanges {
857        &self.added
858    }
859
860    pub fn removed(&self) -> &WorldChanges {
861        &self.removed
862    }
863
864    pub fn updated(&'_ self) -> Option<RwLockReadGuard<'_, WorldChanges>> {
865        self.updated.try_read().ok()
866    }
867
868    pub fn entity_did_changed(&self, entity: Entity) -> bool {
869        self.added.has_entity(entity)
870            || self.removed.has_entity(entity)
871            || self
872                .updated
873                .try_read()
874                .ok()
875                .map(|updated| updated.has_entity(entity))
876                .unwrap_or_default()
877    }
878
879    pub fn component_did_changed<T>(&self) -> bool {
880        self.component_did_changed_raw(TypeHash::of::<T>())
881    }
882
883    pub fn component_did_changed_raw(&self, type_hash: TypeHash) -> bool {
884        self.added.has_component_raw(type_hash)
885            || self.removed.has_component_raw(type_hash)
886            || self
887                .updated
888                .try_read()
889                .ok()
890                .map(|updated| updated.has_component_raw(type_hash))
891                .unwrap_or_default()
892    }
893
894    pub fn entity_component_did_changed<T>(&self, entity: Entity) -> bool {
895        self.entity_component_did_changed_raw(entity, TypeHash::of::<T>())
896    }
897
898    pub fn entity_component_did_changed_raw(&self, entity: Entity, type_hash: TypeHash) -> bool {
899        self.added.has_entity_component_raw(entity, type_hash)
900            || self.removed.has_entity_component_raw(entity, type_hash)
901            || self
902                .updated
903                .try_read()
904                .ok()
905                .map(|updated| updated.has_entity_component_raw(entity, type_hash))
906                .unwrap_or_default()
907    }
908
909    pub fn update<T>(&self, entity: Entity) {
910        self.update_raw(entity, TypeHash::of::<T>());
911    }
912
913    pub fn update_raw(&self, entity: Entity, type_hash: TypeHash) {
914        if let Ok(mut updated) = self.updated.try_write() {
915            let components = updated.table.entry(entity).or_default();
916            if !components.contains(&type_hash) {
917                components.push(type_hash);
918            }
919        }
920    }
921
922    pub fn validate_sdir(&self) -> Result<(), ArchetypeError> {
923        for archetype in self.archetypes.iter() {
924            archetype.validate_sdir()?;
925        }
926        Ok(())
927    }
928
929    pub fn is_column_sdir_locked_raw(&self, type_hash: TypeHash) -> bool {
930        self.archetypes
931            .iter()
932            .any(|archetype| archetype.is_column_sdir_locked_raw(type_hash))
933    }
934
935    pub fn is_column_sdir_locked<T: Component>(&self) -> bool {
936        self.is_column_sdir_locked_raw(TypeHash::of::<T>())
937    }
938
939    pub fn clear_changes(&mut self) {
940        self.added.clear();
941        self.removed.clear();
942        if let Ok(mut updated) = self.updated.try_write() {
943            updated.clear();
944        }
945    }
946
947    #[inline]
948    pub fn clear(&mut self) {
949        self.clear_changes();
950        self.despawn_all();
951    }
952
953    pub fn spawn(&mut self, bundle: impl Bundle) -> Result<Entity, WorldError> {
954        let bundle_columns = bundle.columns();
955        if bundle_columns.is_empty() {
956            return Err(WorldError::EmptyColumnSet);
957        }
958        let bundle_types = bundle_columns
959            .iter()
960            .map(|column| column.type_hash())
961            .collect::<Vec<_>>();
962        let (entity, id) = self.entities.acquire()?;
963        let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&bundle_columns)
964        {
965            *id = Some(archetype_id);
966            archetype_id
967        } else {
968            let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
969                Ok(result) => result,
970                Err(error) => {
971                    self.entities.release(entity)?;
972                    return Err(error);
973                }
974            };
975            let archetype = match Archetype::new(bundle_columns, self.new_archetype_capacity) {
976                Ok(result) => result,
977                Err(error) => {
978                    self.entities.release(entity)?;
979                    return Err(error.into());
980                }
981            };
982            *archetype_slot = Some(archetype);
983            *id = Some(archetype_id);
984            archetype_id
985        };
986        let archetype = match self.archetypes.get_mut(id) {
987            Ok(result) => result,
988            Err(error) => {
989                self.entities.release(entity)?;
990                return Err(error);
991            }
992        };
993        match archetype.insert(entity, bundle) {
994            Ok(_) => {
995                self.added
996                    .table
997                    .entry(entity)
998                    .or_default()
999                    .extend(bundle_types);
1000                Ok(entity)
1001            }
1002            Err(error) => {
1003                self.entities.release(entity)?;
1004                Err(error.into())
1005            }
1006        }
1007    }
1008
1009    /// # Safety
1010    pub unsafe fn spawn_uninitialized<T: BundleColumns>(
1011        &'_ mut self,
1012    ) -> Result<(Entity, ArchetypeEntityRowAccess<'_>), WorldError> {
1013        unsafe { self.spawn_uninitialized_raw(T::columns_static()) }
1014    }
1015
1016    /// # Safety
1017    pub unsafe fn spawn_uninitialized_raw(
1018        &'_ mut self,
1019        columns: Vec<ArchetypeColumnInfo>,
1020    ) -> Result<(Entity, ArchetypeEntityRowAccess<'_>), WorldError> {
1021        if columns.is_empty() {
1022            return Err(WorldError::EmptyColumnSet);
1023        }
1024        let bundle_types = columns
1025            .iter()
1026            .map(|column| column.type_hash())
1027            .collect::<Vec<_>>();
1028        let (entity, id) = self.entities.acquire()?;
1029        let id = if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1030            *id = Some(archetype_id);
1031            archetype_id
1032        } else {
1033            let (archetype_id, archetype_slot) = match self.archetypes.acquire() {
1034                Ok(result) => result,
1035                Err(error) => {
1036                    self.entities.release(entity)?;
1037                    return Err(error);
1038                }
1039            };
1040            let archetype = match Archetype::new(columns, self.new_archetype_capacity) {
1041                Ok(result) => result,
1042                Err(error) => {
1043                    self.entities.release(entity)?;
1044                    return Err(error.into());
1045                }
1046            };
1047            *archetype_slot = Some(archetype);
1048            *id = Some(archetype_id);
1049            archetype_id
1050        };
1051        let archetype = match self.archetypes.get_mut(id) {
1052            Ok(result) => result,
1053            Err(error) => {
1054                self.entities.release(entity)?;
1055                return Err(error);
1056            }
1057        };
1058        match archetype.add(entity) {
1059            Ok(result) => {
1060                self.added
1061                    .table
1062                    .entry(entity)
1063                    .or_default()
1064                    .extend(bundle_types);
1065                Ok((entity, result))
1066            }
1067            Err(error) => {
1068                self.entities.release(entity)?;
1069                Err(error.into())
1070            }
1071        }
1072    }
1073
1074    pub fn despawn(&mut self, entity: Entity) -> Result<(), WorldError> {
1075        let id = self.entities.release(entity)?;
1076        let archetype = self.archetypes.get_mut(id).unwrap();
1077        match archetype.remove(entity) {
1078            Ok(_) => {
1079                self.removed
1080                    .table
1081                    .entry(entity)
1082                    .or_default()
1083                    .extend(archetype.columns().map(|column| column.type_hash()));
1084                Ok(())
1085            }
1086            Err(error) => {
1087                self.entities.acquire()?;
1088                Err(error.into())
1089            }
1090        }
1091    }
1092
1093    /// # Safety
1094    pub unsafe fn despawn_uninitialized(&mut self, entity: Entity) -> Result<(), WorldError> {
1095        let id = self.entities.release(entity)?;
1096        let archetype = self.archetypes.get_mut(id).unwrap();
1097        match unsafe { archetype.remove_uninitialized(entity) } {
1098            Ok(_) => {
1099                self.removed
1100                    .table
1101                    .entry(entity)
1102                    .or_default()
1103                    .extend(archetype.columns().map(|column| column.type_hash()));
1104                Ok(())
1105            }
1106            Err(error) => {
1107                self.entities.acquire()?;
1108                Err(error.into())
1109            }
1110        }
1111    }
1112
1113    #[inline]
1114    pub fn despawn_all(&mut self) {
1115        self.archetypes.clear();
1116        self.entities.clear();
1117    }
1118
1119    pub fn insert(&mut self, entity: Entity, bundle: impl Bundle) -> Result<(), WorldError> {
1120        let bundle_columns = bundle.columns();
1121        if bundle_columns.is_empty() {
1122            return Err(WorldError::EmptyColumnSet);
1123        }
1124        let bundle_types = bundle_columns
1125            .iter()
1126            .map(|column| column.type_hash())
1127            .collect::<Vec<_>>();
1128        let old_id = self.entities.get(entity)?;
1129        let mut new_columns = self
1130            .archetypes
1131            .get_mut(old_id)?
1132            .columns()
1133            .cloned()
1134            .collect::<Vec<_>>();
1135        for column in bundle_columns {
1136            if !new_columns
1137                .iter()
1138                .any(|c| c.type_hash() == column.type_hash())
1139            {
1140                new_columns.push(column);
1141            }
1142        }
1143        if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
1144            if new_id == old_id {
1145                return Ok(());
1146            }
1147            let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
1148            let access = old_archetype.transfer(new_archetype, entity)?;
1149            bundle.initialize_into(&access);
1150            self.entities.set(entity, new_id)?;
1151        } else {
1152            let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1153            let access = self
1154                .archetypes
1155                .get_mut(old_id)
1156                .unwrap()
1157                .transfer(&mut archetype, entity)?;
1158            bundle.initialize_into(&access);
1159            drop(access);
1160            let (new_id, archetype_slot) = self.archetypes.acquire()?;
1161            *archetype_slot = Some(archetype);
1162            self.entities.set(entity, new_id)?;
1163        }
1164        self.added
1165            .table
1166            .entry(entity)
1167            .or_default()
1168            .extend(bundle_types);
1169        Ok(())
1170    }
1171
1172    pub fn remove<T: BundleColumns>(&mut self, entity: Entity) -> Result<(), WorldError> {
1173        self.remove_raw(entity, T::columns_static())
1174    }
1175
1176    pub fn remove_raw(
1177        &mut self,
1178        entity: Entity,
1179        columns: Vec<ArchetypeColumnInfo>,
1180    ) -> Result<(), WorldError> {
1181        if columns.is_empty() {
1182            return Err(WorldError::EmptyColumnSet);
1183        }
1184        let bundle_types = columns
1185            .iter()
1186            .map(|column| column.type_hash())
1187            .collect::<Vec<_>>();
1188        let old_id = self.entities.get(entity)?;
1189        let mut new_columns = self
1190            .archetypes
1191            .get_mut(old_id)?
1192            .columns()
1193            .cloned()
1194            .collect::<Vec<_>>();
1195        let despawn = new_columns.is_empty();
1196        for column in columns {
1197            if let Some(index) = new_columns
1198                .iter()
1199                .position(|c| c.type_hash() == column.type_hash())
1200            {
1201                new_columns.swap_remove(index);
1202            }
1203        }
1204        if let Some(new_id) = self.archetypes.find_by_columns_exact(&new_columns) {
1205            if new_id == old_id {
1206                return Ok(());
1207            }
1208            let [old_archetype, new_archetype] = self.archetypes.get_mut_two([old_id, new_id])?;
1209            old_archetype.transfer(new_archetype, entity)?;
1210            self.entities.set(entity, new_id)?;
1211        } else {
1212            let mut archetype = Archetype::new(new_columns, self.new_archetype_capacity)?;
1213            self.archetypes
1214                .get_mut(old_id)
1215                .unwrap()
1216                .transfer(&mut archetype, entity)?;
1217            let (new_id, archetype_slot) = self.archetypes.acquire()?;
1218            *archetype_slot = Some(archetype);
1219            self.entities.set(entity, new_id)?;
1220        }
1221        if despawn {
1222            let _ = self.entities.release(entity);
1223        }
1224        self.removed
1225            .table
1226            .entry(entity)
1227            .or_default()
1228            .extend(bundle_types);
1229        Ok(())
1230    }
1231
1232    pub fn merge<const LOCKING: bool>(
1233        &mut self,
1234        mut other: Self,
1235        processor: &WorldProcessor,
1236    ) -> Result<(), WorldError> {
1237        let mut mappings = HashMap::<_, _>::with_capacity(other.len());
1238        let mut archetype_offsets = Vec::with_capacity(other.archetypes().count());
1239        for archetype_from in other.archetypes_mut() {
1240            let columns = archetype_from.columns().cloned().collect::<Vec<_>>();
1241            let archetype_id =
1242                if let Some(archetype_id) = self.archetypes.find_by_columns_exact(&columns) {
1243                    archetype_id
1244                } else {
1245                    let (archetype_id, archetype_slot) = self.archetypes.acquire()?;
1246                    let archetype = Archetype::new(columns.clone(), self.new_archetype_capacity)?;
1247                    *archetype_slot = Some(archetype);
1248                    archetype_id
1249                };
1250            let archetype = self.archetypes.get_mut(archetype_id)?;
1251            let offset = archetype.len();
1252            let entities_from = archetype_from.entities().iter().collect::<Vec<_>>();
1253            for entity_from in entities_from {
1254                let (entity, access) = unsafe { self.spawn_uninitialized_raw(columns.clone())? };
1255                let access_from = match archetype_from.row::<LOCKING>(entity_from) {
1256                    Ok(access_from) => access_from,
1257                    Err(error) => {
1258                        drop(access);
1259                        unsafe { self.despawn_uninitialized(entity)? };
1260                        return Err(error.into());
1261                    }
1262                };
1263                for column in &columns {
1264                    unsafe {
1265                        let data = access.data(column.type_hash()).unwrap();
1266                        let data_from = access_from.data(column.type_hash()).unwrap();
1267                        data.copy_from(data_from, column.layout().size());
1268                    }
1269                }
1270                mappings.insert(entity_from, entity);
1271            }
1272            archetype_offsets.push((columns, offset));
1273            unsafe { archetype_from.clear_uninitialized() };
1274        }
1275        for (columns, offset) in archetype_offsets {
1276            if let Some(id) = self.archetypes.find_by_columns_exact(&columns) {
1277                let archetype = self.archetype_by_id(id)?;
1278                for column in archetype.columns() {
1279                    let access = archetype.dynamic_column::<LOCKING>(column.type_hash(), true)?;
1280                    for index in offset..archetype.len() {
1281                        unsafe {
1282                            processor.remap_entities_raw(
1283                                column.type_hash(),
1284                                access.data(index)?,
1285                                WorldProcessorEntityMapping::new(&mappings),
1286                            );
1287                        }
1288                    }
1289                }
1290            }
1291        }
1292        Ok(())
1293    }
1294
1295    pub fn has_entity(&self, entity: Entity) -> bool {
1296        self.entities.get(entity).is_ok()
1297    }
1298
1299    pub fn has_entity_component<T: Component>(&self, entity: Entity) -> bool {
1300        self.has_entity_component_raw(entity, TypeHash::of::<T>())
1301    }
1302
1303    pub fn has_entity_component_raw(&self, entity: Entity, component: TypeHash) -> bool {
1304        self.entities
1305            .get(entity)
1306            .and_then(|index| self.archetypes.get(index))
1307            .map(|archetype| archetype.has_type(component))
1308            .unwrap_or_default()
1309    }
1310
1311    pub fn has_component<T: Component>(&self) -> bool {
1312        self.has_component_raw(TypeHash::of::<T>())
1313    }
1314
1315    pub fn has_component_raw(&self, component: TypeHash) -> bool {
1316        self.archetypes
1317            .iter()
1318            .any(|archetype| archetype.has_type(component) && !archetype.is_empty())
1319    }
1320
1321    pub fn find_by<const LOCKING: bool, T: Component + PartialEq>(
1322        &self,
1323        data: &T,
1324    ) -> Option<Entity> {
1325        for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1326            if component == data {
1327                return Some(entity);
1328            }
1329        }
1330        None
1331    }
1332
1333    pub fn find_with<const LOCKING: bool, T: Component>(
1334        &self,
1335        f: impl Fn(&T) -> bool,
1336    ) -> Option<Entity> {
1337        for (entity, component) in self.query::<LOCKING, (Entity, &T)>() {
1338            if f(component) {
1339                return Some(entity);
1340            }
1341        }
1342        None
1343    }
1344
1345    pub fn component<const LOCKING: bool, T: Component>(
1346        &'_ self,
1347        entity: Entity,
1348    ) -> Result<ComponentRef<'_, LOCKING, T>, WorldError> {
1349        Ok(ComponentRef {
1350            inner: self.get::<LOCKING, T>(entity, false)?,
1351        })
1352    }
1353
1354    pub fn component_mut<const LOCKING: bool, T: Component>(
1355        &'_ self,
1356        entity: Entity,
1357    ) -> Result<ComponentRefMut<'_, LOCKING, T>, WorldError> {
1358        Ok(ComponentRefMut {
1359            inner: self.get::<LOCKING, T>(entity, true)?,
1360        })
1361    }
1362
1363    pub fn get<const LOCKING: bool, T: Component>(
1364        &'_ self,
1365        entity: Entity,
1366        unique: bool,
1367    ) -> Result<ArchetypeEntityColumnAccess<'_, LOCKING, T>, WorldError> {
1368        Ok(self
1369            .archetypes
1370            .get(self.entities.get(entity)?)?
1371            .entity::<LOCKING, T>(entity, unique)?)
1372    }
1373
1374    pub fn dynamic_get<const LOCKING: bool>(
1375        &'_ self,
1376        type_hash: TypeHash,
1377        entity: Entity,
1378        unique: bool,
1379    ) -> Result<ArchetypeDynamicEntityColumnAccess<'_, LOCKING>, WorldError> {
1380        Ok(self
1381            .archetypes
1382            .get(self.entities.get(entity)?)?
1383            .dynamic_entity::<LOCKING>(type_hash, entity, unique)?)
1384    }
1385
1386    pub fn row<const LOCKING: bool>(
1387        &'_ self,
1388        entity: Entity,
1389    ) -> Result<ArchetypeEntityRowAccess<'_>, WorldError> {
1390        Ok(self
1391            .archetypes
1392            .get(self.entities.get(entity)?)?
1393            .row::<LOCKING>(entity)?)
1394    }
1395
1396    pub fn entity<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1397        &'a self,
1398        entity: Entity,
1399    ) -> Option<Fetch::Value> {
1400        // TODO: this might be fucked up here, i believe we could potentially extend
1401        // fetched references lifetimes, which can lead to memory corruption - INVESTIGATE!
1402        self.lookup_access::<LOCKING, Fetch>().access(entity)
1403    }
1404
1405    pub fn query<'a, const LOCKING: bool, Fetch: TypedQueryFetch<'a, LOCKING>>(
1406        &'a self,
1407    ) -> TypedQueryIter<'a, LOCKING, Fetch> {
1408        TypedQueryIter::new(self)
1409    }
1410
1411    pub fn dynamic_query<'a, const LOCKING: bool>(
1412        &'a self,
1413        filter: &DynamicQueryFilter,
1414    ) -> DynamicQueryIter<'a, LOCKING> {
1415        DynamicQueryIter::new(filter, self)
1416    }
1417
1418    pub fn lookup<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1419        &'a self,
1420        entities: impl IntoIterator<Item = Entity> + 'a,
1421    ) -> TypedLookupIter<'a, LOCKING, Fetch> {
1422        TypedLookupIter::new(self, entities)
1423    }
1424
1425    pub fn lookup_access<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1426        &'a self,
1427    ) -> TypedLookupAccess<'a, LOCKING, Fetch> {
1428        TypedLookupAccess::new(self)
1429    }
1430
1431    pub fn lookup_one<'a, const LOCKING: bool, Fetch: TypedLookupFetch<'a, LOCKING>>(
1432        &'a self,
1433        entity: Entity,
1434    ) -> Option<Fetch::ValueOne> {
1435        Fetch::fetch_one(self, entity)
1436    }
1437
1438    pub fn dynamic_lookup<'a, const LOCKING: bool>(
1439        &'a self,
1440        filter: &DynamicQueryFilter,
1441        entities: impl IntoIterator<Item = Entity> + 'a,
1442    ) -> DynamicLookupIter<'a, LOCKING> {
1443        DynamicLookupIter::new(filter, self, entities)
1444    }
1445
1446    pub fn dynamic_lookup_access<'a, const LOCKING: bool>(
1447        &'a self,
1448        filter: &DynamicQueryFilter,
1449    ) -> DynamicLookupAccess<'a, LOCKING> {
1450        DynamicLookupAccess::new(filter, self)
1451    }
1452
1453    pub fn relate<const LOCKING: bool, T: Component>(
1454        &mut self,
1455        payload: T,
1456        from: Entity,
1457        to: Entity,
1458    ) -> Result<(), WorldError> {
1459        if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1460            if let Some(relation) = relation.write() {
1461                relation.add(payload, to);
1462            }
1463            return Ok(());
1464        }
1465        self.insert(from, (Relation::<T>::new(payload, to),))
1466    }
1467
1468    pub fn relate_one<const LOCKING: bool, T: Component>(
1469        &mut self,
1470        payload: T,
1471        from: Entity,
1472        to: Entity,
1473    ) -> Result<(), WorldError> {
1474        if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1475            if let Some(relation) = relation.write() {
1476                relation.clear();
1477                relation.add(payload, to);
1478            }
1479            return Ok(());
1480        }
1481        self.insert(from, (Relation::<T>::new(payload, to),))
1482    }
1483
1484    pub fn relate_pair<const LOCKING: bool, I: Component, O: Component>(
1485        &mut self,
1486        payload_incoming: I,
1487        payload_outgoing: O,
1488        from: Entity,
1489        to: Entity,
1490    ) -> Result<(), WorldError> {
1491        self.relate::<LOCKING, _>(payload_outgoing, from, to)?;
1492        self.relate::<LOCKING, _>(payload_incoming, to, from)?;
1493        Ok(())
1494    }
1495
1496    pub fn unrelate<const LOCKING: bool, T: Component>(
1497        &mut self,
1498        from: Entity,
1499        to: Entity,
1500    ) -> Result<(), WorldError> {
1501        let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(from, true) {
1502            if let Some(relation) = relation.write() {
1503                relation.remove(to);
1504                relation.is_empty()
1505            } else {
1506                false
1507            }
1508        } else {
1509            false
1510        };
1511        if remove {
1512            self.remove::<(Relation<T>,)>(from)?;
1513        }
1514        Ok(())
1515    }
1516
1517    pub fn unrelate_pair<const LOCKING: bool, I: Component, O: Component>(
1518        &mut self,
1519        from: Entity,
1520        to: Entity,
1521    ) -> Result<(), WorldError> {
1522        self.unrelate::<LOCKING, O>(from, to)?;
1523        self.unrelate::<LOCKING, I>(to, from)?;
1524        Ok(())
1525    }
1526
1527    pub fn unrelate_any<const LOCKING: bool, T: Component>(
1528        &mut self,
1529        entity: Entity,
1530    ) -> Result<(), WorldError> {
1531        let to_remove = self
1532            .query::<LOCKING, (Entity, &mut Relation<T>)>()
1533            .filter_map(|(e, relation)| {
1534                relation.remove(entity);
1535                if relation.is_empty() { Some(e) } else { None }
1536            })
1537            .collect::<Vec<_>>();
1538        for entity in to_remove {
1539            self.remove::<(Relation<T>,)>(entity)?;
1540        }
1541        Ok(())
1542    }
1543
1544    pub fn unrelate_all<const LOCKING: bool, T: Component>(
1545        &mut self,
1546        entity: Entity,
1547    ) -> Result<(), WorldError> {
1548        let remove = if let Ok(mut relation) = self.get::<LOCKING, Relation<T>>(entity, true) {
1549            if let Some(relation) = relation.write() {
1550                relation.clear();
1551                relation.is_empty()
1552            } else {
1553                false
1554            }
1555        } else {
1556            false
1557        };
1558        if remove {
1559            self.remove::<(Relation<T>,)>(entity)?;
1560        }
1561        Ok(())
1562    }
1563
1564    pub fn has_relation<const LOCKING: bool, T: Component>(
1565        &self,
1566        from: Entity,
1567        to: Entity,
1568    ) -> bool {
1569        self.get::<LOCKING, Relation<T>>(from, false)
1570            .ok()
1571            .and_then(|relation| Some(relation.read()?.has(to)))
1572            .unwrap_or_default()
1573    }
1574
1575    pub fn relations<const LOCKING: bool, T: Component>(
1576        &self,
1577    ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1578        self.query::<LOCKING, (Entity, &Relation<T>)>()
1579            .flat_map(|(from, relation)| {
1580                relation
1581                    .iter()
1582                    .map(move |(payload, to)| (from, payload, to))
1583            })
1584    }
1585
1586    pub fn relations_mut<const LOCKING: bool, T: Component>(
1587        &self,
1588    ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1589        self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1590            .flat_map(|(from, relation)| {
1591                relation
1592                    .iter_mut()
1593                    .map(move |(payload, to)| (from, payload, to))
1594            })
1595    }
1596
1597    pub fn relations_outgoing<const LOCKING: bool, T: Component>(
1598        &self,
1599        from: Entity,
1600    ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1601        self.query::<LOCKING, (Entity, &Relation<T>)>()
1602            .filter(move |(entity, _)| *entity == from)
1603            .flat_map(|(from, relation)| {
1604                relation
1605                    .iter()
1606                    .map(move |(payload, to)| (from, payload, to))
1607            })
1608    }
1609
1610    pub fn relations_outgoing_mut<const LOCKING: bool, T: Component>(
1611        &self,
1612        from: Entity,
1613    ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1614        self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1615            .filter(move |(entity, _)| *entity == from)
1616            .flat_map(|(from, relation)| {
1617                relation
1618                    .iter_mut()
1619                    .map(move |(payload, to)| (from, payload, to))
1620            })
1621    }
1622
1623    pub fn relations_incomming<const LOCKING: bool, T: Component>(
1624        &self,
1625        to: Entity,
1626    ) -> impl Iterator<Item = (Entity, &T, Entity)> + '_ {
1627        self.query::<LOCKING, (Entity, &Relation<T>)>()
1628            .flat_map(move |(from, relation)| {
1629                relation
1630                    .iter()
1631                    .filter(move |(_, entity)| *entity == to)
1632                    .map(move |(payload, to)| (from, payload, to))
1633            })
1634    }
1635
1636    pub fn relations_incomming_mut<const LOCKING: bool, T: Component>(
1637        &self,
1638        to: Entity,
1639    ) -> impl Iterator<Item = (Entity, &mut T, Entity)> + '_ {
1640        self.query::<LOCKING, (Entity, &mut Relation<T>)>()
1641            .flat_map(move |(from, relation)| {
1642                relation
1643                    .iter_mut()
1644                    .filter(move |(_, entity)| *entity == to)
1645                    .map(move |(payload, to)| (from, payload, to))
1646            })
1647    }
1648
1649    pub fn traverse_outgoing<const LOCKING: bool, T: Component>(
1650        &'_ self,
1651        entities: impl IntoIterator<Item = Entity>,
1652    ) -> RelationsTraverseIter<'_, LOCKING, T> {
1653        RelationsTraverseIter {
1654            world: self,
1655            incoming: false,
1656            stack: entities.into_iter().map(|entity| (None, entity)).collect(),
1657            visited: Default::default(),
1658            _phantom: Default::default(),
1659        }
1660    }
1661
1662    pub fn traverse_incoming<const LOCKING: bool, T: Component>(
1663        &'_ self,
1664        entities: impl IntoIterator<Item = Entity>,
1665    ) -> RelationsTraverseIter<'_, LOCKING, T> {
1666        RelationsTraverseIter {
1667            world: self,
1668            incoming: true,
1669            stack: entities.into_iter().map(|entity| (None, entity)).collect(),
1670            visited: Default::default(),
1671            _phantom: Default::default(),
1672        }
1673    }
1674
1675    pub fn relation_lookup<'a, const LOCKING: bool, Fetch: TypedRelationLookupFetch<'a>>(
1676        &'a self,
1677        entity: Entity,
1678    ) -> TypedRelationLookupIter<'a, Fetch> {
1679        TypedRelationLookupIter::new(self, entity)
1680    }
1681}
1682
1683#[cfg(test)]
1684mod tests {
1685    use super::*;
1686    use crate::{
1687        commands::{CommandBuffer, DespawnCommand},
1688        query::{Exclude, Include, Update},
1689    };
1690    use std::{
1691        sync::{Arc, RwLock},
1692        thread::spawn,
1693        time::{Duration, Instant},
1694    };
1695
1696    #[test]
1697    fn test_world_changes() {
1698        let mut world = World::default();
1699        assert!(world.is_empty());
1700        assert!(world.spawn(()).is_err());
1701
1702        let (entity, row) = unsafe { world.spawn_uninitialized::<(u8, u16, u32)>().unwrap() };
1703        assert_eq!(entity, Entity::new(0, 0).unwrap());
1704        unsafe { row.initialize(1u8).unwrap() };
1705        unsafe { row.initialize(2u16).unwrap() };
1706        unsafe { row.initialize(3u32).unwrap() };
1707        assert_eq!(*row.read::<u8>().unwrap(), 1);
1708        assert_eq!(*row.read::<u16>().unwrap(), 2);
1709        assert_eq!(*row.read::<u32>().unwrap(), 3);
1710        drop(row);
1711        world.despawn(entity).unwrap();
1712        assert!(world.is_empty());
1713
1714        let entity = world.spawn((1u8, 2u16, 3u32)).unwrap();
1715        assert_eq!(entity, Entity::new(0, 1).unwrap());
1716        assert_eq!(
1717            *world
1718                .get::<true, u8>(entity, false)
1719                .unwrap()
1720                .read()
1721                .unwrap(),
1722            1
1723        );
1724        assert_eq!(
1725            *world
1726                .get::<true, u16>(entity, false)
1727                .unwrap()
1728                .read()
1729                .unwrap(),
1730            2
1731        );
1732        assert_eq!(
1733            *world
1734                .get::<true, u32>(entity, false)
1735                .unwrap()
1736                .read()
1737                .unwrap(),
1738            3
1739        );
1740        assert!(world.get::<true, u64>(entity, false).is_err());
1741        assert_eq!(world.len(), 1);
1742
1743        world.insert(entity, (4u64,)).unwrap();
1744        assert_eq!(
1745            *world
1746                .get::<true, u8>(entity, false)
1747                .unwrap()
1748                .read()
1749                .unwrap(),
1750            1
1751        );
1752        assert_eq!(
1753            *world
1754                .get::<true, u16>(entity, false)
1755                .unwrap()
1756                .read()
1757                .unwrap(),
1758            2
1759        );
1760        assert_eq!(
1761            *world
1762                .get::<true, u32>(entity, false)
1763                .unwrap()
1764                .read()
1765                .unwrap(),
1766            3
1767        );
1768        assert_eq!(
1769            *world
1770                .get::<true, u64>(entity, false)
1771                .unwrap()
1772                .read()
1773                .unwrap(),
1774            4
1775        );
1776
1777        world.remove::<(u8,)>(entity).unwrap();
1778        assert!(world.get::<true, u8>(entity, false).is_err());
1779        assert_eq!(
1780            *world
1781                .get::<true, u16>(entity, false)
1782                .unwrap()
1783                .read()
1784                .unwrap(),
1785            2
1786        );
1787        assert_eq!(
1788            *world
1789                .get::<true, u32>(entity, false)
1790                .unwrap()
1791                .read()
1792                .unwrap(),
1793            3
1794        );
1795        assert_eq!(
1796            *world
1797                .get::<true, u64>(entity, false)
1798                .unwrap()
1799                .read()
1800                .unwrap(),
1801            4
1802        );
1803
1804        world.clear();
1805        assert!(world.is_empty());
1806    }
1807
1808    #[test]
1809    fn test_world_query() {
1810        const N: usize = if cfg!(miri) { 10 } else { 1000 };
1811
1812        let mut world = World::default().with_new_archetype_capacity(N);
1813
1814        for index in 0..N {
1815            world.spawn((index as u8,)).unwrap();
1816        }
1817        for index in N..(N * 2) {
1818            world.spawn((index as u8, index as u16)).unwrap();
1819        }
1820        for index in (N * 2)..(N * 3) {
1821            world.spawn((index as u16,)).unwrap();
1822        }
1823
1824        for (index, v) in world.query::<true, &u8>().enumerate() {
1825            assert_eq!(*v, index as u8);
1826        }
1827
1828        for (index, item) in world
1829            .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>())
1830            .enumerate()
1831        {
1832            let v = item.read::<u8>().unwrap().read::<u8>().unwrap();
1833            assert_eq!(*v, index as u8);
1834        }
1835
1836        for (index, v) in world.query::<true, &u16>().enumerate() {
1837            assert_eq!(*v, (index + N) as u16);
1838        }
1839
1840        for (index, item) in world
1841            .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u16>())
1842            .enumerate()
1843        {
1844            let v = item.read::<u16>().unwrap().read::<u16>().unwrap();
1845            assert_eq!(*v, (index + N) as u16);
1846        }
1847
1848        for (index, (entity, a, b)) in world.query::<true, (Entity, &u8, &u16)>().enumerate() {
1849            assert!(entity.is_valid());
1850            assert_eq!(*a, (index + N) as u8);
1851            assert_eq!(*b, (index + N) as u16);
1852        }
1853
1854        for (index, item) in world
1855            .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().read::<u16>())
1856            .enumerate()
1857        {
1858            let a = item.read::<u8>().unwrap().read::<u8>().unwrap();
1859            let b = item.read::<u16>().unwrap().read::<u16>().unwrap();
1860            assert!(item.entity().is_valid());
1861            assert_eq!(*a, (index + N) as u8);
1862            assert_eq!(*b, (index + N) as u16);
1863        }
1864
1865        for (index, (a, b)) in world.query::<true, (&u8, Option<&u16>)>().enumerate() {
1866            assert_eq!(*a, index as u8);
1867            if let Some(b) = b {
1868                assert_eq!(*b, index as u16);
1869            }
1870        }
1871
1872        for (entity, _, _) in world.query::<true, (Entity, &u8, Include<u16>)>() {
1873            assert!((entity.id() as usize) >= N);
1874            assert!((entity.id() as usize) < N * 2);
1875        }
1876
1877        for item in world
1878            .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().include::<u16>())
1879        {
1880            assert!((item.entity().id() as usize) >= N);
1881            assert!((item.entity().id() as usize) < N * 2);
1882        }
1883
1884        for (entity, _, _) in world.query::<true, (Entity, &u8, Exclude<u16>)>() {
1885            assert!((entity.id() as usize) < N);
1886        }
1887
1888        for item in world
1889            .dynamic_query::<true>(&DynamicQueryFilter::default().read::<u8>().exclude::<u16>())
1890        {
1891            assert!((item.entity().id() as usize) < N);
1892        }
1893    }
1894
1895    #[test]
1896    fn test_world_lookup() {
1897        const N: usize = if cfg!(miri) { 10 } else { 1000 };
1898
1899        let mut world = World::default().with_new_archetype_capacity(N);
1900
1901        let mut entities = vec![];
1902        for index in 0..N {
1903            let entity = world.spawn((index as u8,)).unwrap();
1904            if index % 2 == 0 {
1905                entities.push(entity);
1906            }
1907        }
1908        assert_eq!(entities.len(), N / 2);
1909
1910        let compare_entities = world
1911            .lookup::<true, (Entity, &u8)>(entities.iter().copied())
1912            .map(|(entity, _)| entity)
1913            .collect::<Vec<_>>();
1914        assert_eq!(compare_entities, entities);
1915
1916        let mut lookup = world.lookup_access::<true, Exclude<f32>>();
1917        for entity in entities.iter().copied() {
1918            assert!(lookup.access(entity).is_some());
1919        }
1920        drop(lookup);
1921
1922        let mut lookup = world.lookup_access::<true, (Entity, &u8)>();
1923        for entity in entities.iter().copied() {
1924            assert_eq!(lookup.access(entity).unwrap().0, entity);
1925        }
1926        drop(lookup);
1927
1928        let compare_entities = world
1929            .dynamic_lookup::<true>(
1930                &DynamicQueryFilter::default().read::<u8>(),
1931                entities.iter().copied(),
1932            )
1933            .map(|item| item.entity())
1934            .collect::<Vec<_>>();
1935        assert_eq!(compare_entities, entities);
1936
1937        let lookup =
1938            world.dynamic_lookup_access::<true>(&DynamicQueryFilter::default().read::<u8>());
1939        for entity in entities.iter().copied() {
1940            let item = lookup.access(entity).unwrap();
1941            assert_eq!(item.entity(), entity);
1942        }
1943        drop(lookup);
1944
1945        let entity = world.spawn((1u8, 2.0f32, "3")).unwrap();
1946        let (a, b) = world.entity::<true, (&u8, &mut f32)>(entity).unwrap();
1947        assert_eq!(*a, 1);
1948        assert_eq!(*b, 2.0);
1949    }
1950
1951    #[test]
1952    fn test_change_detection() {
1953        let mut world = World::default();
1954
1955        for index in 0..10usize {
1956            world.spawn((index,)).unwrap();
1957        }
1958        let mut list = world.added().iter_of::<usize>().collect::<Vec<_>>();
1959        list.sort();
1960        assert_eq!(
1961            list,
1962            (0..10)
1963                .map(|index| Entity::new(index, 0).unwrap())
1964                .collect::<Vec<_>>()
1965        );
1966
1967        for mut v in world.query::<true, Update<usize>>() {
1968            *v.write_notified(&world) *= 2;
1969        }
1970        for (entity, v) in world.query::<true, (Entity, &usize)>() {
1971            assert_eq!(entity.id() as usize * 2, *v);
1972        }
1973        let mut list = world
1974            .updated()
1975            .unwrap()
1976            .iter_of::<usize>()
1977            .collect::<Vec<_>>();
1978        list.sort();
1979        assert_eq!(
1980            list,
1981            (0..10)
1982                .map(|index| Entity::new(index, 0).unwrap())
1983                .collect::<Vec<_>>()
1984        );
1985
1986        let mut commands = CommandBuffer::default();
1987        for entity in world.entities() {
1988            commands.command(DespawnCommand::new(entity));
1989        }
1990        commands.execute(&mut world);
1991        let mut list = world.removed().iter_of::<usize>().collect::<Vec<_>>();
1992        list.sort();
1993        assert_eq!(
1994            list,
1995            (0..10)
1996                .map(|index| Entity::new(index, 0).unwrap())
1997                .collect::<Vec<_>>()
1998        );
1999    }
2000
2001    #[test]
2002    fn test_zst_components() {
2003        #[derive(Debug, PartialEq, Eq)]
2004        struct Foo;
2005
2006        #[derive(Debug, PartialEq, Eq)]
2007        struct Bar(bool);
2008
2009        let mut world = World::default();
2010        world.spawn((Foo,)).unwrap();
2011        assert_eq!(world.query::<true, &Foo>().count(), 1);
2012        for v in world.query::<true, &Foo>() {
2013            assert_eq!(v, &Foo);
2014        }
2015        world.spawn((Bar(true),)).unwrap();
2016        assert_eq!(world.query::<true, &Bar>().count(), 1);
2017        for v in world.query::<true, &Bar>() {
2018            assert_eq!(v, &Bar(true));
2019        }
2020        world.spawn((Foo, Bar(false))).unwrap();
2021        assert_eq!(world.query::<true, &Foo>().count(), 2);
2022        assert_eq!(world.query::<true, &Bar>().count(), 2);
2023        assert_eq!(world.query::<true, (&Bar, &Foo)>().count(), 1);
2024        for (a, b) in world.query::<true, (&Bar, &Foo)>() {
2025            assert_eq!(a, &Bar(false));
2026            assert_eq!(b, &Foo);
2027        }
2028    }
2029
2030    #[test]
2031    fn test_world_relations() {
2032        struct Parent;
2033        struct Child;
2034        struct Root;
2035
2036        let mut world = World::default();
2037        let a = world.spawn((0u8, false, Root)).unwrap();
2038        let b = world.spawn((1u8, false)).unwrap();
2039        let c = world.spawn((2u8, false)).unwrap();
2040        let d = world.spawn((3u8, false)).unwrap();
2041        world
2042            .relate_pair::<true, _, _>(Parent, Child, a, b)
2043            .unwrap();
2044        world
2045            .relate_pair::<true, _, _>(Parent, Child, a, c)
2046            .unwrap();
2047        world
2048            .relate_pair::<true, _, _>(Parent, Child, c, d)
2049            .unwrap();
2050
2051        assert_eq!(
2052            world
2053                .relations_incomming::<true, Parent>(a)
2054                .map(|(entity, _, _)| entity)
2055                .collect::<Vec<_>>(),
2056            vec![b, c]
2057        );
2058        assert_eq!(
2059            world
2060                .relations_incomming::<true, Parent>(b)
2061                .map(|(entity, _, _)| entity)
2062                .collect::<Vec<_>>(),
2063            vec![]
2064        );
2065        assert_eq!(
2066            world
2067                .relations_incomming::<true, Parent>(c)
2068                .map(|(entity, _, _)| entity)
2069                .collect::<Vec<_>>(),
2070            vec![d]
2071        );
2072        assert_eq!(
2073            world
2074                .relations_incomming::<true, Parent>(d)
2075                .map(|(entity, _, _)| entity)
2076                .collect::<Vec<_>>(),
2077            vec![]
2078        );
2079
2080        assert_eq!(
2081            world
2082                .relations_outgoing::<true, Parent>(a)
2083                .map(|(_, _, entity)| entity)
2084                .collect::<Vec<_>>(),
2085            vec![]
2086        );
2087        assert_eq!(
2088            world
2089                .relations_outgoing::<true, Parent>(b)
2090                .map(|(_, _, entity)| entity)
2091                .collect::<Vec<_>>(),
2092            vec![a]
2093        );
2094        assert_eq!(
2095            world
2096                .relations_outgoing::<true, Parent>(c)
2097                .map(|(_, _, entity)| entity)
2098                .collect::<Vec<_>>(),
2099            vec![a]
2100        );
2101        assert_eq!(
2102            world
2103                .relations_outgoing::<true, Parent>(d)
2104                .map(|(_, _, entity)| entity)
2105                .collect::<Vec<_>>(),
2106            vec![c]
2107        );
2108
2109        assert_eq!(
2110            world
2111                .traverse_outgoing::<true, Child>([a])
2112                .collect::<Vec<_>>(),
2113            vec![(Entity::INVALID, a), (a, b), (a, c), (c, d)]
2114        );
2115
2116        for (entity, _) in world.query::<true, (Entity, Include<Root>)>() {
2117            for (other, _, _) in world.relations_incomming::<true, Parent>(entity) {
2118                let mut v = world.get::<true, bool>(other, true).unwrap();
2119                let v = v.write().unwrap();
2120                *v = !*v;
2121            }
2122        }
2123
2124        assert!(!*world.get::<true, bool>(a, false).unwrap().read().unwrap());
2125        assert!(*world.get::<true, bool>(b, false).unwrap().read().unwrap());
2126        assert!(*world.get::<true, bool>(c, false).unwrap().read().unwrap());
2127        assert!(!*world.get::<true, bool>(d, false).unwrap().read().unwrap());
2128
2129        world.unrelate::<true, Parent>(b, a).unwrap();
2130        world.unrelate::<true, Parent>(c, a).unwrap();
2131        world.unrelate::<true, Parent>(d, c).unwrap();
2132        assert!(world.query::<true, &Relation<Parent>>().count() == 0);
2133    }
2134
2135    #[test]
2136    fn test_world_async() {
2137        const N: usize = if cfg!(miri) { 10 } else { 1000 };
2138
2139        fn is_async<T: Send + Sync>() {}
2140
2141        is_async::<World>();
2142
2143        let world = Arc::new(RwLock::new(World::default().with_new_archetype_capacity(N)));
2144        let world2 = world.clone();
2145
2146        {
2147            let mut world = world.write().unwrap();
2148            for index in 0..N {
2149                world.spawn((index as u8, index as u16)).unwrap();
2150            }
2151        }
2152
2153        let handle = spawn(move || {
2154            let timer = Instant::now();
2155            while timer.elapsed() < Duration::from_secs(1) {
2156                let world = world2.read().unwrap();
2157                for v in world.query::<true, &mut u16>() {
2158                    *v = v.wrapping_add(1);
2159                }
2160            }
2161        });
2162
2163        let timer = Instant::now();
2164        while timer.elapsed() < Duration::from_secs(1) {
2165            let world = world.read().unwrap();
2166            for v in world.query::<true, &mut u8>() {
2167                *v = v.wrapping_add(1);
2168            }
2169        }
2170
2171        let _ = handle.join();
2172    }
2173
2174    #[test]
2175    fn test_add_remove_components() {
2176        struct A(#[allow(dead_code)] f32);
2177        struct B(#[allow(dead_code)] f32);
2178
2179        const N: usize = if cfg!(miri) { 10 } else { 10000 };
2180
2181        let mut world = World::default().with_new_archetype_capacity(1);
2182
2183        let entities = (0..N)
2184            .map(|_| world.spawn((A(0.0),)).unwrap())
2185            .collect::<Vec<_>>();
2186
2187        for entity in &entities {
2188            world.insert(*entity, (B(0.0),)).unwrap();
2189        }
2190
2191        for entity in &entities {
2192            world.remove::<(B,)>(*entity).unwrap();
2193        }
2194    }
2195}