Thanks to visit codestin.com
Credit goes to docs.rs

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