Skip to main content

bevy_ecs/entity/
mod.rs

1//! This module contains all entity types and utilities for interacting with their ids.
2//!
3//! # What is an Entity?
4//!
5//! The ecs [docs](crate) give an overview of what entities are and generally how to use them.
6//! These docs provide more detail into how they actually work.
7//! In these docs [`Entity`] and "entity id" are synonymous and refer to the [`Entity`] type, which identifies an entity.
8//! The term "entity" used on its own refers to the "thing"/"game object" that id references.
9//!
10//! # In this Module
11//!
12//! This module contains four main things:
13//!
14//!  - Core ECS types like [`Entity`], [`Entities`], and [`EntityAllocator`].
15//!  - Utilities for [`Entity`] ids like [`MapEntities`], [`EntityHash`], and [`UniqueEntityVec`].
16//!  - Helpers for entity tasks like [`EntityCloner`].
17//!  - Entity-related error types like [`EntityNotSpawnedError`].
18//!
19//! # Entity Life Cycle
20//!
21//! Entities have life cycles.
22//! They are created, used for a while, and eventually destroyed.
23//! Let's start from the top:
24//!
25//! **Spawn:** An entity is created.
26//! In bevy, this is called spawning.
27//! Most commonly, this is done through [`World::spawn`](crate::world::World::spawn) or [`Commands::spawn`](crate::system::Commands::spawn).
28//! This creates a fresh entity in the world and returns its [`Entity`] id, which can be used to interact with the entity it identifies.
29//! These methods initialize the entity with a [`Bundle`], a group of [components](crate::component::Component) that it starts with.
30//! It is also possible to use [`World::spawn_empty`](crate::world::World::spawn_empty) or [`Commands::spawn_empty`](crate::system::Commands::spawn_empty), which are similar but do not add any components to the entity.
31//! In either case, the returned [`Entity`] id is used to further interact with the entity.
32//!
33//! **Update:** Once an entity is created, you will need its [`Entity`] id to perform further actions on it.
34//! This can be done through [`World::entity_mut`](crate::world::World::entity_mut) and [`Commands::entity`](crate::system::Commands::entity).
35//! Even if you don't store the id, you can still find the entity you spawned by searching for it in a [`Query`].
36//! Queries are also the primary way of interacting with an entity's components.
37//! You can use [`EntityWorldMut::remove`](crate::world::EntityWorldMut::remove) and [`EntityCommands::remove`](crate::system::EntityCommands::remove) to remove components,
38//! and you can use [`EntityWorldMut::insert`](crate::world::EntityWorldMut::insert) and [`EntityCommands::insert`](crate::system::EntityCommands::insert) to insert more components.
39//! Be aware that each entity can only have 0 or 1 values for each kind of component, so inserting a bundle may overwrite existing component values.
40//! This can also be further configured based on the insert method.
41//!
42//! **Despawn:** Despawn an entity when it is no longer needed.
43//! This destroys it and all its components.
44//! The entity is no longer reachable through the [`World`], [`Commands`], or [`Query`]s.
45//! Note that this means an [`Entity`] id may refer to an entity that has since been despawned!
46//! Not all [`Entity`] ids refer to active entities.
47//! If an [`Entity`] id is used when its entity has been despawned, an [`EntityNotSpawnedError`] is emitted.
48//! Any [`System`](crate::system) could despawn any entity; even if you never share its id, it could still be despawned unexpectedly.
49//! Your code should do its best to handle these errors gracefully.
50//!
51//! In short:
52//!
53//! - Entities are spawned through methods like [`World::spawn`](crate::world::World::spawn), which return an [`Entity`] id for the new entity.
54//! - Once spawned, they can be accessed and modified through [`Query`]s and other apis.
55//! - You can get the [`Entity`] id of an entity through [`Query`]s, so losing an [`Entity`] id is not a problem.
56//! - Entities can have components inserted and removed via [`World::entity_mut`](crate::world::World::entity_mut) and [`Commands::entity`](crate::system::Commands::entity).
57//! - Entities are eventually despawned, destroying the entity and causing its [`Entity`] id to no longer refer to an entity.
58//! - Not all [`Entity`] ids point to actual entities, which makes many entity methods fallible.
59//!
60//! # [`Entity`] Allocation
61//!
62//! Entity spawning is actually done in two stages:
63//! 1. Allocate: We generate a new valid / unique [`Entity`].
64//! 2. Spawn: We make the entity "exist" in the [`World`]. It will show up in queries, it can have components, etc.
65//!
66//! The reason for this split is that we need to be able to _allocate_ entity ids concurrently,
67//! whereas spawning requires unique (non-concurrent) access to the world.
68//!
69//! An [`Entity`] therefore goes through the following lifecycle:
70//! 1. Unallocated (and "valid"): Only the allocator has any knowledge of this [`Entity`], but it _could_ be spawned, theoretically.
71//! 2. Allocated (and "valid"): The allocator has handed out the [`Entity`], but it is not yet spawned.
72//! 3. Spawned: The entity now "exists" in the [`World`]. It will show up in queries, it can have components, etc.
73//! 4. Despawned: The entity no longer "exist" in the [`World`].
74//! 5. Freed (and "invalid"): The [`Entity`] is returned to the allocator. The [`Entity::generation`] is bumped, which makes all existing [`Entity`] references with the previous generation "invalid".
75//!
76//! Note that by default, most spawn and despawn APIs handle the [`Entity`] allocation and freeing process for developers.
77//!
78//! [`World`]: crate::world::World
79//! [`Query`]: crate::system::Query
80//! [`Bundle`]: crate::bundle::Bundle
81//! [`Component`]: crate::component::Component
82//! [`Commands`]: crate::system::Commands
83
84mod clone_entities;
85mod entity_set;
86mod map_entities;
87
88pub use clone_entities::*;
89pub use entity_set::*;
90pub use map_entities::*;
91
92mod remote_allocator;
93pub use remote_allocator::RemoteAllocator;
94
95mod hash;
96pub use hash::*;
97
98pub mod hash_map;
99pub mod hash_set;
100
101pub use hash_map::EntityHashMap;
102pub use hash_set::EntityHashSet;
103
104pub mod index_map;
105pub mod index_set;
106
107pub use index_map::EntityIndexMap;
108pub use index_set::EntityIndexSet;
109
110pub mod unique_array;
111pub mod unique_slice;
112pub mod unique_vec;
113
114pub use unique_array::{UniqueEntityArray, UniqueEntityEquivalentArray};
115pub use unique_slice::{UniqueEntityEquivalentSlice, UniqueEntitySlice};
116pub use unique_vec::{UniqueEntityEquivalentVec, UniqueEntityVec};
117
118use crate::{
119    archetype::{ArchetypeId, ArchetypeRow},
120    change_detection::{CheckChangeTicks, MaybeLocation, Tick},
121    storage::{SparseSetIndex, TableId, TableRow},
122};
123use alloc::vec::Vec;
124use core::{fmt, hash::Hash, mem, num::NonZero, panic::Location};
125use derive_more::derive::Display;
126use log::warn;
127use nonmax::NonMaxU32;
128
129#[cfg(feature = "bevy_reflect")]
130use bevy_reflect::Reflect;
131#[cfg(all(feature = "bevy_reflect", feature = "serialize"))]
132use bevy_reflect::{ReflectDeserialize, ReflectSerialize};
133#[cfg(feature = "serialize")]
134use serde::{Deserialize, Serialize};
135
136/// This represents the index of an [`Entity`] within the [`Entities`] array.
137/// This is a lighter weight version of [`Entity`].
138///
139/// This is a unique identifier for an entity in the world.
140/// This differs from [`Entity`] in that [`Entity`] is unique for all entities total (unless the [`Entity::generation`] wraps),
141/// but this is only unique for entities that are active.
142///
143/// This can be used over [`Entity`] to improve performance in some cases,
144/// but improper use can cause this to identify a different entity than intended.
145/// Use with caution.
146#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, Display)]
147#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
148#[cfg_attr(feature = "bevy_reflect", reflect(opaque))]
149#[cfg_attr(feature = "bevy_reflect", reflect(Hash, PartialEq, Debug, Clone))]
150#[repr(transparent)]
151pub struct EntityIndex(NonMaxU32);
152
153impl EntityIndex {
154    const PLACEHOLDER: Self = Self(NonMaxU32::MAX);
155
156    /// Constructs a new [`EntityIndex`] from its index.
157    pub const fn new(index: NonMaxU32) -> Self {
158        Self(index)
159    }
160
161    /// Equivalent to [`new`](Self::new) except that it takes a `u32` instead of a `NonMaxU32`.
162    ///
163    /// Returns `None` if the index is `u32::MAX`.
164    pub const fn from_raw_u32(index: u32) -> Option<Self> {
165        match NonMaxU32::new(index) {
166            Some(index) => Some(Self(index)),
167            None => None,
168        }
169    }
170
171    /// Gets the index of the entity.
172    #[inline(always)]
173    pub const fn index(self) -> u32 {
174        self.0.get()
175    }
176
177    /// Gets some bits that represent this value.
178    /// The bits are opaque and should not be regarded as meaningful.
179    #[inline(always)]
180    const fn to_bits(self) -> u32 {
181        // SAFETY: NonMax is repr transparent.
182        unsafe { mem::transmute::<NonMaxU32, u32>(self.0) }
183    }
184
185    /// Reconstruct an [`EntityIndex`] previously destructured with [`EntityIndex::to_bits`].
186    ///
187    /// Only useful when applied to results from `to_bits` in the same instance of an application.
188    ///
189    /// # Panics
190    ///
191    /// This method will likely panic if given `u32` values that did not come from [`EntityIndex::to_bits`].
192    #[inline]
193    const fn from_bits(bits: u32) -> Self {
194        Self::try_from_bits(bits).expect("Attempted to initialize invalid bits as an entity index")
195    }
196
197    /// Reconstruct an [`EntityIndex`] previously destructured with [`EntityIndex::to_bits`].
198    ///
199    /// Only useful when applied to results from `to_bits` in the same instance of an application.
200    ///
201    /// This method is the fallible counterpart to [`EntityIndex::from_bits`].
202    #[inline(always)]
203    const fn try_from_bits(bits: u32) -> Option<Self> {
204        match NonZero::<u32>::new(bits) {
205            // SAFETY: NonMax and NonZero are repr transparent.
206            Some(underlying) => Some(Self(unsafe {
207                mem::transmute::<NonZero<u32>, NonMaxU32>(underlying)
208            })),
209            None => None,
210        }
211    }
212}
213
214impl SparseSetIndex for EntityIndex {
215    #[inline]
216    fn sparse_set_index(&self) -> usize {
217        self.index() as usize
218    }
219
220    #[inline]
221    fn get_sparse_set_index(value: usize) -> Self {
222        Self::from_bits(value as u32)
223    }
224}
225
226/// This tracks different versions or generations of an [`EntityIndex`].
227/// Importantly, this can wrap, meaning each generation is not necessarily unique per [`EntityIndex`].
228///
229/// This should be treated as a opaque identifier, and its internal representation may be subject to change.
230///
231/// # Aliasing
232///
233/// Internally [`EntityGeneration`] wraps a `u32`, so it can't represent *every* possible generation.
234/// Eventually, generations can (and do) wrap or alias.
235/// This can cause [`Entity`] and [`EntityGeneration`] values to be equal while still referring to different conceptual entities.
236/// This can cause some surprising behavior:
237///
238/// ```
239/// # use bevy_ecs::entity::EntityGeneration;
240/// let (aliased, did_alias) = EntityGeneration::FIRST.after_versions(1u32 << 31).after_versions_and_could_alias(1u32 << 31);
241/// assert!(did_alias);
242/// assert!(EntityGeneration::FIRST == aliased);
243/// ```
244///
245/// This can cause some unintended side effects.
246/// See [`Entity`] docs for practical concerns and how to minimize any risks.
247#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, Display)]
248#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
249#[cfg_attr(feature = "bevy_reflect", reflect(opaque))]
250#[cfg_attr(feature = "bevy_reflect", reflect(Hash, PartialEq, Debug, Clone))]
251#[repr(transparent)]
252pub struct EntityGeneration(u32);
253
254impl EntityGeneration {
255    /// Represents the first generation of an [`EntityIndex`].
256    pub const FIRST: Self = Self(0);
257
258    /// Non-wrapping difference between two generations after which a signed interpretation becomes negative.
259    const DIFF_MAX: u32 = 1u32 << 31;
260
261    /// Gets some bits that represent this value.
262    /// The bits are opaque and should not be regarded as meaningful.
263    #[inline(always)]
264    pub const fn to_bits(self) -> u32 {
265        self.0
266    }
267
268    /// Reconstruct an [`EntityGeneration`] previously destructured with [`EntityGeneration::to_bits`].
269    ///
270    /// Only useful when applied to results from `to_bits` in the same instance of an application.
271    #[inline]
272    pub const fn from_bits(bits: u32) -> Self {
273        Self(bits)
274    }
275
276    /// Returns the [`EntityGeneration`] that would result from this many more `versions` of the corresponding [`EntityIndex`] from passing.
277    #[inline]
278    pub const fn after_versions(self, versions: u32) -> Self {
279        Self(self.0.wrapping_add(versions))
280    }
281
282    /// Identical to [`after_versions`](Self::after_versions) but also returns a `bool` indicating if,
283    /// after these `versions`, one such version could conflict with a previous one.
284    ///
285    /// If this happens, this will no longer uniquely identify a version of an [`EntityIndex`].
286    /// This is called entity aliasing.
287    #[inline]
288    pub const fn after_versions_and_could_alias(self, versions: u32) -> (Self, bool) {
289        let raw = self.0.overflowing_add(versions);
290        (Self(raw.0), raw.1)
291    }
292
293    /// Compares two generations.
294    ///
295    /// Generations that are later will be [`Greater`](core::cmp::Ordering::Greater) than earlier ones.
296    ///
297    /// ```
298    /// # use bevy_ecs::entity::EntityGeneration;
299    /// # use core::cmp::Ordering;
300    /// let later_generation = EntityGeneration::FIRST.after_versions(400);
301    /// assert_eq!(EntityGeneration::FIRST.cmp_approx(&later_generation), Ordering::Less);
302    ///
303    /// let (aliased, did_alias) = EntityGeneration::FIRST.after_versions(400).after_versions_and_could_alias(u32::MAX);
304    /// assert!(did_alias);
305    /// assert_eq!(EntityGeneration::FIRST.cmp_approx(&aliased), Ordering::Less);
306    /// ```
307    ///
308    /// Ordering will be incorrect and [non-transitive](https://en.wikipedia.org/wiki/Transitive_relation)
309    /// for distant generations:
310    ///
311    /// ```should_panic
312    /// # use bevy_ecs::entity::EntityGeneration;
313    /// # use core::cmp::Ordering;
314    /// let later_generation = EntityGeneration::FIRST.after_versions(3u32 << 31);
315    /// let much_later_generation = later_generation.after_versions(3u32 << 31);
316    ///
317    /// // while these orderings are correct and pass assertions...
318    /// assert_eq!(EntityGeneration::FIRST.cmp_approx(&later_generation), Ordering::Less);
319    /// assert_eq!(later_generation.cmp_approx(&much_later_generation), Ordering::Less);
320    ///
321    /// // ... this ordering is not and the assertion fails!
322    /// assert_eq!(EntityGeneration::FIRST.cmp_approx(&much_later_generation), Ordering::Less);
323    /// ```
324    ///
325    /// Because of this, `EntityGeneration` does not implement `Ord`/`PartialOrd`.
326    #[inline]
327    pub const fn cmp_approx(&self, other: &Self) -> core::cmp::Ordering {
328        use core::cmp::Ordering;
329        match self.0.wrapping_sub(other.0) {
330            0 => Ordering::Equal,
331            1..Self::DIFF_MAX => Ordering::Greater,
332            _ => Ordering::Less,
333        }
334    }
335}
336
337/// Unique identifier for an entity in a [`World`].
338/// Note that this is just an id, not the entity itself.
339/// Further, the entity this id refers to may no longer exist in the [`World`].
340/// For more information about entities, their ids, and how to use them, see the module [docs](crate::entity).
341///
342/// # Aliasing
343///
344/// Once an entity is despawned, it ceases to exist.
345/// However, its [`Entity`] id is still present, and may still be contained in some data.
346/// This becomes problematic because it is possible for a later entity to be spawned at the exact same id!
347/// If this happens, which is rare but very possible, it will be logged.
348///
349/// Aliasing can happen without warning.
350/// Holding onto a [`Entity`] id corresponding to an entity well after that entity was despawned can cause un-intuitive behavior for both ordering, and comparing in general.
351/// To prevent these bugs, it is generally best practice to stop holding an [`Entity`] or [`EntityGeneration`] value as soon as you know it has been despawned.
352/// If you must do otherwise, do not assume the [`Entity`] id corresponds to the same entity it originally did.
353/// See [`EntityGeneration`]'s docs for more information about aliasing and why it occurs.
354///
355/// # Stability warning
356/// For all intents and purposes, `Entity` should be treated as an opaque identifier. The internal bit
357/// representation is liable to change from release to release as are the behaviors or performance
358/// characteristics of any of its trait implementations (i.e. `Ord`, `Hash`, etc.). This means that changes in
359/// `Entity`'s representation, though made readable through various functions on the type, are not considered
360/// breaking changes under [SemVer].
361///
362/// In particular, directly serializing with `Serialize` and `Deserialize` make zero guarantee of long
363/// term wire format compatibility. Changes in behavior will cause serialized `Entity` values persisted
364/// to long term storage (i.e. disk, databases, etc.) will fail to deserialize upon being updated.
365///
366/// # Usage
367///
368/// This data type is returned by iterating a `Query` that has `Entity` as part of its query fetch type parameter ([learn more]).
369/// It can also be obtained by calling [`EntityCommands::id`] or [`EntityWorldMut::id`].
370///
371/// ```
372/// # use bevy_ecs::prelude::*;
373/// # #[derive(Component)]
374/// # struct SomeComponent;
375/// fn setup(mut commands: Commands) {
376///     // Calling `spawn` returns `EntityCommands`.
377///     let entity = commands.spawn(SomeComponent).id();
378/// }
379///
380/// fn exclusive_system(world: &mut World) {
381///     // Calling `spawn` returns `EntityWorldMut`.
382///     let entity = world.spawn(SomeComponent).id();
383/// }
384/// #
385/// # bevy_ecs::system::assert_is_system(setup);
386/// # bevy_ecs::system::assert_is_system(exclusive_system);
387/// ```
388///
389/// It can be used to refer to a specific entity to apply [`EntityCommands`], or to call [`Query::get`] (or similar methods) to access its components.
390///
391/// ```
392/// # use bevy_ecs::prelude::*;
393/// #
394/// # #[derive(Component)]
395/// # struct Expired;
396/// #
397/// fn dispose_expired_food(mut commands: Commands, query: Query<Entity, With<Expired>>) {
398///     for food_entity in &query {
399///         commands.entity(food_entity).despawn();
400///     }
401/// }
402/// #
403/// # bevy_ecs::system::assert_is_system(dispose_expired_food);
404/// ```
405///
406/// [learn more]: crate::system::Query#entity-id-access
407/// [`EntityCommands::id`]: crate::system::EntityCommands::id
408/// [`EntityWorldMut::id`]: crate::world::EntityWorldMut::id
409/// [`EntityCommands`]: crate::system::EntityCommands
410/// [`Query::get`]: crate::system::Query::get
411/// [`World`]: crate::world::World
412/// [SemVer]: https://semver.org/
413#[derive(Clone, Copy)]
414#[cfg_attr(feature = "bevy_reflect", derive(Reflect))]
415#[cfg_attr(feature = "bevy_reflect", reflect(opaque))]
416#[cfg_attr(feature = "bevy_reflect", reflect(Hash, PartialEq, Debug, Clone))]
417#[cfg_attr(
418    all(feature = "bevy_reflect", feature = "serialize"),
419    reflect(Serialize, Deserialize)
420)]
421// Alignment repr necessary to allow LLVM to better output
422// optimized codegen for `to_bits`, `PartialEq` and `Ord`.
423#[repr(C, align(8))]
424pub struct Entity {
425    // Do not reorder the fields here. The ordering is explicitly used by repr(C)
426    // to make this struct equivalent to a u64.
427    #[cfg(target_endian = "little")]
428    index: EntityIndex,
429    generation: EntityGeneration,
430    #[cfg(target_endian = "big")]
431    index: EntityIndex,
432}
433
434// By not short-circuiting in comparisons, we get better codegen.
435// See <https://github.com/rust-lang/rust/issues/117800>
436impl PartialEq for Entity {
437    #[inline]
438    fn eq(&self, other: &Entity) -> bool {
439        // By using `to_bits`, the codegen can be optimized out even
440        // further potentially. Relies on the correct alignment/field
441        // order of `Entity`.
442        self.to_bits() == other.to_bits()
443    }
444}
445
446impl Eq for Entity {}
447
448// The derive macro codegen output is not optimal and can't be optimized as well
449// by the compiler. This impl resolves the issue of non-optimal codegen by relying
450// on comparing against the bit representation of `Entity` instead of comparing
451// the fields. The result is then LLVM is able to optimize the codegen for Entity
452// far beyond what the derive macro can.
453// See <https://github.com/rust-lang/rust/issues/106107>
454impl PartialOrd for Entity {
455    #[inline]
456    fn partial_cmp(&self, other: &Self) -> Option<core::cmp::Ordering> {
457        // Make use of our `Ord` impl to ensure optimal codegen output
458        Some(self.cmp(other))
459    }
460}
461
462// The derive macro codegen output is not optimal and can't be optimized as well
463// by the compiler. This impl resolves the issue of non-optimal codegen by relying
464// on comparing against the bit representation of `Entity` instead of comparing
465// the fields. The result is then LLVM is able to optimize the codegen for Entity
466// far beyond what the derive macro can.
467// See <https://github.com/rust-lang/rust/issues/106107>
468impl Ord for Entity {
469    #[inline]
470    fn cmp(&self, other: &Self) -> core::cmp::Ordering {
471        // This will result in better codegen for ordering comparisons, plus
472        // avoids pitfalls with regards to macro codegen relying on property
473        // position when we want to compare against the bit representation.
474        self.to_bits().cmp(&other.to_bits())
475    }
476}
477
478impl Hash for Entity {
479    #[inline]
480    fn hash<H: core::hash::Hasher>(&self, state: &mut H) {
481        self.to_bits().hash(state);
482    }
483}
484
485impl Entity {
486    /// Creates a new instance with the given index and generation.
487    #[inline(always)]
488    pub const fn from_index_and_generation(
489        index: EntityIndex,
490        generation: EntityGeneration,
491    ) -> Entity {
492        Self { index, generation }
493    }
494
495    /// An entity ID with a placeholder value. This may or may not correspond to an actual entity,
496    /// and should be overwritten by a new value before being used.
497    ///
498    /// ## Examples
499    ///
500    /// Initializing a collection (e.g. `array` or `Vec`) with a known size:
501    ///
502    /// ```no_run
503    /// # use bevy_ecs::prelude::*;
504    /// // Create a new array of size 10 filled with invalid entity ids.
505    /// let mut entities: [Entity; 10] = [Entity::PLACEHOLDER; 10];
506    ///
507    /// // ... replace the entities with valid ones.
508    /// ```
509    ///
510    /// Deriving [`Reflect`] for a component that has an `Entity` field:
511    ///
512    /// ```no_run
513    /// # use bevy_ecs::{prelude::*, component::*};
514    /// # use bevy_reflect::Reflect;
515    /// #[derive(Reflect, Component)]
516    /// #[reflect(Component)]
517    /// pub struct MyStruct {
518    ///     pub entity: Entity,
519    /// }
520    ///
521    /// impl FromWorld for MyStruct {
522    ///     fn from_world(_world: &mut World) -> Self {
523    ///         Self {
524    ///             entity: Entity::PLACEHOLDER,
525    ///         }
526    ///     }
527    /// }
528    /// ```
529    pub const PLACEHOLDER: Self = Self::from_index(EntityIndex::PLACEHOLDER);
530
531    /// Creates a new entity ID with the specified `index` and an unspecified generation.
532    ///
533    /// # Note
534    ///
535    /// Spawning a specific `entity` value is __rarely the right choice__. Most apps should favor
536    /// [`Commands::spawn`](crate::system::Commands::spawn). This method should generally
537    /// only be used for sharing entities across apps, and only when they have a scheme
538    /// worked out to share an index space (which doesn't happen by default).
539    ///
540    /// In general, one should not try to synchronize the ECS by attempting to ensure that
541    /// `Entity` lines up between instances, but instead insert a secondary identifier as
542    /// a component.
543    #[inline(always)]
544    pub const fn from_index(index: EntityIndex) -> Entity {
545        Self::from_index_and_generation(index, EntityGeneration::FIRST)
546    }
547
548    /// This is equivalent to [`from_index`](Self::from_index) except that it takes a `u32` instead of an [`EntityIndex`].
549    ///
550    /// Returns `None` if the index is `u32::MAX`.
551    #[inline(always)]
552    pub const fn from_raw_u32(index: u32) -> Option<Entity> {
553        match NonMaxU32::new(index) {
554            Some(index) => Some(Self::from_index(EntityIndex::new(index))),
555            None => None,
556        }
557    }
558
559    /// Convert to a form convenient for passing outside of rust.
560    ///
561    /// Only useful for identifying entities within the same instance of an application. Do not use
562    /// for serialization between runs.
563    ///
564    /// No particular structure is guaranteed for the returned bits.
565    #[inline(always)]
566    pub const fn to_bits(self) -> u64 {
567        self.index.to_bits() as u64 | ((self.generation.to_bits() as u64) << 32)
568    }
569
570    /// Reconstruct an `Entity` previously destructured with [`Entity::to_bits`].
571    ///
572    /// Only useful when applied to results from `to_bits` in the same instance of an application.
573    ///
574    /// # Panics
575    ///
576    /// This method will likely panic if given `u64` values that did not come from [`Entity::to_bits`].
577    #[inline]
578    pub const fn from_bits(bits: u64) -> Self {
579        if let Some(id) = Self::try_from_bits(bits) {
580            id
581        } else {
582            panic!("Attempted to initialize invalid bits as an entity")
583        }
584    }
585
586    /// Reconstruct an `Entity` previously destructured with [`Entity::to_bits`].
587    ///
588    /// Only useful when applied to results from `to_bits` in the same instance of an application.
589    ///
590    /// This method is the fallible counterpart to [`Entity::from_bits`].
591    #[inline(always)]
592    pub const fn try_from_bits(bits: u64) -> Option<Self> {
593        let raw_index = bits as u32;
594        let raw_gen = (bits >> 32) as u32;
595
596        if let Some(index) = EntityIndex::try_from_bits(raw_index) {
597            Some(Self {
598                index,
599                generation: EntityGeneration::from_bits(raw_gen),
600            })
601        } else {
602            None
603        }
604    }
605
606    /// Return a transiently unique identifier.
607    /// See also [`EntityIndex`].
608    ///
609    /// No two simultaneously-live entities share the same index, but dead entities' indices may collide
610    /// with both live and dead entities. Useful for compactly representing entities within a
611    /// specific snapshot of the world, such as when serializing.
612    #[inline]
613    pub const fn index(self) -> EntityIndex {
614        self.index
615    }
616
617    /// Equivalent to `self.index().index()`. See [`Self::index`] for details.
618    #[inline]
619    pub const fn index_u32(self) -> u32 {
620        self.index.index()
621    }
622
623    /// Returns the generation of this Entity's index. The generation is incremented each time an
624    /// entity with a given index is despawned. This serves as a "count" of the number of times a
625    /// given index has been reused (index, generation) pairs uniquely identify a given Entity.
626    #[inline]
627    pub const fn generation(self) -> EntityGeneration {
628        self.generation
629    }
630}
631
632#[cfg(feature = "serialize")]
633impl Serialize for Entity {
634    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
635    where
636        S: serde::Serializer,
637    {
638        serializer.serialize_u64(self.to_bits())
639    }
640}
641
642#[cfg(feature = "serialize")]
643impl<'de> Deserialize<'de> for Entity {
644    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
645    where
646        D: serde::Deserializer<'de>,
647    {
648        use serde::de::Error;
649        let id: u64 = Deserialize::deserialize(deserializer)?;
650        Entity::try_from_bits(id)
651            .ok_or_else(|| D::Error::custom("Attempting to deserialize an invalid entity."))
652    }
653}
654
655/// Outputs the short entity identifier, including the index and generation.
656///
657/// This takes the format: `{index}v{generation}`.
658///
659/// For [`Entity::PLACEHOLDER`], this outputs `PLACEHOLDER`.
660///
661/// For a unique [`u64`] representation, use [`Entity::to_bits`].
662impl fmt::Debug for Entity {
663    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
664        fmt::Display::fmt(self, f)
665    }
666}
667
668/// Outputs the short entity identifier, including the index and generation.
669///
670/// This takes the format: `{index}v{generation}`.
671///
672/// For [`Entity::PLACEHOLDER`], this outputs `PLACEHOLDER`.
673impl fmt::Display for Entity {
674    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
675        if self == &Self::PLACEHOLDER {
676            f.pad("PLACEHOLDER")
677        } else {
678            f.pad(&alloc::fmt::format(format_args!(
679                "{}v{}",
680                self.index(),
681                self.generation()
682            )))
683        }
684    }
685}
686
687impl SparseSetIndex for Entity {
688    #[inline]
689    fn sparse_set_index(&self) -> usize {
690        self.index().sparse_set_index()
691    }
692
693    #[inline]
694    fn get_sparse_set_index(value: usize) -> Self {
695        Entity::from_index(EntityIndex::get_sparse_set_index(value))
696    }
697}
698
699/// Allocates [`Entity`] ids uniquely.
700/// This is used in [`World::spawn_at`](crate::world::World::spawn_at) and [`World::despawn_no_free`](crate::world::World::despawn_no_free) to track entity ids no longer in use.
701/// Allocating is fully concurrent and can be done from multiple threads.
702///
703/// Conceptually, this is a collection of [`Entity`] ids who's [`EntityIndex`] is despawned and who's [`EntityGeneration`] is the most recent.
704/// See the module docs for how these ids and this allocator participate in the life cycle of an entity.
705#[derive(Default, Debug)]
706pub struct EntityAllocator {
707    pub(crate) inner: remote_allocator::Allocator,
708}
709
710impl EntityAllocator {
711    /// Restarts the allocator.
712    pub(crate) fn restart(&mut self) {
713        self.inner = remote_allocator::Allocator::new();
714    }
715
716    /// Builds a new remote allocator that hooks into this [`EntityAllocator`].
717    /// This is useful when you need to allocate entities without holding a reference to the world (like in async).
718    pub fn build_remote_allocator(&self) -> RemoteAllocator {
719        RemoteAllocator::new(&self.inner)
720    }
721
722    /// Returns `true` when the `allocator` is connected to this [`EntityAllocator`]
723    /// and its allocated [`Entity`] values can still be used in this world.
724    pub fn has_remote_allocator(&self, allocator: &RemoteAllocator) -> bool {
725        allocator.is_connected_to(&self.inner)
726    }
727
728    /// This allows `freed` to be retrieved from [`alloc`](Self::alloc), etc.
729    /// Freeing an [`Entity`] such that one [`EntityIndex`] is in the allocator in multiple places can cause panics when spawning the allocated entity.
730    /// Additionally, to differentiate versions of an [`Entity`], updating the [`EntityGeneration`] before freeing is a good idea
731    /// (but not strictly necessary if you don't mind [`Entity`] id aliasing.)
732    pub fn free(&mut self, freed: Entity) {
733        self.inner.free(freed);
734    }
735
736    /// This allows `freed` to be retrieved from [`alloc`](Self::alloc), etc.
737    ///
738    /// The same caveats of [`free`](Self::free) apply here.
739    /// (Eg. the slice should not contain duplicates.)
740    pub fn free_many(&mut self, freed: &[Entity]) {
741        self.inner.free_many(freed);
742    }
743
744    /// Allocates some [`Entity`].
745    /// The result could have come from a [`free`](Self::free) or be a brand new [`EntityIndex`].
746    ///
747    /// The returned entity is valid and unique, but it is not yet spawned.
748    /// Using the id as if it were spawned may produce errors.
749    /// It can not be queried, and it has no [`EntityLocation`].
750    /// See module [docs](crate::entity) for more information about entity validity vs spawning.
751    ///
752    /// This is different from empty entities, which are spawned and
753    /// just happen to have no components.
754    ///
755    /// These ids must be used; otherwise, they will be forgotten.
756    /// For example, the result must be eventually used to either spawn an entity or be [`free`](Self::free)d.
757    ///
758    /// # Panics
759    ///
760    /// If there are no more entities available, this panics.
761    ///
762    ///
763    /// # Example
764    ///
765    /// This is particularly useful when spawning entities in special ways.
766    /// For example, [`Commands`](crate::system::Commands) uses this to allocate an entity and [`spawn_at`](crate::world::World::spawn_at) it later.
767    /// But remember, since this entity is not queryable and is not discoverable, losing the returned [`Entity`] effectively leaks it, never to be used again!
768    ///
769    /// ```
770    /// # use bevy_ecs::{prelude::*};
771    /// let mut world = World::new();
772    /// let entity = world.entity_allocator().alloc();
773    /// // wait as long as you like
774    /// let entity_access = world.spawn_empty_at(entity).unwrap(); // or spawn_at(entity, my_bundle)
775    /// // treat it as a normal entity
776    /// entity_access.despawn();
777    /// ```
778    ///
779    /// More generally, manually spawning and [`despawn_no_free`](crate::world::World::despawn_no_free)ing entities allows you to skip Bevy's default entity allocator.
780    /// This is useful if you want to enforce properties about the [`EntityIndex`]s of a group of entities, make a custom allocator, etc.
781    pub fn alloc(&self) -> Entity {
782        self.inner.alloc()
783    }
784
785    /// A more efficient way of calling [`alloc`](Self::alloc) repeatedly `count` times.
786    /// See [`alloc`](Self::alloc) for details.
787    ///
788    /// Like [`alloc`](Self::alloc), these entities must be used, otherwise they will be forgotten.
789    /// If the iterator is not exhausted, its remaining entities are forgotten.
790    /// See [`AllocEntitiesIterator`] docs for more.
791    pub fn alloc_many(&self, count: u32) -> AllocEntitiesIterator<'_> {
792        AllocEntitiesIterator {
793            inner: self.inner.alloc_many(count),
794        }
795    }
796}
797
798/// An [`Iterator`] returning a sequence of unique [`Entity`] values from [`Entities`].
799/// Dropping this will still retain the entities as allocated; this is effectively a leak.
800/// To prevent this, ensure the iterator is exhausted before dropping it.
801pub struct AllocEntitiesIterator<'a> {
802    inner: remote_allocator::AllocEntitiesIterator<'a>,
803}
804
805impl<'a> Iterator for AllocEntitiesIterator<'a> {
806    type Item = Entity;
807
808    fn next(&mut self) -> Option<Self::Item> {
809        self.inner.next()
810    }
811
812    fn size_hint(&self) -> (usize, Option<usize>) {
813        self.inner.size_hint()
814    }
815}
816
817impl<'a> ExactSizeIterator for AllocEntitiesIterator<'a> {}
818
819impl<'a> core::iter::FusedIterator for AllocEntitiesIterator<'a> {}
820
821// SAFETY: Newly allocated entity values are unique.
822unsafe impl EntitySetIterator for AllocEntitiesIterator<'_> {}
823
824/// [`Entities`] tracks all known [`EntityIndex`]s and their metadata.
825/// This is like a base table of information all entities have.
826#[derive(Debug, Clone)]
827pub struct Entities {
828    meta: Vec<EntityMeta>,
829}
830
831impl Entities {
832    pub(crate) const fn new() -> Self {
833        Self { meta: Vec::new() }
834    }
835
836    /// Clears all entity information
837    pub fn clear(&mut self) {
838        self.meta.clear();
839    }
840
841    /// Returns the [`EntityLocation`] of an [`Entity`] if it is valid and spawned.
842    /// This will return an error if the [`EntityGeneration`] of this entity has passed or if the [`EntityIndex`] is not spawned.
843    ///
844    /// See the module [docs](crate::entity) for a full explanation of these ids, entity life cycles, and the meaning of this result.
845    #[inline]
846    pub fn get_spawned(&self, entity: Entity) -> Result<EntityLocation, EntityNotSpawnedError> {
847        let meta = self.meta.get(entity.index_u32() as usize);
848        let meta = meta.unwrap_or(&EntityMeta::FRESH);
849        if entity.generation() != meta.generation {
850            return Err(EntityNotSpawnedError::Invalid(InvalidEntityError {
851                entity,
852                current_generation: meta.generation,
853            }));
854        };
855        meta.location
856            .ok_or(EntityNotSpawnedError::ValidButNotSpawned(
857                EntityValidButNotSpawnedError {
858                    entity,
859                    location: meta.spawned_or_despawned.by,
860                },
861            ))
862    }
863
864    /// Returns the [`EntityLocation`] of an [`Entity`] if it is valid.
865    /// The location will be `None` if the entity is not spawned.
866    /// If you expect the entity to be spawned, use [`get_spawned`](Self::get_spawned).
867    ///
868    /// This will fail if the [`Entity`] is not valid (ex: the generation is mismatched).
869    ///
870    /// See the module [docs](crate::entity) for a full explanation of these ids, entity life cycles, and the meaning of this result.
871    #[inline]
872    pub fn get(&self, entity: Entity) -> Result<Option<EntityLocation>, InvalidEntityError> {
873        match self.get_spawned(entity) {
874            Ok(location) => Ok(Some(location)),
875            Err(EntityNotSpawnedError::ValidButNotSpawned { .. }) => Ok(None),
876            Err(EntityNotSpawnedError::Invalid(err)) => Err(err),
877        }
878    }
879
880    /// Get the [`Entity`] for the given [`EntityIndex`].
881    /// Note that this entity may not be spawned yet.
882    ///
883    /// See the module [docs](crate::entity) for a full explanation of these ids, entity life cycles, and the meaning of this result.
884    #[inline]
885    pub fn resolve_from_index(&self, index: EntityIndex) -> Entity {
886        self.meta
887            .get(index.index() as usize)
888            .map(|meta| Entity::from_index_and_generation(index, meta.generation))
889            .unwrap_or(Entity::from_index(index))
890    }
891
892    /// Returns whether the entity at this `index` is spawned or not.
893    ///
894    /// See the module [docs](crate::entity) for a full explanation of these ids, entity life cycles, and the meaning of this result.
895    #[inline]
896    pub fn is_index_spawned(&self, index: EntityIndex) -> bool {
897        self.meta
898            .get(index.index() as usize)
899            .is_some_and(|meta| meta.location.is_some())
900    }
901
902    /// Returns true if the entity is valid.
903    /// This will return true for entities that are valid but have not been spawned.
904    ///
905    /// See the module [docs](crate::entity) for a full explanation of these ids, entity life cycles, and the meaning of this result.
906    pub fn contains(&self, entity: Entity) -> bool {
907        self.resolve_from_index(entity.index()).generation() == entity.generation()
908    }
909
910    /// Returns true if the entity is valid and is spawned.
911    ///
912    /// See the module [docs](crate::entity) for a full explanation of these ids, entity life cycles, and the meaning of this result.
913    pub fn contains_spawned(&self, entity: Entity) -> bool {
914        self.get_spawned(entity).is_ok()
915    }
916
917    /// Provides information regarding if `entity` may be safely spawned.
918    /// This can error if the entity is invalid or is already spawned.
919    ///
920    /// See the module [docs](crate::entity) for a full explanation of these ids, entity life cycles, and the meaning of this result.
921    #[inline]
922    pub fn check_can_spawn_at(&self, entity: Entity) -> Result<(), SpawnError> {
923        match self.get(entity) {
924            Ok(Some(_)) => Err(SpawnError::AlreadySpawned),
925            Ok(None) => Ok(()),
926            Err(err) => Err(SpawnError::Invalid(err)),
927        }
928    }
929
930    /// Updates the location of an [`EntityIndex`].
931    /// This must be called when moving the components of the existing entity around in storage.
932    /// Returns the previous location of the index.
933    ///
934    /// # Safety
935    ///  - The current location of the `index` must already be set. If not, use [`set_location`](Self::set_location).
936    ///  - `location` must be valid for the entity at `index` or immediately made valid afterwards
937    ///    before handing control to unknown code.
938    #[inline]
939    pub(crate) unsafe fn update_existing_location(
940        &mut self,
941        index: EntityIndex,
942        location: Option<EntityLocation>,
943    ) -> Option<EntityLocation> {
944        // SAFETY: Caller guarantees that `index` already had a location, so `declare` must have made the index valid already.
945        let meta = unsafe { self.meta.get_unchecked_mut(index.index() as usize) };
946        mem::replace(&mut meta.location, location)
947    }
948
949    /// Declares the location of an [`EntityIndex`].
950    /// This must be called when spawning entities, but when possible, prefer [`update_existing_location`](Self::update_existing_location).
951    /// Returns the previous location of the index.
952    ///
953    /// # Safety
954    ///  - `location` must be valid for the entity at `index` or immediately made valid afterwards
955    ///    before handing control to unknown code.
956    #[inline]
957    pub(crate) unsafe fn set_location(
958        &mut self,
959        index: EntityIndex,
960        location: Option<EntityLocation>,
961    ) -> Option<EntityLocation> {
962        self.ensure_index_index_is_valid(index);
963        // SAFETY: We just did `ensure_index`
964        unsafe { self.update_existing_location(index, location) }
965    }
966
967    /// Ensures the index is within the bounds of [`Self::meta`], expanding it if necessary.
968    #[inline]
969    fn ensure_index_index_is_valid(&mut self, index: EntityIndex) {
970        #[cold] // to help with branch prediction
971        fn expand(meta: &mut Vec<EntityMeta>, len: usize) {
972            meta.resize(len, EntityMeta::FRESH);
973            // Set these up too while we're here.
974            meta.resize(meta.capacity(), EntityMeta::FRESH);
975        }
976
977        let index = index.index() as usize;
978        if self.meta.len() <= index {
979            // TODO: hint unlikely once stable.
980            expand(&mut self.meta, index + 1);
981        }
982    }
983
984    /// Marks the `index` as free, returning the [`Entity`] to reuse that [`EntityIndex`].
985    ///
986    /// # Safety
987    ///
988    /// - `index` must be despawned (have no location) already.
989    pub(crate) unsafe fn mark_free(&mut self, index: EntityIndex, generations: u32) -> Entity {
990        // We need to do this in case an entity is being freed that was never spawned.
991        self.ensure_index_index_is_valid(index);
992        // SAFETY: We just did `ensure_index`
993        let meta = unsafe { self.meta.get_unchecked_mut(index.index() as usize) };
994
995        let (new_generation, aliased) = meta.generation.after_versions_and_could_alias(generations);
996        meta.generation = new_generation;
997        if aliased {
998            warn!("EntityIndex({index}) generation wrapped on Entities::free, aliasing may occur",);
999        }
1000
1001        Entity::from_index_and_generation(index, meta.generation)
1002    }
1003
1004    /// Mark an [`EntityIndex`] as spawned or despawned in the given tick.
1005    ///
1006    /// # Safety
1007    ///  - `index` must have been spawned at least once, ensuring its index is valid.
1008    #[inline]
1009    pub(crate) unsafe fn mark_spawned_or_despawned(
1010        &mut self,
1011        index: EntityIndex,
1012        by: MaybeLocation,
1013        tick: Tick,
1014    ) {
1015        // SAFETY: Caller guarantees that `index` already had a location, so `declare` must have made the index valid already.
1016        let meta = unsafe { self.meta.get_unchecked_mut(index.index() as usize) };
1017        meta.spawned_or_despawned = SpawnedOrDespawned { by, tick };
1018    }
1019
1020    /// Try to get the source code location from which this entity has last been spawned or despawned.
1021    ///
1022    /// Returns `None` if the entity does not exist or has never been construced/despawned.
1023    pub fn entity_get_spawned_or_despawned_by(
1024        &self,
1025        entity: Entity,
1026    ) -> MaybeLocation<Option<&'static Location<'static>>> {
1027        MaybeLocation::new_with_flattened(|| {
1028            self.entity_get_spawned_or_despawned(entity)
1029                .map(|spawned_or_despawned| spawned_or_despawned.by)
1030        })
1031    }
1032
1033    /// Try to get the [`Tick`] at which this entity has last been spawned or despawned.
1034    ///
1035    /// Returns `None` if the entity does not exist or has never been construced/despawned.
1036    pub fn entity_get_spawn_or_despawn_tick(&self, entity: Entity) -> Option<Tick> {
1037        self.entity_get_spawned_or_despawned(entity)
1038            .map(|spawned_or_despawned| spawned_or_despawned.tick)
1039    }
1040
1041    /// Try to get the [`SpawnedOrDespawned`] related to the entity's last spawning or despawning.
1042    ///
1043    /// Returns `None` if the entity does not exist or has never been construced/despawned.
1044    #[inline]
1045    fn entity_get_spawned_or_despawned(&self, entity: Entity) -> Option<SpawnedOrDespawned> {
1046        self.meta
1047            .get(entity.index_u32() as usize)
1048            .filter(|meta|
1049            // Generation is incremented immediately upon despawn
1050            (meta.generation == entity.generation)
1051            || (meta.location.is_none() && meta.generation == entity.generation.after_versions(1)))
1052            .map(|meta| meta.spawned_or_despawned)
1053    }
1054
1055    /// Returns the source code location from which this entity has last been spawned
1056    /// or despawned and the Tick of when that happened.
1057    ///
1058    /// # Safety
1059    ///
1060    /// The entity index must belong to an entity that is currently alive or, if it
1061    /// despawned, was not overwritten by a new entity of the same index.
1062    #[inline]
1063    pub(crate) unsafe fn entity_get_spawned_or_despawned_unchecked(
1064        &self,
1065        entity: Entity,
1066    ) -> (MaybeLocation, Tick) {
1067        // SAFETY: caller ensures entity is allocated
1068        let meta = unsafe { self.meta.get_unchecked(entity.index_u32() as usize) };
1069        (meta.spawned_or_despawned.by, meta.spawned_or_despawned.tick)
1070    }
1071
1072    #[inline]
1073    pub(crate) fn check_change_ticks(&mut self, check: CheckChangeTicks) {
1074        for meta in &mut self.meta {
1075            meta.spawned_or_despawned.tick.check_tick(check);
1076        }
1077    }
1078
1079    /// The count of currently allocated entity indices.
1080    /// For information on active entities, see [`Self::count_spawned`].
1081    #[inline]
1082    pub fn len(&self) -> u32 {
1083        self.meta.len() as u32
1084    }
1085
1086    /// Checks if any entity has been declared.
1087    /// For information on active entities, see [`Self::any_spawned`].
1088    #[inline]
1089    pub fn is_empty(&self) -> bool {
1090        self.len() == 0
1091    }
1092
1093    /// Counts the number of entity indices currently spawned.
1094    /// See the module docs for a more precise explanation of what spawning means.
1095    /// Be aware that this is O(n) and is intended only to be used as a diagnostic for tests.
1096    pub fn count_spawned(&self) -> u32 {
1097        self.meta
1098            .iter()
1099            .filter(|meta| meta.location.is_some())
1100            .count() as u32
1101    }
1102
1103    /// Returns true if there are any entity indices currently spawned.
1104    /// See the module docs for a more precise explanation of what spawning means.
1105    pub fn any_spawned(&self) -> bool {
1106        self.meta.iter().any(|meta| meta.location.is_some())
1107    }
1108}
1109
1110/// An error that occurs when a specified [`Entity`] can not be spawned.
1111#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq)]
1112pub enum SpawnError {
1113    /// The [`Entity`] to spawn was invalid.
1114    /// It probably had the wrong generation or was created erroneously.
1115    #[error("Invalid id: {0}")]
1116    Invalid(InvalidEntityError),
1117    /// The [`Entity`] to spawn was already spawned.
1118    #[error("The entity can not be spawned as it already has a location.")]
1119    AlreadySpawned,
1120}
1121
1122/// An error that occurs when a specified [`Entity`] does not exist in the entity id space.
1123/// See [module](crate::entity) docs for more about entity validity.
1124#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq)]
1125#[error(
1126    "The entity with ID {entity} is invalid; its index now has generation {current_generation}."
1127)]
1128pub struct InvalidEntityError {
1129    /// The entity's ID.
1130    pub entity: Entity,
1131    /// The generation of the [`EntityIndex`], which did not match the requested entity.
1132    pub current_generation: EntityGeneration,
1133}
1134
1135/// An error that occurs when a specified [`Entity`] is certain to be valid and is expected to be spawned but is not spawned yet.
1136/// This includes when an [`EntityIndex`] is requested but is not spawned, since each index always corresponds to exactly one valid entity.
1137#[derive(thiserror::Error, Debug, Clone, Copy, PartialEq, Eq)]
1138pub struct EntityValidButNotSpawnedError {
1139    /// The entity's ID.
1140    pub entity: Entity,
1141    /// The location of what last despawned the entity.
1142    pub location: MaybeLocation<&'static Location<'static>>,
1143}
1144
1145impl fmt::Display for EntityValidButNotSpawnedError {
1146    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1147        let entity = self.entity;
1148        match self.location.into_option() {
1149            Some(location) => write!(f, "The entity with ID {entity} is not spawned; its index was last despawned by {location}."),
1150            None => write!(
1151                f,
1152                "The entity with ID {entity} is not spawned; enable `track_location` feature for more details."
1153            ),
1154        }
1155    }
1156}
1157
1158/// An error that occurs when a specified [`Entity`] is expected to be valid and spawned but is not.
1159/// Represents an error of either [`InvalidEntityError`] (when the entity is invalid) or [`EntityValidButNotSpawnedError`] (when the [`EntityGeneration`] is correct but the [`EntityIndex`] is not spawned).
1160#[derive(thiserror::Error, Copy, Clone, Debug, Eq, PartialEq)]
1161pub enum EntityNotSpawnedError {
1162    /// The entity was invalid.
1163    #[error("Entity despawned: {0}\nNote that interacting with a despawned entity is the most common cause of this error but there are others")]
1164    Invalid(#[from] InvalidEntityError),
1165    /// The entity was valid but was not spawned.
1166    #[error("Entity not yet spawned: {0}\nNote that interacting with a not-yet-spawned entity is the most common cause of this error but there are others")]
1167    ValidButNotSpawned(#[from] EntityValidButNotSpawnedError),
1168}
1169
1170impl EntityNotSpawnedError {
1171    /// The entity that did not exist or was not spawned.
1172    pub fn entity(&self) -> Entity {
1173        match self {
1174            EntityNotSpawnedError::Invalid(err) => err.entity,
1175            EntityNotSpawnedError::ValidButNotSpawned(err) => err.entity,
1176        }
1177    }
1178}
1179
1180#[derive(Copy, Clone, Debug)]
1181struct EntityMeta {
1182    /// The current [`EntityGeneration`] of the [`EntityIndex`].
1183    generation: EntityGeneration,
1184    /// The current location of the [`EntityIndex`].
1185    location: Option<EntityLocation>,
1186    /// Location and tick of the last spawn/despawn
1187    spawned_or_despawned: SpawnedOrDespawned,
1188}
1189
1190#[derive(Copy, Clone, Debug)]
1191struct SpawnedOrDespawned {
1192    by: MaybeLocation,
1193    tick: Tick,
1194}
1195
1196impl EntityMeta {
1197    /// The metadata for a fresh entity: Never spawned/despawned, no location, etc.
1198    const FRESH: EntityMeta = EntityMeta {
1199        generation: EntityGeneration::FIRST,
1200        location: None,
1201        spawned_or_despawned: SpawnedOrDespawned {
1202            by: MaybeLocation::caller(),
1203            tick: Tick::new(0),
1204        },
1205    };
1206}
1207
1208/// A location of an entity in an archetype.
1209#[derive(Copy, Clone, Debug, PartialEq)]
1210pub struct EntityLocation {
1211    /// The ID of the [`Archetype`] the [`Entity`] belongs to.
1212    ///
1213    /// [`Archetype`]: crate::archetype::Archetype
1214    pub archetype_id: ArchetypeId,
1215
1216    /// The index of the [`Entity`] within its [`Archetype`].
1217    ///
1218    /// [`Archetype`]: crate::archetype::Archetype
1219    pub archetype_row: ArchetypeRow,
1220
1221    /// The ID of the [`Table`] the [`Entity`] belongs to.
1222    ///
1223    /// [`Table`]: crate::storage::Table
1224    pub table_id: TableId,
1225
1226    /// The index of the [`Entity`] within its [`Table`].
1227    ///
1228    /// [`Table`]: crate::storage::Table
1229    pub table_row: TableRow,
1230}
1231
1232#[cfg(test)]
1233mod tests {
1234    use super::*;
1235    use alloc::format;
1236
1237    #[test]
1238    fn entity_niche_optimization() {
1239        assert_eq!(size_of::<Entity>(), size_of::<Option<Entity>>());
1240    }
1241
1242    #[test]
1243    fn entity_bits_roundtrip() {
1244        let r = EntityIndex::from_raw_u32(0xDEADBEEF).unwrap();
1245        assert_eq!(EntityIndex::from_bits(r.to_bits()), r);
1246
1247        let e = Entity::from_index_and_generation(
1248            EntityIndex::from_raw_u32(0xDEADBEEF).unwrap(),
1249            EntityGeneration::from_bits(0x5AADF00D),
1250        );
1251        assert_eq!(Entity::from_bits(e.to_bits()), e);
1252    }
1253
1254    #[test]
1255    fn entity_const() {
1256        const C1: Entity = Entity::from_index(EntityIndex::from_raw_u32(42).unwrap());
1257        assert_eq!(42, C1.index_u32());
1258        assert_eq!(0, C1.generation().to_bits());
1259
1260        const C2: Entity = Entity::from_bits(0x0000_00ff_0000_00cc);
1261        assert_eq!(!0x0000_00cc, C2.index_u32());
1262        assert_eq!(0x0000_00ff, C2.generation().to_bits());
1263
1264        const C3: u32 = Entity::from_index(EntityIndex::from_raw_u32(33).unwrap()).index_u32();
1265        assert_eq!(33, C3);
1266
1267        const C4: u32 = Entity::from_bits(0x00dd_00ff_1111_1111)
1268            .generation()
1269            .to_bits();
1270        assert_eq!(0x00dd_00ff, C4);
1271    }
1272
1273    #[test]
1274    #[expect(
1275        clippy::nonminimal_bool,
1276        reason = "This intentionally tests all possible comparison operators as separate functions; thus, we don't want to rewrite these comparisons to use different operators."
1277    )]
1278    fn entity_comparison() {
1279        assert_eq!(
1280            Entity::from_index_and_generation(
1281                EntityIndex::from_raw_u32(123).unwrap(),
1282                EntityGeneration::from_bits(456)
1283            ),
1284            Entity::from_index_and_generation(
1285                EntityIndex::from_raw_u32(123).unwrap(),
1286                EntityGeneration::from_bits(456)
1287            )
1288        );
1289        assert_ne!(
1290            Entity::from_index_and_generation(
1291                EntityIndex::from_raw_u32(123).unwrap(),
1292                EntityGeneration::from_bits(789)
1293            ),
1294            Entity::from_index_and_generation(
1295                EntityIndex::from_raw_u32(123).unwrap(),
1296                EntityGeneration::from_bits(456)
1297            )
1298        );
1299        assert_ne!(
1300            Entity::from_index_and_generation(
1301                EntityIndex::from_raw_u32(123).unwrap(),
1302                EntityGeneration::from_bits(456)
1303            ),
1304            Entity::from_index_and_generation(
1305                EntityIndex::from_raw_u32(123).unwrap(),
1306                EntityGeneration::from_bits(789)
1307            )
1308        );
1309        assert_ne!(
1310            Entity::from_index_and_generation(
1311                EntityIndex::from_raw_u32(123).unwrap(),
1312                EntityGeneration::from_bits(456)
1313            ),
1314            Entity::from_index_and_generation(
1315                EntityIndex::from_raw_u32(456).unwrap(),
1316                EntityGeneration::from_bits(123)
1317            )
1318        );
1319
1320        // ordering is by generation then by index
1321
1322        assert!(
1323            Entity::from_index_and_generation(
1324                EntityIndex::from_raw_u32(123).unwrap(),
1325                EntityGeneration::from_bits(456)
1326            ) >= Entity::from_index_and_generation(
1327                EntityIndex::from_raw_u32(123).unwrap(),
1328                EntityGeneration::from_bits(456)
1329            )
1330        );
1331        assert!(
1332            Entity::from_index_and_generation(
1333                EntityIndex::from_raw_u32(123).unwrap(),
1334                EntityGeneration::from_bits(456)
1335            ) <= Entity::from_index_and_generation(
1336                EntityIndex::from_raw_u32(123).unwrap(),
1337                EntityGeneration::from_bits(456)
1338            )
1339        );
1340        assert!(
1341            !(Entity::from_index_and_generation(
1342                EntityIndex::from_raw_u32(123).unwrap(),
1343                EntityGeneration::from_bits(456)
1344            ) < Entity::from_index_and_generation(
1345                EntityIndex::from_raw_u32(123).unwrap(),
1346                EntityGeneration::from_bits(456)
1347            ))
1348        );
1349        assert!(
1350            !(Entity::from_index_and_generation(
1351                EntityIndex::from_raw_u32(123).unwrap(),
1352                EntityGeneration::from_bits(456)
1353            ) > Entity::from_index_and_generation(
1354                EntityIndex::from_raw_u32(123).unwrap(),
1355                EntityGeneration::from_bits(456)
1356            ))
1357        );
1358
1359        assert!(
1360            Entity::from_index_and_generation(
1361                EntityIndex::from_raw_u32(9).unwrap(),
1362                EntityGeneration::from_bits(1)
1363            ) < Entity::from_index_and_generation(
1364                EntityIndex::from_raw_u32(1).unwrap(),
1365                EntityGeneration::from_bits(9)
1366            )
1367        );
1368        assert!(
1369            Entity::from_index_and_generation(
1370                EntityIndex::from_raw_u32(1).unwrap(),
1371                EntityGeneration::from_bits(9)
1372            ) > Entity::from_index_and_generation(
1373                EntityIndex::from_raw_u32(9).unwrap(),
1374                EntityGeneration::from_bits(1)
1375            )
1376        );
1377
1378        assert!(
1379            Entity::from_index_and_generation(
1380                EntityIndex::from_raw_u32(1).unwrap(),
1381                EntityGeneration::from_bits(1)
1382            ) > Entity::from_index_and_generation(
1383                EntityIndex::from_raw_u32(2).unwrap(),
1384                EntityGeneration::from_bits(1)
1385            )
1386        );
1387        assert!(
1388            Entity::from_index_and_generation(
1389                EntityIndex::from_raw_u32(1).unwrap(),
1390                EntityGeneration::from_bits(1)
1391            ) >= Entity::from_index_and_generation(
1392                EntityIndex::from_raw_u32(2).unwrap(),
1393                EntityGeneration::from_bits(1)
1394            )
1395        );
1396        assert!(
1397            Entity::from_index_and_generation(
1398                EntityIndex::from_raw_u32(2).unwrap(),
1399                EntityGeneration::from_bits(2)
1400            ) < Entity::from_index_and_generation(
1401                EntityIndex::from_raw_u32(1).unwrap(),
1402                EntityGeneration::from_bits(2)
1403            )
1404        );
1405        assert!(
1406            Entity::from_index_and_generation(
1407                EntityIndex::from_raw_u32(2).unwrap(),
1408                EntityGeneration::from_bits(2)
1409            ) <= Entity::from_index_and_generation(
1410                EntityIndex::from_raw_u32(1).unwrap(),
1411                EntityGeneration::from_bits(2)
1412            )
1413        );
1414    }
1415
1416    // Feel free to change this test if needed, but it seemed like an important
1417    // part of the best-case performance changes in PR#9903.
1418    #[test]
1419    fn entity_hash_keeps_similar_ids_together() {
1420        use core::hash::BuildHasher;
1421        let hash = EntityHash;
1422
1423        let first_id = 0xC0FFEE << 8;
1424        let first_hash = hash.hash_one(Entity::from_index(
1425            EntityIndex::from_raw_u32(first_id).unwrap(),
1426        ));
1427
1428        for i in 1..=255 {
1429            let id = first_id + i;
1430            let hash = hash.hash_one(Entity::from_index(EntityIndex::from_raw_u32(id).unwrap()));
1431            assert_eq!(first_hash.wrapping_sub(hash) as u32, i);
1432        }
1433    }
1434
1435    #[test]
1436    fn entity_hash_id_bitflip_affects_high_7_bits() {
1437        use core::hash::BuildHasher;
1438
1439        let hash = EntityHash;
1440
1441        let first_id = 0xC0FFEE;
1442        let first_hash = hash.hash_one(Entity::from_index(
1443            EntityIndex::from_raw_u32(first_id).unwrap(),
1444        )) >> 57;
1445
1446        for bit in 0..u32::BITS {
1447            let id = first_id ^ (1 << bit);
1448            let hash =
1449                hash.hash_one(Entity::from_index(EntityIndex::from_raw_u32(id).unwrap())) >> 57;
1450            assert_ne!(hash, first_hash);
1451        }
1452    }
1453
1454    #[test]
1455    fn entity_generation_is_approximately_ordered() {
1456        use core::cmp::Ordering;
1457
1458        let old = EntityGeneration::FIRST;
1459        let middle = old.after_versions(1);
1460        let younger_before_ord_wrap = middle.after_versions(EntityGeneration::DIFF_MAX);
1461        let younger_after_ord_wrap = younger_before_ord_wrap.after_versions(1);
1462
1463        assert_eq!(middle.cmp_approx(&old), Ordering::Greater);
1464        assert_eq!(middle.cmp_approx(&middle), Ordering::Equal);
1465        assert_eq!(middle.cmp_approx(&younger_before_ord_wrap), Ordering::Less);
1466        assert_eq!(
1467            middle.cmp_approx(&younger_after_ord_wrap),
1468            Ordering::Greater
1469        );
1470    }
1471
1472    #[test]
1473    fn entity_debug() {
1474        let entity = Entity::from_index(EntityIndex::from_raw_u32(42).unwrap());
1475        let string = format!("{entity:?}");
1476        assert_eq!(string, "42v0");
1477
1478        let entity = Entity::PLACEHOLDER;
1479        let string = format!("{entity:?}");
1480        assert_eq!(string, "PLACEHOLDER");
1481    }
1482
1483    #[test]
1484    fn entity_display() {
1485        let entity = Entity::from_index(EntityIndex::from_raw_u32(42).unwrap());
1486        let string = format!("{entity}");
1487        assert_eq!(string, "42v0");
1488
1489        let padded_left = format!("{entity:<5}");
1490        assert_eq!(padded_left, "42v0 ");
1491
1492        let padded_right = format!("{entity:>6}");
1493        assert_eq!(padded_right, "  42v0");
1494
1495        let entity = Entity::PLACEHOLDER;
1496        let string = format!("{entity}");
1497        assert_eq!(string, "PLACEHOLDER");
1498    }
1499
1500    #[test]
1501    fn allocator() {
1502        let mut allocator = EntityAllocator::default();
1503        let mut entities = allocator.alloc_many(2048).collect::<Vec<_>>();
1504        for _ in 0..2048 {
1505            entities.push(allocator.alloc());
1506        }
1507
1508        let pre_len = entities.len();
1509        entities.sort();
1510        entities.dedup();
1511        assert_eq!(pre_len, entities.len());
1512
1513        for e in entities.drain(..) {
1514            allocator.free(e);
1515        }
1516
1517        entities.extend(allocator.alloc_many(5000));
1518        let pre_len = entities.len();
1519        entities.sort();
1520        entities.dedup();
1521        assert_eq!(pre_len, entities.len());
1522    }
1523}