Thanks to visit codestin.com
Credit goes to docs.rs

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    #[inline]
204    unsafe fn fetch_ref(
205        self,
206        cell: UnsafeWorldCell<'_>,
207    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
208        let ecell = cell.get_entity(self)?;
209        // SAFETY: caller ensures that the world cell has read-only access to the entity.
210        Ok(unsafe { EntityRef::new(ecell) })
211    }
212
213    #[inline]
214    unsafe fn fetch_mut(
215        self,
216        cell: UnsafeWorldCell<'_>,
217    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
218        let location = cell
219            .entities()
220            .get(self)
221            .ok_or(EntityDoesNotExistError::new(self, cell.entities()))?;
222        // SAFETY: caller ensures that the world cell has mutable access to the entity.
223        let world = unsafe { cell.world_mut() };
224        // SAFETY: location was fetched from the same world's `Entities`.
225        Ok(unsafe { EntityWorldMut::new(world, self, Some(location)) })
226    }
227
228    #[inline]
229    unsafe fn fetch_deferred_mut(
230        self,
231        cell: UnsafeWorldCell<'_>,
232    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
233        let ecell = cell.get_entity(self)?;
234        // SAFETY: caller ensures that the world cell has mutable access to the entity.
235        Ok(unsafe { EntityMut::new(ecell) })
236    }
237}
238
239// SAFETY:
240// - No aliased mutability is caused because the array is checked for duplicates.
241// - No mutable references are returned by `fetch_ref`.
242// - No structurally-mutable references are returned by `fetch_deferred_mut`.
243unsafe impl<const N: usize> WorldEntityFetch for [Entity; N] {
244    type Ref<'w> = [EntityRef<'w>; N];
245    type Mut<'w> = [EntityMut<'w>; N];
246    type DeferredMut<'w> = [EntityMut<'w>; N];
247
248    #[inline]
249    unsafe fn fetch_ref(
250        self,
251        cell: UnsafeWorldCell<'_>,
252    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
253        <&Self>::fetch_ref(&self, cell)
254    }
255
256    #[inline]
257    unsafe fn fetch_mut(
258        self,
259        cell: UnsafeWorldCell<'_>,
260    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
261        <&Self>::fetch_mut(&self, cell)
262    }
263
264    #[inline]
265    unsafe fn fetch_deferred_mut(
266        self,
267        cell: UnsafeWorldCell<'_>,
268    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
269        <&Self>::fetch_deferred_mut(&self, cell)
270    }
271}
272
273// SAFETY:
274// - No aliased mutability is caused because the array is checked for duplicates.
275// - No mutable references are returned by `fetch_ref`.
276// - No structurally-mutable references are returned by `fetch_deferred_mut`.
277unsafe impl<const N: usize> WorldEntityFetch for &'_ [Entity; N] {
278    type Ref<'w> = [EntityRef<'w>; N];
279    type Mut<'w> = [EntityMut<'w>; N];
280    type DeferredMut<'w> = [EntityMut<'w>; N];
281
282    #[inline]
283    unsafe fn fetch_ref(
284        self,
285        cell: UnsafeWorldCell<'_>,
286    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
287        let mut refs = [MaybeUninit::uninit(); N];
288        for (r, &id) in core::iter::zip(&mut refs, self) {
289            let ecell = cell.get_entity(id)?;
290            // SAFETY: caller ensures that the world cell has read-only access to the entity.
291            *r = MaybeUninit::new(unsafe { EntityRef::new(ecell) });
292        }
293
294        // SAFETY: Each item was initialized in the loop above.
295        let refs = refs.map(|r| unsafe { MaybeUninit::assume_init(r) });
296
297        Ok(refs)
298    }
299
300    #[inline]
301    unsafe fn fetch_mut(
302        self,
303        cell: UnsafeWorldCell<'_>,
304    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
305        // Check for duplicate entities.
306        for i in 0..self.len() {
307            for j in 0..i {
308                if self[i] == self[j] {
309                    return Err(EntityMutableFetchError::AliasedMutability(self[i]));
310                }
311            }
312        }
313
314        let mut refs = [const { MaybeUninit::uninit() }; N];
315        for (r, &id) in core::iter::zip(&mut refs, self) {
316            let ecell = cell.get_entity(id)?;
317            // SAFETY: caller ensures that the world cell has mutable access to the entity.
318            *r = MaybeUninit::new(unsafe { EntityMut::new(ecell) });
319        }
320
321        // SAFETY: Each item was initialized in the loop above.
322        let refs = refs.map(|r| unsafe { MaybeUninit::assume_init(r) });
323
324        Ok(refs)
325    }
326
327    #[inline]
328    unsafe fn fetch_deferred_mut(
329        self,
330        cell: UnsafeWorldCell<'_>,
331    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
332        // SAFETY: caller ensures that the world cell has mutable access to the entity,
333        // and `fetch_mut` does not return structurally-mutable references.
334        unsafe { self.fetch_mut(cell) }
335    }
336}
337
338// SAFETY:
339// - No aliased mutability is caused because the slice is checked for duplicates.
340// - No mutable references are returned by `fetch_ref`.
341// - No structurally-mutable references are returned by `fetch_deferred_mut`.
342unsafe impl WorldEntityFetch for &'_ [Entity] {
343    type Ref<'w> = Vec<EntityRef<'w>>;
344    type Mut<'w> = Vec<EntityMut<'w>>;
345    type DeferredMut<'w> = Vec<EntityMut<'w>>;
346
347    #[inline]
348    unsafe fn fetch_ref(
349        self,
350        cell: UnsafeWorldCell<'_>,
351    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
352        let mut refs = Vec::with_capacity(self.len());
353        for &id in self {
354            let ecell = cell.get_entity(id)?;
355            // SAFETY: caller ensures that the world cell has read-only access to the entity.
356            refs.push(unsafe { EntityRef::new(ecell) });
357        }
358
359        Ok(refs)
360    }
361
362    #[inline]
363    unsafe fn fetch_mut(
364        self,
365        cell: UnsafeWorldCell<'_>,
366    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
367        // Check for duplicate entities.
368        for i in 0..self.len() {
369            for j in 0..i {
370                if self[i] == self[j] {
371                    return Err(EntityMutableFetchError::AliasedMutability(self[i]));
372                }
373            }
374        }
375
376        let mut refs = Vec::with_capacity(self.len());
377        for &id in self {
378            let ecell = cell.get_entity(id)?;
379            // SAFETY: caller ensures that the world cell has mutable access to the entity.
380            refs.push(unsafe { EntityMut::new(ecell) });
381        }
382
383        Ok(refs)
384    }
385
386    #[inline]
387    unsafe fn fetch_deferred_mut(
388        self,
389        cell: UnsafeWorldCell<'_>,
390    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
391        // SAFETY: caller ensures that the world cell has mutable access to the entity,
392        // and `fetch_mut` does not return structurally-mutable references.
393        unsafe { self.fetch_mut(cell) }
394    }
395}
396
397// SAFETY:
398// - No aliased mutability is caused because `EntityHashSet` guarantees no duplicates.
399// - No mutable references are returned by `fetch_ref`.
400// - No structurally-mutable references are returned by `fetch_deferred_mut`.
401unsafe impl WorldEntityFetch for &'_ EntityHashSet {
402    type Ref<'w> = EntityHashMap<EntityRef<'w>>;
403    type Mut<'w> = EntityHashMap<EntityMut<'w>>;
404    type DeferredMut<'w> = EntityHashMap<EntityMut<'w>>;
405
406    #[inline]
407    unsafe fn fetch_ref(
408        self,
409        cell: UnsafeWorldCell<'_>,
410    ) -> Result<Self::Ref<'_>, EntityDoesNotExistError> {
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 read-only access to the entity.
415            refs.insert(id, unsafe { EntityRef::new(ecell) });
416        }
417        Ok(refs)
418    }
419
420    #[inline]
421    unsafe fn fetch_mut(
422        self,
423        cell: UnsafeWorldCell<'_>,
424    ) -> Result<Self::Mut<'_>, EntityMutableFetchError> {
425        let mut refs = EntityHashMap::with_capacity(self.len());
426        for &id in self {
427            let ecell = cell.get_entity(id)?;
428            // SAFETY: caller ensures that the world cell has mutable access to the entity.
429            refs.insert(id, unsafe { EntityMut::new(ecell) });
430        }
431        Ok(refs)
432    }
433
434    #[inline]
435    unsafe fn fetch_deferred_mut(
436        self,
437        cell: UnsafeWorldCell<'_>,
438    ) -> Result<Self::DeferredMut<'_>, EntityMutableFetchError> {
439        // SAFETY: caller ensures that the world cell has mutable access to the entity,
440        // and `fetch_mut` does not return structurally-mutable references.
441        unsafe { self.fetch_mut(cell) }
442    }
443}