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