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}