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