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