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