Skip to main content

bevy_ecs/world/
unsafe_world_cell.rs

1//! Contains types that allow disjoint mutable access to a [`World`].
2
3use super::{Mut, Ref, World, WorldId};
4use crate::{
5    archetype::{Archetype, Archetypes},
6    bundle::Bundles,
7    change_detection::{
8        ComponentTickCells, ComponentTicks, ComponentTicksMut, ComponentTicksRef, MaybeLocation,
9        MutUntyped, Tick,
10    },
11    component::{ComponentId, Components, Mutable, StorageType},
12    entity::{
13        ContainsEntity, Entities, Entity, EntityAllocator, EntityLocation, EntityNotSpawnedError,
14    },
15    error::{ErrorHandler, FallbackErrorHandler},
16    lifecycle::RemovedComponentMessages,
17    observer::Observers,
18    prelude::Component,
19    query::{DebugCheckedUnwrap, QueryAccessError, ReleaseStateQueryData, SingleEntityQueryData},
20    resource::{Resource, ResourceEntities},
21    storage::{ComponentSparseSet, Storages, Table},
22    system::Commands,
23};
24use bevy_platform::sync::atomic::Ordering;
25use bevy_ptr::{Ptr, UnsafeCellDeref};
26use core::{any::TypeId, cell::UnsafeCell, fmt::Debug, marker::PhantomData, ptr::NonNull};
27use thiserror::Error;
28
29/// Variant of the [`World`] where resource and component accesses take `&self`, and the responsibility to avoid
30/// aliasing violations are given to the caller instead of being checked at compile-time by rust's unique XOR shared rule.
31///
32/// ### Rationale
33/// In rust, having a `&mut World` means that there are absolutely no other references to the safe world alive at the same time,
34/// without exceptions. Not even unsafe code can change this.
35///
36/// But there are situations where careful shared mutable access through a type is possible and safe. For this, rust provides the [`UnsafeCell`]
37/// escape hatch, which allows you to get a `*mut T` from a `&UnsafeCell<T>` and around which safe abstractions can be built.
38///
39/// 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`].
40/// These methods use lifetimes to check at compile time that no aliasing rules are being broken.
41///
42/// 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
43/// resources and components (and [`ComponentTicks`]) in [`UnsafeCell`]s, and carefully validates disjoint access patterns using
44/// APIs like [`System::initialize`](crate::system::System::initialize).
45///
46/// 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.
47///
48/// ### Example Usage
49///
50/// [`UnsafeWorldCell`] can be used as a building block for writing APIs that safely allow disjoint access into the world.
51/// In the following example, the world is split into a resource access half and a component access half, where each one can
52/// safely hand out mutable references.
53///
54/// ```
55/// use bevy_ecs::world::World;
56/// use bevy_ecs::change_detection::Mut;
57/// use bevy_ecs::resource::Resource;
58/// use bevy_ecs::component::Mutable;
59/// use bevy_ecs::world::unsafe_world_cell::UnsafeWorldCell;
60///
61/// // INVARIANT: existence of this struct means that users of it are the only ones being able to access resources in the world
62/// struct OnlyResourceAccessWorld<'w>(UnsafeWorldCell<'w>);
63/// // INVARIANT: existence of this struct means that users of it are the only ones being able to access components in the world
64/// struct OnlyComponentAccessWorld<'w>(UnsafeWorldCell<'w>);
65///
66/// impl<'w> OnlyResourceAccessWorld<'w> {
67///     fn get_resource_mut<T: Resource<Mutability = Mutable>>(&mut self) -> Option<Mut<'_, T>> {
68///         // SAFETY: resource access is allowed through this UnsafeWorldCell
69///         unsafe { self.0.get_resource_mut::<T>() }
70///     }
71/// }
72/// // impl<'w> OnlyComponentAccessWorld<'w> {
73/// //     ...
74/// // }
75///
76/// // the two `UnsafeWorldCell`s borrow from the `&mut World`, so it cannot be accessed while they are live
77/// fn split_world_access(world: &mut World) -> (OnlyResourceAccessWorld<'_>, OnlyComponentAccessWorld<'_>) {
78///     let unsafe_world_cell = world.as_unsafe_world_cell();
79///     let resource_access = OnlyResourceAccessWorld(unsafe_world_cell);
80///     let component_access = OnlyComponentAccessWorld(unsafe_world_cell);
81///     (resource_access, component_access)
82/// }
83/// ```
84#[derive(Copy, Clone)]
85pub struct UnsafeWorldCell<'w> {
86    ptr: NonNull<World>,
87    #[cfg(debug_assertions)]
88    allows_mutable_access: bool,
89    _marker: PhantomData<(&'w World, &'w UnsafeCell<World>)>,
90}
91
92// SAFETY: `&World` and `&mut World` are both `Send`
93unsafe impl Send for UnsafeWorldCell<'_> {}
94// SAFETY: `&World` and `&mut World` are both `Sync`
95unsafe impl Sync for UnsafeWorldCell<'_> {}
96
97impl<'w> From<&'w mut World> for UnsafeWorldCell<'w> {
98    fn from(value: &'w mut World) -> Self {
99        value.as_unsafe_world_cell()
100    }
101}
102
103impl<'w> From<&'w World> for UnsafeWorldCell<'w> {
104    fn from(value: &'w World) -> Self {
105        value.as_unsafe_world_cell_readonly()
106    }
107}
108
109impl<'w> UnsafeWorldCell<'w> {
110    /// Creates a [`UnsafeWorldCell`] that can be used to access everything immutably
111    #[inline]
112    pub(crate) fn new_readonly(world: &'w World) -> Self {
113        Self {
114            ptr: NonNull::from_ref(world),
115            #[cfg(debug_assertions)]
116            allows_mutable_access: false,
117            _marker: PhantomData,
118        }
119    }
120
121    /// Creates [`UnsafeWorldCell`] that can be used to access everything mutably
122    #[inline]
123    pub(crate) fn new_mutable(world: &'w mut World) -> Self {
124        Self {
125            ptr: NonNull::from_mut(world),
126            #[cfg(debug_assertions)]
127            allows_mutable_access: true,
128            _marker: PhantomData,
129        }
130    }
131
132    /// Creates a pointer from [`UnsafeWorldCell`] that allows mutable access.
133    ///
134    /// This function is safe because to use a raw pointer once must dereference it in an unsafe
135    /// block
136    pub fn as_ptr_mut(self) -> *mut World {
137        #[cfg(debug_assertions)]
138        self.assert_allows_mutable_access();
139        self.ptr.as_ptr()
140    }
141
142    /// Creates a pointer from [`UnsafeWorldCell`] that does not allow mutable access.
143    ///
144    /// This function is safe because to use a raw pointer once must dereference it in an unsafe
145    /// block
146    pub fn as_ptr_ref(self) -> *const World {
147        self.ptr.as_ptr().cast_const()
148    }
149
150    /// Creates [`UnsafeWorldCell`] directly from a raw pointer that can be used to access
151    /// everything mutably
152    /// # Safety
153    /// - `world` must be a pointer obtained from [`UnsafeWorldCell::as_ptr_mut`]
154    ///   within the lifetime of the original [`UnsafeWorldCell`] it was obtained from
155    #[inline]
156    pub unsafe fn new_mutable_from_ptr(world: *mut World) -> Self {
157        Self {
158            // SAFETY: caller ensures that the pointer came from a already valid `UnsafeWorldCell`
159            ptr: unsafe { NonNull::new(world).debug_checked_unwrap() },
160            #[cfg(debug_assertions)]
161            allows_mutable_access: true,
162            _marker: PhantomData,
163        }
164    }
165
166    /// Creates a [`UnsafeWorldCell`] directly from a raw pointer that can be used to access
167    /// everything immutably
168    /// # Safety
169    /// - `world` must be a pointer obtained from [`UnsafeWorldCell::as_ptr_ref`]
170    ///   within the lifetime of the original [`UnsafeWorldCell`] it was obtained from
171    #[inline]
172    pub unsafe fn new_readonly_from_ptr(world: *const World) -> Self {
173        Self {
174            // SAFETY: caller ensures that the pointer came from a already valid `UnsafeWorldCell`
175            ptr: unsafe { NonNull::new(world.cast_mut()).debug_checked_unwrap() },
176            #[cfg(debug_assertions)]
177            allows_mutable_access: false,
178            _marker: PhantomData,
179        }
180    }
181
182    #[cfg_attr(debug_assertions, inline(never), track_caller)]
183    #[cfg_attr(not(debug_assertions), inline(always))]
184    pub(crate) fn assert_allows_mutable_access(self) {
185        // This annotation is needed because the
186        // allows_mutable_access field doesn't exist otherwise.
187        // Kinda weird, since debug_assert would never be called,
188        // but CI complained in https://github.com/bevyengine/bevy/pull/17393
189        #[cfg(debug_assertions)]
190        debug_assert!(
191            self.allows_mutable_access,
192            "mutating world data via `World::as_unsafe_world_cell_readonly` is forbidden"
193        );
194    }
195
196    /// Gets a mutable reference to the [`World`] this [`UnsafeWorldCell`] belongs to.
197    /// This is an incredibly error-prone operation and is only valid in a small number of circumstances.
198    ///
199    /// Calling this method implies mutable access to the *whole* world (see first point on safety section
200    /// below), which includes all entities, components, and resources. Notably, calling this on
201    /// [`WorldQuery::init_fetch`](crate::query::WorldQuery::init_fetch) and
202    /// [`SystemParam::get_param`](crate::system::SystemParam::get_param) are most likely *unsound* unless
203    /// you can prove that the underlying [`World`] is exclusive, which in normal circumstances is not.
204    ///
205    /// # Safety
206    /// - `self` must have been obtained from a call to [`World::as_unsafe_world_cell`]
207    ///   (*not* `as_unsafe_world_cell_readonly` or any other method of construction that
208    ///   does not provide mutable access to the entire world).
209    ///   - This means that if you have an `UnsafeWorldCell` that you didn't create yourself,
210    ///     it is likely *unsound* to call this method.
211    /// - The returned `&mut World` *must* be unique: it must never be allowed to exist
212    ///   at the same time as any other borrows of the world or any accesses to its data.
213    ///   This includes safe ways of accessing world data, such as [`UnsafeWorldCell::archetypes`].
214    ///   - The `&mut World` *may* exist at the same time as instances of `UnsafeWorldCell`,
215    ///     so long as none of those instances are used to access world data in any way
216    ///     while the mutable borrow is active.
217    ///   - When called from within `bevy_ecs`: The `&mut World` *may* exist at the same time as borrows of
218    ///     any data the world holds behind a pointer (e.g. into an archetype), as long as the `&mut World`
219    ///     is never used to dereference that pointer.
220    ///
221    /// [//]: # (This test fails miri.)
222    /// ```no_run
223    /// # use bevy_ecs::prelude::*;
224    /// # #[derive(Component)] struct Player;
225    /// # fn store_but_dont_use<T>(_: T) {}
226    /// # let mut world = World::new();
227    /// // Make an UnsafeWorldCell.
228    /// let world_cell = world.as_unsafe_world_cell();
229    ///
230    /// // SAFETY: `world_cell` was originally created from `&mut World`.
231    /// // We must be sure not to access any world data while `world_mut` is active.
232    /// let world_mut = unsafe { world_cell.world_mut() };
233    ///
234    /// // We can still use `world_cell` so long as we don't access the world with it.
235    /// store_but_dont_use(world_cell);
236    ///
237    /// // !!This is unsound!! Even though this method is safe, we cannot call it until
238    /// // `world_mut` is no longer active.
239    /// let tick = world_cell.change_tick();
240    ///
241    /// // Use mutable access to spawn an entity.
242    /// world_mut.spawn(Player);
243    ///
244    /// // Since we never use `world_mut` after this, the borrow is released
245    /// // and we are once again allowed to access the world using `world_cell`.
246    /// let archetypes = world_cell.archetypes();
247    /// ```
248    #[inline]
249    pub unsafe fn world_mut(mut self) -> &'w mut World {
250        self.assert_allows_mutable_access();
251        // SAFETY:
252        // - caller ensures the created `&mut World` is the only borrow of world
253        unsafe { self.ptr.as_mut() }
254    }
255
256    /// Gets a reference to the [`&World`](World) this [`UnsafeWorldCell`] belongs to.
257    /// This can be used for arbitrary shared/readonly access.
258    ///
259    /// # Safety
260    /// - must have permission to access the whole world immutably
261    /// - there must be no live exclusive borrows of world data
262    /// - there must be no live exclusive borrow of world
263    #[inline]
264    pub unsafe fn world(self) -> &'w World {
265        // SAFETY:
266        // - caller ensures there is no `&mut World` this makes it okay to make a `&World`
267        // - caller ensures there are no mutable borrows of world data, this means the caller cannot
268        //   misuse the returned `&World`
269        unsafe { self.unsafe_world() }
270    }
271
272    /// Gets a reference to the [`World`] this [`UnsafeWorldCell`] belong to.
273    /// This can be used for arbitrary read only access of world metadata
274    ///
275    /// You should attempt to use various safe methods on [`UnsafeWorldCell`] for
276    /// metadata access before using this method.
277    ///
278    /// # Safety
279    /// - must only be used to access world metadata
280    #[inline]
281    pub unsafe fn world_metadata(self) -> &'w World {
282        // SAFETY: caller ensures that returned reference is not used to violate aliasing rules
283        unsafe { self.unsafe_world() }
284    }
285
286    /// Variant on [`UnsafeWorldCell::world`] solely used for implementing this type's methods.
287    /// It allows having an `&World` even with live mutable borrows of components and resources
288    /// so the returned `&World` should not be handed out to safe code and care should be taken
289    /// when working with it.
290    ///
291    /// Deliberately private as the correct way to access data in a [`World`] that may have existing
292    /// mutable borrows of data inside it, is to use [`UnsafeWorldCell`].
293    ///
294    /// # Safety
295    /// - must not be used in a way that would conflict with any
296    ///   live exclusive borrows of world data
297    #[inline]
298    unsafe fn unsafe_world(self) -> &'w World {
299        // SAFETY:
300        // - caller ensures that the returned `&World` is not used in a way that would conflict
301        //   with any existing mutable borrows of world data
302        unsafe { self.ptr.as_ref() }
303    }
304
305    /// Retrieves this world's unique [ID](WorldId).
306    #[inline]
307    pub fn id(self) -> WorldId {
308        // SAFETY:
309        // - we only access world metadata
310        unsafe { self.world_metadata() }.id()
311    }
312
313    /// Retrieves this world's [`Entities`] collection.
314    #[inline]
315    pub fn entities(self) -> &'w Entities {
316        // SAFETY:
317        // - we only access world metadata
318        &unsafe { self.world_metadata() }.entities
319    }
320
321    /// Retrieves this world's [`Entities`] collection.
322    #[inline]
323    pub fn entity_allocator(self) -> &'w EntityAllocator {
324        // SAFETY:
325        // - we only access world metadata
326        &unsafe { self.world_metadata() }.entity_allocator
327    }
328
329    /// Retrieves this world's [`Archetypes`] collection.
330    #[inline]
331    pub fn archetypes(self) -> &'w Archetypes {
332        // SAFETY:
333        // - we only access world metadata
334        &unsafe { self.world_metadata() }.archetypes
335    }
336
337    /// Retrieves this world's [`Components`] collection.
338    #[inline]
339    pub fn components(self) -> &'w Components {
340        // SAFETY:
341        // - we only access world metadata
342        &unsafe { self.world_metadata() }.components
343    }
344
345    /// Retrieves this world's resource-entity map.
346    ///
347    /// # Safety
348    /// The caller must have exclusive read or write access to the resources that are updated in the cache.
349    #[inline]
350    pub unsafe fn resource_entities(self) -> &'w ResourceEntities {
351        // SAFETY:
352        // - we only access world metadata
353        &unsafe { self.world_metadata() }.resource_entities
354    }
355
356    /// Retrieves this world's collection of [removed components](RemovedComponentMessages).
357    pub fn removed_components(self) -> &'w RemovedComponentMessages {
358        // SAFETY:
359        // - we only access world metadata
360        &unsafe { self.world_metadata() }.removed_components
361    }
362
363    /// Retrieves this world's [`Observers`] collection.
364    pub(crate) fn observers(self) -> &'w Observers {
365        // SAFETY:
366        // - we only access world metadata
367        &unsafe { self.world_metadata() }.observers
368    }
369
370    /// Retrieves this world's [`Bundles`] collection.
371    #[inline]
372    pub fn bundles(self) -> &'w Bundles {
373        // SAFETY:
374        // - we only access world metadata
375        &unsafe { self.world_metadata() }.bundles
376    }
377
378    /// Gets the current change tick of this world.
379    #[inline]
380    pub fn change_tick(self) -> Tick {
381        // SAFETY:
382        // - we only access world metadata
383        unsafe { self.world_metadata() }.read_change_tick()
384    }
385
386    /// Returns the id of the last ECS event that was fired.
387    /// Used internally to ensure observers don't trigger multiple times for the same event.
388    #[inline]
389    pub fn last_trigger_id(&self) -> u32 {
390        // SAFETY:
391        // - we only access world metadata
392        unsafe { self.world_metadata() }.last_trigger_id()
393    }
394
395    /// Returns the [`Tick`] indicating the last time that [`World::clear_trackers`] was called.
396    ///
397    /// If this `UnsafeWorldCell` was created from inside of an exclusive system (a [`System`] that
398    /// takes `&mut World` as its first parameter), this will instead return the `Tick` indicating
399    /// the last time the system was run.
400    ///
401    /// See [`World::last_change_tick()`].
402    ///
403    /// [`System`]: crate::system::System
404    #[inline]
405    pub fn last_change_tick(self) -> Tick {
406        // SAFETY:
407        // - we only access world metadata
408        unsafe { self.world_metadata() }.last_change_tick()
409    }
410
411    /// Increments the world's current change tick and returns the old value.
412    #[inline]
413    pub fn increment_change_tick(self) -> Tick {
414        // SAFETY:
415        // - we only access world metadata
416        let change_tick = unsafe { &self.world_metadata().change_tick };
417        // NOTE: We can used a relaxed memory ordering here, since nothing
418        // other than the atomic value itself is relying on atomic synchronization
419        Tick::new(change_tick.fetch_add(1, Ordering::Relaxed))
420    }
421
422    /// Provides unchecked access to the internal data stores of the [`World`].
423    ///
424    /// # Safety
425    ///
426    /// The caller must ensure that this is only used to access world data
427    /// that this [`UnsafeWorldCell`] is allowed to.
428    /// As always, any mutable access to a component must not exist at the same
429    /// time as any other accesses to that same component.
430    #[inline]
431    pub unsafe fn storages(self) -> &'w Storages {
432        // SAFETY: The caller promises to only access world data allowed by this instance.
433        &unsafe { self.unsafe_world() }.storages
434    }
435
436    /// Retrieves an [`UnsafeEntityCell`] that exposes read and write operations for the given `entity`.
437    /// Similar to the [`UnsafeWorldCell`], you are in charge of making sure that no aliasing rules are violated.
438    #[inline]
439    pub fn get_entity(self, entity: Entity) -> Result<UnsafeEntityCell<'w>, EntityNotSpawnedError> {
440        let location = self.entities().get_spawned(entity)?;
441        Ok(UnsafeEntityCell::new(
442            self,
443            entity,
444            location,
445            self.last_change_tick(),
446            self.change_tick(),
447        ))
448    }
449
450    /// Retrieves an [`UnsafeEntityCell`] that exposes read and write operations for the given `entity`.
451    /// Similar to the [`UnsafeWorldCell`], you are in charge of making sure that no aliasing rules are violated.
452    #[inline]
453    pub fn get_entity_with_ticks(
454        self,
455        entity: Entity,
456        last_run: Tick,
457        this_run: Tick,
458    ) -> Result<UnsafeEntityCell<'w>, EntityNotSpawnedError> {
459        let location = self.entities().get_spawned(entity)?;
460        Ok(UnsafeEntityCell::new(
461            self, entity, location, last_run, this_run,
462        ))
463    }
464
465    /// Gets a reference to the resource of the given type if it exists
466    ///
467    /// # Safety
468    /// It is the caller's responsibility to ensure that
469    /// - the [`UnsafeWorldCell`] has permission to access the resource
470    /// - no mutable reference to the resource exists at the same time
471    #[inline]
472    pub unsafe fn get_resource<R: Resource>(self) -> Option<&'w R> {
473        let component_id = self.components().get_valid_id(TypeId::of::<R>())?;
474        // SAFETY: caller ensures `self` has permission to access the resource
475        //  caller also ensure that no mutable reference to the resource exists
476        unsafe {
477            self.get_resource_by_id(component_id)
478                // SAFETY: `component_id` was obtained from the type ID of `R`.
479                .map(|ptr| ptr.deref::<R>())
480        }
481    }
482
483    /// Gets a reference including change detection to the resource of the given type if it exists.
484    ///
485    /// # Safety
486    /// It is the caller's responsibility to ensure that
487    /// - the [`UnsafeWorldCell`] has permission to access the resource
488    /// - no mutable reference to the resource exists at the same time
489    #[inline]
490    pub unsafe fn get_resource_ref<R: Resource>(self) -> Option<Ref<'w, R>> {
491        let component_id = self.components().get_valid_id(TypeId::of::<R>())?;
492
493        // SAFETY: caller ensures `self` has permission to access the resource
494        // caller also ensures that no mutable reference to the resource exists
495        let (ptr, ticks) = unsafe { self.get_resource_with_ticks(component_id)? };
496
497        // SAFETY: `component_id` was obtained from the type ID of `R`
498        let value = unsafe { ptr.deref::<R>() };
499
500        // SAFETY: caller ensures that no mutable reference to the resource exists
501        let ticks = unsafe {
502            ComponentTicksRef::from_tick_cells(ticks, self.last_change_tick(), self.change_tick())
503        };
504
505        Some(Ref { value, ticks })
506    }
507
508    /// Gets a pointer to the resource with the id [`ComponentId`] if it exists.
509    /// The returned pointer must not be used to modify the resource, and must not be
510    /// dereferenced after the borrow of the [`World`] ends.
511    ///
512    /// **You should prefer to use the typed API [`UnsafeWorldCell::get_resource`] where possible and only
513    /// use this in cases where the actual types are not known at compile time.**
514    ///
515    /// # Safety
516    /// It is the caller's responsibility to ensure that
517    /// - the [`UnsafeWorldCell`] has permission to access the resource
518    /// - no mutable reference to the resource exists at the same time
519    #[inline]
520    pub unsafe fn get_resource_by_id(self, component_id: ComponentId) -> Option<Ptr<'w>> {
521        // SAFETY: We have permission to access the resource of `component_id`.
522        let entity = unsafe { self.resource_entities() }.get(component_id)?;
523        let entity_cell = self.get_entity(entity).ok()?;
524        // SAFETY: Exclusive access per preconditions
525        unsafe { entity_cell.get_by_id(component_id) }
526    }
527
528    /// Gets a reference to non-send data of the given type if it exists
529    ///
530    /// # Safety
531    /// It is the caller's responsibility to ensure that
532    /// - the [`UnsafeWorldCell`] has permission to access the data
533    /// - no mutable reference to the data exists at the same time
534    #[inline]
535    pub unsafe fn get_non_send<R: 'static>(self) -> Option<&'w R> {
536        let component_id = self.components().get_valid_id(TypeId::of::<R>())?;
537        // SAFETY: caller ensures that `self` has permission to access `R`
538        //  caller ensures that no mutable reference exists to `R`
539        unsafe {
540            self.get_non_send_by_id(component_id)
541                // SAFETY: `component_id` was obtained from `TypeId::of::<R>()`
542                .map(|ptr| ptr.deref::<R>())
543        }
544    }
545
546    /// Gets a pointer to `!Send` data with the id [`ComponentId`] if it exists.
547    /// The returned pointer must not be used to modify the data, and must not be
548    /// dereferenced after the immutable borrow of the [`World`] ends.
549    ///
550    /// **You should prefer to use the typed API [`UnsafeWorldCell::get_non_send`] where possible and only
551    /// use this in cases where the actual types are not known at compile time.**
552    ///
553    /// # Panics
554    /// This function will panic if it isn't called from the same thread that the data was inserted from.
555    ///
556    /// # Safety
557    /// It is the caller's responsibility to ensure that
558    /// - the [`UnsafeWorldCell`] has permission to access the data
559    /// - no mutable reference to the data exists at the same time
560    #[inline]
561    pub unsafe fn get_non_send_by_id(self, component_id: ComponentId) -> Option<Ptr<'w>> {
562        // SAFETY: we only access data on world that the caller has ensured is unaliased and we have
563        //  permission to access.
564        unsafe { self.storages() }
565            .non_sends
566            .get(component_id)?
567            .get_data()
568    }
569
570    /// Gets a mutable reference to the resource of the given type if it exists
571    ///
572    /// # Safety
573    /// It is the caller's responsibility to ensure that
574    /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
575    /// - no other references to the resource exist at the same time
576    #[inline]
577    pub unsafe fn get_resource_mut<R: Resource<Mutability = Mutable>>(self) -> Option<Mut<'w, R>> {
578        self.assert_allows_mutable_access();
579        let component_id = self.components().get_valid_id(TypeId::of::<R>())?;
580        // SAFETY:
581        // - caller ensures `self` has permission to access the resource mutably
582        // - caller ensures no other references to the resource exist
583        unsafe {
584            self.get_resource_mut_by_id(component_id)
585                // `component_id` was gotten from `TypeId::of::<R>()`
586                .map(|ptr| ptr.with_type::<R>())
587        }
588    }
589
590    /// Gets a pointer to the resource with the id [`ComponentId`] if it exists and is mutable.
591    /// The returned pointer may be used to modify the resource, as long as the mutable borrow
592    /// of the [`UnsafeWorldCell`] is still valid.
593    ///
594    /// **You should prefer to use the typed API [`UnsafeWorldCell::get_resource_mut`] where possible and only
595    /// use this in cases where the actual types are not known at compile time.**
596    ///
597    /// # Safety
598    /// It is the caller's responsibility to ensure that
599    /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
600    /// - no other references to the resource exist at the same time
601    #[inline]
602    pub unsafe fn get_resource_mut_by_id(
603        self,
604        component_id: ComponentId,
605    ) -> Option<MutUntyped<'w>> {
606        self.assert_allows_mutable_access();
607        // SAFETY: We have permission to access the resource of `component_id`.
608        let entity = unsafe { self.resource_entities() }.get(component_id)?;
609        let entity_cell = self.get_entity(entity).ok()?;
610        // SAFETY: Access permissions and uniqueness per preconditions
611        unsafe { entity_cell.get_mut_by_id(component_id).ok() }
612    }
613
614    /// # Safety
615    /// It is the caller's responsibility to ensure that
616    /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
617    /// - no other references to the resource exist at the same time
618    /// - the resource `R` is mutable
619    #[inline]
620    pub unsafe fn get_resource_mut_assume_mutable<R: Resource>(self) -> Option<Mut<'w, R>> {
621        let component_id = self.components().get_valid_id(TypeId::of::<R>())?;
622        // SAFETY:
623        // - caller ensures `self` has permission to access the resource mutably
624        // - caller ensures no other references to the resource exist
625        // - caller ensures the resource is mutable
626        unsafe {
627            self.get_resource_mut_by_id(component_id)
628                // `component_id` was gotten from `TypeId::of::<R>()`
629                .map(|ptr| ptr.with_type::<R>())
630        }
631    }
632
633    /// Gets a mutable reference to the non-send data of the given type if it exists
634    ///
635    /// # Safety
636    /// It is the caller's responsibility to ensure that
637    /// - the [`UnsafeWorldCell`] has permission to access the data mutably
638    /// - no other references to the data exist at the same time
639    #[inline]
640    pub unsafe fn get_non_send_mut<R: 'static>(self) -> Option<Mut<'w, R>> {
641        self.assert_allows_mutable_access();
642        let component_id = self.components().get_valid_id(TypeId::of::<R>())?;
643        // SAFETY:
644        // - caller ensures that `self` has permission to access the data
645        // - caller ensures that the data is unaliased
646        unsafe {
647            self.get_non_send_mut_by_id(component_id)
648                // SAFETY: `component_id` was gotten by `TypeId::of::<R>()`
649                .map(|ptr| ptr.with_type::<R>())
650        }
651    }
652
653    /// Gets mutable access to `!Send` data with the id [`ComponentId`] if it exists.
654    /// The returned pointer may be used to modify the data, as long as the mutable borrow
655    /// of the [`World`] is still valid.
656    ///
657    /// **You should prefer to use the typed API [`UnsafeWorldCell::get_non_send_mut`] where possible and only
658    /// use this in cases where the actual types are not known at compile time.**
659    ///
660    /// # Panics
661    /// This function will panic if it isn't called from the same thread that the data was inserted from.
662    ///
663    /// # Safety
664    /// It is the caller's responsibility to ensure that
665    /// - the [`UnsafeWorldCell`] has permission to access the data mutably
666    /// - no other references to the data exist at the same time
667    #[inline]
668    pub unsafe fn get_non_send_mut_by_id(
669        self,
670        component_id: ComponentId,
671    ) -> Option<MutUntyped<'w>> {
672        self.assert_allows_mutable_access();
673        let change_tick = self.change_tick();
674        // SAFETY: we only access data that the caller has ensured is unaliased and `self`
675        //  has permission to access.
676        let (ptr, ticks) = unsafe { self.storages() }
677            .non_sends
678            .get(component_id)?
679            .get_with_ticks()?;
680
681        let ticks =
682            // SAFETY: This function has exclusive access to the world so nothing aliases `ticks`.
683            // - index is in-bounds because the column is initialized and non-empty
684            // - no other reference to the ticks of the same row can exist at the same time
685            unsafe {
686                ComponentTicksMut::from_tick_cells(ticks, self.last_change_tick(), change_tick)
687            };
688
689        Some(MutUntyped {
690            // SAFETY: This function has exclusive access to the world so nothing aliases `ptr`.
691            value: unsafe { ptr.assert_unique() },
692            ticks,
693        })
694    }
695
696    // Shorthand helper function for getting the data and change ticks for a resource.
697    /// # Safety
698    /// It is the caller's responsibility to ensure that
699    /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
700    /// - no mutable references to the resource exist at the same time
701    #[inline]
702    pub(crate) unsafe fn get_resource_with_ticks(
703        self,
704        component_id: ComponentId,
705    ) -> Option<(Ptr<'w>, ComponentTickCells<'w>)> {
706        // SAFETY: We have permission to access the resource of `component_id`.
707        let entity = unsafe { self.resource_entities() }.get(component_id)?;
708        let storage_type = self.components().get_info(component_id)?.storage_type();
709        let location = self.get_entity(entity).ok()?.location();
710        // SAFETY:
711        // - caller ensures there is no `&mut World`
712        // - caller ensures there are no mutable borrows of this resource
713        // - caller ensures that we have permission to access this resource
714        // - storage_type and location are valid
715        unsafe { get_component_and_ticks(self, component_id, storage_type, entity, location) }
716    }
717
718    // Shorthand helper function for getting the data and change ticks for a resource.
719    /// # Panics
720    /// This function will panic if it isn't called from the same thread that the resource was inserted from.
721    ///
722    /// # Safety
723    /// It is the caller's responsibility to ensure that
724    /// - the [`UnsafeWorldCell`] has permission to access the resource mutably
725    /// - no mutable references to the resource exist at the same time
726    #[inline]
727    pub(crate) unsafe fn get_non_send_with_ticks(
728        self,
729        component_id: ComponentId,
730    ) -> Option<(Ptr<'w>, ComponentTickCells<'w>)> {
731        // SAFETY:
732        // - caller ensures there is no `&mut World`
733        // - caller ensures there are no mutable borrows of this resource
734        // - caller ensures that we have permission to access this resource
735        unsafe { self.storages() }
736            .non_sends
737            .get(component_id)?
738            .get_with_ticks()
739    }
740
741    /// Creates a [`Commands`] instance that pushes to the world's command queue
742    /// # Safety
743    /// It is the caller's responsibility to ensure that
744    /// - the [`UnsafeWorldCell`] has permission to access the queue mutably
745    /// - no references to the queue exist at the same time
746    pub(crate) unsafe fn commands(self) -> Commands<'w, 'w> {
747        self.assert_allows_mutable_access();
748        // SAFETY:
749        // - caller ensures there are no existing references
750        // - caller ensures that we have permission to access the queue
751        let command_queue = unsafe { &mut *(*self.ptr.as_ptr()).command_queue.get() };
752
753        Commands::new_from_entities(command_queue, self.entity_allocator(), self.entities())
754    }
755
756    /// # Safety
757    /// It is the caller's responsibility to ensure that there are no outstanding
758    /// references to `last_trigger_id`.
759    pub(crate) unsafe fn increment_trigger_id(self) {
760        self.assert_allows_mutable_access();
761        // SAFETY: Caller ensure there are no outstanding references
762        unsafe {
763            (*self.ptr.as_ptr()).last_trigger_id =
764                (*self.ptr.as_ptr()).last_trigger_id.wrapping_add(1);
765        }
766    }
767
768    /// Convenience method for accessing the world's fallback error handler,
769    ///
770    /// # Safety
771    /// Must have read access to [`FallbackErrorHandler`].
772    #[inline]
773    pub unsafe fn fallback_error_handler(&self) -> ErrorHandler {
774        // SAFETY: Upheld by caller
775        unsafe { self.get_resource::<FallbackErrorHandler>() }
776            .copied()
777            .unwrap_or_default()
778            .0
779    }
780}
781
782impl Debug for UnsafeWorldCell<'_> {
783    fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
784        // SAFETY: World's Debug implementation only accesses metadata.
785        Debug::fmt(unsafe { self.world_metadata() }, f)
786    }
787}
788
789/// An interior-mutable reference to a particular [`Entity`] and all of its components
790#[derive(Copy, Clone)]
791pub struct UnsafeEntityCell<'w> {
792    world: UnsafeWorldCell<'w>,
793    entity: Entity,
794    location: EntityLocation,
795    last_run: Tick,
796    this_run: Tick,
797}
798
799impl<'w> UnsafeEntityCell<'w> {
800    #[inline]
801    pub(crate) fn new(
802        world: UnsafeWorldCell<'w>,
803        entity: Entity,
804        location: EntityLocation,
805        last_run: Tick,
806        this_run: Tick,
807    ) -> Self {
808        UnsafeEntityCell {
809            world,
810            entity,
811            location,
812            last_run,
813            this_run,
814        }
815    }
816
817    /// Returns the [ID](Entity) of the current entity.
818    #[inline]
819    #[must_use = "Omit the .id() call if you do not need to store the `Entity` identifier."]
820    pub fn id(self) -> Entity {
821        self.entity
822    }
823
824    /// Gets metadata indicating the location where the current entity is stored.
825    #[inline]
826    pub fn location(self) -> EntityLocation {
827        self.location
828    }
829
830    /// Returns the archetype that the current entity belongs to.
831    #[inline]
832    pub fn archetype(self) -> &'w Archetype {
833        &self.world.archetypes()[self.location.archetype_id]
834    }
835
836    /// Gets the world that the current entity belongs to.
837    #[inline]
838    pub fn world(self) -> UnsafeWorldCell<'w> {
839        self.world
840    }
841
842    /// Returns `true` if the current entity has a component of type `T`.
843    /// Otherwise, this returns `false`.
844    ///
845    /// ## Notes
846    ///
847    /// If you do not know the concrete type of a component, consider using
848    /// [`Self::contains_id`] or [`Self::contains_type_id`].
849    #[inline]
850    pub fn contains<T: Component>(self) -> bool {
851        self.contains_type_id(TypeId::of::<T>())
852    }
853
854    /// Returns `true` if the current entity has a component identified by `component_id`.
855    /// Otherwise, this returns false.
856    ///
857    /// ## Notes
858    ///
859    /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
860    /// - If you know the component's [`TypeId`] but not its [`ComponentId`], consider using
861    ///   [`Self::contains_type_id`].
862    #[inline]
863    pub fn contains_id(self, component_id: ComponentId) -> bool {
864        self.archetype().contains(component_id)
865    }
866
867    /// Returns `true` if the current entity has a component with the type identified by `type_id`.
868    /// Otherwise, this returns false.
869    ///
870    /// ## Notes
871    ///
872    /// - If you know the concrete type of the component, you should prefer [`Self::contains`].
873    /// - If you have a [`ComponentId`] instead of a [`TypeId`], consider using [`Self::contains_id`].
874    #[inline]
875    pub fn contains_type_id(self, type_id: TypeId) -> bool {
876        let Some(id) = self.world.components().get_id(type_id) else {
877            return false;
878        };
879        self.contains_id(id)
880    }
881
882    /// # Safety
883    /// It is the caller's responsibility to ensure that
884    /// - the [`UnsafeEntityCell`] has permission to access the component
885    /// - no other mutable references to the component exist at the same time
886    #[inline]
887    pub unsafe fn get<T: Component>(self) -> Option<&'w T> {
888        let component_id = self.world.components().get_valid_id(TypeId::of::<T>())?;
889        // SAFETY:
890        // - `storage_type` is correct (T component_id + T::STORAGE_TYPE)
891        // - `location` is valid
892        // - proper aliasing is promised by caller
893        unsafe {
894            get_component(
895                self.world,
896                component_id,
897                T::STORAGE_TYPE,
898                self.entity,
899                self.location,
900            )
901            // SAFETY: returned component is of type T
902            .map(|value| value.deref::<T>())
903        }
904    }
905
906    /// # Safety
907    /// It is the caller's responsibility to ensure that
908    /// - the [`UnsafeEntityCell`] has permission to access the component
909    /// - no other mutable references to the component exist at the same time
910    #[inline]
911    pub unsafe fn get_ref<T: Component>(self) -> Option<Ref<'w, T>> {
912        let last_change_tick = self.last_run;
913        let change_tick = self.this_run;
914        let component_id = self.world.components().get_valid_id(TypeId::of::<T>())?;
915
916        // SAFETY:
917        // - `storage_type` is correct (T component_id + T::STORAGE_TYPE)
918        // - `location` is valid
919        // - proper aliasing is promised by caller
920        unsafe {
921            get_component_and_ticks(
922                self.world,
923                component_id,
924                T::STORAGE_TYPE,
925                self.entity,
926                self.location,
927            )
928            .map(|(value, cells)| Ref {
929                // SAFETY: returned component is of type T
930                value: value.deref::<T>(),
931                ticks: ComponentTicksRef::from_tick_cells(cells, last_change_tick, change_tick),
932            })
933        }
934    }
935
936    /// Retrieves the change ticks for the given component. This can be useful for implementing change
937    /// detection in custom runtimes.
938    ///
939    /// # Safety
940    /// It is the caller's responsibility to ensure that
941    /// - the [`UnsafeEntityCell`] has permission to access the component
942    /// - no other mutable references to the component exist at the same time
943    #[inline]
944    pub unsafe fn get_change_ticks<T: Component>(self) -> Option<ComponentTicks> {
945        let component_id = self.world.components().get_valid_id(TypeId::of::<T>())?;
946
947        // SAFETY:
948        // - entity location is valid
949        // - proper world access is promised by caller
950        unsafe {
951            get_ticks(
952                self.world,
953                component_id,
954                T::STORAGE_TYPE,
955                self.entity,
956                self.location,
957            )
958        }
959    }
960
961    /// Get the [`MaybeLocation`] from where the given [`Component`] was last changed from.
962    /// This contains information regarding the last place (in code) that changed this component and can be useful for debugging.
963    /// For more information, see [`Location`](https://doc.rust-lang.org/nightly/core/panic/struct.Location.html), and enable the `track_location` feature.
964    ///
965    /// # Safety
966    /// It is the caller's responsibility to ensure that
967    /// - the [`UnsafeEntityCell`] has permission to access the component
968    /// - no other mutable references to the component exist at the same time
969    #[inline]
970    pub unsafe fn get_changed_by<T: Component>(self) -> Option<MaybeLocation> {
971        let component_id = self.world.components().get_valid_id(TypeId::of::<T>())?;
972
973        // SAFETY:
974        // - entity location is valid
975        // - proper world access is promised by caller
976        unsafe {
977            get_changed_by(
978                self.world,
979                component_id,
980                T::STORAGE_TYPE,
981                self.entity,
982                self.location,
983            )
984        }
985    }
986
987    /// Retrieves the change ticks for the given [`ComponentId`]. This can be useful for implementing change
988    /// detection in custom runtimes.
989    ///
990    /// **You should prefer to use the typed API [`UnsafeEntityCell::get_change_ticks`] where possible and only
991    /// use this in cases where the actual component types are not known at
992    /// compile time.**
993    ///
994    /// # Safety
995    /// It is the caller's responsibility to ensure that
996    /// - the [`UnsafeEntityCell`] has permission to access the component
997    /// - no other mutable references to the component exist at the same time
998    #[inline]
999    pub unsafe fn get_change_ticks_by_id(
1000        &self,
1001        component_id: ComponentId,
1002    ) -> Option<ComponentTicks> {
1003        let info = self.world.components().get_info(component_id)?;
1004        // SAFETY:
1005        // - entity location and entity is valid
1006        // - world access is immutable, lifetime tied to `&self`
1007        // - the storage type provided is correct for T
1008        unsafe {
1009            get_ticks(
1010                self.world,
1011                component_id,
1012                info.storage_type(),
1013                self.entity,
1014                self.location,
1015            )
1016        }
1017    }
1018
1019    /// # Safety
1020    /// It is the caller's responsibility to ensure that
1021    /// - the [`UnsafeEntityCell`] has permission to access the component mutably
1022    /// - no other references to the component exist at the same time
1023    #[inline]
1024    pub unsafe fn get_mut<T: Component<Mutability = Mutable>>(self) -> Option<Mut<'w, T>> {
1025        // SAFETY:
1026        // - trait bound `T: Component<Mutability = Mutable>` ensures component is mutable
1027        // - same safety requirements
1028        unsafe { self.get_mut_assume_mutable() }
1029    }
1030
1031    /// # Safety
1032    /// It is the caller's responsibility to ensure that
1033    /// - the [`UnsafeEntityCell`] has permission to access the component mutably
1034    /// - no other references to the component exist at the same time
1035    /// - the component `T` is mutable
1036    #[inline]
1037    pub unsafe fn get_mut_assume_mutable<T: Component>(self) -> Option<Mut<'w, T>> {
1038        // SAFETY: same safety requirements
1039        unsafe { self.get_mut_using_ticks_assume_mutable(self.last_run, self.this_run) }
1040    }
1041
1042    /// # Safety
1043    /// It is the caller's responsibility to ensure that
1044    /// - the [`UnsafeEntityCell`] has permission to access the component mutably
1045    /// - no other references to the component exist at the same time
1046    /// - The component `T` is mutable
1047    #[inline]
1048    pub(crate) unsafe fn get_mut_using_ticks_assume_mutable<T: Component>(
1049        &self,
1050        last_change_tick: Tick,
1051        change_tick: Tick,
1052    ) -> Option<Mut<'w, T>> {
1053        self.world.assert_allows_mutable_access();
1054
1055        let component_id = self.world.components().get_valid_id(TypeId::of::<T>())?;
1056
1057        // SAFETY:
1058        // - `storage_type` is correct
1059        // - `location` is valid
1060        // - aliasing rules are ensured by caller
1061        unsafe {
1062            get_component_and_ticks(
1063                self.world,
1064                component_id,
1065                T::STORAGE_TYPE,
1066                self.entity,
1067                self.location,
1068            )
1069            .map(|(value, cells)| {
1070                Mut {
1071                    // SAFETY: returned component is of type T
1072                    value: value.assert_unique().deref_mut::<T>(),
1073                    ticks: ComponentTicksMut::from_tick_cells(cells, last_change_tick, change_tick),
1074                }
1075            })
1076        }
1077    }
1078
1079    /// Returns read-only components for the current entity that match the query `Q`,
1080    /// or `None` if the entity does not have the components required by the query `Q`.
1081    ///
1082    /// # Safety
1083    /// It is the caller's responsibility to ensure that
1084    /// - the [`UnsafeEntityCell`] has permission to access the queried data immutably
1085    /// - no mutable references to the queried data exist at the same time
1086    /// - The `QueryData` does not provide aliasing mutable references to the same component.
1087    pub(crate) unsafe fn get_components<Q: ReleaseStateQueryData + SingleEntityQueryData>(
1088        &self,
1089    ) -> Result<Q::Item<'w, 'static>, QueryAccessError> {
1090        // SAFETY: World is only used to access query data and initialize query state
1091        let state = unsafe {
1092            let world = self.world().world();
1093            Q::get_state(world.components()).ok_or(QueryAccessError::ComponentNotRegistered)?
1094        };
1095        let location = self.location();
1096        // SAFETY: Location is guaranteed to exist
1097        let archetype = unsafe {
1098            self.world
1099                .archetypes()
1100                .get(location.archetype_id)
1101                .debug_checked_unwrap()
1102        };
1103        if Q::matches_component_set(&state, &|id| archetype.contains(id)) {
1104            // SAFETY: state was initialized above using the world passed into this function
1105            let mut fetch =
1106                unsafe { Q::init_fetch(self.world, &state, self.last_run, self.this_run) };
1107            // SAFETY: Table is guaranteed to exist
1108            let table = unsafe {
1109                self.world
1110                    .storages()
1111                    .tables
1112                    .get(location.table_id)
1113                    .debug_checked_unwrap()
1114            };
1115            // SAFETY: Archetype and table are from the same world used to initialize state and fetch.
1116            // Table corresponds to archetype. State is the same state used to init fetch above.
1117            unsafe { Q::set_archetype(&mut fetch, &state, archetype, table) }
1118            // SAFETY: Called after set_archetype above. Entity and location are guaranteed to exist.
1119            let item = unsafe { Q::fetch(&state, &mut fetch, self.id(), location.table_row) };
1120            item.map(Q::release_state)
1121                .ok_or(QueryAccessError::EntityDoesNotMatch)
1122        } else {
1123            Err(QueryAccessError::EntityDoesNotMatch)
1124        }
1125    }
1126
1127    /// Gets the component of the given [`ComponentId`] from the entity.
1128    ///
1129    /// **You should prefer to use the typed API where possible and only
1130    /// use this in cases where the actual component types are not known at
1131    /// compile time.**
1132    ///
1133    /// Unlike [`UnsafeEntityCell::get`], this returns a raw pointer to the component,
1134    /// which is only valid while the `'w` borrow of the lifetime is active.
1135    ///
1136    /// # Safety
1137    /// It is the caller's responsibility to ensure that
1138    /// - the [`UnsafeEntityCell`] has permission to access the component
1139    /// - no other mutable references to the component exist at the same time
1140    #[inline]
1141    pub unsafe fn get_by_id(self, component_id: ComponentId) -> Option<Ptr<'w>> {
1142        let info = self.world.components().get_info(component_id)?;
1143        // SAFETY: entity_location is valid, component_id is valid as checked by the line above
1144        unsafe {
1145            get_component(
1146                self.world,
1147                component_id,
1148                info.storage_type(),
1149                self.entity,
1150                self.location,
1151            )
1152        }
1153    }
1154
1155    /// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].
1156    /// Returns `None` if the `entity` does not have a [`Component`] of the given type,
1157    /// or if the component is immutable.
1158    ///
1159    /// **You should prefer to use the typed API [`UnsafeEntityCell::get_mut`] where possible and only
1160    /// use this in cases where the actual types are not known at compile time.**
1161    ///
1162    /// # Safety
1163    /// It is the caller's responsibility to ensure that
1164    /// - the [`UnsafeEntityCell`] has permission to access the component mutably
1165    /// - no other references to the component exist at the same time
1166    #[inline]
1167    pub unsafe fn get_mut_by_id(
1168        self,
1169        component_id: ComponentId,
1170    ) -> Result<MutUntyped<'w>, GetEntityMutByIdError> {
1171        self.world.assert_allows_mutable_access();
1172
1173        let info = self
1174            .world
1175            .components()
1176            .get_info(component_id)
1177            .ok_or(GetEntityMutByIdError::InfoNotFound)?;
1178
1179        // If a component is immutable then a mutable reference to it doesn't exist
1180        if !info.mutable() {
1181            return Err(GetEntityMutByIdError::ComponentIsImmutable);
1182        }
1183
1184        // SAFETY: entity_location is valid, component_id is valid as checked by the line above
1185        unsafe {
1186            get_component_and_ticks(
1187                self.world,
1188                component_id,
1189                info.storage_type(),
1190                self.entity,
1191                self.location,
1192            )
1193            .map(|(value, cells)| {
1194                MutUntyped {
1195                    // SAFETY: world access validated by caller and ties world lifetime to `MutUntyped` lifetime
1196                    value: value.assert_unique(),
1197                    ticks: ComponentTicksMut::from_tick_cells(cells, self.last_run, self.this_run),
1198                }
1199            })
1200            .ok_or(GetEntityMutByIdError::ComponentNotFound)
1201        }
1202    }
1203
1204    /// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].
1205    /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
1206    /// This method assumes the [`Component`] is mutable, skipping that check.
1207    ///
1208    /// **You should prefer to use the typed API [`UnsafeEntityCell::get_mut_assume_mutable`] where possible and only
1209    /// use this in cases where the actual types are not known at compile time.**
1210    ///
1211    /// # Safety
1212    /// It is the caller's responsibility to ensure that
1213    /// - the [`UnsafeEntityCell`] has permission to access the component mutably
1214    /// - no other references to the component exist at the same time
1215    /// - the component `T` is mutable
1216    #[inline]
1217    pub unsafe fn get_mut_assume_mutable_by_id(
1218        self,
1219        component_id: ComponentId,
1220    ) -> Result<MutUntyped<'w>, GetEntityMutByIdError> {
1221        self.world.assert_allows_mutable_access();
1222
1223        let info = self
1224            .world
1225            .components()
1226            .get_info(component_id)
1227            .ok_or(GetEntityMutByIdError::InfoNotFound)?;
1228
1229        // SAFETY: entity_location is valid, component_id is valid as checked by the line above
1230        unsafe {
1231            get_component_and_ticks(
1232                self.world,
1233                component_id,
1234                info.storage_type(),
1235                self.entity,
1236                self.location,
1237            )
1238            .map(|(value, cells)| {
1239                MutUntyped {
1240                    // SAFETY: world access validated by caller and ties world lifetime to `MutUntyped` lifetime
1241                    value: value.assert_unique(),
1242                    ticks: ComponentTicksMut::from_tick_cells(cells, self.last_run, self.this_run),
1243                }
1244            })
1245            .ok_or(GetEntityMutByIdError::ComponentNotFound)
1246        }
1247    }
1248
1249    /// Returns the source code location from which this entity has been spawned.
1250    pub fn spawned_by(self) -> MaybeLocation {
1251        self.world()
1252            .entities()
1253            .entity_get_spawned_or_despawned_by(self.entity)
1254            .map(|o| o.unwrap())
1255    }
1256
1257    /// Returns the [`Tick`] at which this entity has been spawned.
1258    pub fn spawn_tick(self) -> Tick {
1259        // SAFETY: UnsafeEntityCell is only constructed for living entities and offers no despawn method
1260        unsafe {
1261            self.world()
1262                .entities()
1263                .entity_get_spawned_or_despawned_unchecked(self.entity)
1264                .1
1265        }
1266    }
1267}
1268
1269/// Error that may be returned when calling [`UnsafeEntityCell::get_mut_by_id`].
1270#[derive(Debug, Clone, Copy, PartialEq, Eq, Error)]
1271pub enum GetEntityMutByIdError {
1272    /// The [`ComponentInfo`](crate::component::ComponentInfo) could not be found.
1273    #[error("the `ComponentInfo` could not be found")]
1274    InfoNotFound,
1275    /// The [`Component`] is immutable. Creating a mutable reference violates its
1276    /// invariants.
1277    #[error("the `Component` is immutable")]
1278    ComponentIsImmutable,
1279    /// This [`Entity`] does not have the desired [`Component`].
1280    #[error("the `Component` could not be found")]
1281    ComponentNotFound,
1282}
1283
1284impl<'w> UnsafeWorldCell<'w> {
1285    #[inline]
1286    /// # Safety
1287    /// - the returned `Table` is only used in ways that this [`UnsafeWorldCell`] has permission for.
1288    /// - the returned `Table` is only used in ways that would not conflict with any existing borrows of world data.
1289    unsafe fn fetch_table(self, location: EntityLocation) -> Option<&'w Table> {
1290        // SAFETY:
1291        // - caller ensures returned data is not misused and we have not created any borrows of component/resource data
1292        // - `location` contains a valid `TableId`, so getting the table won't fail
1293        unsafe { self.storages().tables.get(location.table_id) }
1294    }
1295
1296    #[inline]
1297    /// # Safety
1298    /// - the returned `ComponentSparseSet` is only used in ways that this [`UnsafeWorldCell`] has permission for.
1299    /// - the returned `ComponentSparseSet` is only used in ways that would not conflict with any existing
1300    ///   borrows of world data.
1301    unsafe fn fetch_sparse_set(self, component_id: ComponentId) -> Option<&'w ComponentSparseSet> {
1302        // SAFETY: caller ensures returned data is not misused and we have not created any borrows
1303        // of component/resource data
1304        unsafe { self.storages() }.sparse_sets.get(component_id)
1305    }
1306}
1307
1308/// Get an untyped pointer to a particular [`Component`] on a particular [`Entity`] in the provided [`World`].
1309///
1310/// # Safety
1311/// - `location` must refer to an archetype that contains `entity`
1312///   the archetype
1313/// - `component_id` must be valid
1314/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
1315/// - the caller must ensure that no aliasing rules are violated
1316#[inline]
1317unsafe fn get_component(
1318    world: UnsafeWorldCell<'_>,
1319    component_id: ComponentId,
1320    storage_type: StorageType,
1321    entity: Entity,
1322    location: EntityLocation,
1323) -> Option<Ptr<'_>> {
1324    // SAFETY:
1325    // - caller ensure aliasing rules
1326    // - archetypes only store valid table_rows
1327    unsafe {
1328        match storage_type {
1329            StorageType::Table => world
1330                .fetch_table(location)?
1331                .get_component(component_id, location.table_row),
1332            StorageType::SparseSet => world.fetch_sparse_set(component_id)?.get(entity),
1333        }
1334    }
1335}
1336
1337/// Get an untyped pointer to a particular [`Component`] and its [`ComponentTicks`]
1338///
1339/// # Safety
1340/// - `location` must refer to an archetype that contains `entity`
1341/// - `component_id` must be valid
1342/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
1343/// - the caller must ensure that no aliasing rules are violated
1344#[inline]
1345unsafe fn get_component_and_ticks(
1346    world: UnsafeWorldCell<'_>,
1347    component_id: ComponentId,
1348    storage_type: StorageType,
1349    entity: Entity,
1350    location: EntityLocation,
1351) -> Option<(Ptr<'_>, ComponentTickCells<'_>)> {
1352    match storage_type {
1353        StorageType::Table => {
1354            // SAFETY: caller upholds aliasing rules
1355            let table = unsafe { world.fetch_table(location)? };
1356
1357            // SAFETY: archetypes only store valid table_rows and caller ensure aliasing rules
1358            Some(unsafe {
1359                (
1360                    table.get_component(component_id, location.table_row)?,
1361                    ComponentTickCells {
1362                        added: table
1363                            .get_added_tick(component_id, location.table_row)
1364                            .debug_checked_unwrap(),
1365                        changed: table
1366                            .get_changed_tick(component_id, location.table_row)
1367                            .debug_checked_unwrap(),
1368                        changed_by: table
1369                            .get_changed_by(component_id, location.table_row)
1370                            .map(|changed_by| changed_by.debug_checked_unwrap()),
1371                        summary_tick: table.get_summary_tick(component_id),
1372                    },
1373                )
1374            })
1375        }
1376        StorageType::SparseSet => {
1377            // SAFETY: caller upholds aliasing rules
1378            unsafe { world.fetch_sparse_set(component_id) }?.get_with_ticks(entity)
1379        }
1380    }
1381}
1382
1383/// Get the [`ComponentTicks`] on a particular [`Entity`]
1384///
1385/// # Safety
1386/// - `location` must refer to an archetype that contains `entity`
1387///   the archetype
1388/// - `component_id` must be valid
1389/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
1390/// - the caller must ensure that no aliasing rules are violated
1391#[inline]
1392unsafe fn get_ticks(
1393    world: UnsafeWorldCell<'_>,
1394    component_id: ComponentId,
1395    storage_type: StorageType,
1396    entity: Entity,
1397    location: EntityLocation,
1398) -> Option<ComponentTicks> {
1399    // SAFETY:
1400    // - caller ensure aliasing rules
1401    // - archetypes only store valid table_rows
1402    unsafe {
1403        match storage_type {
1404            StorageType::Table => {
1405                let table = world.fetch_table(location)?;
1406                table.get_ticks_unchecked(component_id, location.table_row)
1407            }
1408            StorageType::SparseSet => world.fetch_sparse_set(component_id)?.get_ticks(entity),
1409        }
1410    }
1411}
1412
1413/// Get the [`MaybeLocation`] for a [`Component`] on a particular [`Entity`].
1414/// This contains information regarding the last place (in code) that changed this component and can be useful for debugging.
1415///
1416/// # Safety
1417/// - `location` must refer to an archetype that contains `entity`
1418///   the archetype
1419/// - `component_id` must be valid
1420/// - `storage_type` must accurately reflect where the components for `component_id` are stored.
1421/// - the caller must ensure that no aliasing rules are violated
1422#[inline]
1423unsafe fn get_changed_by(
1424    world: UnsafeWorldCell<'_>,
1425    component_id: ComponentId,
1426    storage_type: StorageType,
1427    entity: Entity,
1428    location: EntityLocation,
1429) -> Option<MaybeLocation> {
1430    // SAFETY:
1431    // - caller ensure aliasing rules
1432    // - archetypes only store valid table_rows
1433    let caller = unsafe {
1434        match storage_type {
1435            StorageType::Table => world
1436                .fetch_table(location)?
1437                .get_changed_by(component_id, location.table_row),
1438            StorageType::SparseSet => world.fetch_sparse_set(component_id)?.get_changed_by(entity),
1439        }
1440    };
1441    Some(
1442        caller
1443            .transpose()?
1444            // SAFETY: Caller ensures there are no mutable aliases
1445            .map(|changed_by| unsafe { *changed_by.deref() }),
1446    )
1447}
1448
1449impl ContainsEntity for UnsafeEntityCell<'_> {
1450    fn entity(&self) -> Entity {
1451        self.id()
1452    }
1453}
1454
1455#[cfg(test)]
1456mod tests {
1457    use super::*;
1458
1459    #[test]
1460    #[should_panic = "is forbidden"]
1461    fn as_unsafe_world_cell_readonly_world_mut_forbidden() {
1462        let world = World::new();
1463        let world_cell = world.as_unsafe_world_cell_readonly();
1464        // SAFETY: this invalid usage will be caught by a runtime panic.
1465        let _ = unsafe { world_cell.world_mut() };
1466    }
1467
1468    #[derive(Resource)]
1469    struct R;
1470
1471    #[test]
1472    #[should_panic = "is forbidden"]
1473    fn as_unsafe_world_cell_readonly_resource_mut_forbidden() {
1474        let mut world = World::new();
1475        world.insert_resource(R);
1476        let world_cell = world.as_unsafe_world_cell_readonly();
1477        // SAFETY: this invalid usage will be caught by a runtime panic.
1478        let _ = unsafe { world_cell.get_resource_mut::<R>() };
1479    }
1480
1481    #[derive(Component)]
1482    struct C;
1483
1484    #[test]
1485    #[should_panic = "is forbidden"]
1486    fn as_unsafe_world_cell_readonly_component_mut_forbidden() {
1487        let mut world = World::new();
1488        let entity = world.spawn(C).id();
1489        let world_cell = world.as_unsafe_world_cell_readonly();
1490        let entity_cell = world_cell.get_entity(entity).unwrap();
1491        // SAFETY: this invalid usage will be caught by a runtime panic.
1492        let _ = unsafe { entity_cell.get_mut::<C>() };
1493    }
1494}