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