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