bevy_ecs/world/unsafe_world_cell.rs
1//! Contains types that allow disjoint mutable access to a [`World`].
2
3#![warn(unsafe_op_in_unsafe_fn)]
4
5use super::{Mut, Ref, World, WorldId};
6use crate::{
7 archetype::{Archetype, Archetypes},
8 bundle::Bundles,
9 change_detection::{MaybeUnsafeCellLocation, MutUntyped, Ticks, TicksMut},
10 component::{ComponentId, ComponentTicks, Components, StorageType, Tick, TickCells},
11 entity::{Entities, Entity, EntityLocation},
12 observer::Observers,
13 prelude::Component,
14 query::{DebugCheckedUnwrap, ReadOnlyQueryData},
15 removal_detection::RemovedComponentEvents,
16 storage::{ComponentSparseSet, Storages, Table},
17 system::Resource,
18 world::RawCommandQueue,
19};
20use bevy_ptr::Ptr;
21#[cfg(feature = "track_change_detection")]
22use bevy_ptr::UnsafeCellDeref;
23use core::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData, ptr};
24
25/// Variant of the [`World`] where resource and component accesses take `&self`, and the responsibility to avoid
26/// aliasing violations are given to the caller instead of being checked at compile-time by rust's unique XOR shared rule.
27///
28/// ### Rationale
29/// In rust, having a `&mut World` means that there are absolutely no other references to the safe world alive at the same time,
30/// without exceptions. Not even unsafe code can change this.
31///
32/// But there are situations where careful shared mutable access through a type is possible and safe. For this, rust provides the [`UnsafeCell`]
33/// escape hatch, which allows you to get a `*mut T` from a `&UnsafeCell<T>` and around which safe abstractions can be built.
34///
35/// Access to resources and components can be done uniquely using [`World::resource_mut`] and [`World::entity_mut`], and shared using [`World::resource`] and [`World::entity`].
36/// These methods use lifetimes to check at compile time that no aliasing rules are being broken.
37///
38/// This alone is not enough to implement bevy systems where multiple systems can access *disjoint* parts of the world concurrently. For this, bevy stores all values of
39/// resources and components (and [`ComponentTicks`]) in [`UnsafeCell`]s, and carefully validates disjoint access patterns using
40/// APIs like [`System::component_access`](crate::system::System::component_access).
41///
42/// A system then can be executed using [`System::run_unsafe`](crate::system::System::run_unsafe) with a `&World` and use methods with interior mutability to access resource values.
43///
44/// ### Example Usage
45///
46/// [`UnsafeWorldCell`] can be used as a building block for writing APIs that safely allow disjoint access into the world.
47/// In the following example, the world is split into a resource access half and a component access half, where each one can
48/// safely hand out mutable references.
49///
50/// ```
51/// use bevy_ecs::world::World;
52/// use bevy_ecs::change_detection::Mut;
53/// use bevy_ecs::system::Resource;
54/// use bevy_ecs::world::unsafe_world_cell::UnsafeWorldCell;
55///
56/// // INVARIANT: existence of this struct means that users of it are the only ones being able to access resources in the world
57/// struct OnlyResourceAccessWorld<'w>(UnsafeWorldCell<'w>);
58/// // INVARIANT: existence of this struct means that users of it are the only ones being able to access components in the world
59/// struct OnlyComponentAccessWorld<'w>(UnsafeWorldCell<'w>);
60///
61/// impl<'w> OnlyResourceAccessWorld<'w> {
62/// fn get_resource_mut<T: Resource>(&mut self) -> Option<Mut<'_, T>> {
63/// // SAFETY: resource access is allowed through this UnsafeWorldCell
64/// unsafe { self.0.get_resource_mut::<T>() }
65/// }
66/// }
67/// // impl<'w> OnlyComponentAccessWorld<'w> {
68/// // ...
69/// // }
70///
71/// // the two `UnsafeWorldCell`s borrow from the `&mut World`, so it cannot be accessed while they are live
72/// fn split_world_access(world: &mut World) -> (OnlyResourceAccessWorld<'_>, OnlyComponentAccessWorld<'_>) {
73/// let unsafe_world_cell = world.as_unsafe_world_cell();
74/// let resource_access = OnlyResourceAccessWorld(unsafe_world_cell);
75/// let component_access = OnlyComponentAccessWorld(unsafe_world_cell);
76/// (resource_access, component_access)
77/// }
78/// ```
79#[derive(Copy, Clone)]
80pub struct UnsafeWorldCell<'w>(*mut World, PhantomData<(&'w World, &'w UnsafeCell<World>)>);
81
82// SAFETY: `&World` and `&mut World` are both `Send`
83unsafe impl Send for UnsafeWorldCell<'_> {}
84// SAFETY: `&World` and `&mut World` are both `Sync`
85unsafe impl Sync for UnsafeWorldCell<'_> {}
86
87impl<'w> From<&'w mut World> for UnsafeWorldCell<'w> {
88 fn from(value: &'w mut World) -> Self {
89 value.as_unsafe_world_cell()
90 }
91}
92
93impl<'w> From<&'w World> for UnsafeWorldCell<'w> {
94 fn from(value: &'w World) -> Self {
95 value.as_unsafe_world_cell_readonly()
96 }
97}
98
99impl<'w> UnsafeWorldCell<'w> {
100 /// Creates a [`UnsafeWorldCell`] that can be used to access everything immutably
101 #[inline]
102 pub(crate) fn new_readonly(world: &'w World) -> Self {
103 Self(ptr::from_ref(world).cast_mut(), PhantomData)
104 }
105
106 /// Creates [`UnsafeWorldCell`] that can be used to access everything mutably
107 #[inline]
108 pub(crate) fn new_mutable(world: &'w mut World) -> Self {
109 Self(ptr::from_mut(world), PhantomData)
110 }
111
112 /// Gets a mutable reference to the [`World`] this [`UnsafeWorldCell`] belongs to.
113 /// This is an incredibly error-prone operation and is only valid in a small number of circumstances.
114 ///
115 /// # Safety
116 /// - `self` must have been obtained from a call to [`World::as_unsafe_world_cell`]
117 /// (*not* `as_unsafe_world_cell_readonly` or any other method of construction that
118 /// does not provide mutable access to the entire world).
119 /// - This means that if you have an `UnsafeWorldCell` that you didn't create yourself,
120 /// it is likely *unsound* to call this method.
121 /// - The returned `&mut World` *must* be unique: it must never be allowed to exist
122 /// at the same time as any other borrows of the world or any accesses to its data.
123 /// This includes safe ways of accessing world data, such as [`UnsafeWorldCell::archetypes`].
124 /// - Note that the `&mut World` *may* exist at the same time as instances of `UnsafeWorldCell`,
125 /// so long as none of those instances are used to access world data in any way
126 /// while the mutable borrow is active.
127 ///
128 /// [//]: # (This test fails miri.)
129 /// ```no_run
130 /// # use bevy_ecs::prelude::*;
131 /// # #[derive(Component)] struct Player;
132 /// # fn store_but_dont_use<T>(_: T) {}
133 /// # let mut world = World::new();
134 /// // Make an UnsafeWorldCell.
135 /// let world_cell = world.as_unsafe_world_cell();
136 ///
137 /// // SAFETY: `world_cell` was originally created from `&mut World`.
138 /// // We must be sure not to access any world data while `world_mut` is active.
139 /// let world_mut = unsafe { world_cell.world_mut() };
140 ///
141 /// // We can still use `world_cell` so long as we don't access the world with it.
142 /// store_but_dont_use(world_cell);
143 ///
144 /// // !!This is unsound!! Even though this method is safe, we cannot call it until
145 /// // `world_mut` is no longer active.
146 /// let tick = world_cell.change_tick();
147 ///
148 /// // Use mutable access to spawn an entity.
149 /// world_mut.spawn(Player);
150 ///
151 /// // Since we never use `world_mut` after this, the borrow is released
152 /// // and we are once again allowed to access the world using `world_cell`.
153 /// let archetypes = world_cell.archetypes();
154 /// ```
155 #[inline]
156 pub unsafe fn world_mut(self) -> &'w mut World {
157 // SAFETY:
158 // - caller ensures the created `&mut World` is the only borrow of world
159 unsafe { &mut *self.0 }
160 }
161
162 /// Gets a reference to the [`&World`](World) this [`UnsafeWorldCell`] belongs to.
163 /// This can be used for arbitrary shared/readonly access.
164 ///
165 /// # Safety
166 /// - must have permission to access the whole world immutably
167 /// - there must be no live exclusive borrows on world data
168 /// - there must be no live exclusive borrow of world
169 #[inline]
170 pub unsafe fn world(self) -> &'w World {
171 // SAFETY:
172 // - caller ensures there is no `&mut World` this makes it okay to make a `&World`
173 // - caller ensures there is no mutable borrows of world data, this means the caller cannot
174 // misuse the returned `&World`
175 unsafe { self.unsafe_world() }
176 }
177
178 /// Gets a reference to the [`World`] this [`UnsafeWorldCell`] belong to.
179 /// This can be used for arbitrary read only access of world metadata
180 ///
181 /// You should attempt to use various safe methods on [`UnsafeWorldCell`] for
182 /// metadata access before using this method.
183 ///
184 /// # Safety
185 /// - must only be used to access world metadata
186 #[inline]
187 pub unsafe fn world_metadata(self) -> &'w World {
188 // SAFETY: caller ensures that returned reference is not used to violate aliasing rules
189 unsafe { self.unsafe_world() }
190 }
191
192 /// Variant on [`UnsafeWorldCell::world`] solely used for implementing this type's methods.
193 /// It allows having an `&World` even with live mutable borrows of components and resources
194 /// so the returned `&World` should not be handed out to safe code and care should be taken
195 /// when working with it.
196 ///
197 /// Deliberately private as the correct way to access data in a [`World`] that may have existing
198 /// mutable borrows of data inside it, is to use [`UnsafeWorldCell`].
199 ///
200 /// # Safety
201 /// - must not be used in a way that would conflict with any
202 /// live exclusive borrows on world data
203 #[inline]
204 unsafe fn unsafe_world(self) -> &'w World {
205 // SAFETY:
206 // - caller ensures that the returned `&World` is not used in a way that would conflict
207 // with any existing mutable borrows of world data
208 unsafe { &*self.0 }
209 }
210
211 /// Retrieves this world's unique [ID](WorldId).
212 #[inline]
213 pub fn id(self) -> WorldId {
214 // SAFETY:
215 // - we only access world metadata
216 unsafe { self.world_metadata() }.id()
217 }
218
219 /// Retrieves this world's [`Entities`] collection.
220 #[inline]
221 pub fn entities(self) -> &'w Entities {
222 // SAFETY:
223 // - we only access world metadata
224 &unsafe { self.world_metadata() }.entities
225 }
226
227 /// Retrieves this world's [`Archetypes`] collection.
228 #[inline]
229 pub fn archetypes(self) -> &'w Archetypes {
230 // SAFETY:
231 // - we only access world metadata
232 &unsafe { self.world_metadata() }.archetypes
233 }
234
235 /// Retrieves this world's [`Components`] collection.
236 #[inline]
237 pub fn components(self) -> &'w Components {
238 // SAFETY:
239 // - we only access world metadata
240 &unsafe { self.world_metadata() }.components
241 }
242
243 /// Retrieves this world's collection of [removed components](RemovedComponentEvents).
244 pub fn removed_components(self) -> &'w RemovedComponentEvents {
245 // SAFETY:
246 // - we only access world metadata
247 &unsafe { self.world_metadata() }.removed_components
248 }
249
250 /// Retrieves this world's [`Observers`] collection.
251 pub(crate) fn observers(self) -> &'w Observers {
252 // SAFETY:
253 // - we only access world metadata
254 &unsafe { self.world_metadata() }.observers
255 }
256
257 /// Retrieves this world's [`Bundles`] collection.
258 #[inline]
259 pub fn bundles(self) -> &'w Bundles {
260 // SAFETY:
261 // - we only access world metadata
262 &unsafe { self.world_metadata() }.bundles
263 }
264
265 /// Gets the current change tick of this world.
266 #[inline]
267 pub fn change_tick(self) -> Tick {
268 // SAFETY:
269 // - we only access world metadata
270 unsafe { self.world_metadata() }.read_change_tick()
271 }
272
273 /// Returns the id of the last ECS event that was fired.
274 /// Used internally to ensure observers don't trigger multiple times for the same event.
275 #[inline]
276 pub fn last_trigger_id(&self) -> u32 {
277 // SAFETY:
278 // - we only access world metadata
279 unsafe { self.world_metadata() }.last_trigger_id()
280 }
281
282 /// Returns the [`Tick`] indicating the last time that [`World::clear_trackers`] was called.
283 ///
284 /// If this `UnsafeWorldCell` was created from inside of an exclusive system (a [`System`] that
285 /// takes `&mut World` as its first parameter), this will instead return the `Tick` indicating
286 /// the last time the system was run.
287 ///
288 /// See [`World::last_change_tick()`].
289 ///
290 /// [`System`]: crate::system::System
291 #[inline]
292 pub fn last_change_tick(self) -> Tick {
293 // SAFETY:
294 // - we only access world metadata
295 unsafe { self.world_metadata() }.last_change_tick()
296 }
297
298 /// Increments the world's current change tick and returns the old value.
299 #[inline]
300 pub fn increment_change_tick(self) -> Tick {
301 // SAFETY:
302 // - we only access world metadata
303 let change_tick = unsafe { &self.world_metadata().change_tick };
304 // NOTE: We can used a relaxed memory ordering here, since nothing
305 // other than the atomic value itself is relying on atomic synchronization
306 Tick::new(change_tick.fetch_add(1, core::sync::atomic::Ordering::Relaxed))
307 }
308
309 /// Provides unchecked access to the internal data stores of the [`World`].
310 ///
311 /// # Safety
312 ///
313 /// The caller must ensure that this is only used to access world data
314 /// that this [`UnsafeWorldCell`] is allowed to.
315 /// As always, any mutable access to a component must not exist at the same
316 /// time as any other accesses to that same component.
317 #[inline]
318 pub unsafe fn storages(self) -> &'w Storages {
319 // SAFETY: The caller promises to only access world data allowed by this instance.
320 &unsafe { self.unsafe_world() }.storages
321 }
322
323 /// Retrieves an [`UnsafeEntityCell`] that exposes read and write operations for the given `entity`.
324 /// Similar to the [`UnsafeWorldCell`], you are in charge of making sure that no aliasing rules are violated.
325 #[inline]
326 pub fn get_entity(self, entity: Entity) -> Option<UnsafeEntityCell<'w>> {
327 let location = self.entities().get(entity)?;
328 Some(UnsafeEntityCell::new(self, entity, location))
329 }
330
331 /// Gets a reference to the resource of the given type if it exists
332 ///
333 /// # Safety
334 /// It is the callers responsibility to ensure that
335 /// - the [`UnsafeWorldCell`] has permission to access the resource
336 /// - no mutable reference to the resource exists at the same time
337 #[inline]
338 pub unsafe fn get_resource<R: Resource>(self) -> Option<&'w R> {
339 let component_id = self.components().get_resource_id(TypeId::of::<R>())?;
340 // SAFETY: caller ensures `self` has permission to access the resource
341 // caller also ensure that no mutable reference to the resource exists
342 unsafe {
343 self.get_resource_by_id(component_id)
344 // SAFETY: `component_id` was obtained from the type ID of `R`.
345 .map(|ptr| ptr.deref::<R>())
346 }
347 }
348
349 /// Gets a reference including change detection to the resource of the given type if it exists.
350 ///
351 /// # Safety
352 /// It is the callers responsibility to ensure that
353 /// - the [`UnsafeWorldCell`] has permission to access the resource
354 /// - no mutable reference to the resource exists at the same time
355 #[inline]
356 pub unsafe fn get_resource_ref<R: Resource>(self) -> Option<Ref<'w, R>> {
357 let component_id = self.components().get_resource_id(TypeId::of::<R>())?;
358
359 // SAFETY: caller ensures `self` has permission to access the resource
360 // caller also ensure that no mutable reference to the resource exists
361 let (ptr, ticks, _caller) = unsafe { self.get_resource_with_ticks(component_id)? };
362
363 // SAFETY: `component_id` was obtained from the type ID of `R`
364 let value = unsafe { ptr.deref::<R>() };
365
366 // SAFETY: caller ensures that no mutable reference to the resource exists
367 let ticks =
368 unsafe { Ticks::from_tick_cells(ticks, self.last_change_tick(), self.change_tick()) };
369
370 // SAFETY: caller ensures that no mutable reference to the resource exists
371 #[cfg(feature = "track_change_detection")]
372 let caller = unsafe { _caller.deref() };
373
374 Some(Ref {
375 value,
376 ticks,
377 #[cfg(feature = "track_change_detection")]
378 changed_by: caller,
379 })
380 }
381
382 /// Gets a pointer to the resource with the id [`ComponentId`] if it exists.
383 /// The returned pointer must not be used to modify the resource, and must not be
384 /// dereferenced after the borrow of the [`World`] ends.
385 ///
386 /// **You should prefer to use the typed API [`UnsafeWorldCell::get_resource`] where possible and only
387 /// use this in cases where the actual types are not known at compile time.**
388 ///
389 /// # Safety
390 /// It is the callers responsibility to ensure that
391 /// - the [`UnsafeWorldCell`] has permission to access the resource
392 /// - no mutable reference to the resource exists at the same time
393 #[inline]
394 pub unsafe fn get_resource_by_id(self, component_id: ComponentId) -> Option<Ptr<'w>> {
395 // SAFETY: caller ensures that `self` has permission to access `R`
396 // caller ensures that no mutable reference exists to `R`
397 unsafe { self.storages() }
398 .resources
399 .get(component_id)?
400 .get_data()
401 }
402
403 /// Gets a reference to the non-send resource of the given type if it exists
404 ///
405 /// # Safety
406 /// It is the callers responsibility to ensure that
407 /// - the [`UnsafeWorldCell`] has permission to access the resource
408 /// - no mutable reference to the resource exists at the same time
409 #[inline]
410 pub unsafe fn get_non_send_resource<R: 'static>(self) -> Option<&'w R> {
411 let component_id = self.components().get_resource_id(TypeId::of::<R>())?;
412 // SAFETY: caller ensures that `self` has permission to access `R`
413 // caller ensures that no mutable reference exists to `R`
414 unsafe {
415 self.get_non_send_resource_by_id(component_id)
416 // SAFETY: `component_id` was obtained from `TypeId::of::<R>()`
417 .map(|ptr| ptr.deref::<R>())
418 }
419 }
420
421 /// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.
422 /// The returned pointer must not be used to modify the resource, and must not be
423 /// dereferenced after the immutable borrow of the [`World`] ends.
424 ///
425 /// **You should prefer to use the typed API [`UnsafeWorldCell::get_non_send_resource`] where possible and only
426 /// use this in cases where the actual types are not known at compile time.**
427 ///
428 /// # Panics
429 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
430 ///
431 /// # Safety
432 /// It is the callers responsibility to ensure that
433 /// - the [`UnsafeWorldCell`] has permission to access the resource
434 /// - no mutable reference to the resource exists at the same time
435 #[inline]
436 pub unsafe fn get_non_send_resource_by_id(self, component_id: ComponentId) -> Option<Ptr<'w>> {
437 // SAFETY: we only access data on world that the caller has ensured is unaliased and we have
438 // permission to access.
439 unsafe { self.storages() }
440 .non_send_resources
441 .get(component_id)?
442 .get_data()
443 }
444
445 /// Gets a mutable reference to the resource of the given type if it exists
446 ///
447 /// # Safety
448 /// It is the callers responsibility to ensure that
449 /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
450 /// - no other references to the resource exist at the same time
451 #[inline]
452 pub unsafe fn get_resource_mut<R: Resource>(self) -> Option<Mut<'w, R>> {
453 let component_id = self.components().get_resource_id(TypeId::of::<R>())?;
454 // SAFETY:
455 // - caller ensures `self` has permission to access the resource mutably
456 // - caller ensures no other references to the resource exist
457 unsafe {
458 self.get_resource_mut_by_id(component_id)
459 // `component_id` was gotten from `TypeId::of::<R>()`
460 .map(|ptr| ptr.with_type::<R>())
461 }
462 }
463
464 /// Gets a pointer to the resource with the id [`ComponentId`] if it exists.
465 /// The returned pointer may be used to modify the resource, as long as the mutable borrow
466 /// of the [`UnsafeWorldCell`] is still valid.
467 ///
468 /// **You should prefer to use the typed API [`UnsafeWorldCell::get_resource_mut`] where possible and only
469 /// use this in cases where the actual types are not known at compile time.**
470 ///
471 /// # Safety
472 /// It is the callers responsibility to ensure that
473 /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
474 /// - no other references to the resource exist at the same time
475 #[inline]
476 pub unsafe fn get_resource_mut_by_id(
477 self,
478 component_id: ComponentId,
479 ) -> Option<MutUntyped<'w>> {
480 // SAFETY: we only access data that the caller has ensured is unaliased and `self`
481 // has permission to access.
482 let (ptr, ticks, _caller) = unsafe { self.storages() }
483 .resources
484 .get(component_id)?
485 .get_with_ticks()?;
486
487 // SAFETY:
488 // - index is in-bounds because the column is initialized and non-empty
489 // - the caller promises that no other reference to the ticks of the same row can exist at the same time
490 let ticks = unsafe {
491 TicksMut::from_tick_cells(ticks, self.last_change_tick(), self.change_tick())
492 };
493
494 Some(MutUntyped {
495 // SAFETY:
496 // - caller ensures that `self` has permission to access the resource
497 // - caller ensures that the resource is unaliased
498 value: unsafe { ptr.assert_unique() },
499 ticks,
500 #[cfg(feature = "track_change_detection")]
501 // SAFETY:
502 // - caller ensures that `self` has permission to access the resource
503 // - caller ensures that the resource is unaliased
504 changed_by: unsafe { _caller.deref_mut() },
505 })
506 }
507
508 /// Gets a mutable reference to the non-send resource of the given type if it exists
509 ///
510 /// # Safety
511 /// It is the callers responsibility to ensure that
512 /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
513 /// - no other references to the resource exist at the same time
514 #[inline]
515 pub unsafe fn get_non_send_resource_mut<R: 'static>(self) -> Option<Mut<'w, R>> {
516 let component_id = self.components().get_resource_id(TypeId::of::<R>())?;
517 // SAFETY:
518 // - caller ensures that `self` has permission to access the resource
519 // - caller ensures that the resource is unaliased
520 unsafe {
521 self.get_non_send_resource_mut_by_id(component_id)
522 // SAFETY: `component_id` was gotten by `TypeId::of::<R>()`
523 .map(|ptr| ptr.with_type::<R>())
524 }
525 }
526
527 /// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.
528 /// The returned pointer may be used to modify the resource, as long as the mutable borrow
529 /// of the [`World`] is still valid.
530 ///
531 /// **You should prefer to use the typed API [`UnsafeWorldCell::get_non_send_resource_mut`] where possible and only
532 /// use this in cases where the actual types are not known at compile time.**
533 ///
534 /// # Panics
535 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
536 ///
537 /// # Safety
538 /// It is the callers responsibility to ensure that
539 /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
540 /// - no other references to the resource exist at the same time
541 #[inline]
542 pub unsafe fn get_non_send_resource_mut_by_id(
543 self,
544 component_id: ComponentId,
545 ) -> Option<MutUntyped<'w>> {
546 let change_tick = self.change_tick();
547 // SAFETY: we only access data that the caller has ensured is unaliased and `self`
548 // has permission to access.
549 let (ptr, ticks, _caller) = unsafe { self.storages() }
550 .non_send_resources
551 .get(component_id)?
552 .get_with_ticks()?;
553
554 let ticks =
555 // SAFETY: This function has exclusive access to the world so nothing aliases `ticks`.
556 // - index is in-bounds because the column is initialized and non-empty
557 // - no other reference to the ticks of the same row can exist at the same time
558 unsafe { TicksMut::from_tick_cells(ticks, self.last_change_tick(), change_tick) };
559
560 Some(MutUntyped {
561 // SAFETY: This function has exclusive access to the world so nothing aliases `ptr`.
562 value: unsafe { ptr.assert_unique() },
563 ticks,
564 #[cfg(feature = "track_change_detection")]
565 // SAFETY: This function has exclusive access to the world
566 changed_by: unsafe { _caller.deref_mut() },
567 })
568 }
569
570 // Shorthand helper function for getting the data and change ticks for a resource.
571 /// # Safety
572 /// It is the callers responsibility to ensure that
573 /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
574 /// - no mutable references to the resource exist at the same time
575 #[inline]
576 pub(crate) unsafe fn get_resource_with_ticks(
577 self,
578 component_id: ComponentId,
579 ) -> Option<(Ptr<'w>, TickCells<'w>, MaybeUnsafeCellLocation<'w>)> {
580 // SAFETY:
581 // - caller ensures there is no `&mut World`
582 // - caller ensures there are no mutable borrows of this resource
583 // - caller ensures that we have permission to access this resource
584 unsafe { self.storages() }
585 .resources
586 .get(component_id)?
587 .get_with_ticks()
588 }
589
590 // Shorthand helper function for getting the data and change ticks for a resource.
591 /// # Panics
592 /// This function will panic if it isn't called from the same thread that the resource was inserted from.
593 ///
594 /// # Safety
595 /// It is the callers responsibility to ensure that
596 /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
597 /// - no mutable references to the resource exist at the same time
598 #[inline]
599 pub(crate) unsafe fn get_non_send_with_ticks(
600 self,
601 component_id: ComponentId,
602 ) -> Option<(Ptr<'w>, TickCells<'w>, MaybeUnsafeCellLocation<'w>)> {
603 // SAFETY:
604 // - caller ensures there is no `&mut World`
605 // - caller ensures there are no mutable borrows of this resource
606 // - caller ensures that we have permission to access this resource
607 unsafe { self.storages() }
608 .non_send_resources
609 .get(component_id)?
610 .get_with_ticks()
611 }
612
613 // Returns a mutable reference to the underlying world's [`CommandQueue`].
614 /// # Safety
615 /// It is the callers responsibility to ensure that
616 /// - the [`UnsafeWorldCell`] has permission to access the queue mutably
617 /// - no mutable references to the queue exist at the same time
618 pub(crate) unsafe fn get_raw_command_queue(self) -> RawCommandQueue {
619 // SAFETY:
620 // - caller ensures there are no existing mutable references
621 // - caller ensures that we have permission to access the queue
622 unsafe { (*self.0).command_queue.clone() }
623 }
624
625 /// # Safety
626 /// It is the callers responsibility to ensure that there are no outstanding
627 /// references to `last_trigger_id`.
628 pub(crate) unsafe fn increment_trigger_id(self) {
629 // SAFETY: Caller ensure there are no outstanding references
630 unsafe { (*self.0).last_trigger_id += 1 }
631 }
632}
633
634impl Debug for UnsafeWorldCell<'_> {
635 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
636 // SAFETY: World's Debug implementation only accesses metadata.
637 Debug::fmt(unsafe { self.world_metadata() }, f)
638 }
639}
640
641/// A interior-mutable reference to a particular [`Entity`] and all of its components
642#[derive(Copy, Clone)]
643pub struct UnsafeEntityCell<'w> {
644 world: UnsafeWorldCell<'w>,
645 entity: Entity,
646 location: EntityLocation,
647}
648
649impl<'w> UnsafeEntityCell<'w> {
650 #[inline]
651 pub(crate) fn new(
652 world: UnsafeWorldCell<'w>,
653 entity: Entity,
654 location: EntityLocation,
655 ) -> Self {
656 UnsafeEntityCell {
657 world,
658 entity,
659 location,
660 }
661 }
662
663 /// Returns the [ID](Entity) of the current entity.
664 #[inline]
665 #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
666 pub fn id(self) -> Entity {
667 self.entity
668 }
669
670 /// Gets metadata indicating the location where the current entity is stored.
671 #[inline]
672 pub fn location(self) -> EntityLocation {
673 self.location
674 }
675
676 /// Returns the archetype that the current entity belongs to.
677 #[inline]
678 pub fn archetype(self) -> &'w Archetype {
679 &self.world.archetypes()[self.location.archetype_id]
680 }
681
682 /// Gets the world that the current entity belongs to.
683 #[inline]
684 pub fn world(self) -> UnsafeWorldCell<'w> {
685 self.world
686 }
687
688 /// Returns `true` if the current entity has a component of type `T`.
689 /// Otherwise, this returns `false`.
690 ///
691 /// ## Notes
692 ///
693 /// If you do not know the concrete type of a component, consider using
694 /// [`Self::contains_id`] or [`Self::contains_type_id`].
695 #[inline]
696 pub fn contains<T: Component>(self) -> bool {
697 self.contains_type_id(TypeId::of::<T>())
698 }
699
700 /// Returns `true` if the current entity has a component identified by `component_id`.
701 /// Otherwise, this returns false.
702 ///
703 /// ## Notes
704 ///
705 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
706 /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
707 /// [`Self::contains_type_id`].
708 #[inline]
709 pub fn contains_id(self, component_id: ComponentId) -> bool {
710 self.archetype().contains(component_id)
711 }
712
713 /// Returns `true` if the current entity has a component with the type identified by `type_id`.
714 /// Otherwise, this returns false.
715 ///
716 /// ## Notes
717 ///
718 /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
719 /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
720 #[inline]
721 pub fn contains_type_id(self, type_id: TypeId) -> bool {
722 let Some(id) = self.world.components().get_id(type_id) else {
723 return false;
724 };
725 self.contains_id(id)
726 }
727
728 /// # Safety
729 /// It is the callers responsibility to ensure that
730 /// - the [`UnsafeEntityCell`] has permission to access the component
731 /// - no other mutable references to the component exist at the same time
732 #[inline]
733 pub unsafe fn get<T: Component>(self) -> Option<&'w T> {
734 let component_id = self.world.components().get_id(TypeId::of::<T>())?;
735 // SAFETY:
736 // - `storage_type` is correct (T component_id + T::STORAGE_TYPE)
737 // - `location` is valid
738 // - proper aliasing is promised by caller
739 unsafe {
740 get_component(
741 self.world,
742 component_id,
743 T::STORAGE_TYPE,
744 self.entity,
745 self.location,
746 )
747 // SAFETY: returned component is of type T
748 .map(|value| value.deref::<T>())
749 }
750 }
751
752 /// # Safety
753 /// It is the callers responsibility to ensure that
754 /// - the [`UnsafeEntityCell`] has permission to access the component
755 /// - no other mutable references to the component exist at the same time
756 #[inline]
757 pub unsafe fn get_ref<T: Component>(self) -> Option<Ref<'w, T>> {
758 let last_change_tick = self.world.last_change_tick();
759 let change_tick = self.world.change_tick();
760 let component_id = self.world.components().get_id(TypeId::of::<T>())?;
761
762 // SAFETY:
763 // - `storage_type` is correct (T component_id + T::STORAGE_TYPE)
764 // - `location` is valid
765 // - proper aliasing is promised by caller
766 unsafe {
767 get_component_and_ticks(
768 self.world,
769 component_id,
770 T::STORAGE_TYPE,
771 self.entity,
772 self.location,
773 )
774 .map(|(value, cells, _caller)| Ref {
775 // SAFETY: returned component is of type T
776 value: value.deref::<T>(),
777 ticks: Ticks::from_tick_cells(cells, last_change_tick, change_tick),
778 #[cfg(feature = "track_change_detection")]
779 changed_by: _caller.deref(),
780 })
781 }
782 }
783
784 /// Retrieves the change ticks for the given component. This can be useful for implementing change
785 /// detection in custom runtimes.
786 ///
787 /// # Safety
788 /// It is the callers responsibility to ensure that
789 /// - the [`UnsafeEntityCell`] has permission to access the component
790 /// - no other mutable references to the component exist at the same time
791 #[inline]
792 pub unsafe fn get_change_ticks<T: Component>(self) -> Option<ComponentTicks> {
793 let component_id = self.world.components().get_id(TypeId::of::<T>())?;
794
795 // SAFETY:
796 // - entity location is valid
797 // - proper world access is promised by caller
798 unsafe {
799 get_ticks(
800 self.world,
801 component_id,
802 T::STORAGE_TYPE,
803 self.entity,
804 self.location,
805 )
806 }
807 }
808
809 /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
810 /// detection in custom runtimes.
811 ///
812 /// **You should prefer to use the typed API [`UnsafeEntityCell::get_change_ticks`] where possible and only
813 /// use this in cases where the actual component types are not known at
814 /// compile time.**
815 ///
816 /// # Safety
817 /// It is the callers responsibility to ensure that
818 /// - the [`UnsafeEntityCell`] has permission to access the component
819 /// - no other mutable references to the component exist at the same time
820 #[inline]
821 pub unsafe fn get_change_ticks_by_id(
822 &self,
823 component_id: ComponentId,
824 ) -> Option<ComponentTicks> {
825 let info = self.world.components().get_info(component_id)?;
826 // SAFETY:
827 // - entity location and entity is valid
828 // - world access is immutable, lifetime tied to `&self`
829 // - the storage type provided is correct for T
830 unsafe {
831 get_ticks(
832 self.world,
833 component_id,
834 info.storage_type(),
835 self.entity,
836 self.location,
837 )
838 }
839 }
840
841 /// # Safety
842 /// It is the callers responsibility to ensure that
843 /// - the [`UnsafeEntityCell`] has permission to access the component mutably
844 /// - no other references to the component exist at the same time
845 #[inline]
846 pub unsafe fn get_mut<T: Component>(self) -> Option<Mut<'w, T>> {
847 // SAFETY: same safety requirements
848 unsafe { self.get_mut_using_ticks(self.world.last_change_tick(), self.world.change_tick()) }
849 }
850
851 /// # Safety
852 /// It is the callers responsibility to ensure that
853 /// - the [`UnsafeEntityCell`] has permission to access the component mutably
854 /// - no other references to the component exist at the same time
855 #[inline]
856 pub(crate) unsafe fn get_mut_using_ticks<T: Component>(
857 &self,
858 last_change_tick: Tick,
859 change_tick: Tick,
860 ) -> Option<Mut<'w, T>> {
861 let component_id = self.world.components().get_id(TypeId::of::<T>())?;
862
863 // SAFETY:
864 // - `storage_type` is correct
865 // - `location` is valid
866 // - aliasing rules are ensured by caller
867 unsafe {
868 get_component_and_ticks(
869 self.world,
870 component_id,
871 T::STORAGE_TYPE,
872 self.entity,
873 self.location,
874 )
875 .map(|(value, cells, _caller)| Mut {
876 // SAFETY: returned component is of type T
877 value: value.assert_unique().deref_mut::<T>(),
878 ticks: TicksMut::from_tick_cells(cells, last_change_tick, change_tick),
879 #[cfg(feature = "track_change_detection")]
880 changed_by: _caller.deref_mut(),
881 })
882 }
883 }
884
885 /// Returns read-only components for the current entity that match the query `Q`,
886 /// or `None` if the entity does not have the components required by the query `Q`.
887 ///
888 /// # Safety
889 /// It is the callers responsibility to ensure that
890 /// - the [`UnsafeEntityCell`] has permission to access the queried data immutably
891 /// - no mutable references to the queried data exist at the same time
892 pub(crate) unsafe fn get_components<Q: ReadOnlyQueryData>(&self) -> Option<Q::Item<'w>> {
893 // SAFETY: World is only used to access query data and initialize query state
894 let state = unsafe {
895 let world = self.world().world();
896 Q::get_state(world.components())?
897 };
898 let location = self.location();
899 // SAFETY: Location is guaranteed to exist
900 let archetype = unsafe {
901 self.world
902 .archetypes()
903 .get(location.archetype_id)
904 .debug_checked_unwrap()
905 };
906 if Q::matches_component_set(&state, &|id| archetype.contains(id)) {
907 // SAFETY: state was initialized above using the world passed into this function
908 let mut fetch = unsafe {
909 Q::init_fetch(
910 self.world,
911 &state,
912 self.world.last_change_tick(),
913 self.world.change_tick(),
914 )
915 };
916 // SAFETY: Table is guaranteed to exist
917 let table = unsafe {
918 self.world
919 .storages()
920 .tables
921 .get(location.table_id)
922 .debug_checked_unwrap()
923 };
924 // SAFETY: Archetype and table are from the same world used to initialize state and fetch.
925 // Table corresponds to archetype. State is the same state used to init fetch above.
926 unsafe { Q::set_archetype(&mut fetch, &state, archetype, table) }
927 // SAFETY: Called after set_archetype above. Entity and location are guaranteed to exist.
928 unsafe { Some(Q::fetch(&mut fetch, self.id(), location.table_row)) }
929 } else {
930 None
931 }
932 }
933}
934
935impl<'w> UnsafeEntityCell<'w> {
936 /// Gets the component of the given [`ComponentId`] from the entity.
937 ///
938 /// **You should prefer to use the typed API where possible and only
939 /// use this in cases where the actual component types are not known at
940 /// compile time.**
941 ///
942 /// Unlike [`UnsafeEntityCell::get`], this returns a raw pointer to the component,
943 /// which is only valid while the `'w` borrow of the lifetime is active.
944 ///
945 /// # Safety
946 /// It is the callers responsibility to ensure that
947 /// - the [`UnsafeEntityCell`] has permission to access the component
948 /// - no other mutable references to the component exist at the same time
949 #[inline]
950 pub unsafe fn get_by_id(self, component_id: ComponentId) -> Option<Ptr<'w>> {
951 let info = self.world.components().get_info(component_id)?;
952 // SAFETY: entity_location is valid, component_id is valid as checked by the line above
953 unsafe {
954 get_component(
955 self.world,
956 component_id,
957 info.storage_type(),
958 self.entity,
959 self.location,
960 )
961 }
962 }
963
964 /// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].
965 /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
966 ///
967 /// **You should prefer to use the typed API [`UnsafeEntityCell::get_mut`] where possible and only
968 /// use this in cases where the actual types are not known at compile time.**
969 ///
970 /// # Safety
971 /// It is the callers responsibility to ensure that
972 /// - the [`UnsafeEntityCell`] has permission to access the component mutably
973 /// - no other references to the component exist at the same time
974 #[inline]
975 pub unsafe fn get_mut_by_id(self, component_id: ComponentId) -> Option<MutUntyped<'w>> {
976 let info = self.world.components().get_info(component_id)?;
977 // SAFETY: entity_location is valid, component_id is valid as checked by the line above
978 unsafe {
979 get_component_and_ticks(
980 self.world,
981 component_id,
982 info.storage_type(),
983 self.entity,
984 self.location,
985 )
986 .map(|(value, cells, _caller)| MutUntyped {
987 // SAFETY: world access validated by caller and ties world lifetime to `MutUntyped` lifetime
988 value: value.assert_unique(),
989 ticks: TicksMut::from_tick_cells(
990 cells,
991 self.world.last_change_tick(),
992 self.world.change_tick(),
993 ),
994 #[cfg(feature = "track_change_detection")]
995 changed_by: _caller.deref_mut(),
996 })
997 }
998 }
999}
1000
1001impl<'w> UnsafeWorldCell<'w> {
1002 #[inline]
1003 /// # Safety
1004 /// - the returned `Table` is only used in ways that this [`UnsafeWorldCell`] has permission for.
1005 /// - the returned `Table` is only used in ways that would not conflict with any existing borrows of world data.
1006 unsafe fn fetch_table(self, location: EntityLocation) -> Option<&'w Table> {
1007 // SAFETY:
1008 // - caller ensures returned data is not misused and we have not created any borrows of component/resource data
1009 // - `location` contains a valid `TableId`, so getting the table won't fail
1010 unsafe { self.storages().tables.get(location.table_id) }
1011 }
1012
1013 #[inline]
1014 /// # Safety
1015 /// - the returned `ComponentSparseSet` is only used in ways that this [`UnsafeWorldCell`] has permission for.
1016 /// - the returned `ComponentSparseSet` is only used in ways that would not conflict with any existing
1017 /// borrows of world data.
1018 unsafe fn fetch_sparse_set(self, component_id: ComponentId) -> Option<&'w ComponentSparseSet> {
1019 // SAFETY: caller ensures returned data is not misused and we have not created any borrows
1020 // of component/resource data
1021 unsafe { self.storages() }.sparse_sets.get(component_id)
1022 }
1023}
1024
1025/// Get an untyped pointer to a particular [`Component`] on a particular [`Entity`] in the provided [`World`].
1026///
1027/// # Safety
1028/// - `location` must refer to an archetype that contains `entity`
1029/// the archetype
1030/// - `component_id` must be valid
1031/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
1032/// - the caller must ensure that no aliasing rules are violated
1033#[inline]
1034#[allow(unsafe_op_in_unsafe_fn)]
1035unsafe fn get_component(
1036 world: UnsafeWorldCell<'_>,
1037 component_id: ComponentId,
1038 storage_type: StorageType,
1039 entity: Entity,
1040 location: EntityLocation,
1041) -> Option<Ptr<'_>> {
1042 // SAFETY: component_id exists and is therefore valid
1043 match storage_type {
1044 StorageType::Table => {
1045 let table = world.fetch_table(location)?;
1046 // SAFETY: archetypes only store valid table_rows and caller ensure aliasing rules
1047 table.get_component(component_id, location.table_row)
1048 }
1049 StorageType::SparseSet => world.fetch_sparse_set(component_id)?.get(entity),
1050 }
1051}
1052
1053/// Get an untyped pointer to a particular [`Component`] and its [`ComponentTicks`]
1054///
1055/// # Safety
1056/// - `location` must refer to an archetype that contains `entity`
1057/// - `component_id` must be valid
1058/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
1059/// - the caller must ensure that no aliasing rules are violated
1060#[inline]
1061#[allow(unsafe_op_in_unsafe_fn)]
1062unsafe fn get_component_and_ticks(
1063 world: UnsafeWorldCell<'_>,
1064 component_id: ComponentId,
1065 storage_type: StorageType,
1066 entity: Entity,
1067 location: EntityLocation,
1068) -> Option<(Ptr<'_>, TickCells<'_>, MaybeUnsafeCellLocation<'_>)> {
1069 match storage_type {
1070 StorageType::Table => {
1071 let table = world.fetch_table(location)?;
1072
1073 // SAFETY: archetypes only store valid table_rows and caller ensure aliasing rules
1074 Some((
1075 table.get_component(component_id, location.table_row)?,
1076 TickCells {
1077 added: table
1078 .get_added_tick(component_id, location.table_row)
1079 .debug_checked_unwrap(),
1080 changed: table
1081 .get_changed_tick(component_id, location.table_row)
1082 .debug_checked_unwrap(),
1083 },
1084 #[cfg(feature = "track_change_detection")]
1085 table
1086 .get_changed_by(component_id, location.table_row)
1087 .debug_checked_unwrap(),
1088 #[cfg(not(feature = "track_change_detection"))]
1089 (),
1090 ))
1091 }
1092 StorageType::SparseSet => world.fetch_sparse_set(component_id)?.get_with_ticks(entity),
1093 }
1094}
1095
1096/// Get an untyped pointer to the [`ComponentTicks`] on a particular [`Entity`]
1097///
1098/// # Safety
1099/// - `location` must refer to an archetype that contains `entity`
1100/// the archetype
1101/// - `component_id` must be valid
1102/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
1103/// - the caller must ensure that no aliasing rules are violated
1104#[inline]
1105#[allow(unsafe_op_in_unsafe_fn)]
1106unsafe fn get_ticks(
1107 world: UnsafeWorldCell<'_>,
1108 component_id: ComponentId,
1109 storage_type: StorageType,
1110 entity: Entity,
1111 location: EntityLocation,
1112) -> Option<ComponentTicks> {
1113 match storage_type {
1114 StorageType::Table => {
1115 let table = world.fetch_table(location)?;
1116 // SAFETY: archetypes only store valid table_rows and caller ensure aliasing rules
1117 table.get_ticks_unchecked(component_id, location.table_row)
1118 }
1119 StorageType::SparseSet => world.fetch_sparse_set(component_id)?.get_ticks(entity),
1120 }
1121}