bevy_ecs/world/
deferred_world.rs

1use core::ops::Deref;
2
3use bevy_utils::prelude::DebugName;
4
5use crate::{
6    archetype::Archetype,
7    change_detection::{MaybeLocation, MutUntyped},
8    component::{ComponentId, Mutable},
9    entity::Entity,
10    event::{EntityComponentsTrigger, Event, EventKey, Trigger},
11    lifecycle::{HookContext, Insert, Replace, INSERT, REPLACE},
12    message::{Message, MessageId, Messages, WriteBatchIds},
13    observer::TriggerContext,
14    prelude::{Component, QueryState},
15    query::{QueryData, QueryFilter},
16    relationship::RelationshipHookMode,
17    resource::Resource,
18    system::{Commands, Query},
19    world::{error::EntityMutableFetchError, EntityFetcher, WorldEntityFetch},
20};
21
22use super::{unsafe_world_cell::UnsafeWorldCell, Mut, World};
23
24/// A [`World`] reference that disallows structural ECS changes.
25/// This includes initializing resources, registering components or spawning entities.
26///
27/// This means that in order to add entities, for example, you will need to use commands instead of the world directly.
28pub struct DeferredWorld<'w> {
29    // SAFETY: Implementers must not use this reference to make structural changes
30    world: UnsafeWorldCell<'w>,
31}
32
33impl<'w> Deref for DeferredWorld<'w> {
34    type Target = World;
35
36    fn deref(&self) -> &Self::Target {
37        // SAFETY: Structural changes cannot be made through &World
38        unsafe { self.world.world() }
39    }
40}
41
42impl<'w> UnsafeWorldCell<'w> {
43    /// Turn self into a [`DeferredWorld`]
44    ///
45    /// # Safety
46    /// Caller must ensure there are no outstanding mutable references to world and no
47    /// outstanding references to the world's command queue, resource or component data
48    #[inline]
49    pub unsafe fn into_deferred(self) -> DeferredWorld<'w> {
50        DeferredWorld { world: self }
51    }
52}
53
54impl<'w> From<&'w mut World> for DeferredWorld<'w> {
55    fn from(world: &'w mut World) -> DeferredWorld<'w> {
56        DeferredWorld {
57            world: world.as_unsafe_world_cell(),
58        }
59    }
60}
61
62impl<'w> DeferredWorld<'w> {
63    /// Reborrow self as a new instance of [`DeferredWorld`]
64    #[inline]
65    pub fn reborrow(&mut self) -> DeferredWorld<'_> {
66        DeferredWorld { world: self.world }
67    }
68
69    /// Creates a [`Commands`] instance that pushes to the world's command queue
70    #[inline]
71    pub fn commands(&mut self) -> Commands<'_, '_> {
72        // SAFETY: &mut self ensure that there are no outstanding accesses to the queue
73        let command_queue = unsafe { self.world.get_raw_command_queue() };
74        // SAFETY: command_queue is stored on world and always valid while the world exists
75        unsafe { Commands::new_raw_from_entities(command_queue, self.world.entities()) }
76    }
77
78    /// Retrieves a mutable reference to the given `entity`'s [`Component`] of the given type.
79    /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
80    #[inline]
81    pub fn get_mut<T: Component<Mutability = Mutable>>(
82        &mut self,
83        entity: Entity,
84    ) -> Option<Mut<'_, T>> {
85        self.get_entity_mut(entity).ok()?.into_mut()
86    }
87
88    /// Temporarily removes a [`Component`] `T` from the provided [`Entity`] and
89    /// runs the provided closure on it, returning the result if `T` was available.
90    /// This will trigger the `Remove` and `Replace` component hooks without
91    /// causing an archetype move.
92    ///
93    /// This is most useful with immutable components, where removal and reinsertion
94    /// is the only way to modify a value.
95    ///
96    /// If you do not need to ensure the above hooks are triggered, and your component
97    /// is mutable, prefer using [`get_mut`](DeferredWorld::get_mut).
98    #[inline]
99    #[track_caller]
100    pub(crate) fn modify_component_with_relationship_hook_mode<T: Component, R>(
101        &mut self,
102        entity: Entity,
103        relationship_hook_mode: RelationshipHookMode,
104        f: impl FnOnce(&mut T) -> R,
105    ) -> Result<Option<R>, EntityMutableFetchError> {
106        // If the component is not registered, then it doesn't exist on this entity, so no action required.
107        let Some(component_id) = self.component_id::<T>() else {
108            return Ok(None);
109        };
110
111        self.modify_component_by_id_with_relationship_hook_mode(
112            entity,
113            component_id,
114            relationship_hook_mode,
115            move |component| {
116                // SAFETY: component matches the component_id collected in the above line
117                let mut component = unsafe { component.with_type::<T>() };
118
119                f(&mut component)
120            },
121        )
122    }
123
124    /// Temporarily removes a [`Component`] identified by the provided
125    /// [`ComponentId`] from the provided [`Entity`] and runs the provided
126    /// closure on it, returning the result if the component was available.
127    /// This will trigger the `Remove` and `Replace` component hooks without
128    /// causing an archetype move.
129    ///
130    /// This is most useful with immutable components, where removal and reinsertion
131    /// is the only way to modify a value.
132    ///
133    /// If you do not need to ensure the above hooks are triggered, and your component
134    /// is mutable, prefer using [`get_mut_by_id`](DeferredWorld::get_mut_by_id).
135    ///
136    /// You should prefer the typed [`modify_component_with_relationship_hook_mode`](DeferredWorld::modify_component_with_relationship_hook_mode)
137    /// whenever possible.
138    #[inline]
139    #[track_caller]
140    pub(crate) fn modify_component_by_id_with_relationship_hook_mode<R>(
141        &mut self,
142        entity: Entity,
143        component_id: ComponentId,
144        relationship_hook_mode: RelationshipHookMode,
145        f: impl for<'a> FnOnce(MutUntyped<'a>) -> R,
146    ) -> Result<Option<R>, EntityMutableFetchError> {
147        let entity_cell = self.get_entity_mut(entity)?;
148
149        if !entity_cell.contains_id(component_id) {
150            return Ok(None);
151        }
152
153        let archetype = &raw const *entity_cell.archetype();
154
155        // SAFETY:
156        // - DeferredWorld ensures archetype pointer will remain valid as no
157        //   relocations will occur.
158        // - component_id exists on this world and this entity
159        // - REPLACE is able to accept ZST events
160        unsafe {
161            let archetype = &*archetype;
162            self.trigger_on_replace(
163                archetype,
164                entity,
165                [component_id].into_iter(),
166                MaybeLocation::caller(),
167                relationship_hook_mode,
168            );
169            if archetype.has_replace_observer() {
170                // SAFETY: the REPLACE event_key corresponds to the Replace event's type
171                self.trigger_raw(
172                    REPLACE,
173                    &mut Replace { entity },
174                    &mut EntityComponentsTrigger {
175                        components: &[component_id],
176                    },
177                    MaybeLocation::caller(),
178                );
179            }
180        }
181
182        let mut entity_cell = self
183            .get_entity_mut(entity)
184            .expect("entity access confirmed above");
185
186        // SAFETY: we will run the required hooks to simulate removal/replacement.
187        let mut component = unsafe {
188            entity_cell
189                .get_mut_assume_mutable_by_id(component_id)
190                .expect("component access confirmed above")
191        };
192
193        let result = f(component.reborrow());
194
195        // Simulate adding this component by updating the relevant ticks
196        *component.ticks.added = *component.ticks.changed;
197
198        // SAFETY:
199        // - DeferredWorld ensures archetype pointer will remain valid as no
200        //   relocations will occur.
201        // - component_id exists on this world and this entity
202        // - REPLACE is able to accept ZST events
203        unsafe {
204            let archetype = &*archetype;
205            self.trigger_on_insert(
206                archetype,
207                entity,
208                [component_id].into_iter(),
209                MaybeLocation::caller(),
210                relationship_hook_mode,
211            );
212            if archetype.has_insert_observer() {
213                // SAFETY: the INSERT event_key corresponds to the Insert event's type
214                self.trigger_raw(
215                    INSERT,
216                    &mut Insert { entity },
217                    &mut EntityComponentsTrigger {
218                        components: &[component_id],
219                    },
220                    MaybeLocation::caller(),
221                );
222            }
223        }
224
225        Ok(Some(result))
226    }
227
228    /// Returns [`EntityMut`]s that expose read and write operations for the
229    /// given `entities`, returning [`Err`] if any of the given entities do not
230    /// exist. Instead of immediately unwrapping the value returned from this
231    /// function, prefer [`World::entity_mut`].
232    ///
233    /// This function supports fetching a single entity or multiple entities:
234    /// - Pass an [`Entity`] to receive a single [`EntityMut`].
235    /// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
236    /// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
237    /// - Pass an [`&EntityHashSet`] to receive an [`EntityHashMap<EntityMut>`].
238    ///
239    /// **As [`DeferredWorld`] does not allow structural changes, all returned
240    /// references are [`EntityMut`]s, which do not allow structural changes
241    /// (i.e. adding/removing components or despawning the entity).**
242    ///
243    /// # Errors
244    ///
245    /// - Returns [`EntityMutableFetchError::EntityDoesNotExist`] if any of the given `entities` do not exist in the world.
246    ///     - Only the first entity found to be missing will be returned.
247    /// - Returns [`EntityMutableFetchError::AliasedMutability`] if the same entity is requested multiple times.
248    ///
249    /// # Examples
250    ///
251    /// For examples, see [`DeferredWorld::entity_mut`].
252    ///
253    /// [`EntityMut`]: crate::world::EntityMut
254    /// [`&EntityHashSet`]: crate::entity::EntityHashSet
255    /// [`EntityHashMap<EntityMut>`]: crate::entity::EntityHashMap
256    /// [`Vec<EntityMut>`]: alloc::vec::Vec
257    #[inline]
258    pub fn get_entity_mut<F: WorldEntityFetch>(
259        &mut self,
260        entities: F,
261    ) -> Result<F::DeferredMut<'_>, EntityMutableFetchError> {
262        let cell = self.as_unsafe_world_cell();
263        // SAFETY: `&mut self` gives mutable access to the entire world,
264        // and prevents any other access to the world.
265        unsafe { entities.fetch_deferred_mut(cell) }
266    }
267
268    /// Returns [`EntityMut`]s that expose read and write operations for the
269    /// given `entities`. This will panic if any of the given entities do not
270    /// exist. Use [`DeferredWorld::get_entity_mut`] if you want to check for
271    /// entity existence instead of implicitly panicking.
272    ///
273    /// This function supports fetching a single entity or multiple entities:
274    /// - Pass an [`Entity`] to receive a single [`EntityMut`].
275    /// - Pass a slice of [`Entity`]s to receive a [`Vec<EntityMut>`].
276    /// - Pass an array of [`Entity`]s to receive an equally-sized array of [`EntityMut`]s.
277    /// - Pass an [`&EntityHashSet`] to receive an [`EntityHashMap<EntityMut>`].
278    ///
279    /// **As [`DeferredWorld`] does not allow structural changes, all returned
280    /// references are [`EntityMut`]s, which do not allow structural changes
281    /// (i.e. adding/removing components or despawning the entity).**
282    ///
283    /// # Panics
284    ///
285    /// If any of the given `entities` do not exist in the world.
286    ///
287    /// # Examples
288    ///
289    /// ## Single [`Entity`]
290    ///
291    /// ```
292    /// # use bevy_ecs::{prelude::*, world::DeferredWorld};
293    /// #[derive(Component)]
294    /// struct Position {
295    ///   x: f32,
296    ///   y: f32,
297    /// }
298    ///
299    /// # let mut world = World::new();
300    /// # let entity = world.spawn(Position { x: 0.0, y: 0.0 }).id();
301    /// let mut world: DeferredWorld = // ...
302    /// #   DeferredWorld::from(&mut world);
303    ///
304    /// let mut entity_mut = world.entity_mut(entity);
305    /// let mut position = entity_mut.get_mut::<Position>().unwrap();
306    /// position.y = 1.0;
307    /// assert_eq!(position.x, 0.0);
308    /// ```
309    ///
310    /// ## Array of [`Entity`]s
311    ///
312    /// ```
313    /// # use bevy_ecs::{prelude::*, world::DeferredWorld};
314    /// #[derive(Component)]
315    /// struct Position {
316    ///   x: f32,
317    ///   y: f32,
318    /// }
319    ///
320    /// # let mut world = World::new();
321    /// # let e1 = world.spawn(Position { x: 0.0, y: 0.0 }).id();
322    /// # let e2 = world.spawn(Position { x: 1.0, y: 1.0 }).id();
323    /// let mut world: DeferredWorld = // ...
324    /// #   DeferredWorld::from(&mut world);
325    ///
326    /// let [mut e1_ref, mut e2_ref] = world.entity_mut([e1, e2]);
327    /// let mut e1_position = e1_ref.get_mut::<Position>().unwrap();
328    /// e1_position.x = 1.0;
329    /// assert_eq!(e1_position.x, 1.0);
330    /// let mut e2_position = e2_ref.get_mut::<Position>().unwrap();
331    /// e2_position.x = 2.0;
332    /// assert_eq!(e2_position.x, 2.0);
333    /// ```
334    ///
335    /// ## Slice of [`Entity`]s
336    ///
337    /// ```
338    /// # use bevy_ecs::{prelude::*, world::DeferredWorld};
339    /// #[derive(Component)]
340    /// struct Position {
341    ///   x: f32,
342    ///   y: f32,
343    /// }
344    ///
345    /// # let mut world = World::new();
346    /// # let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
347    /// # let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
348    /// # let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
349    /// let mut world: DeferredWorld = // ...
350    /// #   DeferredWorld::from(&mut world);
351    ///
352    /// let ids = vec![e1, e2, e3];
353    /// for mut eref in world.entity_mut(&ids[..]) {
354    ///     let mut pos = eref.get_mut::<Position>().unwrap();
355    ///     pos.y = 2.0;
356    ///     assert_eq!(pos.y, 2.0);
357    /// }
358    /// ```
359    ///
360    /// ## [`&EntityHashSet`]
361    ///
362    /// ```
363    /// # use bevy_ecs::{prelude::*, entity::EntityHashSet, world::DeferredWorld};
364    /// #[derive(Component)]
365    /// struct Position {
366    ///   x: f32,
367    ///   y: f32,
368    /// }
369    ///
370    /// # let mut world = World::new();
371    /// # let e1 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
372    /// # let e2 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
373    /// # let e3 = world.spawn(Position { x: 0.0, y: 1.0 }).id();
374    /// let mut world: DeferredWorld = // ...
375    /// #   DeferredWorld::from(&mut world);
376    ///
377    /// let ids = EntityHashSet::from_iter([e1, e2, e3]);
378    /// for (_id, mut eref) in world.entity_mut(&ids) {
379    ///     let mut pos = eref.get_mut::<Position>().unwrap();
380    ///     pos.y = 2.0;
381    ///     assert_eq!(pos.y, 2.0);
382    /// }
383    /// ```
384    ///
385    /// [`EntityMut`]: crate::world::EntityMut
386    /// [`&EntityHashSet`]: crate::entity::EntityHashSet
387    /// [`EntityHashMap<EntityMut>`]: crate::entity::EntityHashMap
388    /// [`Vec<EntityMut>`]: alloc::vec::Vec
389    #[inline]
390    pub fn entity_mut<F: WorldEntityFetch>(&mut self, entities: F) -> F::DeferredMut<'_> {
391        self.get_entity_mut(entities).unwrap()
392    }
393
394    /// Simultaneously provides access to entity data and a command queue, which
395    /// will be applied when the [`World`] is next flushed.
396    ///
397    /// This allows using borrowed entity data to construct commands where the
398    /// borrow checker would otherwise prevent it.
399    ///
400    /// See [`World::entities_and_commands`] for the non-deferred version.
401    ///
402    /// # Example
403    ///
404    /// ```rust
405    /// # use bevy_ecs::{prelude::*, world::DeferredWorld};
406    /// #[derive(Component)]
407    /// struct Targets(Vec<Entity>);
408    /// #[derive(Component)]
409    /// struct TargetedBy(Entity);
410    ///
411    /// # let mut _world = World::new();
412    /// # let e1 = _world.spawn_empty().id();
413    /// # let e2 = _world.spawn_empty().id();
414    /// # let eid = _world.spawn(Targets(vec![e1, e2])).id();
415    /// let mut world: DeferredWorld = // ...
416    /// #   DeferredWorld::from(&mut _world);
417    /// let (entities, mut commands) = world.entities_and_commands();
418    ///
419    /// let entity = entities.get(eid).unwrap();
420    /// for &target in entity.get::<Targets>().unwrap().0.iter() {
421    ///     commands.entity(target).insert(TargetedBy(eid));
422    /// }
423    /// # _world.flush();
424    /// # assert_eq!(_world.get::<TargetedBy>(e1).unwrap().0, eid);
425    /// # assert_eq!(_world.get::<TargetedBy>(e2).unwrap().0, eid);
426    /// ```
427    pub fn entities_and_commands(&mut self) -> (EntityFetcher<'_>, Commands<'_, '_>) {
428        let cell = self.as_unsafe_world_cell();
429        // SAFETY: `&mut self` gives mutable access to the entire world, and prevents simultaneous access.
430        let fetcher = unsafe { EntityFetcher::new(cell) };
431        // SAFETY:
432        // - `&mut self` gives mutable access to the entire world, and prevents simultaneous access.
433        // - Command queue access does not conflict with entity access.
434        let raw_queue = unsafe { cell.get_raw_command_queue() };
435        // SAFETY: `&mut self` ensures the commands does not outlive the world.
436        let commands = unsafe { Commands::new_raw_from_entities(raw_queue, cell.entities()) };
437
438        (fetcher, commands)
439    }
440
441    /// Returns [`Query`] for the given [`QueryState`], which is used to efficiently
442    /// run queries on the [`World`] by storing and reusing the [`QueryState`].
443    ///
444    /// # Panics
445    /// If state is from a different world then self
446    #[inline]
447    pub fn query<'s, D: QueryData, F: QueryFilter>(
448        &mut self,
449        state: &'s mut QueryState<D, F>,
450    ) -> Query<'_, 's, D, F> {
451        // SAFETY: We have mutable access to the entire world
452        unsafe { state.query_unchecked(self.world) }
453    }
454
455    /// Gets a mutable reference to the resource of the given type
456    ///
457    /// # Panics
458    ///
459    /// Panics if the resource does not exist.
460    /// Use [`get_resource_mut`](DeferredWorld::get_resource_mut) instead if you want to handle this case.
461    #[inline]
462    #[track_caller]
463    pub fn resource_mut<R: Resource>(&mut self) -> Mut<'_, R> {
464        match self.get_resource_mut() {
465            Some(x) => x,
466            None => panic!(
467                "Requested resource {} does not exist in the `World`.
468                Did you forget to add it using `app.insert_resource` / `app.init_resource`?
469                Resources are also implicitly added via `app.add_message`,
470                and can be added by plugins.",
471                DebugName::type_name::<R>()
472            ),
473        }
474    }
475
476    /// Gets a mutable reference to the resource of the given type if it exists
477    #[inline]
478    pub fn get_resource_mut<R: Resource>(&mut self) -> Option<Mut<'_, R>> {
479        // SAFETY: &mut self ensure that there are no outstanding accesses to the resource
480        unsafe { self.world.get_resource_mut() }
481    }
482
483    /// Gets a mutable reference to the non-send resource of the given type, if it exists.
484    ///
485    /// # Panics
486    ///
487    /// Panics if the resource does not exist.
488    /// Use [`get_non_send_resource_mut`](World::get_non_send_resource_mut) instead if you want to handle this case.
489    ///
490    /// This function will panic if it isn't called from the same thread that the resource was inserted from.
491    #[inline]
492    #[track_caller]
493    pub fn non_send_resource_mut<R: 'static>(&mut self) -> Mut<'_, R> {
494        match self.get_non_send_resource_mut() {
495            Some(x) => x,
496            None => panic!(
497                "Requested non-send resource {} does not exist in the `World`.
498                Did you forget to add it using `app.insert_non_send_resource` / `app.init_non_send_resource`?
499                Non-send resources can also be added by plugins.",
500                DebugName::type_name::<R>()
501            ),
502        }
503    }
504
505    /// Gets a mutable reference to the non-send resource of the given type, if it exists.
506    /// Otherwise returns `None`.
507    ///
508    /// # Panics
509    /// This function will panic if it isn't called from the same thread that the resource was inserted from.
510    #[inline]
511    pub fn get_non_send_resource_mut<R: 'static>(&mut self) -> Option<Mut<'_, R>> {
512        // SAFETY: &mut self ensure that there are no outstanding accesses to the resource
513        unsafe { self.world.get_non_send_resource_mut() }
514    }
515
516    /// Writes a [`Message`].
517    /// This method returns the [`MessageId`] of the written `message`,
518    /// or [`None`] if the `message` could not be written.
519    #[inline]
520    pub fn write_message<M: Message>(&mut self, message: M) -> Option<MessageId<M>> {
521        self.write_message_batch(core::iter::once(message))?.next()
522    }
523
524    /// Writes a [`Message`].
525    /// This method returns the [ID](`MessageId`) of the written `event`,
526    /// or [`None`] if the `event` could not be written.
527    #[inline]
528    #[deprecated(since = "0.17.0", note = "Use `DeferredWorld::write_message` instead.")]
529    pub fn send_event<E: Message>(&mut self, event: E) -> Option<MessageId<E>> {
530        self.write_message(event)
531    }
532
533    /// Writes the default value of the [`Message`] of type `E`.
534    /// This method returns the [`MessageId`] of the written `event`,
535    /// or [`None`] if the `event` could not be written.
536    #[inline]
537    pub fn write_message_default<E: Message + Default>(&mut self) -> Option<MessageId<E>> {
538        self.write_message(E::default())
539    }
540
541    /// Writes the default value of the [`Message`] of type `E`.
542    /// This method returns the [ID](`MessageId`) of the written `event`,
543    /// or [`None`] if the `event` could not be written.
544    #[inline]
545    #[deprecated(
546        since = "0.17.0",
547        note = "Use `DeferredWorld::write_message_default` instead."
548    )]
549    pub fn send_event_default<E: Message + Default>(&mut self) -> Option<MessageId<E>> {
550        self.write_message_default::<E>()
551    }
552
553    /// Writes a batch of [`Message`]s from an iterator.
554    /// This method returns the [IDs](`MessageId`) of the written `events`,
555    /// or [`None`] if the `event` could not be written.
556    #[inline]
557    pub fn write_message_batch<E: Message>(
558        &mut self,
559        events: impl IntoIterator<Item = E>,
560    ) -> Option<WriteBatchIds<E>> {
561        let Some(mut events_resource) = self.get_resource_mut::<Messages<E>>() else {
562            log::error!(
563                "Unable to send message `{}`\n\tMessages must be added to the app with `add_message()`\n\thttps://docs.rs/bevy/*/bevy/app/struct.App.html#method.add_message ",
564                DebugName::type_name::<E>()
565            );
566            return None;
567        };
568        Some(events_resource.write_batch(events))
569    }
570
571    /// Writes a batch of [`Message`]s from an iterator.
572    /// This method returns the [IDs](`MessageId`) of the written `events`,
573    /// or [`None`] if the `event` could not be written.
574    #[inline]
575    #[deprecated(
576        since = "0.17.0",
577        note = "Use `DeferredWorld::write_message_batch` instead."
578    )]
579    pub fn send_event_batch<E: Message>(
580        &mut self,
581        events: impl IntoIterator<Item = E>,
582    ) -> Option<WriteBatchIds<E>> {
583        self.write_message_batch(events)
584    }
585
586    /// Gets a pointer to the resource with the id [`ComponentId`] if it exists.
587    /// The returned pointer may be used to modify the resource, as long as the mutable borrow
588    /// of the [`World`] is still valid.
589    ///
590    /// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only
591    /// use this in cases where the actual types are not known at compile time.**
592    #[inline]
593    pub fn get_resource_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
594        // SAFETY: &mut self ensure that there are no outstanding accesses to the resource
595        unsafe { self.world.get_resource_mut_by_id(component_id) }
596    }
597
598    /// Gets a `!Send` resource to the resource with the id [`ComponentId`] if it exists.
599    /// The returned pointer may be used to modify the resource, as long as the mutable borrow
600    /// of the [`World`] is still valid.
601    ///
602    /// **You should prefer to use the typed API [`World::get_resource_mut`] where possible and only
603    /// use this in cases where the actual types are not known at compile time.**
604    ///
605    /// # Panics
606    /// This function will panic if it isn't called from the same thread that the resource was inserted from.
607    #[inline]
608    pub fn get_non_send_mut_by_id(&mut self, component_id: ComponentId) -> Option<MutUntyped<'_>> {
609        // SAFETY: &mut self ensure that there are no outstanding accesses to the resource
610        unsafe { self.world.get_non_send_resource_mut_by_id(component_id) }
611    }
612
613    /// Retrieves a mutable untyped reference to the given `entity`'s [`Component`] of the given [`ComponentId`].
614    /// Returns `None` if the `entity` does not have a [`Component`] of the given type.
615    ///
616    /// **You should prefer to use the typed API [`World::get_mut`] where possible and only
617    /// use this in cases where the actual types are not known at compile time.**
618    #[inline]
619    pub fn get_mut_by_id(
620        &mut self,
621        entity: Entity,
622        component_id: ComponentId,
623    ) -> Option<MutUntyped<'_>> {
624        self.get_entity_mut(entity)
625            .ok()?
626            .into_mut_by_id(component_id)
627            .ok()
628    }
629
630    /// Triggers all `on_add` hooks for [`ComponentId`] in target.
631    ///
632    /// # Safety
633    /// Caller must ensure [`ComponentId`] in target exist in self.
634    #[inline]
635    pub(crate) unsafe fn trigger_on_add(
636        &mut self,
637        archetype: &Archetype,
638        entity: Entity,
639        targets: impl Iterator<Item = ComponentId>,
640        caller: MaybeLocation,
641    ) {
642        if archetype.has_add_hook() {
643            for component_id in targets {
644                // SAFETY: Caller ensures that these components exist
645                let hooks = unsafe { self.components().get_info_unchecked(component_id) }.hooks();
646                if let Some(hook) = hooks.on_add {
647                    hook(
648                        DeferredWorld { world: self.world },
649                        HookContext {
650                            entity,
651                            component_id,
652                            caller,
653                            relationship_hook_mode: RelationshipHookMode::Run,
654                        },
655                    );
656                }
657            }
658        }
659    }
660
661    /// Triggers all `on_insert` hooks for [`ComponentId`] in target.
662    ///
663    /// # Safety
664    /// Caller must ensure [`ComponentId`] in target exist in self.
665    #[inline]
666    pub(crate) unsafe fn trigger_on_insert(
667        &mut self,
668        archetype: &Archetype,
669        entity: Entity,
670        targets: impl Iterator<Item = ComponentId>,
671        caller: MaybeLocation,
672        relationship_hook_mode: RelationshipHookMode,
673    ) {
674        if archetype.has_insert_hook() {
675            for component_id in targets {
676                // SAFETY: Caller ensures that these components exist
677                let hooks = unsafe { self.components().get_info_unchecked(component_id) }.hooks();
678                if let Some(hook) = hooks.on_insert {
679                    hook(
680                        DeferredWorld { world: self.world },
681                        HookContext {
682                            entity,
683                            component_id,
684                            caller,
685                            relationship_hook_mode,
686                        },
687                    );
688                }
689            }
690        }
691    }
692
693    /// Triggers all `on_replace` hooks for [`ComponentId`] in target.
694    ///
695    /// # Safety
696    /// Caller must ensure [`ComponentId`] in target exist in self.
697    #[inline]
698    pub(crate) unsafe fn trigger_on_replace(
699        &mut self,
700        archetype: &Archetype,
701        entity: Entity,
702        targets: impl Iterator<Item = ComponentId>,
703        caller: MaybeLocation,
704        relationship_hook_mode: RelationshipHookMode,
705    ) {
706        if archetype.has_replace_hook() {
707            for component_id in targets {
708                // SAFETY: Caller ensures that these components exist
709                let hooks = unsafe { self.components().get_info_unchecked(component_id) }.hooks();
710                if let Some(hook) = hooks.on_replace {
711                    hook(
712                        DeferredWorld { world: self.world },
713                        HookContext {
714                            entity,
715                            component_id,
716                            caller,
717                            relationship_hook_mode,
718                        },
719                    );
720                }
721            }
722        }
723    }
724
725    /// Triggers all `on_remove` hooks for [`ComponentId`] in target.
726    ///
727    /// # Safety
728    /// Caller must ensure [`ComponentId`] in target exist in self.
729    #[inline]
730    pub(crate) unsafe fn trigger_on_remove(
731        &mut self,
732        archetype: &Archetype,
733        entity: Entity,
734        targets: impl Iterator<Item = ComponentId>,
735        caller: MaybeLocation,
736    ) {
737        if archetype.has_remove_hook() {
738            for component_id in targets {
739                // SAFETY: Caller ensures that these components exist
740                let hooks = unsafe { self.components().get_info_unchecked(component_id) }.hooks();
741                if let Some(hook) = hooks.on_remove {
742                    hook(
743                        DeferredWorld { world: self.world },
744                        HookContext {
745                            entity,
746                            component_id,
747                            caller,
748                            relationship_hook_mode: RelationshipHookMode::Run,
749                        },
750                    );
751                }
752            }
753        }
754    }
755
756    /// Triggers all `on_despawn` hooks for [`ComponentId`] in target.
757    ///
758    /// # Safety
759    /// Caller must ensure [`ComponentId`] in target exist in self.
760    #[inline]
761    pub(crate) unsafe fn trigger_on_despawn(
762        &mut self,
763        archetype: &Archetype,
764        entity: Entity,
765        targets: impl Iterator<Item = ComponentId>,
766        caller: MaybeLocation,
767    ) {
768        if archetype.has_despawn_hook() {
769            for component_id in targets {
770                // SAFETY: Caller ensures that these components exist
771                let hooks = unsafe { self.components().get_info_unchecked(component_id) }.hooks();
772                if let Some(hook) = hooks.on_despawn {
773                    hook(
774                        DeferredWorld { world: self.world },
775                        HookContext {
776                            entity,
777                            component_id,
778                            caller,
779                            relationship_hook_mode: RelationshipHookMode::Run,
780                        },
781                    );
782                }
783            }
784        }
785    }
786
787    /// Triggers all `event` observers for the given `targets`
788    ///
789    /// # Safety
790    /// - Caller must ensure `E` is accessible as the type represented by `event_key`
791    #[inline]
792    pub unsafe fn trigger_raw<'a, E: Event>(
793        &mut self,
794        event_key: EventKey,
795        event: &mut E,
796        trigger: &mut E::Trigger<'a>,
797        caller: MaybeLocation,
798    ) {
799        // SAFETY: You cannot get a mutable reference to `observers` from `DeferredWorld`
800        let (mut world, observers) = unsafe {
801            let world = self.as_unsafe_world_cell();
802            let observers = world.observers();
803            let Some(observers) = observers.try_get_observers(event_key) else {
804                return;
805            };
806            // SAFETY: The only outstanding reference to world is `observers`
807            (world.into_deferred(), observers)
808        };
809        let context = TriggerContext { event_key, caller };
810
811        // SAFETY:
812        // - `observers` comes from `world`, and corresponds to the `event_key`, as it was looked up above
813        // - trigger_context contains the correct event_key for `event`, as enforced by the call to `trigger_raw`
814        // - This method is being called for an `event` whose `Event::Trigger` matches, as the input trigger is E::Trigger.
815        unsafe {
816            trigger.trigger(world.reborrow(), observers, &context, event);
817        }
818    }
819
820    /// Sends a global [`Event`] without any targets.
821    ///
822    /// This will run any [`Observer`] of the given [`Event`] that isn't scoped to specific targets.
823    ///
824    /// [`Observer`]: crate::observer::Observer
825    pub fn trigger<'a>(&mut self, event: impl Event<Trigger<'a>: Default>) {
826        self.commands().trigger(event);
827    }
828
829    /// Gets an [`UnsafeWorldCell`] containing the underlying world.
830    ///
831    /// # Safety
832    /// - must only be used to make non-structural ECS changes
833    #[inline]
834    pub(crate) fn as_unsafe_world_cell(&mut self) -> UnsafeWorldCell<'_> {
835        self.world
836    }
837}