Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
bevyengine
GitHub Repository: bevyengine/bevy
Path: blob/main/crates/bevy_ecs/src/world/entity_fetch.rs
6604 views
1
use alloc::vec::Vec;
2
use core::mem::MaybeUninit;
3
4
use 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
23
pub struct EntityFetcher<'w> {
24
cell: UnsafeWorldCell<'w>,
25
}
26
27
impl<'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
123
pub 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`.
198
unsafe 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`.
243
unsafe 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`.
277
unsafe 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`.
342
unsafe 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`.
401
unsafe 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
}
444
445