Skip to main content

bevy_ecs/relationship/
mod.rs

1//! This module provides functionality to link entities to each other using specialized components called "relationships". See the [`Relationship`] trait for more info.
2
3mod related_methods;
4mod relationship_query;
5mod relationship_source_collection;
6
7use alloc::boxed::Box;
8use bevy_platform::sync::Arc;
9use bevy_ptr::Ptr;
10use core::{any::TypeId, marker::PhantomData};
11
12use alloc::format;
13
14use bevy_utils::prelude::DebugName;
15pub use related_methods::*;
16pub use relationship_query::*;
17pub use relationship_source_collection::*;
18
19use crate::{
20    component::{Component, ComponentCloneBehavior, ComponentId, Components, Mutable},
21    entity::{ComponentCloneCtx, Entity},
22    lifecycle::HookContext,
23    system::EntityCommand,
24    world::{DeferredWorld, EntityWorldMut},
25};
26use log::warn;
27
28/// A [`Component`] on a "source" [`Entity`] that references another target [`Entity`], creating a "relationship" between them. Every [`Relationship`]
29/// has a corresponding [`RelationshipTarget`] type (and vice-versa), which exists on the "target" entity of a relationship and contains the list of all
30/// "source" entities that relate to the given "target".
31///
32/// A [`Relationship`] may only be one-to-many (or one-to-one): an [`Entity`] may point to at most one [`Entity`] through the [`Relationship`] component.
33///
34/// The [`Relationship`] component is the "source of truth" and the [`RelationshipTarget`] component reflects that source of truth. When a [`Relationship`]
35/// component is inserted on an [`Entity`], the corresponding [`RelationshipTarget`] component is immediately inserted on the target component if it does
36/// not already exist, and the "source" entity is automatically added to the [`RelationshipTarget`] collection (this is done via "component hooks").
37///
38/// A common example of a [`Relationship`] is the parent / child relationship. Bevy ECS includes a canonical form of this via the [`ChildOf`](crate::hierarchy::ChildOf)
39/// [`Relationship`] and the [`Children`](crate::hierarchy::Children) [`RelationshipTarget`].
40///
41/// [`Relationship`] and [`RelationshipTarget`] should always be derived via the [`Component`] trait to ensure the hooks are set up properly.
42///
43/// ## Derive
44///
45/// [`Relationship`] and [`RelationshipTarget`] can only be derived for structs with a single unnamed field, single named field
46/// or for named structs where one field is annotated with `#[relationship]`.
47/// If there are additional fields, they must all implement [`Default`].
48///
49/// [`RelationshipTarget`] also requires that the relationship field is private to prevent direct mutation,
50/// ensuring the correctness of relationships.
51/// ```
52/// # use bevy_ecs::component::Component;
53/// # use bevy_ecs::entity::Entity;
54/// #[derive(Component)]
55/// #[relationship(relationship_target = Children)]
56/// pub struct ChildOf {
57///     #[relationship]
58///     pub parent: Entity,
59///     internal: u8,
60/// };
61///
62/// #[derive(Component)]
63/// #[relationship_target(relationship = ChildOf)]
64/// pub struct Children(Vec<Entity>);
65/// ```
66///
67/// A one-to-one relationship can be created by putting a single [`Entity`] in the [`RelationshipTarget`]'s field.
68/// In that case, if another entity is added to the relationship, the original entity is removed.
69///
70/// ```
71/// # use bevy_ecs::component::Component;
72/// # use bevy_ecs::entity::Entity;
73/// #[derive(Component)]
74/// #[relationship(relationship_target = View)]
75/// pub struct ViewOf(pub Entity);
76///
77/// #[derive(Component)]
78/// #[relationship_target(relationship = ViewOf)]
79/// pub struct View(Entity);
80/// ```
81///
82/// When deriving [`RelationshipTarget`] you can specify the `#[relationship_target(linked_spawn)]` attribute to
83/// automatically despawn entities stored in an entity's [`RelationshipTarget`] when that entity is despawned:
84///
85/// ```
86/// # use bevy_ecs::component::Component;
87/// # use bevy_ecs::entity::Entity;
88/// #[derive(Component)]
89/// #[relationship(relationship_target = Children)]
90/// pub struct ChildOf(pub Entity);
91///
92/// #[derive(Component)]
93/// #[relationship_target(relationship = ChildOf, linked_spawn)]
94/// pub struct Children(Vec<Entity>);
95/// ```
96///
97/// By default, relationships cannot point to their own entity. If you want to allow self-referential
98/// relationships, you can use the `allow_self_referential` attribute:
99///
100/// ```
101/// # use bevy_ecs::component::Component;
102/// # use bevy_ecs::entity::Entity;
103/// #[derive(Component)]
104/// #[relationship(relationship_target = PeopleILike, allow_self_referential)]
105/// pub struct LikedBy(pub Entity);
106///
107/// #[derive(Component)]
108/// #[relationship_target(relationship = LikedBy)]
109/// pub struct PeopleILike(Vec<Entity>);
110/// ```
111pub trait Relationship: Component + Sized {
112    /// The [`Component`] added to the "target" entities of this [`Relationship`], which contains the list of all "source"
113    /// entities that relate to the "target".
114    type RelationshipTarget: RelationshipTarget<Relationship = Self>;
115
116    /// If `true`, a relationship is allowed to point to its own entity.
117    ///
118    /// Set this to `true` when self-relationships are semantically valid for your use case,
119    /// such as `Likes(self)`, `EmployedBy(self)`, or a `ColliderOf` relationship where
120    /// a collider can be attached to its own entity.
121    ///
122    /// # Warning
123    ///
124    /// When `ALLOW_SELF` is `true`, be careful when using recursive traversal methods
125    /// like `iter_ancestors` or `root_ancestor`, as they will loop infinitely if an entity
126    /// points to itself.
127    const ALLOW_SELF_REFERENTIAL: bool = false;
128
129    /// Gets the [`Entity`] ID of the related entity.
130    fn get(&self) -> Entity;
131
132    /// Creates this [`Relationship`] from the given `entity`.
133    fn from(entity: Entity) -> Self;
134
135    /// Changes the current [`Entity`] ID of the entity containing the [`RelationshipTarget`] to another one.
136    ///
137    /// This is useful for updating the relationship without overwriting other fields stored in `Self`.
138    ///
139    /// # Warning
140    ///
141    /// This should generally not be called by user code, as modifying the related entity could invalidate the
142    /// relationship. If this method is used, then the hooks [`on_discard`](Relationship::on_discard) have to
143    /// run before and [`on_insert`](Relationship::on_insert) after it.
144    /// This happens automatically when this method is called with [`EntityWorldMut::modify_component`].
145    ///
146    /// Prefer to use regular means of insertions when possible.
147    fn set_risky(&mut self, entity: Entity);
148
149    /// The `on_insert` component hook that maintains the [`Relationship`] / [`RelationshipTarget`] connection.
150    fn on_insert(
151        mut world: DeferredWorld,
152        HookContext {
153            entity,
154            caller,
155            relationship_hook_mode,
156            ..
157        }: HookContext,
158    ) {
159        match relationship_hook_mode {
160            RelationshipHookMode::Run => {}
161            RelationshipHookMode::Skip => return,
162            RelationshipHookMode::RunIfNotLinked => {
163                if <Self::RelationshipTarget as RelationshipTarget>::LINKED_SPAWN {
164                    return;
165                }
166            }
167        }
168        let target_entity = world.entity(entity).get::<Self>().unwrap().get();
169        if !Self::ALLOW_SELF_REFERENTIAL && target_entity == entity {
170            warn!(
171                "{}The {}({target_entity:?}) relationship on entity {entity:?} points to itself. The invalid {} relationship has been removed.\nIf this is intended behavior self-referential relations can be enabled with the allow_self_referential attribute: #[relationship(allow_self_referential)]",
172                caller.map(|location|format!("{location}: ")).unwrap_or_default(),
173                DebugName::type_name::<Self>(),
174                DebugName::type_name::<Self>()
175            );
176            world.commands().entity(entity).remove::<Self>();
177            return;
178        }
179        // For one-to-one relationships, remove existing relationship before adding new one
180        let current_source_to_remove = world
181            .get_entity(target_entity)
182            .ok()
183            .and_then(|target_entity_ref| target_entity_ref.get::<Self::RelationshipTarget>())
184            .and_then(|relationship_target| {
185                relationship_target
186                    .collection()
187                    .source_to_remove_before_add()
188            });
189
190        if let Some(current_source) = current_source_to_remove {
191            world.commands().entity(current_source).try_remove::<Self>();
192        }
193
194        if let Ok(mut entity_commands) = world.commands().get_entity(target_entity) {
195            // Deferring is necessary for batch mode
196            entity_commands
197                .entry::<Self::RelationshipTarget>()
198                .and_modify(move |mut relationship_target| {
199                    relationship_target.collection_mut_risky().add(entity);
200                })
201                .or_insert_with(move || {
202                    let mut target = Self::RelationshipTarget::with_capacity(1);
203                    target.collection_mut_risky().add(entity);
204                    target
205                });
206        } else {
207            warn!(
208                "{}The {}({target_entity:?}) relationship on entity {entity:?} relates to an entity that does not exist. The invalid {} relationship has been removed.",
209                caller.map(|location|format!("{location}: ")).unwrap_or_default(),
210                DebugName::type_name::<Self>(),
211                DebugName::type_name::<Self>()
212            );
213            world.commands().entity(entity).remove::<Self>();
214        }
215    }
216
217    /// The `on_discard` component hook that maintains the [`Relationship`] / [`RelationshipTarget`] connection.
218    // note: think of this as "on_drop"
219    fn on_discard(
220        mut world: DeferredWorld,
221        HookContext {
222            entity,
223            relationship_hook_mode,
224            ..
225        }: HookContext,
226    ) {
227        match relationship_hook_mode {
228            RelationshipHookMode::Run => {}
229            RelationshipHookMode::Skip => return,
230            RelationshipHookMode::RunIfNotLinked => {
231                if <Self::RelationshipTarget as RelationshipTarget>::LINKED_SPAWN {
232                    return;
233                }
234            }
235        }
236        let target_entity = world.entity(entity).get::<Self>().unwrap().get();
237        if let Ok(mut target_entity_mut) = world.get_entity_mut(target_entity)
238            && let Some(mut relationship_target) =
239                target_entity_mut.get_mut::<Self::RelationshipTarget>()
240        {
241            relationship_target.collection_mut_risky().remove(entity);
242            if relationship_target.len() == 0 {
243                let command = |mut entity: EntityWorldMut| {
244                    // this "remove" operation must check emptiness because in the event that an identical
245                    // relationship is inserted on top, this despawn would result in the removal of that identical
246                    // relationship ... not what we want!
247                    if entity
248                        .get::<Self::RelationshipTarget>()
249                        .is_some_and(RelationshipTarget::is_empty)
250                    {
251                        entity.remove::<Self::RelationshipTarget>();
252                    }
253                };
254
255                world
256                    .commands()
257                    .queue_silenced(command.with_entity(target_entity));
258            }
259        }
260    }
261}
262
263/// The iterator type for the source entities in a [`RelationshipTarget`] collection,
264/// as defined in the [`RelationshipSourceCollection`] trait.
265pub type SourceIter<'w, R> =
266    <<R as RelationshipTarget>::Collection as RelationshipSourceCollection>::SourceIter<'w>;
267
268/// A [`Component`] containing the collection of entities that relate to this [`Entity`] via the associated `Relationship` type.
269/// See the [`Relationship`] documentation for more information.
270pub trait RelationshipTarget: Component<Mutability = Mutable> + Sized {
271    /// If this is true, when despawning or cloning (when [linked cloning is enabled](crate::entity::EntityClonerBuilder::linked_cloning)), the related entities targeting this entity will also be despawned or cloned.
272    ///
273    /// For example, this is set to `true` for Bevy's built-in parent-child relation, defined by [`ChildOf`](crate::prelude::ChildOf) and [`Children`](crate::prelude::Children).
274    /// This means that when a parent is despawned, any children targeting that parent are also despawned (and the same applies to cloning).
275    ///
276    /// To get around this behavior, you can first break the relationship between entities, and *then* despawn or clone.
277    /// This defaults to false when derived.
278    const LINKED_SPAWN: bool;
279    /// The [`Relationship`] that populates this [`RelationshipTarget`] collection.
280    type Relationship: Relationship<RelationshipTarget = Self>;
281    /// The collection type that stores the "source" entities for this [`RelationshipTarget`] component.
282    ///
283    /// Check the list of types which implement [`RelationshipSourceCollection`] for the data structures that can be used inside of your component.
284    /// If you need a new collection type, you can implement the [`RelationshipSourceCollection`] trait
285    /// for a type you own which wraps the collection you want to use (to avoid the orphan rule),
286    /// or open an issue on the Bevy repository to request first-party support for your collection type.
287    type Collection: RelationshipSourceCollection;
288
289    /// Returns a reference to the stored [`RelationshipTarget::Collection`].
290    fn collection(&self) -> &Self::Collection;
291    /// Returns a mutable reference to the stored [`RelationshipTarget::Collection`].
292    ///
293    /// # Warning
294    /// This should generally not be called by user code, as modifying the internal collection could invalidate the relationship.
295    /// The collection should not contain duplicates.
296    fn collection_mut_risky(&mut self) -> &mut Self::Collection;
297
298    /// Creates a new [`RelationshipTarget`] from the given [`RelationshipTarget::Collection`].
299    ///
300    /// # Warning
301    /// This should generally not be called by user code, as constructing the internal collection could invalidate the relationship.
302    /// The collection should not contain duplicates.
303    fn from_collection_risky(collection: Self::Collection) -> Self;
304
305    /// The `on_discard` component hook that maintains the [`Relationship`] / [`RelationshipTarget`] connection.
306    // note: think of this as "on_drop"
307    fn on_discard(
308        mut world: DeferredWorld,
309        HookContext {
310            entity,
311            relationship_hook_mode,
312            ..
313        }: HookContext,
314    ) {
315        match relationship_hook_mode {
316            RelationshipHookMode::Run => {}
317            // For RelationshipTarget we don't want to run this hook even if it isn't linked, but for Relationship we do.
318            RelationshipHookMode::Skip | RelationshipHookMode::RunIfNotLinked => return,
319        }
320        let (entities, mut commands) = world.entities_and_commands();
321        let relationship_target = entities.get(entity).unwrap().get::<Self>().unwrap();
322        for source_entity in relationship_target.iter() {
323            commands
324                .entity(source_entity)
325                .try_remove::<Self::Relationship>();
326        }
327    }
328
329    /// The `on_despawn` component hook that despawns entities stored in an entity's [`RelationshipTarget`] when
330    /// that entity is despawned.
331    // note: think of this as "on_drop"
332    fn on_despawn(mut world: DeferredWorld, HookContext { entity, .. }: HookContext) {
333        let (entities, mut commands) = world.entities_and_commands();
334        let relationship_target = entities.get(entity).unwrap().get::<Self>().unwrap();
335        for source_entity in relationship_target.iter() {
336            commands.entity(source_entity).try_despawn();
337        }
338    }
339
340    /// Creates this [`RelationshipTarget`] with the given pre-allocated entity capacity.
341    fn with_capacity(capacity: usize) -> Self {
342        let collection =
343            <Self::Collection as RelationshipSourceCollection>::with_capacity(capacity);
344        Self::from_collection_risky(collection)
345    }
346
347    /// Iterates the entities stored in this collection.
348    #[inline]
349    fn iter(&self) -> SourceIter<'_, Self> {
350        self.collection().iter()
351    }
352
353    /// Returns the number of entities in this collection.
354    #[inline]
355    fn len(&self) -> usize {
356        self.collection().len()
357    }
358
359    /// Returns true if this entity collection is empty.
360    #[inline]
361    fn is_empty(&self) -> bool {
362        self.collection().is_empty()
363    }
364}
365
366/// The "clone behavior" for [`RelationshipTarget`]. The [`RelationshipTarget`] will be populated with the proper components
367/// when the corresponding [`Relationship`] sources of truth are inserted. Cloning the actual entities
368/// in the original [`RelationshipTarget`] would result in duplicates, so we don't do that!
369///
370/// This will also queue up clones of the relationship sources if the [`EntityCloner`](crate::entity::EntityCloner) is configured
371/// to spawn recursively.
372pub fn clone_relationship_target<T: RelationshipTarget>(
373    component: &T,
374    cloned: &mut T,
375    context: &mut ComponentCloneCtx,
376) {
377    if context.linked_cloning() && T::LINKED_SPAWN {
378        let collection = cloned.collection_mut_risky();
379        for entity in component.iter() {
380            collection.add(entity);
381            context.queue_entity_clone(entity);
382        }
383    } else if context.moving() {
384        let target = context.target();
385        let collection = cloned.collection_mut_risky();
386        for entity in component.iter() {
387            collection.add(entity);
388            context.queue_deferred(move |world, _mapper| {
389                // We don't want relationships hooks to run because we are manually constructing the collection here
390                _ = DeferredWorld::from(world)
391                    .modify_component_with_relationship_hook_mode::<T::Relationship, ()>(
392                        entity,
393                        RelationshipHookMode::Skip,
394                        |r| r.set_risky(target),
395                    );
396            });
397        }
398    }
399}
400
401/// Configures the conditions under which the Relationship insert/discard hooks will be run.
402#[derive(Copy, Clone, Debug)]
403pub enum RelationshipHookMode {
404    /// Relationship insert/discard hooks will always run
405    Run,
406    /// Relationship insert/discard hooks will run if [`RelationshipTarget::LINKED_SPAWN`] is false
407    RunIfNotLinked,
408    /// Relationship insert/discard hooks will always be skipped
409    Skip,
410}
411
412/// Wrapper for components clone specialization using autoderef.
413#[doc(hidden)]
414pub struct RelationshipCloneBehaviorSpecialization<T>(PhantomData<T>);
415
416impl<T> Default for RelationshipCloneBehaviorSpecialization<T> {
417    fn default() -> Self {
418        Self(PhantomData)
419    }
420}
421
422/// Base trait for relationship clone specialization using autoderef.
423#[doc(hidden)]
424pub trait RelationshipCloneBehaviorBase {
425    fn default_clone_behavior(&self) -> ComponentCloneBehavior;
426}
427
428impl<C> RelationshipCloneBehaviorBase for RelationshipCloneBehaviorSpecialization<C> {
429    fn default_clone_behavior(&self) -> ComponentCloneBehavior {
430        // Relationships currently must have `Clone`/`Reflect`-based handler for cloning/moving logic to properly work.
431        ComponentCloneBehavior::Ignore
432    }
433}
434
435/// Specialized trait for relationship clone specialization using autoderef.
436#[doc(hidden)]
437pub trait RelationshipCloneBehaviorViaReflect {
438    fn default_clone_behavior(&self) -> ComponentCloneBehavior;
439}
440
441#[cfg(feature = "bevy_reflect")]
442impl<C: Relationship + bevy_reflect::Reflect> RelationshipCloneBehaviorViaReflect
443    for &RelationshipCloneBehaviorSpecialization<C>
444{
445    fn default_clone_behavior(&self) -> ComponentCloneBehavior {
446        ComponentCloneBehavior::reflect()
447    }
448}
449
450/// Specialized trait for relationship clone specialization using autoderef.
451#[doc(hidden)]
452pub trait RelationshipCloneBehaviorViaClone {
453    fn default_clone_behavior(&self) -> ComponentCloneBehavior;
454}
455
456impl<C: Relationship + Clone> RelationshipCloneBehaviorViaClone
457    for &&RelationshipCloneBehaviorSpecialization<C>
458{
459    fn default_clone_behavior(&self) -> ComponentCloneBehavior {
460        ComponentCloneBehavior::clone::<C>()
461    }
462}
463
464/// Specialized trait for relationship target clone specialization using autoderef.
465#[doc(hidden)]
466pub trait RelationshipTargetCloneBehaviorViaReflect {
467    fn default_clone_behavior(&self) -> ComponentCloneBehavior;
468}
469
470#[cfg(feature = "bevy_reflect")]
471impl<C: RelationshipTarget + bevy_reflect::Reflect + bevy_reflect::TypePath>
472    RelationshipTargetCloneBehaviorViaReflect for &&&RelationshipCloneBehaviorSpecialization<C>
473{
474    fn default_clone_behavior(&self) -> ComponentCloneBehavior {
475        ComponentCloneBehavior::Custom(|source, context| {
476            if let Some(component) = source.read::<C>()
477                && let Ok(mut cloned) = component.reflect_clone_and_take::<C>()
478            {
479                cloned.collection_mut_risky().clear();
480                clone_relationship_target(component, &mut cloned, context);
481                context.write_target_component(cloned);
482            }
483        })
484    }
485}
486
487/// Specialized trait for relationship target clone specialization using autoderef.
488#[doc(hidden)]
489pub trait RelationshipTargetCloneBehaviorViaClone {
490    fn default_clone_behavior(&self) -> ComponentCloneBehavior;
491}
492
493impl<C: RelationshipTarget + Clone> RelationshipTargetCloneBehaviorViaClone
494    for &&&&RelationshipCloneBehaviorSpecialization<C>
495{
496    fn default_clone_behavior(&self) -> ComponentCloneBehavior {
497        ComponentCloneBehavior::Custom(|source, context| {
498            if let Some(component) = source.read::<C>() {
499                let mut cloned = component.clone();
500                cloned.collection_mut_risky().clear();
501                clone_relationship_target(component, &mut cloned, context);
502                context.write_target_component(cloned);
503            }
504        })
505    }
506}
507
508/// We know there's no additional data on Children, so this handler is an optimization to avoid cloning the entire Collection.
509#[doc(hidden)]
510pub trait RelationshipTargetCloneBehaviorHierarchy {
511    fn default_clone_behavior(&self) -> ComponentCloneBehavior;
512}
513
514impl RelationshipTargetCloneBehaviorHierarchy
515    for &&&&&RelationshipCloneBehaviorSpecialization<crate::hierarchy::Children>
516{
517    fn default_clone_behavior(&self) -> ComponentCloneBehavior {
518        ComponentCloneBehavior::Custom(|source, context| {
519            if let Some(component) = source.read::<crate::hierarchy::Children>() {
520                let mut cloned = crate::hierarchy::Children::with_capacity(component.len());
521                clone_relationship_target(component, &mut cloned, context);
522                context.write_target_component(cloned);
523            }
524        })
525    }
526}
527
528/// Initializer enum for [`RelationshipAccessor`] that allows to configure relationship for dynamic components.
529#[derive(Clone)]
530pub enum RelationshipAccessorInitializer {
531    /// Describes a [`Relationship`] component.
532    Relationship {
533        /// Offset of the field containing [`Entity`] from the base of the component.
534        ///
535        /// Dynamic equivalent of [`Relationship::get`].
536        entity_field_offset: usize,
537        /// Value of [`RelationshipTarget::LINKED_SPAWN`] for the [`Relationship::RelationshipTarget`] of this [`Relationship`].
538        linked_spawn: bool,
539        /// Value of [`Relationship::ALLOW_SELF_REFERENTIAL`] of this [`Relationship`].
540        allow_self_referential: bool,
541        /// Getter for [`ComponentId`] of the [`RelationshipTarget`] counterpart.
542        /// Should return `None` if [`RelationshipTarget`] isn't registered yet.
543        relationship_target_getter: Arc<dyn Fn(&Components) -> Option<ComponentId>>,
544    },
545    /// Describes a [`RelationshipTarget`] component.
546    RelationshipTarget {
547        /// Function that returns an iterator over all [`Entity`]s of this [`RelationshipTarget`]'s collection.
548        ///
549        /// Dynamic equivalent of [`RelationshipTarget::iter`].
550        /// # Safety
551        /// Passed pointer must point to the value of the same component as the one that this accessor was registered to.
552        iter: for<'a> unsafe fn(Ptr<'a>) -> Box<dyn Iterator<Item = Entity> + 'a>,
553        /// Value of [`RelationshipTarget::LINKED_SPAWN`] of this [`RelationshipTarget`].
554        linked_spawn: bool,
555        /// Value of [`Relationship::ALLOW_SELF_REFERENTIAL`] for the [`Relationship`] of this [`RelationshipTarget`].
556        allow_self_referential: bool,
557        /// Getter for [`ComponentId`] of the [`Relationship`] counterpart.
558        /// Should return `None` if [`Relationship`] isn't registered yet.
559        relationship_getter: Arc<dyn Fn(&Components) -> Option<ComponentId>>,
560    },
561}
562
563impl core::fmt::Debug for RelationshipAccessorInitializer {
564    fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
565        match self {
566            Self::Relationship {
567                entity_field_offset,
568                linked_spawn,
569                allow_self_referential,
570                relationship_target_getter: _,
571            } => f
572                .debug_struct("Relationship")
573                .field("entity_field_offset", entity_field_offset)
574                .field("linked_spawn", linked_spawn)
575                .field("allow_self_referential", allow_self_referential)
576                .finish(),
577            Self::RelationshipTarget {
578                iter,
579                linked_spawn,
580                allow_self_referential,
581                relationship_getter: _,
582            } => f
583                .debug_struct("RelationshipTarget")
584                .field("iter", iter)
585                .field("linked_spawn", linked_spawn)
586                .field("allow_self_referential", allow_self_referential)
587                .finish(),
588        }
589    }
590}
591
592#[derive(Clone, Debug, Default)]
593pub(crate) enum MaybeRelationshipAccessor {
594    /// Not a relationship
595    #[default]
596    NoAccessor,
597    /// Uninitialized relationship, which will be initialized when the second component of the relationship is registered.
598    /// Boxed to reduce size overhead.
599    Initializer(Box<RelationshipAccessorInitializer>),
600    /// Relationship
601    Accessor(RelationshipAccessor),
602}
603
604impl MaybeRelationshipAccessor {
605    /// Returns [`RelationshipAccessor`] if this component is a part of relationship and the accessor is initialized.
606    pub fn accessor(&self) -> Option<&RelationshipAccessor> {
607        match self {
608            MaybeRelationshipAccessor::Accessor(relationship_accessor) => {
609                Some(relationship_accessor)
610            }
611            _ => None,
612        }
613    }
614
615    /// Initializes the relationship accessor if it isn't initialized already and the counterpart is registered.
616    pub fn initialize(&mut self, id: ComponentId, components: &mut Components) {
617        _ = (|| {
618            let accessor = self.initializer_to_accessor(|getter| getter(components))?;
619            let counterpart_id = accessor.counterpart_id();
620            let counterpart_slot = components.get_relationship_accessor_mut(counterpart_id)?;
621            let counterpart_accessor = counterpart_slot.initializer_to_accessor(|_| Some(id))?;
622            *counterpart_slot = MaybeRelationshipAccessor::Accessor(counterpart_accessor);
623            *self = MaybeRelationshipAccessor::Accessor(accessor);
624            Some(())
625        })();
626    }
627
628    fn initializer_to_accessor(
629        &self,
630        mapper: impl FnOnce(&dyn Fn(&Components) -> Option<ComponentId>) -> Option<ComponentId>,
631    ) -> Option<RelationshipAccessor> {
632        let MaybeRelationshipAccessor::Initializer(initializer) = self else {
633            return None;
634        };
635        Some(match *initializer.as_ref() {
636            RelationshipAccessorInitializer::Relationship {
637                entity_field_offset,
638                linked_spawn,
639                allow_self_referential,
640                ref relationship_target_getter,
641            } => {
642                let relationship_target = mapper(relationship_target_getter.as_ref())?;
643                RelationshipAccessor::Relationship {
644                    entity_field_offset,
645                    linked_spawn,
646                    allow_self_referential,
647                    relationship_target,
648                }
649            }
650            RelationshipAccessorInitializer::RelationshipTarget {
651                iter,
652                linked_spawn,
653                allow_self_referential,
654                ref relationship_getter,
655            } => {
656                let relationship = mapper(relationship_getter.as_ref())?;
657                RelationshipAccessor::RelationshipTarget {
658                    iter,
659                    linked_spawn,
660                    allow_self_referential,
661                    relationship,
662                }
663            }
664        })
665    }
666}
667
668impl From<Option<RelationshipAccessorInitializer>> for MaybeRelationshipAccessor {
669    fn from(value: Option<RelationshipAccessorInitializer>) -> Self {
670        value
671            .map(|v| MaybeRelationshipAccessor::Initializer(Box::new(v)))
672            .unwrap_or(MaybeRelationshipAccessor::NoAccessor)
673    }
674}
675
676/// This enum describes a way to access the entities of [`Relationship`] and [`RelationshipTarget`] components
677/// in a type-erased context.
678#[derive(Debug, Clone, Copy)]
679pub enum RelationshipAccessor {
680    /// This component is a [`Relationship`].
681    Relationship {
682        /// Offset of the field containing [`Entity`] from the base of the component.
683        ///
684        /// Dynamic equivalent of [`Relationship::get`].
685        entity_field_offset: usize,
686        /// Value of [`RelationshipTarget::LINKED_SPAWN`] for the [`Relationship::RelationshipTarget`] of this [`Relationship`].
687        linked_spawn: bool,
688        /// Value of [`Relationship::ALLOW_SELF_REFERENTIAL`] of this [`Relationship`].
689        allow_self_referential: bool,
690        /// [`ComponentId`] of the [`RelationshipTarget`] counterpart.
691        relationship_target: ComponentId,
692    },
693    /// This component is a [`RelationshipTarget`].
694    RelationshipTarget {
695        /// Function that returns an iterator over all [`Entity`]s of this [`RelationshipTarget`]'s collection.
696        ///
697        /// Dynamic equivalent of [`RelationshipTarget::iter`].
698        /// # Safety
699        /// Passed pointer must point to the value of the same component as the one that this accessor was registered to.
700        iter: for<'a> unsafe fn(Ptr<'a>) -> Box<dyn Iterator<Item = Entity> + 'a>,
701        /// Value of [`RelationshipTarget::LINKED_SPAWN`] of this [`RelationshipTarget`].
702        linked_spawn: bool,
703        /// Value of [`Relationship::ALLOW_SELF_REFERENTIAL`] for the [`Relationship`] of this [`RelationshipTarget`].
704        allow_self_referential: bool,
705        /// [`ComponentId`] of the [`Relationship`] counterpart.
706        relationship: ComponentId,
707    },
708}
709
710impl RelationshipAccessor {
711    /// Returns [`ComponentId`] of [`RelationshipTarget`] for this [`Relationship`] and vice-versa.
712    pub fn counterpart_id(&self) -> ComponentId {
713        match self {
714            RelationshipAccessor::Relationship {
715                relationship_target,
716                ..
717            } => *relationship_target,
718            RelationshipAccessor::RelationshipTarget { relationship, .. } => *relationship,
719        }
720    }
721
722    /// Returns the value of [`RelationshipTarget::LINKED_SPAWN`].
723    pub fn linked_spawn(&self) -> bool {
724        match self {
725            RelationshipAccessor::Relationship { linked_spawn, .. }
726            | RelationshipAccessor::RelationshipTarget { linked_spawn, .. } => *linked_spawn,
727        }
728    }
729
730    /// Returns the value of [`Relationship::ALLOW_SELF_REFERENTIAL`].
731    pub fn allow_self_referential(&self) -> bool {
732        match self {
733            RelationshipAccessor::Relationship {
734                allow_self_referential,
735                ..
736            }
737            | RelationshipAccessor::RelationshipTarget {
738                allow_self_referential,
739                ..
740            } => *allow_self_referential,
741        }
742    }
743}
744
745/// A type-safe convenience wrapper over [`RelationshipAccessor`].
746pub struct ComponentRelationshipAccessor<C: ?Sized> {
747    pub(crate) initializer: RelationshipAccessorInitializer,
748    phantom: PhantomData<C>,
749}
750
751impl<C> ComponentRelationshipAccessor<C> {
752    /// Create a new [`ComponentRelationshipAccessor`] for a [`Relationship`] component.
753    /// # Safety
754    /// `entity_field_offset` should be the offset from the base of this component and point to a field that stores value of type [`Entity`].
755    /// This value can be obtained using the [`core::mem::offset_of`] macro.
756    pub unsafe fn relationship(entity_field_offset: usize) -> Self
757    where
758        C: Relationship,
759    {
760        // Due to https://github.com/taiki-e/portable-atomic/issues/143 we have to box this first, and then get the Arc from the box
761        let getter: Box<dyn Fn(&Components) -> Option<ComponentId>> =
762            Box::new(|components| components.get_id(TypeId::of::<C::RelationshipTarget>()));
763        Self {
764            initializer: RelationshipAccessorInitializer::Relationship {
765                entity_field_offset,
766                linked_spawn: C::RelationshipTarget::LINKED_SPAWN,
767                allow_self_referential: C::ALLOW_SELF_REFERENTIAL,
768                relationship_target_getter: Arc::from(getter),
769            },
770            phantom: Default::default(),
771        }
772    }
773
774    /// Create a new [`ComponentRelationshipAccessor`] for a [`RelationshipTarget`] component.
775    pub fn relationship_target() -> Self
776    where
777        C: RelationshipTarget,
778    {
779        // Due to https://github.com/taiki-e/portable-atomic/issues/143 we have to box this first, and then get the Arc from the box
780        let getter: Box<dyn Fn(&Components) -> Option<ComponentId>> =
781            Box::new(|components| components.get_id(TypeId::of::<C::Relationship>()));
782        Self {
783            initializer: RelationshipAccessorInitializer::RelationshipTarget {
784                // Safety: caller ensures that `ptr` is of type `C`.
785                iter: |ptr| unsafe { Box::new(RelationshipTarget::iter(ptr.deref::<C>())) },
786                linked_spawn: C::LINKED_SPAWN,
787                allow_self_referential: C::Relationship::ALLOW_SELF_REFERENTIAL,
788                relationship_getter: Arc::from(getter),
789            },
790            phantom: Default::default(),
791        }
792    }
793}
794
795#[cfg(test)]
796mod tests {
797    use core::marker::PhantomData;
798    use core::sync::atomic::AtomicBool;
799
800    use crate::lifecycle::HookContext;
801    use crate::prelude::{ChildOf, Children};
802    use crate::relationship::{Relationship, RelationshipAccessor};
803    use crate::world::{DeferredWorld, World};
804    use crate::{component::Component, entity::Entity};
805    use alloc::vec::Vec;
806
807    #[test]
808    fn custom_relationship() {
809        #[derive(Component)]
810        #[relationship(relationship_target = LikedBy)]
811        struct Likes(pub Entity);
812
813        #[derive(Component)]
814        #[relationship_target(relationship = Likes)]
815        struct LikedBy(Vec<Entity>);
816
817        let mut world = World::new();
818        let a = world.spawn_empty().id();
819        let b = world.spawn(Likes(a)).id();
820        let c = world.spawn(Likes(a)).id();
821        assert_eq!(world.entity(a).get::<LikedBy>().unwrap().0, &[b, c]);
822    }
823
824    #[test]
825    fn self_relationship_fails_by_default() {
826        #[derive(Component)]
827        #[relationship(relationship_target = RelTarget)]
828        struct Rel(Entity);
829
830        #[derive(Component)]
831        #[relationship_target(relationship = Rel)]
832        struct RelTarget(Vec<Entity>);
833
834        let mut world = World::new();
835        let a = world.spawn_empty().id();
836        world.entity_mut(a).insert(Rel(a));
837        assert!(!world.entity(a).contains::<Rel>());
838        assert!(!world.entity(a).contains::<RelTarget>());
839    }
840
841    #[test]
842    fn self_relationship_succeeds_with_allow_self_referential() {
843        #[derive(Component)]
844        #[relationship(relationship_target = RelTarget, allow_self_referential)]
845        struct Rel(Entity);
846
847        #[derive(Component)]
848        #[relationship_target(relationship = Rel)]
849        struct RelTarget(Vec<Entity>);
850
851        let mut world = World::new();
852        let a = world.spawn_empty().id();
853        world.entity_mut(a).insert(Rel(a));
854        assert!(world.entity(a).contains::<Rel>());
855        assert!(world.entity(a).contains::<RelTarget>());
856        assert_eq!(world.entity(a).get::<Rel>().unwrap().get(), a);
857        assert_eq!(&*world.entity(a).get::<RelTarget>().unwrap().0, &[a]);
858    }
859
860    #[test]
861    fn self_relationship_removal_with_allow_self_referential() {
862        #[derive(Component)]
863        #[relationship(relationship_target = RelTarget, allow_self_referential)]
864        struct Rel(Entity);
865
866        #[derive(Component)]
867        #[relationship_target(relationship = Rel)]
868        struct RelTarget(Vec<Entity>);
869
870        let mut world = World::new();
871        let a = world.spawn_empty().id();
872        world.entity_mut(a).insert(Rel(a));
873        assert!(world.entity(a).contains::<Rel>());
874        assert!(world.entity(a).contains::<RelTarget>());
875
876        // Remove the relationship and verify cleanup
877        world.entity_mut(a).remove::<Rel>();
878        assert!(!world.entity(a).contains::<Rel>());
879        assert!(!world.entity(a).contains::<RelTarget>());
880    }
881
882    #[test]
883    fn relationship_with_missing_target_fails() {
884        #[derive(Component)]
885        #[relationship(relationship_target = RelTarget)]
886        struct Rel(Entity);
887
888        #[derive(Component)]
889        #[relationship_target(relationship = Rel)]
890        struct RelTarget(Vec<Entity>);
891
892        let mut world = World::new();
893        let a = world.spawn_empty().id();
894        world.despawn(a);
895        let b = world.spawn(Rel(a)).id();
896        assert!(!world.entity(b).contains::<Rel>());
897        assert!(!world.entity(b).contains::<RelTarget>());
898    }
899
900    #[test]
901    fn relationship_with_multiple_non_target_fields_compiles() {
902        #[expect(
903            dead_code,
904            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
905        )]
906        #[derive(Component)]
907        #[relationship(relationship_target=Target)]
908        struct Source {
909            #[relationship]
910            target: Entity,
911            foo: u8,
912            bar: u8,
913        }
914
915        #[expect(
916            dead_code,
917            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
918        )]
919        #[derive(Component)]
920        #[relationship_target(relationship=Source)]
921        struct Target(Vec<Entity>);
922
923        // No assert necessary, looking to make sure compilation works with the macros
924    }
925    #[test]
926    fn relationship_target_with_multiple_non_target_fields_compiles() {
927        #[expect(
928            dead_code,
929            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
930        )]
931        #[derive(Component)]
932        #[relationship(relationship_target=Target)]
933        struct Source(Entity);
934
935        #[expect(
936            dead_code,
937            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
938        )]
939        #[derive(Component)]
940        #[relationship_target(relationship=Source)]
941        struct Target {
942            #[relationship]
943            target: Vec<Entity>,
944            foo: u8,
945            bar: u8,
946        }
947
948        // No assert necessary, looking to make sure compilation works with the macros
949    }
950
951    #[test]
952    fn relationship_with_multiple_unnamed_non_target_fields_compiles() {
953        #[expect(
954            dead_code,
955            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
956        )]
957        #[derive(Component)]
958        #[relationship(relationship_target=Target<T>)]
959        struct Source<T: Send + Sync + 'static>(#[relationship] Entity, PhantomData<T>);
960
961        #[expect(
962            dead_code,
963            reason = "This struct is used as a compilation test to test the derive macros, and as such is intentionally never constructed."
964        )]
965        #[derive(Component)]
966        #[relationship_target(relationship=Source<T>)]
967        struct Target<T: Send + Sync + 'static>(#[relationship] Vec<Entity>, PhantomData<T>);
968
969        // No assert necessary, looking to make sure compilation works with the macros
970    }
971
972    #[test]
973    fn parent_child_relationship_with_custom_relationship() {
974        #[derive(Component)]
975        #[relationship(relationship_target = RelTarget)]
976        struct Rel(Entity);
977
978        #[derive(Component)]
979        #[relationship_target(relationship = Rel)]
980        struct RelTarget(Entity);
981
982        let mut world = World::new();
983
984        // Rel on Parent
985        // Despawn Parent
986        let mut commands = world.commands();
987        let child = commands.spawn_empty().id();
988        let parent = commands.spawn(Rel(child)).add_child(child).id();
989        commands.entity(parent).despawn();
990        world.flush();
991
992        assert!(world.get_entity(child).is_err());
993        assert!(world.get_entity(parent).is_err());
994
995        // Rel on Parent
996        // Despawn Child
997        let mut commands = world.commands();
998        let child = commands.spawn_empty().id();
999        let parent = commands.spawn(Rel(child)).add_child(child).id();
1000        commands.entity(child).despawn();
1001        world.flush();
1002
1003        assert!(world.get_entity(child).is_err());
1004        assert!(!world.entity(parent).contains::<Rel>());
1005
1006        // Rel on Child
1007        // Despawn Parent
1008        let mut commands = world.commands();
1009        let parent = commands.spawn_empty().id();
1010        let child = commands.spawn((ChildOf(parent), Rel(parent))).id();
1011        commands.entity(parent).despawn();
1012        world.flush();
1013
1014        assert!(world.get_entity(child).is_err());
1015        assert!(world.get_entity(parent).is_err());
1016
1017        // Rel on Child
1018        // Despawn Child
1019        let mut commands = world.commands();
1020        let parent = commands.spawn_empty().id();
1021        let child = commands.spawn((ChildOf(parent), Rel(parent))).id();
1022        commands.entity(child).despawn();
1023        world.flush();
1024
1025        assert!(world.get_entity(child).is_err());
1026        assert!(!world.entity(parent).contains::<RelTarget>());
1027    }
1028
1029    #[test]
1030    fn spawn_batch_with_relationship() {
1031        let mut world = World::new();
1032        let parent = world.spawn_empty().id();
1033        let children = world
1034            .spawn_batch((0..10).map(|_| ChildOf(parent)))
1035            .collect::<Vec<_>>();
1036
1037        for &child in &children {
1038            assert!(world
1039                .get::<ChildOf>(child)
1040                .is_some_and(|child_of| child_of.parent() == parent));
1041        }
1042        assert!(world
1043            .get::<Children>(parent)
1044            .is_some_and(|children| children.len() == 10));
1045    }
1046
1047    #[test]
1048    fn insert_batch_with_relationship() {
1049        let mut world = World::new();
1050        let parent = world.spawn_empty().id();
1051        let child = world.spawn_empty().id();
1052        world.insert_batch([(child, ChildOf(parent))]);
1053        world.flush();
1054
1055        assert!(world.get::<ChildOf>(child).is_some());
1056        assert!(world.get::<Children>(parent).is_some());
1057    }
1058
1059    #[test]
1060    fn dynamically_traverse_hierarchy() {
1061        let mut world = World::new();
1062        let child_of_id = world.register_component::<ChildOf>();
1063        let children_id = world.register_component::<Children>();
1064
1065        let parent = world.spawn_empty().id();
1066        let child = world.spawn_empty().id();
1067        world.entity_mut(child).insert(ChildOf(parent));
1068        world.flush();
1069
1070        let children_ptr = world.get_by_id(parent, children_id).unwrap();
1071        let RelationshipAccessor::RelationshipTarget { iter, .. } = world
1072            .components()
1073            .get_info(children_id)
1074            .unwrap()
1075            .relationship_accessor()
1076            .unwrap()
1077        else {
1078            unreachable!()
1079        };
1080        // Safety: `children_ptr` contains value of the same type as the one this accessor was registered for.
1081        let children: Vec<_> = unsafe { iter(children_ptr).collect() };
1082        assert_eq!(children, alloc::vec![child]);
1083
1084        let child_of_ptr = world.get_by_id(child, child_of_id).unwrap();
1085        let RelationshipAccessor::Relationship {
1086            entity_field_offset,
1087            ..
1088        } = world
1089            .components()
1090            .get_info(child_of_id)
1091            .unwrap()
1092            .relationship_accessor()
1093            .unwrap()
1094        else {
1095            unreachable!()
1096        };
1097        // Safety:
1098        // - offset is in bounds, aligned and has the same lifetime as the original pointer.
1099        // - value at offset is guaranteed to be a valid Entity
1100        let child_of_entity: Entity =
1101            unsafe { *child_of_ptr.byte_add(*entity_field_offset).deref() };
1102        assert_eq!(child_of_entity, parent);
1103    }
1104
1105    #[test]
1106    fn relationship_accessor() {
1107        #[derive(Component)]
1108        #[relationship(relationship_target = LikedBy)]
1109        struct Likes {
1110            _a: u16,
1111            #[relationship]
1112            e: Entity,
1113            _b: (i8, u8),
1114        }
1115
1116        #[derive(Component)]
1117        #[relationship_target(relationship = Likes)]
1118        struct LikedBy(Vec<Entity>);
1119
1120        let mut world = World::new();
1121        let likes_id = world.register_component::<Likes>();
1122        let liked_by_id = world.register_component::<LikedBy>();
1123
1124        let likes_accessor = world
1125            .components()
1126            .get_info(likes_id)
1127            .unwrap()
1128            .relationship_accessor()
1129            .unwrap();
1130        match *likes_accessor {
1131            RelationshipAccessor::Relationship {
1132                entity_field_offset,
1133                linked_spawn,
1134                allow_self_referential,
1135                relationship_target,
1136            } => {
1137                assert_eq!(entity_field_offset, core::mem::offset_of!(Likes, e));
1138                assert!(!linked_spawn);
1139                assert!(!allow_self_referential);
1140                assert_eq!(relationship_target, liked_by_id);
1141            }
1142            _ => {
1143                panic!("Not a Relationship")
1144            }
1145        }
1146
1147        let liked_by_accessor = world
1148            .components()
1149            .get_info(liked_by_id)
1150            .unwrap()
1151            .relationship_accessor()
1152            .unwrap();
1153        match *liked_by_accessor {
1154            RelationshipAccessor::RelationshipTarget {
1155                iter,
1156                linked_spawn,
1157                allow_self_referential,
1158                relationship,
1159            } => {
1160                let liked_by = LikedBy(alloc::vec![
1161                    world.spawn_empty().id(),
1162                    world.spawn_empty().id(),
1163                    world.spawn_empty().id()
1164                ]);
1165                // SAFETY: liked_by is of type LikedBy
1166                unsafe {
1167                    assert_eq!(iter((&liked_by).into()).collect::<Vec<_>>(), liked_by.0);
1168                }
1169                assert!(!linked_spawn);
1170                assert!(!allow_self_referential);
1171                assert_eq!(relationship, likes_id);
1172            }
1173            _ => {
1174                panic!("Not a RelationshipTarget")
1175            }
1176        }
1177
1178        #[derive(Component)]
1179        #[relationship(relationship_target = RelTarget, allow_self_referential)]
1180        struct Rel(Entity);
1181
1182        #[derive(Component)]
1183        #[relationship_target(relationship = Rel, linked_spawn)]
1184        struct RelTarget(Vec<Entity>);
1185
1186        let rel_id = world.register_component::<Rel>();
1187        let rel_target_id = world.register_component::<RelTarget>();
1188
1189        let rel_accessor = world
1190            .components()
1191            .get_info(rel_id)
1192            .unwrap()
1193            .relationship_accessor()
1194            .unwrap();
1195        assert!(rel_accessor.linked_spawn());
1196        assert!(rel_accessor.allow_self_referential());
1197        let rel_target_accessor = world
1198            .components()
1199            .get_info(rel_target_id)
1200            .unwrap()
1201            .relationship_accessor()
1202            .unwrap();
1203        assert!(rel_target_accessor.linked_spawn());
1204        assert!(rel_target_accessor.allow_self_referential());
1205    }
1206
1207    #[test]
1208    pub fn component_hooks_compatibility() {
1209        static ADD_CALLED: AtomicBool = AtomicBool::new(false);
1210        static INSERT_CALLED: AtomicBool = AtomicBool::new(false);
1211        static DISCARD_CALLED: AtomicBool = AtomicBool::new(false);
1212        static REMOVE_CALLED: AtomicBool = AtomicBool::new(false);
1213        static DESPAWN_CALLED: AtomicBool = AtomicBool::new(false);
1214
1215        #[derive(Component)]
1216        #[relationship(relationship_target = RelTarget)]
1217        #[component(on_add, on_insert, on_discard, on_remove, on_despawn)]
1218        struct Rel(Entity);
1219
1220        #[derive(Component)]
1221        #[relationship_target(relationship = Rel)]
1222        struct RelTarget(Entity);
1223
1224        impl Rel {
1225            fn on_add(world: DeferredWorld, context: HookContext) {
1226                let &Rel(target) = world.get(context.entity).unwrap();
1227                assert!(!world.entity(target).contains::<RelTarget>());
1228                ADD_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1229            }
1230
1231            fn on_insert(world: DeferredWorld, context: HookContext) {
1232                let &Rel(target) = world.get(context.entity).unwrap();
1233                assert!(!world.entity(target).contains::<RelTarget>());
1234                INSERT_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1235            }
1236
1237            fn on_discard(world: DeferredWorld, context: HookContext) {
1238                let &Rel(target) = world.get(context.entity).unwrap();
1239                assert!(world.entity(target).contains::<RelTarget>());
1240                DISCARD_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1241            }
1242
1243            fn on_remove(world: DeferredWorld, context: HookContext) {
1244                let &Rel(target) = world.get(context.entity).unwrap();
1245                assert!(world.entity(target).contains::<RelTarget>());
1246                REMOVE_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1247            }
1248
1249            fn on_despawn(world: DeferredWorld, context: HookContext) {
1250                let &Rel(target) = world.get(context.entity).unwrap();
1251                assert!(world.entity(target).contains::<RelTarget>());
1252                DESPAWN_CALLED.store(true, core::sync::atomic::Ordering::Relaxed);
1253            }
1254        }
1255
1256        let mut world = World::new();
1257        let target = world.spawn_empty().id();
1258        let source = world.spawn(Rel(target)).id();
1259        assert!(world.entity(target).contains::<RelTarget>());
1260        assert!(ADD_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1261        assert!(INSERT_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1262        world.despawn(source);
1263        assert!(DISCARD_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1264        assert!(REMOVE_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1265        assert!(DESPAWN_CALLED.load(core::sync::atomic::Ordering::Relaxed));
1266    }
1267}