Skip to main content

bevy_ecs/world/
unsafe_world_cell.rs

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