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}