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