bevy_ecs/world/
unsafe_world_cell.rs

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