bevy_ecs/
archetype.rs

1//! Types for defining [`Archetype`]s, collections of entities that have the same set of
2//! components.
3//!
4//! An archetype uniquely describes a group of entities that share the same components:
5//! a world only has one archetype for each unique combination of components, and all
6//! entities that have those components and only those components belong to that
7//! archetype.
8//!
9//! Archetypes are not to be confused with [`Table`]s. Each archetype stores its table
10//! components in one table, and each archetype uniquely points to one table, but multiple
11//! archetypes may store their table components in the same table. These archetypes
12//! differ only by the [`SparseSet`] components.
13//!
14//! Like tables, archetypes can be created but are never cleaned up. Empty archetypes are
15//! not removed, and persist until the world is dropped.
16//!
17//! Archetypes can be fetched from [`Archetypes`], which is accessible via [`World::archetypes`].
18//!
19//! [`Table`]: crate::storage::Table
20//! [`World::archetypes`]: crate::world::World::archetypes
21
22use crate::{
23    bundle::BundleId,
24    component::{ComponentId, Components, RequiredComponentConstructor, StorageType},
25    entity::{Entity, EntityLocation},
26    observer::Observers,
27    storage::{ImmutableSparseSet, SparseArray, SparseSet, SparseSetIndex, TableId, TableRow},
28};
29use bevy_utils::HashMap;
30use core::{
31    hash::Hash,
32    ops::{Index, IndexMut, RangeFrom},
33};
34
35/// An opaque location within a [`Archetype`].
36///
37/// This can be used in conjunction with [`ArchetypeId`] to find the exact location
38/// of an [`Entity`] within a [`World`]. An entity's archetype and index can be
39/// retrieved via [`Entities::get`].
40///
41/// [`World`]: crate::world::World
42/// [`Entities::get`]: crate::entity::Entities
43#[derive(Debug, Copy, Clone, Eq, PartialEq)]
44// SAFETY: Must be repr(transparent) due to the safety requirements on EntityLocation
45#[repr(transparent)]
46pub struct ArchetypeRow(u32);
47
48impl ArchetypeRow {
49    /// Index indicating an invalid archetype row.
50    /// This is meant to be used as a placeholder.
51    pub const INVALID: ArchetypeRow = ArchetypeRow(u32::MAX);
52
53    /// Creates a `ArchetypeRow`.
54    #[inline]
55    pub const fn new(index: usize) -> Self {
56        Self(index as u32)
57    }
58
59    /// Gets the index of the row.
60    #[inline]
61    pub const fn index(self) -> usize {
62        self.0 as usize
63    }
64}
65
66/// An opaque unique ID for a single [`Archetype`] within a [`World`].
67///
68/// Archetype IDs are only valid for a given World, and are not globally unique.
69/// Attempting to use an archetype ID on a world that it wasn't sourced from will
70/// not return the archetype with the same components. The only exception to this is
71/// [`EMPTY`] which is guaranteed to be identical for all Worlds.
72///
73/// [`World`]: crate::world::World
74/// [`EMPTY`]: ArchetypeId::EMPTY
75#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash, PartialOrd, Ord)]
76// SAFETY: Must be repr(transparent) due to the safety requirements on EntityLocation
77#[repr(transparent)]
78pub struct ArchetypeId(u32);
79
80impl ArchetypeId {
81    /// The ID for the [`Archetype`] without any components.
82    pub const EMPTY: ArchetypeId = ArchetypeId(0);
83    /// # Safety:
84    ///
85    /// This must always have an all-1s bit pattern to ensure soundness in fast entity id space allocation.
86    pub const INVALID: ArchetypeId = ArchetypeId(u32::MAX);
87
88    /// Create an `ArchetypeId` from a plain value.
89    ///
90    /// This is useful if you need to store the `ArchetypeId` as a plain value,
91    /// for example in a specialized data structure such as a bitset.
92    ///
93    /// While it doesn't break any safety invariants, you should ensure the
94    /// values comes from a pre-existing [`ArchetypeId::index`] in this world
95    /// to avoid panics and other unexpected behaviors.
96    #[inline]
97    pub const fn new(index: usize) -> Self {
98        ArchetypeId(index as u32)
99    }
100
101    /// The plain value of this `ArchetypeId`.
102    ///
103    /// In bevy, this is mostly used to store archetype ids in [`FixedBitSet`]s.
104    ///
105    /// [`FixedBitSet`]: fixedbitset::FixedBitSet
106    #[inline]
107    pub fn index(self) -> usize {
108        self.0 as usize
109    }
110}
111
112/// Used in [`AddBundle`] to track whether components in the bundle are newly
113/// added or already existed in the entity's archetype.
114#[derive(Copy, Clone, Eq, PartialEq)]
115pub(crate) enum ComponentStatus {
116    Added,
117    Existing,
118}
119
120pub(crate) struct AddBundle {
121    /// The target archetype after the bundle is added to the source archetype
122    pub archetype_id: ArchetypeId,
123    /// For each component iterated in the same order as the source [`Bundle`](crate::bundle::Bundle),
124    /// indicate if the component is newly added to the target archetype or if it already existed
125    pub bundle_status: Vec<ComponentStatus>,
126    /// The set of additional required components that must be initialized immediately when adding this Bundle.
127    ///
128    /// The initial values are determined based on the provided constructor, falling back to the `Default` trait if none is given.
129    pub required_components: Vec<RequiredComponentConstructor>,
130    /// The components added by this bundle. This includes any Required Components that are inserted when adding this bundle.
131    pub added: Vec<ComponentId>,
132    /// The components that were explicitly contributed by this bundle, but already existed in the archetype. This _does not_ include any
133    /// Required Components.
134    pub existing: Vec<ComponentId>,
135}
136
137impl AddBundle {
138    pub(crate) fn iter_inserted(&self) -> impl Iterator<Item = ComponentId> + Clone + '_ {
139        self.added.iter().chain(self.existing.iter()).copied()
140    }
141
142    pub(crate) fn iter_added(&self) -> impl Iterator<Item = ComponentId> + Clone + '_ {
143        self.added.iter().copied()
144    }
145
146    pub(crate) fn iter_existing(&self) -> impl Iterator<Item = ComponentId> + Clone + '_ {
147        self.existing.iter().copied()
148    }
149}
150
151/// This trait is used to report the status of [`Bundle`](crate::bundle::Bundle) components
152/// being added to a given entity, relative to that entity's original archetype.
153/// See [`crate::bundle::BundleInfo::write_components`] for more info.
154pub(crate) trait BundleComponentStatus {
155    /// Returns the Bundle's component status for the given "bundle index"
156    ///
157    /// # Safety
158    /// Callers must ensure that index is always a valid bundle index for the
159    /// Bundle associated with this [`BundleComponentStatus`]
160    unsafe fn get_status(&self, index: usize) -> ComponentStatus;
161}
162
163impl BundleComponentStatus for AddBundle {
164    #[inline]
165    unsafe fn get_status(&self, index: usize) -> ComponentStatus {
166        // SAFETY: caller has ensured index is a valid bundle index for this bundle
167        unsafe { *self.bundle_status.get_unchecked(index) }
168    }
169}
170
171pub(crate) struct SpawnBundleStatus;
172
173impl BundleComponentStatus for SpawnBundleStatus {
174    #[inline]
175    unsafe fn get_status(&self, _index: usize) -> ComponentStatus {
176        // Components added during a spawn call are always treated as added
177        ComponentStatus::Added
178    }
179}
180
181/// Archetypes and bundles form a graph. Adding or removing a bundle moves
182/// an [`Entity`] to a new [`Archetype`].
183///
184/// [`Edges`] caches the results of these moves. Each archetype caches
185/// the result of a structural alteration. This can be used to monitor the
186/// state of the archetype graph.
187///
188/// Note: This type only contains edges the [`World`] has already traversed.
189/// If any of functions return `None`, it doesn't mean there is guaranteed
190/// not to be a result of adding or removing that bundle, but rather that
191/// operation that has moved an entity along that edge has not been performed
192/// yet.
193///
194/// [`World`]: crate::world::World
195#[derive(Default)]
196pub struct Edges {
197    add_bundle: SparseArray<BundleId, AddBundle>,
198    remove_bundle: SparseArray<BundleId, Option<ArchetypeId>>,
199    take_bundle: SparseArray<BundleId, Option<ArchetypeId>>,
200}
201
202impl Edges {
203    /// Checks the cache for the target archetype when adding a bundle to the
204    /// source archetype. For more information, see [`EntityWorldMut::insert`].
205    ///
206    /// If this returns `None`, it means there has not been a transition from
207    /// the source archetype via the provided bundle.
208    ///
209    /// [`EntityWorldMut::insert`]: crate::world::EntityWorldMut::insert
210    #[inline]
211    pub fn get_add_bundle(&self, bundle_id: BundleId) -> Option<ArchetypeId> {
212        self.get_add_bundle_internal(bundle_id)
213            .map(|bundle| bundle.archetype_id)
214    }
215
216    /// Internal version of `get_add_bundle` that fetches the full `AddBundle`.
217    #[inline]
218    pub(crate) fn get_add_bundle_internal(&self, bundle_id: BundleId) -> Option<&AddBundle> {
219        self.add_bundle.get(bundle_id)
220    }
221
222    /// Caches the target archetype when adding a bundle to the source archetype.
223    /// For more information, see [`EntityWorldMut::insert`].
224    ///
225    /// [`EntityWorldMut::insert`]: crate::world::EntityWorldMut::insert
226    #[inline]
227    pub(crate) fn insert_add_bundle(
228        &mut self,
229        bundle_id: BundleId,
230        archetype_id: ArchetypeId,
231        bundle_status: Vec<ComponentStatus>,
232        required_components: Vec<RequiredComponentConstructor>,
233        added: Vec<ComponentId>,
234        existing: Vec<ComponentId>,
235    ) {
236        self.add_bundle.insert(
237            bundle_id,
238            AddBundle {
239                archetype_id,
240                bundle_status,
241                required_components,
242                added,
243                existing,
244            },
245        );
246    }
247
248    /// Checks the cache for the target archetype when removing a bundle to the
249    /// source archetype. For more information, see [`EntityWorldMut::remove`].
250    ///
251    /// If this returns `None`, it means there has not been a transition from
252    /// the source archetype via the provided bundle.
253    ///
254    /// If this returns `Some(None)`, it means that the bundle cannot be removed
255    /// from the source archetype.
256    ///
257    /// [`EntityWorldMut::remove`]: crate::world::EntityWorldMut::remove
258    #[inline]
259    pub fn get_remove_bundle(&self, bundle_id: BundleId) -> Option<Option<ArchetypeId>> {
260        self.remove_bundle.get(bundle_id).cloned()
261    }
262
263    /// Caches the target archetype when removing a bundle to the source archetype.
264    /// For more information, see [`EntityWorldMut::remove`].
265    ///
266    /// [`EntityWorldMut::remove`]: crate::world::EntityWorldMut::remove
267    #[inline]
268    pub(crate) fn insert_remove_bundle(
269        &mut self,
270        bundle_id: BundleId,
271        archetype_id: Option<ArchetypeId>,
272    ) {
273        self.remove_bundle.insert(bundle_id, archetype_id);
274    }
275
276    /// Checks the cache for the target archetype when removing a bundle to the
277    /// source archetype. For more information, see [`EntityWorldMut::remove`].
278    ///
279    /// If this returns `None`, it means there has not been a transition from
280    /// the source archetype via the provided bundle.
281    ///
282    /// [`EntityWorldMut::remove`]: crate::world::EntityWorldMut::remove
283    #[inline]
284    pub fn get_take_bundle(&self, bundle_id: BundleId) -> Option<Option<ArchetypeId>> {
285        self.take_bundle.get(bundle_id).cloned()
286    }
287
288    /// Caches the target archetype when removing a bundle to the source archetype.
289    /// For more information, see [`EntityWorldMut::take`].
290    ///
291    /// [`EntityWorldMut::take`]: crate::world::EntityWorldMut::take
292    #[inline]
293    pub(crate) fn insert_take_bundle(
294        &mut self,
295        bundle_id: BundleId,
296        archetype_id: Option<ArchetypeId>,
297    ) {
298        self.take_bundle.insert(bundle_id, archetype_id);
299    }
300}
301
302/// Metadata about an [`Entity`] in a [`Archetype`].
303pub struct ArchetypeEntity {
304    entity: Entity,
305    table_row: TableRow,
306}
307
308impl ArchetypeEntity {
309    /// The ID of the entity.
310    #[inline]
311    pub const fn id(&self) -> Entity {
312        self.entity
313    }
314
315    /// The row in the [`Table`] where the entity's components are stored.
316    ///
317    /// [`Table`]: crate::storage::Table
318    #[inline]
319    pub const fn table_row(&self) -> TableRow {
320        self.table_row
321    }
322}
323
324/// Internal metadata for an [`Entity`] getting removed from an [`Archetype`].
325pub(crate) struct ArchetypeSwapRemoveResult {
326    /// If the [`Entity`] was not the last in the [`Archetype`], it gets removed by swapping it out
327    /// with the last entity in the archetype. In that case, this field contains the swapped entity.
328    pub(crate) swapped_entity: Option<Entity>,
329    /// The [`TableRow`] where the removed entity's components are stored.
330    pub(crate) table_row: TableRow,
331}
332
333/// Internal metadata for a [`Component`] within a given [`Archetype`].
334///
335/// [`Component`]: crate::component::Component
336struct ArchetypeComponentInfo {
337    storage_type: StorageType,
338    archetype_component_id: ArchetypeComponentId,
339}
340
341bitflags::bitflags! {
342    /// Flags used to keep track of metadata about the component in this [`Archetype`]
343    ///
344    /// Used primarily to early-out when there are no [`ComponentHook`] registered for any contained components.
345    #[derive(Clone, Copy)]
346    pub(crate) struct ArchetypeFlags: u32 {
347        const ON_ADD_HOOK    = (1 << 0);
348        const ON_INSERT_HOOK = (1 << 1);
349        const ON_REPLACE_HOOK = (1 << 2);
350        const ON_REMOVE_HOOK = (1 << 3);
351        const ON_ADD_OBSERVER = (1 << 4);
352        const ON_INSERT_OBSERVER = (1 << 5);
353        const ON_REPLACE_OBSERVER = (1 << 6);
354        const ON_REMOVE_OBSERVER = (1 << 7);
355    }
356}
357
358/// Metadata for a single archetype within a [`World`].
359///
360/// For more information, see the *[module level documentation]*.
361///
362/// [`World`]: crate::world::World
363/// [module level documentation]: crate::archetype
364pub struct Archetype {
365    id: ArchetypeId,
366    table_id: TableId,
367    edges: Edges,
368    entities: Vec<ArchetypeEntity>,
369    components: ImmutableSparseSet<ComponentId, ArchetypeComponentInfo>,
370    pub(crate) flags: ArchetypeFlags,
371}
372
373impl Archetype {
374    /// `table_components` and `sparse_set_components` must be sorted
375    pub(crate) fn new(
376        components: &Components,
377        component_index: &mut ComponentIndex,
378        observers: &Observers,
379        id: ArchetypeId,
380        table_id: TableId,
381        table_components: impl Iterator<Item = (ComponentId, ArchetypeComponentId)>,
382        sparse_set_components: impl Iterator<Item = (ComponentId, ArchetypeComponentId)>,
383    ) -> Self {
384        let (min_table, _) = table_components.size_hint();
385        let (min_sparse, _) = sparse_set_components.size_hint();
386        let mut flags = ArchetypeFlags::empty();
387        let mut archetype_components = SparseSet::with_capacity(min_table + min_sparse);
388        for (idx, (component_id, archetype_component_id)) in table_components.enumerate() {
389            // SAFETY: We are creating an archetype that includes this component so it must exist
390            let info = unsafe { components.get_info_unchecked(component_id) };
391            info.update_archetype_flags(&mut flags);
392            observers.update_archetype_flags(component_id, &mut flags);
393            archetype_components.insert(
394                component_id,
395                ArchetypeComponentInfo {
396                    storage_type: StorageType::Table,
397                    archetype_component_id,
398                },
399            );
400            // NOTE: the `table_components` are sorted AND they were inserted in the `Table` in the same
401            // sorted order, so the index of the `Column` in the `Table` is the same as the index of the
402            // component in the `table_components` vector
403            component_index
404                .entry(component_id)
405                .or_insert_with(HashMap::new)
406                .insert(id, ArchetypeRecord { column: Some(idx) });
407        }
408
409        for (component_id, archetype_component_id) in sparse_set_components {
410            // SAFETY: We are creating an archetype that includes this component so it must exist
411            let info = unsafe { components.get_info_unchecked(component_id) };
412            info.update_archetype_flags(&mut flags);
413            observers.update_archetype_flags(component_id, &mut flags);
414            archetype_components.insert(
415                component_id,
416                ArchetypeComponentInfo {
417                    storage_type: StorageType::SparseSet,
418                    archetype_component_id,
419                },
420            );
421            component_index
422                .entry(component_id)
423                .or_insert_with(HashMap::new)
424                .insert(id, ArchetypeRecord { column: None });
425        }
426        Self {
427            id,
428            table_id,
429            entities: Vec::new(),
430            components: archetype_components.into_immutable(),
431            edges: Default::default(),
432            flags,
433        }
434    }
435
436    /// Fetches the ID for the archetype.
437    #[inline]
438    pub fn id(&self) -> ArchetypeId {
439        self.id
440    }
441
442    /// Fetches the flags for the archetype.
443    #[inline]
444    pub(crate) fn flags(&self) -> ArchetypeFlags {
445        self.flags
446    }
447
448    /// Fetches the archetype's [`Table`] ID.
449    ///
450    /// [`Table`]: crate::storage::Table
451    #[inline]
452    pub fn table_id(&self) -> TableId {
453        self.table_id
454    }
455
456    /// Fetches the entities contained in this archetype.
457    #[inline]
458    pub fn entities(&self) -> &[ArchetypeEntity] {
459        &self.entities
460    }
461
462    /// Gets an iterator of all of the components stored in [`Table`]s.
463    ///
464    /// All of the IDs are unique.
465    ///
466    /// [`Table`]: crate::storage::Table
467    #[inline]
468    pub fn table_components(&self) -> impl Iterator<Item = ComponentId> + '_ {
469        self.components
470            .iter()
471            .filter(|(_, component)| component.storage_type == StorageType::Table)
472            .map(|(id, _)| *id)
473    }
474
475    /// Gets an iterator of all of the components stored in [`ComponentSparseSet`]s.
476    ///
477    /// All of the IDs are unique.
478    ///
479    /// [`ComponentSparseSet`]: crate::storage::ComponentSparseSet
480    #[inline]
481    pub fn sparse_set_components(&self) -> impl Iterator<Item = ComponentId> + '_ {
482        self.components
483            .iter()
484            .filter(|(_, component)| component.storage_type == StorageType::SparseSet)
485            .map(|(id, _)| *id)
486    }
487
488    /// Gets an iterator of all of the components in the archetype.
489    ///
490    /// All of the IDs are unique.
491    #[inline]
492    pub fn components(&self) -> impl Iterator<Item = ComponentId> + Clone + '_ {
493        self.components.indices()
494    }
495
496    /// Returns the total number of components in the archetype
497    #[inline]
498    pub fn component_count(&self) -> usize {
499        self.components.len()
500    }
501
502    /// Gets an iterator of all of the components in the archetype, along with
503    /// their archetype component ID.
504    pub(crate) fn components_with_archetype_component_id(
505        &self,
506    ) -> impl Iterator<Item = (ComponentId, ArchetypeComponentId)> + '_ {
507        self.components
508            .iter()
509            .map(|(component_id, info)| (*component_id, info.archetype_component_id))
510    }
511
512    /// Fetches an immutable reference to the archetype's [`Edges`], a cache of
513    /// archetypal relationships.
514    #[inline]
515    pub fn edges(&self) -> &Edges {
516        &self.edges
517    }
518
519    /// Fetches a mutable reference to the archetype's [`Edges`], a cache of
520    /// archetypal relationships.
521    #[inline]
522    pub(crate) fn edges_mut(&mut self) -> &mut Edges {
523        &mut self.edges
524    }
525
526    /// Fetches the row in the [`Table`] where the components for the entity at `index`
527    /// is stored.
528    ///
529    /// An entity's archetype row can be fetched from [`EntityLocation::archetype_row`], which
530    /// can be retrieved from [`Entities::get`].
531    ///
532    /// # Panics
533    /// This function will panic if `index >= self.len()`.
534    ///
535    /// [`Table`]: crate::storage::Table
536    /// [`EntityLocation::archetype_row`]: crate::entity::EntityLocation::archetype_row
537    /// [`Entities::get`]: crate::entity::Entities::get
538    #[inline]
539    pub fn entity_table_row(&self, row: ArchetypeRow) -> TableRow {
540        self.entities[row.index()].table_row
541    }
542
543    /// Updates if the components for the entity at `index` can be found
544    /// in the corresponding table.
545    ///
546    /// # Panics
547    /// This function will panic if `index >= self.len()`.
548    #[inline]
549    pub(crate) fn set_entity_table_row(&mut self, row: ArchetypeRow, table_row: TableRow) {
550        self.entities[row.index()].table_row = table_row;
551    }
552
553    /// Allocates an entity to the archetype.
554    ///
555    /// # Safety
556    /// valid component values must be immediately written to the relevant storages
557    /// `table_row` must be valid
558    #[inline]
559    pub(crate) unsafe fn allocate(
560        &mut self,
561        entity: Entity,
562        table_row: TableRow,
563    ) -> EntityLocation {
564        let archetype_row = ArchetypeRow::new(self.entities.len());
565        self.entities.push(ArchetypeEntity { entity, table_row });
566
567        EntityLocation {
568            archetype_id: self.id,
569            archetype_row,
570            table_id: self.table_id,
571            table_row,
572        }
573    }
574
575    #[inline]
576    pub(crate) fn reserve(&mut self, additional: usize) {
577        self.entities.reserve(additional);
578    }
579
580    /// Removes the entity at `index` by swapping it out. Returns the table row the entity is stored
581    /// in.
582    ///
583    /// # Panics
584    /// This function will panic if `index >= self.len()`
585    #[inline]
586    pub(crate) fn swap_remove(&mut self, row: ArchetypeRow) -> ArchetypeSwapRemoveResult {
587        let is_last = row.index() == self.entities.len() - 1;
588        let entity = self.entities.swap_remove(row.index());
589        ArchetypeSwapRemoveResult {
590            swapped_entity: if is_last {
591                None
592            } else {
593                Some(self.entities[row.index()].entity)
594            },
595            table_row: entity.table_row,
596        }
597    }
598
599    /// Gets the total number of entities that belong to the archetype.
600    #[inline]
601    pub fn len(&self) -> usize {
602        self.entities.len()
603    }
604
605    /// Checks if the archetype has any entities.
606    #[inline]
607    pub fn is_empty(&self) -> bool {
608        self.entities.is_empty()
609    }
610
611    /// Checks if the archetype contains a specific component. This runs in `O(1)` time.
612    #[inline]
613    pub fn contains(&self, component_id: ComponentId) -> bool {
614        self.components.contains(component_id)
615    }
616
617    /// Gets the type of storage where a component in the archetype can be found.
618    /// Returns `None` if the component is not part of the archetype.
619    /// This runs in `O(1)` time.
620    #[inline]
621    pub fn get_storage_type(&self, component_id: ComponentId) -> Option<StorageType> {
622        self.components
623            .get(component_id)
624            .map(|info| info.storage_type)
625    }
626
627    /// Fetches the corresponding [`ArchetypeComponentId`] for a component in the archetype.
628    /// Returns `None` if the component is not part of the archetype.
629    /// This runs in `O(1)` time.
630    #[inline]
631    pub fn get_archetype_component_id(
632        &self,
633        component_id: ComponentId,
634    ) -> Option<ArchetypeComponentId> {
635        self.components
636            .get(component_id)
637            .map(|info| info.archetype_component_id)
638    }
639
640    /// Clears all entities from the archetype.
641    pub(crate) fn clear_entities(&mut self) {
642        self.entities.clear();
643    }
644
645    /// Returns true if any of the components in this archetype have `on_add` hooks
646    #[inline]
647    pub fn has_add_hook(&self) -> bool {
648        self.flags().contains(ArchetypeFlags::ON_ADD_HOOK)
649    }
650
651    /// Returns true if any of the components in this archetype have `on_insert` hooks
652    #[inline]
653    pub fn has_insert_hook(&self) -> bool {
654        self.flags().contains(ArchetypeFlags::ON_INSERT_HOOK)
655    }
656
657    /// Returns true if any of the components in this archetype have `on_replace` hooks
658    #[inline]
659    pub fn has_replace_hook(&self) -> bool {
660        self.flags().contains(ArchetypeFlags::ON_REPLACE_HOOK)
661    }
662
663    /// Returns true if any of the components in this archetype have `on_remove` hooks
664    #[inline]
665    pub fn has_remove_hook(&self) -> bool {
666        self.flags().contains(ArchetypeFlags::ON_REMOVE_HOOK)
667    }
668
669    /// Returns true if any of the components in this archetype have at least one [`OnAdd`] observer
670    ///
671    /// [`OnAdd`]: crate::world::OnAdd
672    #[inline]
673    pub fn has_add_observer(&self) -> bool {
674        self.flags().contains(ArchetypeFlags::ON_ADD_OBSERVER)
675    }
676
677    /// Returns true if any of the components in this archetype have at least one [`OnInsert`] observer
678    ///
679    /// [`OnInsert`]: crate::world::OnInsert
680    #[inline]
681    pub fn has_insert_observer(&self) -> bool {
682        self.flags().contains(ArchetypeFlags::ON_INSERT_OBSERVER)
683    }
684
685    /// Returns true if any of the components in this archetype have at least one [`OnReplace`] observer
686    ///
687    /// [`OnReplace`]: crate::world::OnReplace
688    #[inline]
689    pub fn has_replace_observer(&self) -> bool {
690        self.flags().contains(ArchetypeFlags::ON_REPLACE_OBSERVER)
691    }
692
693    /// Returns true if any of the components in this archetype have at least one [`OnRemove`] observer
694    ///
695    /// [`OnRemove`]: crate::world::OnRemove
696    #[inline]
697    pub fn has_remove_observer(&self) -> bool {
698        self.flags().contains(ArchetypeFlags::ON_REMOVE_OBSERVER)
699    }
700}
701
702/// The next [`ArchetypeId`] in an [`Archetypes`] collection.
703///
704/// This is used in archetype update methods to limit archetype updates to the
705/// ones added since the last time the method ran.
706#[derive(Debug, Copy, Clone, PartialEq)]
707pub struct ArchetypeGeneration(pub(crate) ArchetypeId);
708
709impl ArchetypeGeneration {
710    /// The first archetype.
711    #[inline]
712    pub const fn initial() -> Self {
713        ArchetypeGeneration(ArchetypeId::EMPTY)
714    }
715}
716
717#[derive(Hash, PartialEq, Eq)]
718struct ArchetypeComponents {
719    table_components: Box<[ComponentId]>,
720    sparse_set_components: Box<[ComponentId]>,
721}
722
723/// An opaque unique joint ID for a [`Component`] in an [`Archetype`] within a [`World`].
724///
725/// A component may be present within multiple archetypes, but each component within
726/// each archetype has its own unique `ArchetypeComponentId`. This is leveraged by the system
727/// schedulers to opportunistically run multiple systems in parallel that would otherwise
728/// conflict. For example, `Query<&mut A, With<B>>` and `Query<&mut A, Without<B>>` can run in
729/// parallel as the matched `ArchetypeComponentId` sets for both queries are disjoint, even
730/// though `&mut A` on both queries point to the same [`ComponentId`].
731///
732/// In SQL terms, these IDs are composite keys on a [many-to-many relationship] between archetypes
733/// and components. Each component type will have only one [`ComponentId`], but may have many
734/// [`ArchetypeComponentId`]s, one for every archetype the component is present in. Likewise, each
735/// archetype will have only one [`ArchetypeId`] but may have many [`ArchetypeComponentId`]s, one
736/// for each component that belongs to the archetype.
737///
738/// Every [`Resource`] is also assigned one of these IDs. As resources do not belong to any
739/// particular archetype, a resource's ID uniquely identifies it.
740///
741/// These IDs are only valid within a given World, and are not globally unique.
742/// Attempting to use an ID on a world that it wasn't sourced from will
743/// not point to the same archetype nor the same component.
744///
745/// [`Component`]: crate::component::Component
746/// [`World`]: crate::world::World
747/// [`Resource`]: crate::system::Resource
748/// [many-to-many relationship]: https://en.wikipedia.org/wiki/Many-to-many_(data_model)
749#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
750pub struct ArchetypeComponentId(usize);
751
752impl SparseSetIndex for ArchetypeComponentId {
753    #[inline]
754    fn sparse_set_index(&self) -> usize {
755        self.0
756    }
757
758    fn get_sparse_set_index(value: usize) -> Self {
759        Self(value)
760    }
761}
762
763/// Maps a [`ComponentId`] to the list of [`Archetypes`]([`Archetype`]) that contain the [`Component`](crate::component::Component),
764/// along with an [`ArchetypeRecord`] which contains some metadata about how the component is stored in the archetype.
765pub type ComponentIndex = HashMap<ComponentId, HashMap<ArchetypeId, ArchetypeRecord>>;
766
767/// The backing store of all [`Archetype`]s within a [`World`].
768///
769/// For more information, see the *[module level documentation]*.
770///
771/// [`World`]: crate::world::World
772/// [module level documentation]: crate::archetype
773pub struct Archetypes {
774    pub(crate) archetypes: Vec<Archetype>,
775    archetype_component_count: usize,
776    /// find the archetype id by the archetype's components
777    by_components: HashMap<ArchetypeComponents, ArchetypeId>,
778    /// find all the archetypes that contain a component
779    pub(crate) by_component: ComponentIndex,
780}
781
782/// Metadata about how a component is stored in an [`Archetype`].
783pub struct ArchetypeRecord {
784    /// Index of the component in the archetype's [`Table`](crate::storage::Table),
785    /// or None if the component is a sparse set component.
786    #[allow(dead_code)]
787    pub(crate) column: Option<usize>,
788}
789
790impl Archetypes {
791    pub(crate) fn new() -> Self {
792        let mut archetypes = Archetypes {
793            archetypes: Vec::new(),
794            by_components: Default::default(),
795            by_component: Default::default(),
796            archetype_component_count: 0,
797        };
798        // SAFETY: Empty archetype has no components
799        unsafe {
800            archetypes.get_id_or_insert(
801                &Components::default(),
802                &Observers::default(),
803                TableId::empty(),
804                Vec::new(),
805                Vec::new(),
806            );
807        }
808        archetypes
809    }
810
811    /// Returns the "generation", a handle to the current highest archetype ID.
812    ///
813    /// This can be used with the `Index` [`Archetypes`] implementation to
814    /// iterate over newly introduced [`Archetype`]s since the last time this
815    /// function was called.
816    #[inline]
817    pub fn generation(&self) -> ArchetypeGeneration {
818        let id = ArchetypeId::new(self.archetypes.len());
819        ArchetypeGeneration(id)
820    }
821
822    /// Fetches the total number of [`Archetype`]s within the world.
823    #[inline]
824    #[allow(clippy::len_without_is_empty)] // the internal vec is never empty.
825    pub fn len(&self) -> usize {
826        self.archetypes.len()
827    }
828
829    /// Fetches an immutable reference to the archetype without any components.
830    ///
831    /// Shorthand for `archetypes.get(ArchetypeId::EMPTY).unwrap()`
832    #[inline]
833    pub fn empty(&self) -> &Archetype {
834        // SAFETY: empty archetype always exists
835        unsafe { self.archetypes.get_unchecked(ArchetypeId::EMPTY.index()) }
836    }
837
838    /// Fetches a mutable reference to the archetype without any components.
839    #[inline]
840    pub(crate) fn empty_mut(&mut self) -> &mut Archetype {
841        // SAFETY: empty archetype always exists
842        unsafe {
843            self.archetypes
844                .get_unchecked_mut(ArchetypeId::EMPTY.index())
845        }
846    }
847
848    /// Generate and store a new [`ArchetypeComponentId`].
849    ///
850    /// This simply increment the counter and return the new value.
851    ///
852    /// # Panics
853    ///
854    /// On archetype component id overflow.
855    pub(crate) fn new_archetype_component_id(&mut self) -> ArchetypeComponentId {
856        let id = ArchetypeComponentId(self.archetype_component_count);
857        self.archetype_component_count = self
858            .archetype_component_count
859            .checked_add(1)
860            .expect("archetype_component_count overflow");
861        id
862    }
863
864    /// Fetches an immutable reference to an [`Archetype`] using its
865    /// ID. Returns `None` if no corresponding archetype exists.
866    #[inline]
867    pub fn get(&self, id: ArchetypeId) -> Option<&Archetype> {
868        self.archetypes.get(id.index())
869    }
870
871    /// # Panics
872    ///
873    /// Panics if `a` and `b` are equal.
874    #[inline]
875    pub(crate) fn get_2_mut(
876        &mut self,
877        a: ArchetypeId,
878        b: ArchetypeId,
879    ) -> (&mut Archetype, &mut Archetype) {
880        if a.index() > b.index() {
881            let (b_slice, a_slice) = self.archetypes.split_at_mut(a.index());
882            (&mut a_slice[0], &mut b_slice[b.index()])
883        } else {
884            let (a_slice, b_slice) = self.archetypes.split_at_mut(b.index());
885            (&mut a_slice[a.index()], &mut b_slice[0])
886        }
887    }
888
889    /// Returns a read-only iterator over all archetypes.
890    #[inline]
891    pub fn iter(&self) -> impl Iterator<Item = &Archetype> {
892        self.archetypes.iter()
893    }
894
895    /// Gets the archetype id matching the given inputs or inserts a new one if it doesn't exist.
896    /// `table_components` and `sparse_set_components` must be sorted
897    ///
898    /// # Safety
899    /// [`TableId`] must exist in tables
900    /// `table_components` and `sparse_set_components` must exist in `components`
901    pub(crate) unsafe fn get_id_or_insert(
902        &mut self,
903        components: &Components,
904        observers: &Observers,
905        table_id: TableId,
906        table_components: Vec<ComponentId>,
907        sparse_set_components: Vec<ComponentId>,
908    ) -> ArchetypeId {
909        let archetype_identity = ArchetypeComponents {
910            sparse_set_components: sparse_set_components.into_boxed_slice(),
911            table_components: table_components.into_boxed_slice(),
912        };
913
914        let archetypes = &mut self.archetypes;
915        let archetype_component_count = &mut self.archetype_component_count;
916        let component_index = &mut self.by_component;
917        let archetype_id = *self
918            .by_components
919            .entry(archetype_identity)
920            .or_insert_with_key(move |identity| {
921                let ArchetypeComponents {
922                    table_components,
923                    sparse_set_components,
924                } = identity;
925                let id = ArchetypeId::new(archetypes.len());
926                let table_start = *archetype_component_count;
927                *archetype_component_count += table_components.len();
928                let table_archetype_components =
929                    (table_start..*archetype_component_count).map(ArchetypeComponentId);
930                let sparse_start = *archetype_component_count;
931                *archetype_component_count += sparse_set_components.len();
932                let sparse_set_archetype_components =
933                    (sparse_start..*archetype_component_count).map(ArchetypeComponentId);
934                archetypes.push(Archetype::new(
935                    components,
936                    component_index,
937                    observers,
938                    id,
939                    table_id,
940                    table_components
941                        .iter()
942                        .copied()
943                        .zip(table_archetype_components),
944                    sparse_set_components
945                        .iter()
946                        .copied()
947                        .zip(sparse_set_archetype_components),
948                ));
949                id
950            });
951        archetype_id
952    }
953
954    /// Returns the number of components that are stored in archetypes.
955    /// Note that if some component `T` is stored in more than one archetype, it will be counted once for each archetype it's present in.
956    #[inline]
957    pub fn archetype_components_len(&self) -> usize {
958        self.archetype_component_count
959    }
960
961    /// Clears all entities from all archetypes.
962    pub(crate) fn clear_entities(&mut self) {
963        for archetype in &mut self.archetypes {
964            archetype.clear_entities();
965        }
966    }
967
968    /// Get the component index
969    pub(crate) fn component_index(&self) -> &ComponentIndex {
970        &self.by_component
971    }
972
973    pub(crate) fn update_flags(
974        &mut self,
975        component_id: ComponentId,
976        flags: ArchetypeFlags,
977        set: bool,
978    ) {
979        if let Some(archetypes) = self.by_component.get(&component_id) {
980            for archetype_id in archetypes.keys() {
981                // SAFETY: the component index only contains valid archetype ids
982                self.archetypes
983                    .get_mut(archetype_id.index())
984                    .unwrap()
985                    .flags
986                    .set(flags, set);
987            }
988        }
989    }
990}
991
992impl Index<RangeFrom<ArchetypeGeneration>> for Archetypes {
993    type Output = [Archetype];
994
995    #[inline]
996    fn index(&self, index: RangeFrom<ArchetypeGeneration>) -> &Self::Output {
997        &self.archetypes[index.start.0.index()..]
998    }
999}
1000impl Index<ArchetypeId> for Archetypes {
1001    type Output = Archetype;
1002
1003    #[inline]
1004    fn index(&self, index: ArchetypeId) -> &Self::Output {
1005        &self.archetypes[index.index()]
1006    }
1007}
1008
1009impl IndexMut<ArchetypeId> for Archetypes {
1010    #[inline]
1011    fn index_mut(&mut self, index: ArchetypeId) -> &mut Self::Output {
1012        &mut self.archetypes[index.index()]
1013    }
1014}