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}