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}