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