Path: blob/main/crates/bevy_ecs/src/world/entity_fetch.rs
6604 views
use alloc::vec::Vec;1use core::mem::MaybeUninit;23use crate::{4entity::{Entity, EntityDoesNotExistError, EntityHashMap, EntityHashSet},5error::Result,6world::{7error::EntityMutableFetchError, unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityRef,8EntityWorldMut,9},10};1112/// Provides a safe interface for non-structural access to the entities in a [`World`].13///14/// This cannot add or remove components, or spawn or despawn entities,15/// making it relatively safe to access in concert with other ECS data.16/// This type can be constructed via [`World::entities_and_commands`],17/// or [`DeferredWorld::entities_and_commands`].18///19/// [`World`]: crate::world::World20/// [`World::entities_and_commands`]: crate::world::World::entities_and_commands21/// [`DeferredWorld::entities_and_commands`]: crate::world::DeferredWorld::entities_and_commands22pub struct EntityFetcher<'w> {23cell: UnsafeWorldCell<'w>,24}2526impl<'w> EntityFetcher<'w> {27// SAFETY:28// - The given `cell` has mutable access to all entities.29// - No other references to entities exist at the same time.30pub(crate) unsafe fn new(cell: UnsafeWorldCell<'w>) -> Self {31Self { cell }32}3334/// Returns [`EntityRef`]s that expose read-only operations for the given35/// `entities`, returning [`Err`] if any of the given entities do not exist.36///37/// This function supports fetching a single entity or multiple entities:38/// - Pass an [`Entity`] to receive a single [`EntityRef`].39/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].40/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.41/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an42/// [`EntityHashMap<EntityRef>`](crate::entity::EntityHashMap).43///44/// # Errors45///46/// If any of the given `entities` do not exist in the world, the first47/// [`Entity`] found to be missing will return an [`EntityDoesNotExistError`].48///49/// # Examples50///51/// For examples, see [`World::entity`].52///53/// [`World::entity`]: crate::world::World::entity54#[inline]55pub fn get<F: WorldEntityFetch>(56&self,57entities: F,58) -> Result<F::Ref<'_>, EntityDoesNotExistError> {59// SAFETY: `&self` gives read access to all entities, and prevents mutable access.60unsafe { entities.fetch_ref(self.cell) }61}6263/// Returns [`EntityMut`]s that expose read and write operations for the64/// given `entities`, returning [`Err`] if any of the given entities do not65/// exist.66///67/// This function supports fetching a single entity or multiple entities:68/// - Pass an [`Entity`] to receive a single [`EntityMut`].69/// - This reference type allows for structural changes to the entity,70/// such as adding or removing components, or despawning the entity.71/// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].72/// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.73/// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an74/// [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).75/// # Errors76///77/// - Returns [`EntityMutableFetchError::EntityDoesNotExist`] if any of the given `entities` do not exist in the world.78/// - Only the first entity found to be missing will be returned.79/// - Returns [`EntityMutableFetchError::AliasedMutability`] if the same entity is requested multiple times.80///81/// # Examples82///83/// For examples, see [`DeferredWorld::entity_mut`].84///85/// [`DeferredWorld::entity_mut`]: crate::world::DeferredWorld::entity_mut86#[inline]87pub fn get_mut<F: WorldEntityFetch>(88&mut self,89entities: F,90) -> Result<F::DeferredMut<'_>, EntityMutableFetchError> {91// SAFETY: `&mut self` gives mutable access to all entities,92// and prevents any other access to entities.93unsafe { entities.fetch_deferred_mut(self.cell) }94}95}9697/// Types that can be used to fetch [`Entity`] references from a [`World`].98///99/// Provided implementations are:100/// - [`Entity`]: Fetch a single entity.101/// - `[Entity; N]`/`&[Entity; N]`: Fetch multiple entities, receiving a102/// same-sized array of references.103/// - `&[Entity]`: Fetch multiple entities, receiving a vector of references.104/// - [`&EntityHashSet`](EntityHashSet): Fetch multiple entities, receiving a105/// hash map of [`Entity`] IDs to references.106///107/// # Performance108///109/// - The slice and array implementations perform an aliased mutability check110/// in [`WorldEntityFetch::fetch_mut`] that is `O(N^2)`.111/// - The single [`Entity`] implementation performs no such check as only one112/// reference is returned.113///114/// # Safety115///116/// Implementor must ensure that:117/// - No aliased mutability is caused by the returned references.118/// - [`WorldEntityFetch::fetch_ref`] returns only read-only references.119/// - [`WorldEntityFetch::fetch_deferred_mut`] returns only non-structurally-mutable references.120///121/// [`World`]: crate::world::World122pub unsafe trait WorldEntityFetch {123/// The read-only reference type returned by [`WorldEntityFetch::fetch_ref`].124type Ref<'w>;125126/// The mutable reference type returned by [`WorldEntityFetch::fetch_mut`].127type Mut<'w>;128129/// The mutable reference type returned by [`WorldEntityFetch::fetch_deferred_mut`],130/// but without structural mutability.131type DeferredMut<'w>;132133/// Returns read-only reference(s) to the entities with the given134/// [`Entity`] IDs, as determined by `self`.135///136/// # Safety137///138/// It is the caller's responsibility to ensure that:139/// - The given [`UnsafeWorldCell`] has read-only access to the fetched entities.140/// - No other mutable references to the fetched entities exist at the same time.141///142/// # Errors143///144/// - Returns [`EntityDoesNotExistError`] if the entity does not exist.145unsafe fn fetch_ref(146self,147cell: UnsafeWorldCell<'_>,148) -> Result<Self::Ref<'_>, EntityDoesNotExistError>;149150/// Returns mutable reference(s) to the entities with the given [`Entity`]151/// IDs, as determined by `self`.152///153/// # Safety154///155/// It is the caller's responsibility to ensure that:156/// - The given [`UnsafeWorldCell`] has mutable access to the fetched entities.157/// - No other references to the fetched entities exist at the same time.158///159/// # Errors160///161/// - Returns [`EntityMutableFetchError::EntityDoesNotExist`] if the entity does not exist.162/// - Returns [`EntityMutableFetchError::AliasedMutability`] if the entity was163/// requested mutably more than once.164unsafe fn fetch_mut(165self,166cell: UnsafeWorldCell<'_>,167) -> Result<Self::Mut<'_>, EntityMutableFetchError>;168169/// Returns mutable reference(s) to the entities with the given [`Entity`]170/// IDs, as determined by `self`, but without structural mutability.171///172/// No structural mutability means components cannot be removed from the173/// entity, new components cannot be added to the entity, and the entity174/// cannot be despawned.175///176/// # Safety177///178/// It is the caller's responsibility to ensure that:179/// - The given [`UnsafeWorldCell`] has mutable access to the fetched entities.180/// - No other references to the fetched entities exist at the same time.181///182/// # Errors183///184/// - Returns [`EntityMutableFetchError::EntityDoesNotExist`] if the entity does not exist.185/// - Returns [`EntityMutableFetchError::AliasedMutability`] if the entity was186/// requested mutably more than once.187unsafe fn fetch_deferred_mut(188self,189cell: UnsafeWorldCell<'_>,190) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError>;191}192193// SAFETY:194// - No aliased mutability is caused because a single reference is returned.195// - No mutable references are returned by `fetch_ref`.196// - No structurally-mutable references are returned by `fetch_deferred_mut`.197unsafe impl WorldEntityFetch for Entity {198type Ref<'w> = EntityRef<'w>;199type Mut<'w> = EntityWorldMut<'w>;200type DeferredMut<'w> = EntityMut<'w>;201202#[inline]203unsafe fn fetch_ref(204self,205cell: UnsafeWorldCell<'_>,206) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {207let ecell = cell.get_entity(self)?;208// SAFETY: caller ensures that the world cell has read-only access to the entity.209Ok(unsafe { EntityRef::new(ecell) })210}211212#[inline]213unsafe fn fetch_mut(214self,215cell: UnsafeWorldCell<'_>,216) -> Result<Self::Mut<'_>, EntityMutableFetchError> {217let location = cell218.entities()219.get(self)220.ok_or(EntityDoesNotExistError::new(self, cell.entities()))?;221// SAFETY: caller ensures that the world cell has mutable access to the entity.222let world = unsafe { cell.world_mut() };223// SAFETY: location was fetched from the same world's `Entities`.224Ok(unsafe { EntityWorldMut::new(world, self, Some(location)) })225}226227#[inline]228unsafe fn fetch_deferred_mut(229self,230cell: UnsafeWorldCell<'_>,231) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {232let ecell = cell.get_entity(self)?;233// SAFETY: caller ensures that the world cell has mutable access to the entity.234Ok(unsafe { EntityMut::new(ecell) })235}236}237238// SAFETY:239// - No aliased mutability is caused because the array is checked for duplicates.240// - No mutable references are returned by `fetch_ref`.241// - No structurally-mutable references are returned by `fetch_deferred_mut`.242unsafe impl<const N: usize> WorldEntityFetch for [Entity; N] {243type Ref<'w> = [EntityRef<'w>; N];244type Mut<'w> = [EntityMut<'w>; N];245type DeferredMut<'w> = [EntityMut<'w>; N];246247#[inline]248unsafe fn fetch_ref(249self,250cell: UnsafeWorldCell<'_>,251) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {252<&Self>::fetch_ref(&self, cell)253}254255#[inline]256unsafe fn fetch_mut(257self,258cell: UnsafeWorldCell<'_>,259) -> Result<Self::Mut<'_>, EntityMutableFetchError> {260<&Self>::fetch_mut(&self, cell)261}262263#[inline]264unsafe fn fetch_deferred_mut(265self,266cell: UnsafeWorldCell<'_>,267) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {268<&Self>::fetch_deferred_mut(&self, cell)269}270}271272// SAFETY:273// - No aliased mutability is caused because the array is checked for duplicates.274// - No mutable references are returned by `fetch_ref`.275// - No structurally-mutable references are returned by `fetch_deferred_mut`.276unsafe impl<const N: usize> WorldEntityFetch for &'_ [Entity; N] {277type Ref<'w> = [EntityRef<'w>; N];278type Mut<'w> = [EntityMut<'w>; N];279type DeferredMut<'w> = [EntityMut<'w>; N];280281#[inline]282unsafe fn fetch_ref(283self,284cell: UnsafeWorldCell<'_>,285) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {286let mut refs = [MaybeUninit::uninit(); N];287for (r, &id) in core::iter::zip(&mut refs, self) {288let ecell = cell.get_entity(id)?;289// SAFETY: caller ensures that the world cell has read-only access to the entity.290*r = MaybeUninit::new(unsafe { EntityRef::new(ecell) });291}292293// SAFETY: Each item was initialized in the loop above.294let refs = refs.map(|r| unsafe { MaybeUninit::assume_init(r) });295296Ok(refs)297}298299#[inline]300unsafe fn fetch_mut(301self,302cell: UnsafeWorldCell<'_>,303) -> Result<Self::Mut<'_>, EntityMutableFetchError> {304// Check for duplicate entities.305for i in 0..self.len() {306for j in 0..i {307if self[i] == self[j] {308return Err(EntityMutableFetchError::AliasedMutability(self[i]));309}310}311}312313let mut refs = [const { MaybeUninit::uninit() }; N];314for (r, &id) in core::iter::zip(&mut refs, self) {315let ecell = cell.get_entity(id)?;316// SAFETY: caller ensures that the world cell has mutable access to the entity.317*r = MaybeUninit::new(unsafe { EntityMut::new(ecell) });318}319320// SAFETY: Each item was initialized in the loop above.321let refs = refs.map(|r| unsafe { MaybeUninit::assume_init(r) });322323Ok(refs)324}325326#[inline]327unsafe fn fetch_deferred_mut(328self,329cell: UnsafeWorldCell<'_>,330) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {331// SAFETY: caller ensures that the world cell has mutable access to the entity,332// and `fetch_mut` does not return structurally-mutable references.333unsafe { self.fetch_mut(cell) }334}335}336337// SAFETY:338// - No aliased mutability is caused because the slice is checked for duplicates.339// - No mutable references are returned by `fetch_ref`.340// - No structurally-mutable references are returned by `fetch_deferred_mut`.341unsafe impl WorldEntityFetch for &'_ [Entity] {342type Ref<'w> = Vec<EntityRef<'w>>;343type Mut<'w> = Vec<EntityMut<'w>>;344type DeferredMut<'w> = Vec<EntityMut<'w>>;345346#[inline]347unsafe fn fetch_ref(348self,349cell: UnsafeWorldCell<'_>,350) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {351let mut refs = Vec::with_capacity(self.len());352for &id in self {353let ecell = cell.get_entity(id)?;354// SAFETY: caller ensures that the world cell has read-only access to the entity.355refs.push(unsafe { EntityRef::new(ecell) });356}357358Ok(refs)359}360361#[inline]362unsafe fn fetch_mut(363self,364cell: UnsafeWorldCell<'_>,365) -> Result<Self::Mut<'_>, EntityMutableFetchError> {366// Check for duplicate entities.367for i in 0..self.len() {368for j in 0..i {369if self[i] == self[j] {370return Err(EntityMutableFetchError::AliasedMutability(self[i]));371}372}373}374375let mut refs = Vec::with_capacity(self.len());376for &id in self {377let ecell = cell.get_entity(id)?;378// SAFETY: caller ensures that the world cell has mutable access to the entity.379refs.push(unsafe { EntityMut::new(ecell) });380}381382Ok(refs)383}384385#[inline]386unsafe fn fetch_deferred_mut(387self,388cell: UnsafeWorldCell<'_>,389) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {390// SAFETY: caller ensures that the world cell has mutable access to the entity,391// and `fetch_mut` does not return structurally-mutable references.392unsafe { self.fetch_mut(cell) }393}394}395396// SAFETY:397// - No aliased mutability is caused because `EntityHashSet` guarantees no duplicates.398// - No mutable references are returned by `fetch_ref`.399// - No structurally-mutable references are returned by `fetch_deferred_mut`.400unsafe impl WorldEntityFetch for &'_ EntityHashSet {401type Ref<'w> = EntityHashMap<EntityRef<'w>>;402type Mut<'w> = EntityHashMap<EntityMut<'w>>;403type DeferredMut<'w> = EntityHashMap<EntityMut<'w>>;404405#[inline]406unsafe fn fetch_ref(407self,408cell: UnsafeWorldCell<'_>,409) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {410let mut refs = EntityHashMap::with_capacity(self.len());411for &id in self {412let ecell = cell.get_entity(id)?;413// SAFETY: caller ensures that the world cell has read-only access to the entity.414refs.insert(id, unsafe { EntityRef::new(ecell) });415}416Ok(refs)417}418419#[inline]420unsafe fn fetch_mut(421self,422cell: UnsafeWorldCell<'_>,423) -> Result<Self::Mut<'_>, EntityMutableFetchError> {424let mut refs = EntityHashMap::with_capacity(self.len());425for &id in self {426let ecell = cell.get_entity(id)?;427// SAFETY: caller ensures that the world cell has mutable access to the entity.428refs.insert(id, unsafe { EntityMut::new(ecell) });429}430Ok(refs)431}432433#[inline]434unsafe fn fetch_deferred_mut(435self,436cell: UnsafeWorldCell<'_>,437) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {438// SAFETY: caller ensures that the world cell has mutable access to the entity,439// and `fetch_mut` does not return structurally-mutable references.440unsafe { self.fetch_mut(cell) }441}442}443444445