bevy_ecs/world/
entity_fetch.rs

1use alloc::vec::Vec;
2use core::mem::MaybeUninit;
3
4use crate::{
5    entity::{Entity, EntityDoesNotExistError, EntityHashMap, EntityHashSet},
6    error::Result,
7    world::{
8        error::EntityMutableFetchError, unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityRef,
9        EntityWorldMut,
10    },
11};
12
13/// Provides a safe interface for non-structural access to the entities in a [`World`].
14///
15/// This cannot add or remove components, or spawn or despawn entities,
16/// making it relatively safe to access in concert with other ECS data.
17/// This type can be constructed via [`World::entities_and_commands`],
18/// or [`DeferredWorld::entities_and_commands`].
19///
20/// [`World`]: crate::world::World
21/// [`World::entities_and_commands`]: crate::world::World::entities_and_commands
22/// [`DeferredWorld::entities_and_commands`]: crate::world::DeferredWorld::entities_and_commands
23pub struct EntityFetcher<'w> {
24    cell: UnsafeWorldCell<'w>,
25}
26
27impl<'w> EntityFetcher<'w> {
28    // SAFETY:
29    // - The given `cell` has mutable access to all entities.
30    // - No other references to entities exist at the same time.
31    pub(crate) unsafe fn new(cell: UnsafeWorldCell<'w>) -> Self {
32        Self { cell }
33    }
34
35    /// Returns [`EntityRef`]s that expose read-only operations for the given
36    /// `entities`, returning [`Err`] if any of the given entities do not exist.
37    ///
38    /// This function supports fetching a single entity or multiple entities:
39    /// - Pass an [`Entity`] to receive a single [`EntityRef`].
40    /// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityRef>`].
41    /// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityRef`]s.
42    /// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an
43    ///   [`EntityHashMap<EntityRef>`](crate::entity::EntityHashMap).
44    ///
45    /// # Errors
46    ///
47    /// If any of the given `entities` do not exist in the world, the first
48    /// [`Entity`] found to be missing will return an [`EntityDoesNotExistError`].
49    ///
50    /// # Examples
51    ///
52    /// For examples, see [`World::entity`].
53    ///
54    /// [`World::entity`]: crate::world::World::entity
55    #[inline]
56    pub fn get<F: WorldEntityFetch>(
57        &self,
58        entities: F,
59    ) -> Result<F::Ref<'_>, EntityDoesNotExistError> {
60        // SAFETY: `&self` gives read access to all entities, and prevents mutable access.
61        unsafe { entities.fetch_ref(self.cell) }
62    }
63
64    /// Returns [`EntityMut`]s that expose read and write operations for the
65    /// given `entities`, returning [`Err`] if any of the given entities do not
66    /// exist.
67    ///
68    /// This function supports fetching a single entity or multiple entities:
69    /// - Pass an [`Entity`] to receive a single [`EntityMut`].
70    ///    - This reference type allows for structural changes to the entity,
71    ///      such as adding or removing components, or despawning the entity.
72    /// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
73    /// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
74    /// - Pass a reference to a [`EntityHashSet`](crate::entity::EntityHashMap) to receive an
75    ///   [`EntityHashMap<EntityMut>`](crate::entity::EntityHashMap).
76    /// # Errors
77    ///
78    /// - Returns [`EntityMutableFetchError::EntityDoesNotExist`] if any of the given `entities` do not exist in the world.
79    ///     - Only the first entity found to be missing will be returned.
80    /// - Returns [`EntityMutableFetchError::AliasedMutability`] if the same entity is requested multiple times.
81    ///
82    /// # Examples
83    ///
84    /// For examples, see [`DeferredWorld::entity_mut`].
85    ///
86    /// [`DeferredWorld::entity_mut`]: crate::world::DeferredWorld::entity_mut
87    #[inline]
88    pub fn get_mut<F: WorldEntityFetch>(
89        &mut self,
90        entities: F,
91    ) -> Result<F::DeferredMut<'_>, EntityMutableFetchError> {
92        // SAFETY: `&mut self` gives mutable access to all entities,
93        // and prevents any other access to entities.
94        unsafe { entities.fetch_deferred_mut(self.cell) }
95    }
96}
97
98/// Types that can be used to fetch [`Entity`] references from a [`World`].
99///
100/// Provided implementations are:
101/// - [`Entity`]: Fetch a single entity.
102/// - `[Entity; N]`/`&[Entity; N]`: Fetch multiple entities, receiving a
103///   same-sized array of references.
104/// - `&[Entity]`: Fetch multiple entities, receiving a vector of references.
105/// - [`&EntityHashSet`](EntityHashSet): Fetch multiple entities, receiving a
106///   hash map of [`Entity`] IDs to references.
107///
108/// # Performance
109///
110/// - The slice and array implementations perform an aliased mutability check
111///   in [`WorldEntityFetch::fetch_mut`] that is `O(N^2)`.
112/// - The single [`Entity`] implementation performs no such check as only one
113///   reference is returned.
114///
115/// # Safety
116///
117/// Implementor must ensure that:
118/// - No aliased mutability is caused by the returned references.
119/// - [`WorldEntityFetch::fetch_ref`] returns only read-only references.
120/// - [`WorldEntityFetch::fetch_deferred_mut`] returns only non-structurally-mutable references.
121///
122/// [`World`]: crate::world::World
123pub unsafe trait WorldEntityFetch {
124    /// The read-only reference type returned by [`WorldEntityFetch::fetch_ref`].
125    type Ref<'w>;
126
127    /// The mutable reference type returned by [`WorldEntityFetch::fetch_mut`].
128    type Mut<'w>;
129
130    /// The mutable reference type returned by [`WorldEntityFetch::fetch_deferred_mut`],
131    /// but without structural mutability.
132    type DeferredMut<'w>;
133
134    /// Returns read-only reference(s) to the entities with the given
135    /// [`Entity`] IDs, as determined by `self`.
136    ///
137    /// # Safety
138    ///
139    /// It is the caller's responsibility to ensure that:
140    /// - The given [`UnsafeWorldCell`] has read-only access to the fetched entities.
141    /// - No other mutable references to the fetched entities exist at the same time.
142    ///
143    /// # Errors
144    ///
145    /// - Returns [`EntityDoesNotExistError`] if the entity does not exist.
146    unsafe fn fetch_ref(
147        self,
148        cell: UnsafeWorldCell<'_>,
149    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError>;
150
151    /// Returns mutable reference(s) to the entities with the given [`Entity`]
152    /// IDs, as determined by `self`.
153    ///
154    /// # Safety
155    ///
156    /// It is the caller's responsibility to ensure that:
157    /// - The given [`UnsafeWorldCell`] has mutable access to the fetched entities.
158    /// - No other references to the fetched entities exist at the same time.
159    ///
160    /// # Errors
161    ///
162    /// - Returns [`EntityMutableFetchError::EntityDoesNotExist`] if the entity does not exist.
163    /// - Returns [`EntityMutableFetchError::AliasedMutability`] if the entity was
164    ///   requested mutably more than once.
165    unsafe fn fetch_mut(
166        self,
167        cell: UnsafeWorldCell<'_>,
168    ) -> Result<Self::Mut<'_>, EntityMutableFetchError>;
169
170    /// Returns mutable reference(s) to the entities with the given [`Entity`]
171    /// IDs, as determined by `self`, but without structural mutability.
172    ///
173    /// No structural mutability means components cannot be removed from the
174    /// entity, new components cannot be added to the entity, and the entity
175    /// cannot be despawned.
176    ///
177    /// # Safety
178    ///
179    /// It is the caller's responsibility to ensure that:
180    /// - The given [`UnsafeWorldCell`] has mutable access to the fetched entities.
181    /// - No other references to the fetched entities exist at the same time.
182    ///
183    /// # Errors
184    ///
185    /// - Returns [`EntityMutableFetchError::EntityDoesNotExist`] if the entity does not exist.
186    /// - Returns [`EntityMutableFetchError::AliasedMutability`] if the entity was
187    ///   requested mutably more than once.
188    unsafe fn fetch_deferred_mut(
189        self,
190        cell: UnsafeWorldCell<'_>,
191    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError>;
192}
193
194// SAFETY:
195// - No aliased mutability is caused because a single reference is returned.
196// - No mutable references are returned by `fetch_ref`.
197// - No structurally-mutable references are returned by `fetch_deferred_mut`.
198unsafe impl WorldEntityFetch for Entity {
199    type Ref<'w> = EntityRef<'w>;
200    type Mut<'w> = EntityWorldMut<'w>;
201    type DeferredMut<'w> = EntityMut<'w>;
202
203    unsafe fn fetch_ref(
204        self,
205        cell: UnsafeWorldCell<'_>,
206    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
207        let ecell = cell.get_entity(self)?;
208        // SAFETY: caller ensures that the world cell has read-only access to the entity.
209        Ok(unsafe { EntityRef::new(ecell) })
210    }
211
212    unsafe fn fetch_mut(
213        self,
214        cell: UnsafeWorldCell<'_>,
215    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
216        let location = cell
217            .entities()
218            .get(self)
219            .ok_or(EntityDoesNotExistError::new(self, cell.entities()))?;
220        // SAFETY: caller ensures that the world cell has mutable access to the entity.
221        let world = unsafe { cell.world_mut() };
222        // SAFETY: location was fetched from the same world's `Entities`.
223        Ok(unsafe { EntityWorldMut::new(world, self, location) })
224    }
225
226    unsafe fn fetch_deferred_mut(
227        self,
228        cell: UnsafeWorldCell<'_>,
229    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
230        let ecell = cell.get_entity(self)?;
231        // SAFETY: caller ensures that the world cell has mutable access to the entity.
232        Ok(unsafe { EntityMut::new(ecell) })
233    }
234}
235
236// SAFETY:
237// - No aliased mutability is caused because the array is checked for duplicates.
238// - No mutable references are returned by `fetch_ref`.
239// - No structurally-mutable references are returned by `fetch_deferred_mut`.
240unsafe impl<const N: usize> WorldEntityFetch for [Entity; N] {
241    type Ref<'w> = [EntityRef<'w>; N];
242    type Mut<'w> = [EntityMut<'w>; N];
243    type DeferredMut<'w> = [EntityMut<'w>; N];
244
245    unsafe fn fetch_ref(
246        self,
247        cell: UnsafeWorldCell<'_>,
248    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
249        <&Self>::fetch_ref(&self, cell)
250    }
251
252    unsafe fn fetch_mut(
253        self,
254        cell: UnsafeWorldCell<'_>,
255    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
256        <&Self>::fetch_mut(&self, cell)
257    }
258
259    unsafe fn fetch_deferred_mut(
260        self,
261        cell: UnsafeWorldCell<'_>,
262    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
263        <&Self>::fetch_deferred_mut(&self, cell)
264    }
265}
266
267// SAFETY:
268// - No aliased mutability is caused because the array is checked for duplicates.
269// - No mutable references are returned by `fetch_ref`.
270// - No structurally-mutable references are returned by `fetch_deferred_mut`.
271unsafe impl<const N: usize> WorldEntityFetch for &'_ [Entity; N] {
272    type Ref<'w> = [EntityRef<'w>; N];
273    type Mut<'w> = [EntityMut<'w>; N];
274    type DeferredMut<'w> = [EntityMut<'w>; N];
275
276    unsafe fn fetch_ref(
277        self,
278        cell: UnsafeWorldCell<'_>,
279    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
280        let mut refs = [MaybeUninit::uninit(); N];
281        for (r, &id) in core::iter::zip(&mut refs, self) {
282            let ecell = cell.get_entity(id)?;
283            // SAFETY: caller ensures that the world cell has read-only access to the entity.
284            *r = MaybeUninit::new(unsafe { EntityRef::new(ecell) });
285        }
286
287        // SAFETY: Each item was initialized in the loop above.
288        let refs = refs.map(|r| unsafe { MaybeUninit::assume_init(r) });
289
290        Ok(refs)
291    }
292
293    unsafe fn fetch_mut(
294        self,
295        cell: UnsafeWorldCell<'_>,
296    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
297        // Check for duplicate entities.
298        for i in 0..self.len() {
299            for j in 0..i {
300                if self[i] == self[j] {
301                    return Err(EntityMutableFetchError::AliasedMutability(self[i]));
302                }
303            }
304        }
305
306        let mut refs = [const { MaybeUninit::uninit() }; N];
307        for (r, &id) in core::iter::zip(&mut refs, self) {
308            let ecell = cell.get_entity(id)?;
309            // SAFETY: caller ensures that the world cell has mutable access to the entity.
310            *r = MaybeUninit::new(unsafe { EntityMut::new(ecell) });
311        }
312
313        // SAFETY: Each item was initialized in the loop above.
314        let refs = refs.map(|r| unsafe { MaybeUninit::assume_init(r) });
315
316        Ok(refs)
317    }
318
319    unsafe fn fetch_deferred_mut(
320        self,
321        cell: UnsafeWorldCell<'_>,
322    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
323        // SAFETY: caller ensures that the world cell has mutable access to the entity,
324        // and `fetch_mut` does not return structurally-mutable references.
325        unsafe { self.fetch_mut(cell) }
326    }
327}
328
329// SAFETY:
330// - No aliased mutability is caused because the slice is checked for duplicates.
331// - No mutable references are returned by `fetch_ref`.
332// - No structurally-mutable references are returned by `fetch_deferred_mut`.
333unsafe impl WorldEntityFetch for &'_ [Entity] {
334    type Ref<'w> = Vec<EntityRef<'w>>;
335    type Mut<'w> = Vec<EntityMut<'w>>;
336    type DeferredMut<'w> = Vec<EntityMut<'w>>;
337
338    unsafe fn fetch_ref(
339        self,
340        cell: UnsafeWorldCell<'_>,
341    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
342        let mut refs = Vec::with_capacity(self.len());
343        for &id in self {
344            let ecell = cell.get_entity(id)?;
345            // SAFETY: caller ensures that the world cell has read-only access to the entity.
346            refs.push(unsafe { EntityRef::new(ecell) });
347        }
348
349        Ok(refs)
350    }
351
352    unsafe fn fetch_mut(
353        self,
354        cell: UnsafeWorldCell<'_>,
355    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
356        // Check for duplicate entities.
357        for i in 0..self.len() {
358            for j in 0..i {
359                if self[i] == self[j] {
360                    return Err(EntityMutableFetchError::AliasedMutability(self[i]));
361                }
362            }
363        }
364
365        let mut refs = Vec::with_capacity(self.len());
366        for &id in self {
367            let ecell = cell.get_entity(id)?;
368            // SAFETY: caller ensures that the world cell has mutable access to the entity.
369            refs.push(unsafe { EntityMut::new(ecell) });
370        }
371
372        Ok(refs)
373    }
374
375    unsafe fn fetch_deferred_mut(
376        self,
377        cell: UnsafeWorldCell<'_>,
378    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
379        // SAFETY: caller ensures that the world cell has mutable access to the entity,
380        // and `fetch_mut` does not return structurally-mutable references.
381        unsafe { self.fetch_mut(cell) }
382    }
383}
384
385// SAFETY:
386// - No aliased mutability is caused because `EntityHashSet` guarantees no duplicates.
387// - No mutable references are returned by `fetch_ref`.
388// - No structurally-mutable references are returned by `fetch_deferred_mut`.
389unsafe impl WorldEntityFetch for &'_ EntityHashSet {
390    type Ref<'w> = EntityHashMap<EntityRef<'w>>;
391    type Mut<'w> = EntityHashMap<EntityMut<'w>>;
392    type DeferredMut<'w> = EntityHashMap<EntityMut<'w>>;
393
394    unsafe fn fetch_ref(
395        self,
396        cell: UnsafeWorldCell<'_>,
397    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
398        let mut refs = EntityHashMap::with_capacity(self.len());
399        for &id in self {
400            let ecell = cell.get_entity(id)?;
401            // SAFETY: caller ensures that the world cell has read-only access to the entity.
402            refs.insert(id, unsafe { EntityRef::new(ecell) });
403        }
404        Ok(refs)
405    }
406
407    unsafe fn fetch_mut(
408        self,
409        cell: UnsafeWorldCell<'_>,
410    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
411        let mut refs = EntityHashMap::with_capacity(self.len());
412        for &id in self {
413            let ecell = cell.get_entity(id)?;
414            // SAFETY: caller ensures that the world cell has mutable access to the entity.
415            refs.insert(id, unsafe { EntityMut::new(ecell) });
416        }
417        Ok(refs)
418    }
419
420    unsafe fn fetch_deferred_mut(
421        self,
422        cell: UnsafeWorldCell<'_>,
423    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
424        // SAFETY: caller ensures that the world cell has mutable access to the entity,
425        // and `fetch_mut` does not return structurally-mutable references.
426        unsafe { self.fetch_mut(cell) }
427    }
428}