bevy_ecs/world/
entity_fetch.rs

1use core::mem::MaybeUninit;
2
3use crate::{
4    entity::{Entity, EntityHash, EntityHashMap, EntityHashSet},
5    world::{
6        error::EntityFetchError, unsafe_world_cell::UnsafeWorldCell, EntityMut, EntityRef,
7        EntityWorldMut,
8    },
9};
10
11/// Types that can be used to fetch [`Entity`] references from a [`World`].
12///
13/// Provided implementations are:
14/// - [`Entity`]: Fetch a single entity.
15/// - `[Entity; N]`/`&[Entity; N]`: Fetch multiple entities, receiving a
16///   same-sized array of references.
17/// - `&[Entity]`: Fetch multiple entities, receiving a vector of references.
18/// - [`&EntityHashSet`](EntityHashSet): Fetch multiple entities, receiving a
19///   hash map of [`Entity`] IDs to references.
20///
21/// # Performance
22///
23/// - The slice and array implementations perform an aliased mutabiltiy check
24///   in [`WorldEntityFetch::fetch_mut`] that is `O(N^2)`.
25/// - The [`EntityHashSet`] implementation performs no such check as the type
26///   itself guarantees no duplicates.
27/// - The single [`Entity`] implementation performs no such check as only one
28///   reference is returned.
29///
30/// # Safety
31///
32/// Implementor must ensure that:
33/// - No aliased mutability is caused by the returned references.
34/// - [`WorldEntityFetch::fetch_ref`] returns only read-only references.
35/// - [`WorldEntityFetch::fetch_deferred_mut`] returns only non-structurally-mutable references.
36///
37/// [`World`]: crate::world::World
38pub unsafe trait WorldEntityFetch {
39    /// The read-only reference type returned by [`WorldEntityFetch::fetch_ref`].
40    type Ref<'w>;
41
42    /// The mutable reference type returned by [`WorldEntityFetch::fetch_mut`].
43    type Mut<'w>;
44
45    /// The mutable reference type returned by [`WorldEntityFetch::fetch_deferred_mut`],
46    /// but without structural mutability.
47    type DeferredMut<'w>;
48
49    /// Returns read-only reference(s) to the entities with the given
50    /// [`Entity`] IDs, as determined by `self`.
51    ///
52    /// # Safety
53    ///
54    /// It is the caller's responsibility to ensure that:
55    /// - The given [`UnsafeWorldCell`] has read-only access to the fetched entities.
56    /// - No other mutable references to the fetched entities exist at the same time.
57    ///
58    /// # Errors
59    ///
60    /// - Returns [`Entity`] if the entity does not exist.
61    unsafe fn fetch_ref(self, cell: UnsafeWorldCell<'_>) -> Result<Self::Ref<'_>, Entity>;
62
63    /// Returns mutable reference(s) to the entities with the given [`Entity`]
64    /// IDs, as determined by `self`.
65    ///
66    /// # Safety
67    ///
68    /// It is the caller's responsibility to ensure that:
69    /// - The given [`UnsafeWorldCell`] has mutable access to the fetched entities.
70    /// - No other references to the fetched entities exist at the same time.
71    ///
72    /// # Errors
73    ///
74    /// - Returns [`EntityFetchError::NoSuchEntity`] if the entity does not exist.
75    /// - Returns [`EntityFetchError::AliasedMutability`] if the entity was
76    ///   requested mutably more than once.
77    unsafe fn fetch_mut(self, cell: UnsafeWorldCell<'_>)
78        -> Result<Self::Mut<'_>, EntityFetchError>;
79
80    /// Returns mutable reference(s) to the entities with the given [`Entity`]
81    /// IDs, as determined by `self`, but without structural mutability.
82    ///
83    /// No structural mutability means components cannot be removed from the
84    /// entity, new components cannot be added to the entity, and the entity
85    /// cannot be despawned.
86    ///
87    /// # Safety
88    ///
89    /// It is the caller's responsibility to ensure that:
90    /// - The given [`UnsafeWorldCell`] has mutable access to the fetched entities.
91    /// - No other references to the fetched entities exist at the same time.
92    ///
93    /// # Errors
94    ///
95    /// - Returns [`EntityFetchError::NoSuchEntity`] if the entity does not exist.
96    /// - Returns [`EntityFetchError::AliasedMutability`] if the entity was
97    ///   requested mutably more than once.
98    unsafe fn fetch_deferred_mut(
99        self,
100        cell: UnsafeWorldCell<'_>,
101    ) -> Result<Self::DeferredMut<'_>, EntityFetchError>;
102}
103
104// SAFETY:
105// - No aliased mutability is caused because a single reference is returned.
106// - No mutable references are returned by `fetch_ref`.
107// - No structurally-mutable references are returned by `fetch_deferred_mut`.
108unsafe impl WorldEntityFetch for Entity {
109    type Ref<'w> = EntityRef<'w>;
110    type Mut<'w> = EntityWorldMut<'w>;
111    type DeferredMut<'w> = EntityMut<'w>;
112
113    unsafe fn fetch_ref(self, cell: UnsafeWorldCell<'_>) -> Result<Self::Ref<'_>, Entity> {
114        let ecell = cell.get_entity(self).ok_or(self)?;
115        // SAFETY: caller ensures that the world cell has read-only access to the entity.
116        Ok(unsafe { EntityRef::new(ecell) })
117    }
118
119    unsafe fn fetch_mut(
120        self,
121        cell: UnsafeWorldCell<'_>,
122    ) -> Result<Self::Mut<'_>, EntityFetchError> {
123        let location = cell
124            .entities()
125            .get(self)
126            .ok_or(EntityFetchError::NoSuchEntity(self))?;
127        // SAFETY: caller ensures that the world cell has mutable access to the entity.
128        let world = unsafe { cell.world_mut() };
129        // SAFETY: location was fetched from the same world's `Entities`.
130        Ok(unsafe { EntityWorldMut::new(world, self, location) })
131    }
132
133    unsafe fn fetch_deferred_mut(
134        self,
135        cell: UnsafeWorldCell<'_>,
136    ) -> Result<Self::DeferredMut<'_>, EntityFetchError> {
137        let ecell = cell
138            .get_entity(self)
139            .ok_or(EntityFetchError::NoSuchEntity(self))?;
140        // SAFETY: caller ensures that the world cell has mutable access to the entity.
141        Ok(unsafe { EntityMut::new(ecell) })
142    }
143}
144
145// SAFETY:
146// - No aliased mutability is caused because the array is checked for duplicates.
147// - No mutable references are returned by `fetch_ref`.
148// - No structurally-mutable references are returned by `fetch_deferred_mut`.
149unsafe impl<const N: usize> WorldEntityFetch for [Entity; N] {
150    type Ref<'w> = [EntityRef<'w>; N];
151    type Mut<'w> = [EntityMut<'w>; N];
152    type DeferredMut<'w> = [EntityMut<'w>; N];
153
154    unsafe fn fetch_ref(self, cell: UnsafeWorldCell<'_>) -> Result<Self::Ref<'_>, Entity> {
155        <&Self>::fetch_ref(&self, cell)
156    }
157
158    unsafe fn fetch_mut(
159        self,
160        cell: UnsafeWorldCell<'_>,
161    ) -> Result<Self::Mut<'_>, EntityFetchError> {
162        <&Self>::fetch_mut(&self, cell)
163    }
164
165    unsafe fn fetch_deferred_mut(
166        self,
167        cell: UnsafeWorldCell<'_>,
168    ) -> Result<Self::DeferredMut<'_>, EntityFetchError> {
169        <&Self>::fetch_deferred_mut(&self, cell)
170    }
171}
172
173// SAFETY:
174// - No aliased mutability is caused because the array is checked for duplicates.
175// - No mutable references are returned by `fetch_ref`.
176// - No structurally-mutable references are returned by `fetch_deferred_mut`.
177unsafe impl<const N: usize> WorldEntityFetch for &'_ [Entity; N] {
178    type Ref<'w> = [EntityRef<'w>; N];
179    type Mut<'w> = [EntityMut<'w>; N];
180    type DeferredMut<'w> = [EntityMut<'w>; N];
181
182    unsafe fn fetch_ref(self, cell: UnsafeWorldCell<'_>) -> Result<Self::Ref<'_>, Entity> {
183        let mut refs = [MaybeUninit::uninit(); N];
184        for (r, &id) in core::iter::zip(&mut refs, self) {
185            let ecell = cell.get_entity(id).ok_or(id)?;
186            // SAFETY: caller ensures that the world cell has read-only access to the entity.
187            *r = MaybeUninit::new(unsafe { EntityRef::new(ecell) });
188        }
189
190        // SAFETY: Each item was initialized in the loop above.
191        let refs = refs.map(|r| unsafe { MaybeUninit::assume_init(r) });
192
193        Ok(refs)
194    }
195
196    unsafe fn fetch_mut(
197        self,
198        cell: UnsafeWorldCell<'_>,
199    ) -> Result<Self::Mut<'_>, EntityFetchError> {
200        // Check for duplicate entities.
201        for i in 0..self.len() {
202            for j in 0..i {
203                if self[i] == self[j] {
204                    return Err(EntityFetchError::AliasedMutability(self[i]));
205                }
206            }
207        }
208
209        let mut refs = [const { MaybeUninit::uninit() }; N];
210        for (r, &id) in core::iter::zip(&mut refs, self) {
211            let ecell = cell
212                .get_entity(id)
213                .ok_or(EntityFetchError::NoSuchEntity(id))?;
214            // SAFETY: caller ensures that the world cell has mutable access to the entity.
215            *r = MaybeUninit::new(unsafe { EntityMut::new(ecell) });
216        }
217
218        // SAFETY: Each item was initialized in the loop above.
219        let refs = refs.map(|r| unsafe { MaybeUninit::assume_init(r) });
220
221        Ok(refs)
222    }
223
224    unsafe fn fetch_deferred_mut(
225        self,
226        cell: UnsafeWorldCell<'_>,
227    ) -> Result<Self::DeferredMut<'_>, EntityFetchError> {
228        // SAFETY: caller ensures that the world cell has mutable access to the entity,
229        // and `fetch_mut` does not return structurally-mutable references.
230        unsafe { self.fetch_mut(cell) }
231    }
232}
233
234// SAFETY:
235// - No aliased mutability is caused because the slice is checked for duplicates.
236// - No mutable references are returned by `fetch_ref`.
237// - No structurally-mutable references are returned by `fetch_deferred_mut`.
238unsafe impl WorldEntityFetch for &'_ [Entity] {
239    type Ref<'w> = Vec<EntityRef<'w>>;
240    type Mut<'w> = Vec<EntityMut<'w>>;
241    type DeferredMut<'w> = Vec<EntityMut<'w>>;
242
243    unsafe fn fetch_ref(self, cell: UnsafeWorldCell<'_>) -> Result<Self::Ref<'_>, Entity> {
244        let mut refs = Vec::with_capacity(self.len());
245        for &id in self {
246            let ecell = cell.get_entity(id).ok_or(id)?;
247            // SAFETY: caller ensures that the world cell has read-only access to the entity.
248            refs.push(unsafe { EntityRef::new(ecell) });
249        }
250
251        Ok(refs)
252    }
253
254    unsafe fn fetch_mut(
255        self,
256        cell: UnsafeWorldCell<'_>,
257    ) -> Result<Self::Mut<'_>, EntityFetchError> {
258        // Check for duplicate entities.
259        for i in 0..self.len() {
260            for j in 0..i {
261                if self[i] == self[j] {
262                    return Err(EntityFetchError::AliasedMutability(self[i]));
263                }
264            }
265        }
266
267        let mut refs = Vec::with_capacity(self.len());
268        for &id in self {
269            let ecell = cell
270                .get_entity(id)
271                .ok_or(EntityFetchError::NoSuchEntity(id))?;
272            // SAFETY: caller ensures that the world cell has mutable access to the entity.
273            refs.push(unsafe { EntityMut::new(ecell) });
274        }
275
276        Ok(refs)
277    }
278
279    unsafe fn fetch_deferred_mut(
280        self,
281        cell: UnsafeWorldCell<'_>,
282    ) -> Result<Self::DeferredMut<'_>, EntityFetchError> {
283        // SAFETY: caller ensures that the world cell has mutable access to the entity,
284        // and `fetch_mut` does not return structurally-mutable references.
285        unsafe { self.fetch_mut(cell) }
286    }
287}
288
289// SAFETY:
290// - No aliased mutability is caused because `EntityHashSet` guarantees no duplicates.
291// - No mutable references are returned by `fetch_ref`.
292// - No structurally-mutable references are returned by `fetch_deferred_mut`.
293unsafe impl WorldEntityFetch for &'_ EntityHashSet {
294    type Ref<'w> = EntityHashMap<EntityRef<'w>>;
295    type Mut<'w> = EntityHashMap<EntityMut<'w>>;
296    type DeferredMut<'w> = EntityHashMap<EntityMut<'w>>;
297
298    unsafe fn fetch_ref(self, cell: UnsafeWorldCell<'_>) -> Result<Self::Ref<'_>, Entity> {
299        let mut refs = EntityHashMap::with_capacity_and_hasher(self.len(), EntityHash);
300        for &id in self {
301            let ecell = cell.get_entity(id).ok_or(id)?;
302            // SAFETY: caller ensures that the world cell has read-only access to the entity.
303            refs.insert(id, unsafe { EntityRef::new(ecell) });
304        }
305        Ok(refs)
306    }
307
308    unsafe fn fetch_mut(
309        self,
310        cell: UnsafeWorldCell<'_>,
311    ) -> Result<Self::Mut<'_>, EntityFetchError> {
312        let mut refs = EntityHashMap::with_capacity_and_hasher(self.len(), EntityHash);
313        for &id in self {
314            let ecell = cell
315                .get_entity(id)
316                .ok_or(EntityFetchError::NoSuchEntity(id))?;
317            // SAFETY: caller ensures that the world cell has mutable access to the entity.
318            refs.insert(id, unsafe { EntityMut::new(ecell) });
319        }
320        Ok(refs)
321    }
322
323    unsafe fn fetch_deferred_mut(
324        self,
325        cell: UnsafeWorldCell<'_>,
326    ) -> Result<Self::DeferredMut<'_>, EntityFetchError> {
327        // SAFETY: caller ensures that the world cell has mutable access to the entity,
328        // and `fetch_mut` does not return structurally-mutable references.
329        unsafe { self.fetch_mut(cell) }
330    }
331}