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