bevy_ecs/
hierarchy.rs

1//! The canonical "parent-child" [`Relationship`] for entities, driven by
2//! the [`ChildOf`] [`Relationship`] and the [`Children`] [`RelationshipTarget`].
3//!
4//! See [`ChildOf`] for a full description of the relationship and how to use it.
5//!
6//! [`Relationship`]: crate::relationship::Relationship
7//! [`RelationshipTarget`]: crate::relationship::RelationshipTarget
8
9#[cfg(feature = "bevy_reflect")]
10use crate::reflect::{ReflectComponent, ReflectFromWorld};
11use crate::{
12    bundle::Bundle,
13    component::{Component, HookContext},
14    entity::Entity,
15    relationship::{RelatedSpawner, RelatedSpawnerCommands},
16    system::EntityCommands,
17    world::{DeferredWorld, EntityWorldMut, FromWorld, World},
18};
19use alloc::{format, string::String, vec::Vec};
20#[cfg(feature = "bevy_reflect")]
21use bevy_reflect::std_traits::ReflectDefault;
22use core::ops::Deref;
23use core::slice;
24use disqualified::ShortName;
25use log::warn;
26
27/// Stores the parent entity of this child entity with this component.
28///
29/// This is a [`Relationship`] component, and creates the canonical
30/// "parent / child" hierarchy. This is the "source of truth" component, and it pairs with
31/// the [`Children`] [`RelationshipTarget`](crate::relationship::RelationshipTarget).
32///
33/// This relationship should be used for things like:
34///
35/// 1. Organizing entities in a scene
36/// 2. Propagating configuration or data inherited from a parent, such as "visibility" or "world-space global transforms".
37/// 3. Ensuring a hierarchy is despawned when an entity is despawned.
38///
39/// [`ChildOf`] contains a single "target" [`Entity`]. When [`ChildOf`] is inserted on a "source" entity,
40/// the "target" entity will automatically (and immediately, via a component hook) have a [`Children`]
41/// component inserted, and the "source" entity will be added to that [`Children`] instance.
42///
43/// If the [`ChildOf`] component is replaced with a different "target" entity, the old target's [`Children`]
44/// will be automatically (and immediately, via a component hook) be updated to reflect that change.
45///
46/// Likewise, when the [`ChildOf`] component is removed, the "source" entity will be removed from the old
47/// target's [`Children`]. If this results in [`Children`] being empty, [`Children`] will be automatically removed.
48///
49/// When a parent is despawned, all children (and their descendants) will _also_ be despawned.
50///
51/// You can create parent-child relationships in a variety of ways. The most direct way is to insert a [`ChildOf`] component:
52///
53/// ```
54/// # use bevy_ecs::prelude::*;
55/// # let mut world = World::new();
56/// let root = world.spawn_empty().id();
57/// let child1 = world.spawn(ChildOf(root)).id();
58/// let child2 = world.spawn(ChildOf(root)).id();
59/// let grandchild = world.spawn(ChildOf(child1)).id();
60///
61/// assert_eq!(&**world.entity(root).get::<Children>().unwrap(), &[child1, child2]);
62/// assert_eq!(&**world.entity(child1).get::<Children>().unwrap(), &[grandchild]);
63///
64/// world.entity_mut(child2).remove::<ChildOf>();
65/// assert_eq!(&**world.entity(root).get::<Children>().unwrap(), &[child1]);
66///
67/// world.entity_mut(root).despawn();
68/// assert!(world.get_entity(root).is_err());
69/// assert!(world.get_entity(child1).is_err());
70/// assert!(world.get_entity(grandchild).is_err());
71/// ```
72///
73/// However if you are spawning many children, you might want to use the [`EntityWorldMut::with_children`] helper instead:
74///
75/// ```
76/// # use bevy_ecs::prelude::*;
77/// # let mut world = World::new();
78/// let mut child1 = Entity::PLACEHOLDER;
79/// let mut child2 = Entity::PLACEHOLDER;
80/// let mut grandchild = Entity::PLACEHOLDER;
81/// let root = world.spawn_empty().with_children(|p| {
82///     child1 = p.spawn_empty().with_children(|p| {
83///         grandchild = p.spawn_empty().id();
84///     }).id();
85///     child2 = p.spawn_empty().id();
86/// }).id();
87///
88/// assert_eq!(&**world.entity(root).get::<Children>().unwrap(), &[child1, child2]);
89/// assert_eq!(&**world.entity(child1).get::<Children>().unwrap(), &[grandchild]);
90/// ```
91///
92/// [`Relationship`]: crate::relationship::Relationship
93#[derive(Component, Clone, PartialEq, Eq, Debug)]
94#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
95#[cfg_attr(
96    feature = "bevy_reflect",
97    reflect(Component, PartialEq, Debug, FromWorld, Clone)
98)]
99#[relationship(relationship_target = Children)]
100#[doc(alias = "IsChild", alias = "Parent")]
101pub struct ChildOf(pub Entity);
102
103impl ChildOf {
104    /// The parent entity of this child entity.
105    #[inline]
106    pub fn parent(&self) -> Entity {
107        self.0
108    }
109
110    /// The parent entity of this child entity.
111    #[deprecated(since = "0.16.0", note = "Use child_of.parent() instead")]
112    #[inline]
113    pub fn get(&self) -> Entity {
114        self.0
115    }
116}
117
118// TODO: We need to impl either FromWorld or Default so ChildOf can be registered as Reflect.
119// This is because Reflect deserialize by creating an instance and apply a patch on top.
120// However ChildOf should only ever be set with a real user-defined entity.  Its worth looking into
121// better ways to handle cases like this.
122impl FromWorld for ChildOf {
123    #[inline(always)]
124    fn from_world(_world: &mut World) -> Self {
125        ChildOf(Entity::PLACEHOLDER)
126    }
127}
128
129/// Tracks which entities are children of this parent entity.
130///
131/// A [`RelationshipTarget`] collection component that is populated
132/// with entities that "target" this entity with the [`ChildOf`] [`Relationship`] component.
133///
134/// Together, these components form the "canonical parent-child hierarchy". See the [`ChildOf`] component for the full
135/// description of this relationship and instructions on how to use it.
136///
137/// # Usage
138///
139/// Like all [`RelationshipTarget`] components, this data should not be directly manipulated to avoid desynchronization.
140/// Instead, modify the [`ChildOf`] components on the "source" entities.
141///
142/// To access the children of an entity, you can iterate over the [`Children`] component,
143/// using the [`IntoIterator`] trait.
144/// For more complex access patterns, see the [`RelationshipTarget`] trait.
145///
146/// [`Relationship`]: crate::relationship::Relationship
147/// [`RelationshipTarget`]: crate::relationship::RelationshipTarget
148#[derive(Component, Default, Debug, PartialEq, Eq)]
149#[relationship_target(relationship = ChildOf, linked_spawn)]
150#[cfg_attr(feature = "bevy_reflect", derive(bevy_reflect::Reflect))]
151#[cfg_attr(feature = "bevy_reflect", reflect(Component, FromWorld, Default))]
152#[doc(alias = "IsParent")]
153pub struct Children(Vec<Entity>);
154
155impl Children {
156    /// Swaps the child at `a_index` with the child at `b_index`.
157    #[inline]
158    pub fn swap(&mut self, a_index: usize, b_index: usize) {
159        self.0.swap(a_index, b_index);
160    }
161
162    /// Sorts children [stably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
163    /// in place using the provided comparator function.
164    ///
165    /// For the underlying implementation, see [`slice::sort_by`].
166    ///
167    /// For the unstable version, see [`sort_unstable_by`](Children::sort_unstable_by).
168    ///
169    /// See also [`sort_by_key`](Children::sort_by_key), [`sort_by_cached_key`](Children::sort_by_cached_key).
170    #[inline]
171    pub fn sort_by<F>(&mut self, compare: F)
172    where
173        F: FnMut(&Entity, &Entity) -> core::cmp::Ordering,
174    {
175        self.0.sort_by(compare);
176    }
177
178    /// Sorts children [stably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
179    /// in place using the provided key extraction function.
180    ///
181    /// For the underlying implementation, see [`slice::sort_by_key`].
182    ///
183    /// For the unstable version, see [`sort_unstable_by_key`](Children::sort_unstable_by_key).
184    ///
185    /// See also [`sort_by`](Children::sort_by), [`sort_by_cached_key`](Children::sort_by_cached_key).
186    #[inline]
187    pub fn sort_by_key<K, F>(&mut self, compare: F)
188    where
189        F: FnMut(&Entity) -> K,
190        K: Ord,
191    {
192        self.0.sort_by_key(compare);
193    }
194
195    /// Sorts children [stably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
196    /// in place using the provided key extraction function. Only evaluates each key at most
197    /// once per sort, caching the intermediate results in memory.
198    ///
199    /// For the underlying implementation, see [`slice::sort_by_cached_key`].
200    ///
201    /// See also [`sort_by`](Children::sort_by), [`sort_by_key`](Children::sort_by_key).
202    #[inline]
203    pub fn sort_by_cached_key<K, F>(&mut self, compare: F)
204    where
205        F: FnMut(&Entity) -> K,
206        K: Ord,
207    {
208        self.0.sort_by_cached_key(compare);
209    }
210
211    /// Sorts children [unstably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
212    /// in place using the provided comparator function.
213    ///
214    /// For the underlying implementation, see [`slice::sort_unstable_by`].
215    ///
216    /// For the stable version, see [`sort_by`](Children::sort_by).
217    ///
218    /// See also [`sort_unstable_by_key`](Children::sort_unstable_by_key).
219    #[inline]
220    pub fn sort_unstable_by<F>(&mut self, compare: F)
221    where
222        F: FnMut(&Entity, &Entity) -> core::cmp::Ordering,
223    {
224        self.0.sort_unstable_by(compare);
225    }
226
227    /// Sorts children [unstably](https://en.wikipedia.org/wiki/Sorting_algorithm#Stability)
228    /// in place using the provided key extraction function.
229    ///
230    /// For the underlying implementation, see [`slice::sort_unstable_by_key`].
231    ///
232    /// For the stable version, see [`sort_by_key`](Children::sort_by_key).
233    ///
234    /// See also [`sort_unstable_by`](Children::sort_unstable_by).
235    #[inline]
236    pub fn sort_unstable_by_key<K, F>(&mut self, compare: F)
237    where
238        F: FnMut(&Entity) -> K,
239        K: Ord,
240    {
241        self.0.sort_unstable_by_key(compare);
242    }
243}
244
245impl<'a> IntoIterator for &'a Children {
246    type Item = <Self::IntoIter as Iterator>::Item;
247
248    type IntoIter = slice::Iter<'a, Entity>;
249
250    #[inline(always)]
251    fn into_iter(self) -> Self::IntoIter {
252        self.0.iter()
253    }
254}
255
256impl Deref for Children {
257    type Target = [Entity];
258
259    fn deref(&self) -> &Self::Target {
260        &self.0
261    }
262}
263
264/// A type alias over [`RelatedSpawner`] used to spawn child entities containing a [`ChildOf`] relationship.
265pub type ChildSpawner<'w> = RelatedSpawner<'w, ChildOf>;
266
267/// A type alias over [`RelatedSpawnerCommands`] used to spawn child entities containing a [`ChildOf`] relationship.
268pub type ChildSpawnerCommands<'w> = RelatedSpawnerCommands<'w, ChildOf>;
269
270impl<'w> EntityWorldMut<'w> {
271    /// Spawns children of this entity (with a [`ChildOf`] relationship) by taking a function that operates on a [`ChildSpawner`].
272    /// See also [`with_related`](Self::with_related).
273    pub fn with_children(&mut self, func: impl FnOnce(&mut ChildSpawner)) -> &mut Self {
274        self.with_related_entities(func);
275        self
276    }
277
278    /// Adds the given children to this entity
279    /// See also [`add_related`](Self::add_related).
280    pub fn add_children(&mut self, children: &[Entity]) -> &mut Self {
281        self.add_related::<ChildOf>(children)
282    }
283
284    /// Insert children at specific index.
285    /// See also [`insert_related`](Self::insert_related).
286    pub fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
287        self.insert_related::<ChildOf>(index, children)
288    }
289
290    /// Adds the given child to this entity
291    /// See also [`add_related`](Self::add_related).
292    pub fn add_child(&mut self, child: Entity) -> &mut Self {
293        self.add_related::<ChildOf>(&[child])
294    }
295
296    /// Removes the relationship between this entity and the given entities.
297    pub fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
298        self.remove_related::<ChildOf>(children)
299    }
300
301    /// Replaces all the related children with a new set of children.
302    pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
303        self.replace_related::<ChildOf>(children)
304    }
305
306    /// Replaces all the related children with a new set of children.
307    ///
308    /// # Warning
309    ///
310    /// Failing to maintain the functions invariants may lead to erratic engine behavior including random crashes.
311    /// Refer to [`Self::replace_related_with_difference`] for a list of these invariants.
312    ///
313    /// # Panics
314    ///
315    /// Panics when debug assertions are enabled if an invariant is is broken and the command is executed.
316    pub fn replace_children_with_difference(
317        &mut self,
318        entities_to_unrelate: &[Entity],
319        entities_to_relate: &[Entity],
320        newly_related_entities: &[Entity],
321    ) -> &mut Self {
322        self.replace_related_with_difference::<ChildOf>(
323            entities_to_unrelate,
324            entities_to_relate,
325            newly_related_entities,
326        )
327    }
328
329    /// Spawns the passed bundle and adds it to this entity as a child.
330    ///
331    /// For efficient spawning of multiple children, use [`with_children`].
332    ///
333    /// [`with_children`]: EntityWorldMut::with_children
334    pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
335        let parent = self.id();
336        self.world_scope(|world| {
337            world.spawn((bundle, ChildOf(parent)));
338        });
339        self
340    }
341
342    /// Removes the [`ChildOf`] component, if it exists.
343    #[deprecated(since = "0.16.0", note = "Use entity_mut.remove::<ChildOf>()")]
344    pub fn remove_parent(&mut self) -> &mut Self {
345        self.remove::<ChildOf>();
346        self
347    }
348
349    /// Inserts the [`ChildOf`] component with the given `parent` entity, if it exists.
350    #[deprecated(since = "0.16.0", note = "Use entity_mut.insert(ChildOf(entity))")]
351    pub fn set_parent(&mut self, parent: Entity) -> &mut Self {
352        self.insert(ChildOf(parent));
353        self
354    }
355}
356
357impl<'a> EntityCommands<'a> {
358    /// Spawns children of this entity (with a [`ChildOf`] relationship) by taking a function that operates on a [`ChildSpawner`].
359    pub fn with_children(
360        &mut self,
361        func: impl FnOnce(&mut RelatedSpawnerCommands<ChildOf>),
362    ) -> &mut Self {
363        self.with_related_entities(func);
364        self
365    }
366
367    /// Adds the given children to this entity
368    pub fn add_children(&mut self, children: &[Entity]) -> &mut Self {
369        self.add_related::<ChildOf>(children)
370    }
371
372    /// Insert children at specific index.
373    /// See also [`insert_related`](Self::insert_related).
374    pub fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
375        self.insert_related::<ChildOf>(index, children)
376    }
377
378    /// Adds the given child to this entity
379    pub fn add_child(&mut self, child: Entity) -> &mut Self {
380        self.add_related::<ChildOf>(&[child])
381    }
382
383    /// Removes the relationship between this entity and the given entities.
384    pub fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
385        self.remove_related::<ChildOf>(children)
386    }
387
388    /// Replaces the children on this entity with a new list of children.
389    pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
390        self.replace_related::<ChildOf>(children)
391    }
392
393    /// Replaces all the related entities with a new set of entities.
394    ///
395    /// # Warning
396    ///
397    /// Failing to maintain the functions invariants may lead to erratic engine behavior including random crashes.
398    /// Refer to [`EntityWorldMut::replace_related_with_difference`] for a list of these invariants.
399    ///
400    /// # Panics
401    ///
402    /// Panics when debug assertions are enabled if an invariant is is broken and the command is executed.
403    pub fn replace_children_with_difference(
404        &mut self,
405        entities_to_unrelate: &[Entity],
406        entities_to_relate: &[Entity],
407        newly_related_entities: &[Entity],
408    ) -> &mut Self {
409        self.replace_related_with_difference::<ChildOf>(
410            entities_to_unrelate,
411            entities_to_relate,
412            newly_related_entities,
413        )
414    }
415
416    /// Spawns the passed bundle and adds it to this entity as a child.
417    ///
418    /// For efficient spawning of multiple children, use [`with_children`].
419    ///
420    /// [`with_children`]: EntityCommands::with_children
421    pub fn with_child(&mut self, bundle: impl Bundle) -> &mut Self {
422        self.with_related::<ChildOf>(bundle);
423        self
424    }
425
426    /// Removes the [`ChildOf`] component, if it exists.
427    #[deprecated(since = "0.16.0", note = "Use entity_commands.remove::<ChildOf>()")]
428    pub fn remove_parent(&mut self) -> &mut Self {
429        self.remove::<ChildOf>();
430        self
431    }
432
433    /// Inserts the [`ChildOf`] component with the given `parent` entity, if it exists.
434    #[deprecated(since = "0.16.0", note = "Use entity_commands.insert(ChildOf(entity))")]
435    pub fn set_parent(&mut self, parent: Entity) -> &mut Self {
436        self.insert(ChildOf(parent));
437        self
438    }
439}
440
441/// An `on_insert` component hook that when run, will validate that the parent of a given entity
442/// contains component `C`. This will print a warning if the parent does not contain `C`.
443pub fn validate_parent_has_component<C: Component>(
444    world: DeferredWorld,
445    HookContext { entity, caller, .. }: HookContext,
446) {
447    let entity_ref = world.entity(entity);
448    let Some(child_of) = entity_ref.get::<ChildOf>() else {
449        return;
450    };
451    if !world
452        .get_entity(child_of.parent())
453        .is_ok_and(|e| e.contains::<C>())
454    {
455        // TODO: print name here once Name lives in bevy_ecs
456        let name: Option<String> = None;
457        warn!(
458            "warning[B0004]: {}{name} with the {ty_name} component has a parent without {ty_name}.\n\
459            This will cause inconsistent behaviors! See: https://bevyengine.org/learn/errors/b0004",
460            caller.map(|c| format!("{c}: ")).unwrap_or_default(),
461            ty_name = ShortName::of::<C>(),
462            name = name.map_or_else(
463                || format!("Entity {}", entity),
464                |s| format!("The {s} entity")
465            ),
466        );
467    }
468}
469
470/// Returns a [`SpawnRelatedBundle`] that will insert the [`Children`] component, spawn a [`SpawnableList`] of entities with given bundles that
471/// relate to the [`Children`] entity via the [`ChildOf`] component, and reserve space in the [`Children`] for each spawned entity.
472///
473/// Any additional arguments will be interpreted as bundles to be spawned.
474///
475/// Also see [`related`](crate::related) for a version of this that works with any [`RelationshipTarget`] type.
476///
477/// ```
478/// # use bevy_ecs::hierarchy::Children;
479/// # use bevy_ecs::name::Name;
480/// # use bevy_ecs::world::World;
481/// # use bevy_ecs::children;
482/// # use bevy_ecs::spawn::{Spawn, SpawnRelated};
483/// let mut world = World::new();
484/// world.spawn((
485///     Name::new("Root"),
486///     children![
487///         Name::new("Child1"),
488///         (
489///             Name::new("Child2"),
490///             children![Name::new("Grandchild")]
491///         )
492///     ]
493/// ));
494/// ```
495///
496/// [`RelationshipTarget`]: crate::relationship::RelationshipTarget
497/// [`SpawnRelatedBundle`]: crate::spawn::SpawnRelatedBundle
498/// [`SpawnableList`]: crate::spawn::SpawnableList
499#[macro_export]
500macro_rules! children {
501    [$($child:expr),*$(,)?] => {
502       $crate::hierarchy::Children::spawn(($($crate::spawn::Spawn($child)),*))
503    };
504}
505
506#[cfg(test)]
507mod tests {
508    use crate::{
509        entity::Entity,
510        hierarchy::{ChildOf, Children},
511        relationship::{RelationshipHookMode, RelationshipTarget},
512        spawn::{Spawn, SpawnRelated},
513        world::World,
514    };
515    use alloc::{vec, vec::Vec};
516
517    #[derive(PartialEq, Eq, Debug)]
518    struct Node {
519        entity: Entity,
520        children: Vec<Node>,
521    }
522
523    impl Node {
524        fn new(entity: Entity) -> Self {
525            Self {
526                entity,
527                children: Vec::new(),
528            }
529        }
530
531        fn new_with(entity: Entity, children: Vec<Node>) -> Self {
532            Self { entity, children }
533        }
534    }
535
536    fn get_hierarchy(world: &World, entity: Entity) -> Node {
537        Node {
538            entity,
539            children: world
540                .entity(entity)
541                .get::<Children>()
542                .map_or_else(Default::default, |c| {
543                    c.iter().map(|e| get_hierarchy(world, e)).collect()
544                }),
545        }
546    }
547
548    #[test]
549    fn hierarchy() {
550        let mut world = World::new();
551        let root = world.spawn_empty().id();
552        let child1 = world.spawn(ChildOf(root)).id();
553        let grandchild = world.spawn(ChildOf(child1)).id();
554        let child2 = world.spawn(ChildOf(root)).id();
555
556        // Spawn
557        let hierarchy = get_hierarchy(&world, root);
558        assert_eq!(
559            hierarchy,
560            Node::new_with(
561                root,
562                vec![
563                    Node::new_with(child1, vec![Node::new(grandchild)]),
564                    Node::new(child2)
565                ]
566            )
567        );
568
569        // Removal
570        world.entity_mut(child1).remove::<ChildOf>();
571        let hierarchy = get_hierarchy(&world, root);
572        assert_eq!(hierarchy, Node::new_with(root, vec![Node::new(child2)]));
573
574        // Insert
575        world.entity_mut(child1).insert(ChildOf(root));
576        let hierarchy = get_hierarchy(&world, root);
577        assert_eq!(
578            hierarchy,
579            Node::new_with(
580                root,
581                vec![
582                    Node::new(child2),
583                    Node::new_with(child1, vec![Node::new(grandchild)])
584                ]
585            )
586        );
587
588        // Recursive Despawn
589        world.entity_mut(root).despawn();
590        assert!(world.get_entity(root).is_err());
591        assert!(world.get_entity(child1).is_err());
592        assert!(world.get_entity(child2).is_err());
593        assert!(world.get_entity(grandchild).is_err());
594    }
595
596    #[test]
597    fn with_children() {
598        let mut world = World::new();
599        let mut child1 = Entity::PLACEHOLDER;
600        let mut child2 = Entity::PLACEHOLDER;
601        let root = world
602            .spawn_empty()
603            .with_children(|p| {
604                child1 = p.spawn_empty().id();
605                child2 = p.spawn_empty().id();
606            })
607            .id();
608
609        let hierarchy = get_hierarchy(&world, root);
610        assert_eq!(
611            hierarchy,
612            Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
613        );
614    }
615
616    #[test]
617    fn add_children() {
618        let mut world = World::new();
619        let child1 = world.spawn_empty().id();
620        let child2 = world.spawn_empty().id();
621        let root = world.spawn_empty().add_children(&[child1, child2]).id();
622
623        let hierarchy = get_hierarchy(&world, root);
624        assert_eq!(
625            hierarchy,
626            Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
627        );
628    }
629
630    #[test]
631    fn insert_children() {
632        let mut world = World::new();
633        let child1 = world.spawn_empty().id();
634        let child2 = world.spawn_empty().id();
635        let child3 = world.spawn_empty().id();
636        let child4 = world.spawn_empty().id();
637
638        let mut entity_world_mut = world.spawn_empty();
639
640        let first_children = entity_world_mut.add_children(&[child1, child2]);
641
642        let root = first_children.insert_children(1, &[child3, child4]).id();
643
644        let hierarchy = get_hierarchy(&world, root);
645        assert_eq!(
646            hierarchy,
647            Node::new_with(
648                root,
649                vec![
650                    Node::new(child1),
651                    Node::new(child3),
652                    Node::new(child4),
653                    Node::new(child2)
654                ]
655            )
656        );
657    }
658
659    #[test]
660    fn remove_children() {
661        let mut world = World::new();
662        let child1 = world.spawn_empty().id();
663        let child2 = world.spawn_empty().id();
664        let child3 = world.spawn_empty().id();
665        let child4 = world.spawn_empty().id();
666
667        let mut root = world.spawn_empty();
668        root.add_children(&[child1, child2, child3, child4]);
669        root.remove_children(&[child2, child3]);
670        let root = root.id();
671
672        let hierarchy = get_hierarchy(&world, root);
673        assert_eq!(
674            hierarchy,
675            Node::new_with(root, vec![Node::new(child1), Node::new(child4)])
676        );
677    }
678
679    #[test]
680    fn self_parenting_invalid() {
681        let mut world = World::new();
682        let id = world.spawn_empty().id();
683        world.entity_mut(id).insert(ChildOf(id));
684        assert!(
685            world.entity(id).get::<ChildOf>().is_none(),
686            "invalid ChildOf relationships should self-remove"
687        );
688    }
689
690    #[test]
691    fn missing_parent_invalid() {
692        let mut world = World::new();
693        let parent = world.spawn_empty().id();
694        world.entity_mut(parent).despawn();
695        let id = world.spawn(ChildOf(parent)).id();
696        assert!(
697            world.entity(id).get::<ChildOf>().is_none(),
698            "invalid ChildOf relationships should self-remove"
699        );
700    }
701
702    #[test]
703    fn reinsert_same_parent() {
704        let mut world = World::new();
705        let parent = world.spawn_empty().id();
706        let id = world.spawn(ChildOf(parent)).id();
707        world.entity_mut(id).insert(ChildOf(parent));
708        assert_eq!(
709            Some(&ChildOf(parent)),
710            world.entity(id).get::<ChildOf>(),
711            "ChildOf should still be there"
712        );
713    }
714
715    #[test]
716    fn spawn_children() {
717        let mut world = World::new();
718        let id = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
719        assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 2,);
720    }
721
722    #[test]
723    fn replace_children() {
724        let mut world = World::new();
725        let parent = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
726        let &[child_a, child_b] = &world.entity(parent).get::<Children>().unwrap().0[..] else {
727            panic!("Tried to spawn 2 children on an entity and didn't get 2 children");
728        };
729
730        let child_c = world.spawn_empty().id();
731
732        world
733            .entity_mut(parent)
734            .replace_children(&[child_a, child_c]);
735
736        let children = world.entity(parent).get::<Children>().unwrap();
737
738        assert!(children.contains(&child_a));
739        assert!(children.contains(&child_c));
740        assert!(!children.contains(&child_b));
741
742        assert_eq!(
743            world.entity(child_a).get::<ChildOf>().unwrap(),
744            &ChildOf(parent)
745        );
746        assert_eq!(
747            world.entity(child_c).get::<ChildOf>().unwrap(),
748            &ChildOf(parent)
749        );
750        assert!(world.entity(child_b).get::<ChildOf>().is_none());
751    }
752
753    #[test]
754    fn replace_children_with_nothing() {
755        let mut world = World::new();
756        let parent = world.spawn_empty().id();
757        let child_a = world.spawn_empty().id();
758        let child_b = world.spawn_empty().id();
759
760        world.entity_mut(parent).add_children(&[child_a, child_b]);
761
762        assert_eq!(world.entity(parent).get::<Children>().unwrap().len(), 2);
763
764        world.entity_mut(parent).replace_children(&[]);
765
766        assert!(world.entity(child_a).get::<ChildOf>().is_none());
767        assert!(world.entity(child_b).get::<ChildOf>().is_none());
768    }
769
770    #[test]
771    fn insert_same_child_twice() {
772        let mut world = World::new();
773
774        let parent = world.spawn_empty().id();
775        let child = world.spawn_empty().id();
776
777        world.entity_mut(parent).add_child(child);
778        world.entity_mut(parent).add_child(child);
779
780        let children = world.get::<Children>(parent).unwrap();
781        assert_eq!(children.0, [child]);
782        assert_eq!(
783            world.entity(child).get::<ChildOf>().unwrap(),
784            &ChildOf(parent)
785        );
786    }
787
788    #[test]
789    fn replace_with_difference() {
790        let mut world = World::new();
791
792        let parent = world.spawn_empty().id();
793        let child_a = world.spawn_empty().id();
794        let child_b = world.spawn_empty().id();
795        let child_c = world.spawn_empty().id();
796        let child_d = world.spawn_empty().id();
797
798        // Test inserting new relations
799        world.entity_mut(parent).replace_children_with_difference(
800            &[],
801            &[child_a, child_b],
802            &[child_a, child_b],
803        );
804
805        assert_eq!(
806            world.entity(child_a).get::<ChildOf>().unwrap(),
807            &ChildOf(parent)
808        );
809        assert_eq!(
810            world.entity(child_b).get::<ChildOf>().unwrap(),
811            &ChildOf(parent)
812        );
813        assert_eq!(
814            world.entity(parent).get::<Children>().unwrap().0,
815            [child_a, child_b]
816        );
817
818        // Test replacing relations and changing order
819        world.entity_mut(parent).replace_children_with_difference(
820            &[child_b],
821            &[child_d, child_c, child_a],
822            &[child_c, child_d],
823        );
824        assert_eq!(
825            world.entity(child_a).get::<ChildOf>().unwrap(),
826            &ChildOf(parent)
827        );
828        assert_eq!(
829            world.entity(child_c).get::<ChildOf>().unwrap(),
830            &ChildOf(parent)
831        );
832        assert_eq!(
833            world.entity(child_d).get::<ChildOf>().unwrap(),
834            &ChildOf(parent)
835        );
836        assert_eq!(
837            world.entity(parent).get::<Children>().unwrap().0,
838            [child_d, child_c, child_a]
839        );
840        assert!(!world.entity(child_b).contains::<ChildOf>());
841
842        // Test removing relationships
843        world.entity_mut(parent).replace_children_with_difference(
844            &[child_a, child_d, child_c],
845            &[],
846            &[],
847        );
848        assert!(!world.entity(parent).contains::<Children>());
849        assert!(!world.entity(child_a).contains::<ChildOf>());
850        assert!(!world.entity(child_b).contains::<ChildOf>());
851        assert!(!world.entity(child_c).contains::<ChildOf>());
852        assert!(!world.entity(child_d).contains::<ChildOf>());
853    }
854
855    #[test]
856    fn replace_with_difference_on_empty() {
857        let mut world = World::new();
858
859        let parent = world.spawn_empty().id();
860        let child_a = world.spawn_empty().id();
861
862        world
863            .entity_mut(parent)
864            .replace_children_with_difference(&[child_a], &[], &[]);
865
866        assert!(!world.entity(parent).contains::<Children>());
867        assert!(!world.entity(child_a).contains::<ChildOf>());
868    }
869
870    #[test]
871    fn replace_with_difference_totally_new_children() {
872        let mut world = World::new();
873
874        let parent = world.spawn_empty().id();
875        let child_a = world.spawn_empty().id();
876        let child_b = world.spawn_empty().id();
877        let child_c = world.spawn_empty().id();
878        let child_d = world.spawn_empty().id();
879
880        // Test inserting new relations
881        world.entity_mut(parent).replace_children_with_difference(
882            &[],
883            &[child_a, child_b],
884            &[child_a, child_b],
885        );
886
887        assert_eq!(
888            world.entity(child_a).get::<ChildOf>().unwrap(),
889            &ChildOf(parent)
890        );
891        assert_eq!(
892            world.entity(child_b).get::<ChildOf>().unwrap(),
893            &ChildOf(parent)
894        );
895        assert_eq!(
896            world.entity(parent).get::<Children>().unwrap().0,
897            [child_a, child_b]
898        );
899
900        // Test replacing relations and changing order
901        world.entity_mut(parent).replace_children_with_difference(
902            &[child_b, child_a],
903            &[child_d, child_c],
904            &[child_c, child_d],
905        );
906        assert_eq!(
907            world.entity(child_c).get::<ChildOf>().unwrap(),
908            &ChildOf(parent)
909        );
910        assert_eq!(
911            world.entity(child_d).get::<ChildOf>().unwrap(),
912            &ChildOf(parent)
913        );
914        assert_eq!(
915            world.entity(parent).get::<Children>().unwrap().0,
916            [child_d, child_c]
917        );
918        assert!(!world.entity(child_a).contains::<ChildOf>());
919        assert!(!world.entity(child_b).contains::<ChildOf>());
920    }
921
922    #[test]
923    fn replace_children_order() {
924        let mut world = World::new();
925
926        let parent = world.spawn_empty().id();
927        let child_a = world.spawn_empty().id();
928        let child_b = world.spawn_empty().id();
929        let child_c = world.spawn_empty().id();
930        let child_d = world.spawn_empty().id();
931
932        let initial_order = [child_a, child_b, child_c, child_d];
933        world.entity_mut(parent).add_children(&initial_order);
934
935        assert_eq!(
936            world.entity_mut(parent).get::<Children>().unwrap().0,
937            initial_order
938        );
939
940        let new_order = [child_d, child_b, child_a, child_c];
941        world.entity_mut(parent).replace_children(&new_order);
942
943        assert_eq!(world.entity(parent).get::<Children>().unwrap().0, new_order);
944    }
945
946    #[test]
947    #[should_panic]
948    #[cfg_attr(
949        not(debug_assertions),
950        ignore = "we don't check invariants if debug assertions are off"
951    )]
952    fn replace_diff_invariant_overlapping_unrelate_with_relate() {
953        let mut world = World::new();
954
955        let parent = world.spawn_empty().id();
956        let child_a = world.spawn_empty().id();
957
958        world
959            .entity_mut(parent)
960            .replace_children_with_difference(&[], &[child_a], &[child_a]);
961
962        // This should panic
963        world
964            .entity_mut(parent)
965            .replace_children_with_difference(&[child_a], &[child_a], &[]);
966    }
967
968    #[test]
969    #[should_panic]
970    #[cfg_attr(
971        not(debug_assertions),
972        ignore = "we don't check invariants if debug assertions are off"
973    )]
974    fn replace_diff_invariant_overlapping_unrelate_with_newly() {
975        let mut world = World::new();
976
977        let parent = world.spawn_empty().id();
978        let child_a = world.spawn_empty().id();
979        let child_b = world.spawn_empty().id();
980
981        world
982            .entity_mut(parent)
983            .replace_children_with_difference(&[], &[child_a], &[child_a]);
984
985        // This should panic
986        world.entity_mut(parent).replace_children_with_difference(
987            &[child_b],
988            &[child_a, child_b],
989            &[child_b],
990        );
991    }
992
993    #[test]
994    #[should_panic]
995    #[cfg_attr(
996        not(debug_assertions),
997        ignore = "we don't check invariants if debug assertions are off"
998    )]
999    fn replace_diff_invariant_newly_not_subset() {
1000        let mut world = World::new();
1001
1002        let parent = world.spawn_empty().id();
1003        let child_a = world.spawn_empty().id();
1004        let child_b = world.spawn_empty().id();
1005
1006        // This should panic
1007        world.entity_mut(parent).replace_children_with_difference(
1008            &[],
1009            &[child_a, child_b],
1010            &[child_a],
1011        );
1012    }
1013
1014    #[test]
1015    fn child_replace_hook_skip() {
1016        let mut world = World::new();
1017        let parent = world.spawn_empty().id();
1018        let other = world.spawn_empty().id();
1019        let child = world.spawn(ChildOf(parent)).id();
1020        world
1021            .entity_mut(child)
1022            .insert_with_relationship_hook_mode(ChildOf(other), RelationshipHookMode::Skip);
1023        assert_eq!(
1024            &**world.entity(parent).get::<Children>().unwrap(),
1025            &[child],
1026            "Children should still have the old value, as on_insert/on_replace didn't run"
1027        );
1028    }
1029}