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/// let mut world = World::new();
541/// world.spawn((
542///     Name::new("Root"),
543///     children![
544///         Name::new("Child1"),
545///         (
546///             Name::new("Child2"),
547///             children![Name::new("Grandchild")]
548///         )
549///     ]
550/// ));
551/// ```
552///
553/// [`RelationshipTarget`]: crate::relationship::RelationshipTarget
554/// [`SpawnRelatedBundle`]: crate::spawn::SpawnRelatedBundle
555/// [`SpawnableList`]: crate::spawn::SpawnableList
556#[macro_export]
557macro_rules! children {
558    [$($child:expr),*$(,)?] => {
559        $crate::related!($crate::hierarchy::Children [$($child),*])
560    };
561}
562
563#[cfg(test)]
564mod tests {
565    use crate::{
566        entity::Entity,
567        hierarchy::{ChildOf, Children},
568        relationship::{RelationshipHookMode, RelationshipTarget},
569        spawn::{Spawn, SpawnRelated},
570        world::World,
571    };
572    use alloc::{vec, vec::Vec};
573
574    #[derive(PartialEq, Eq, Debug)]
575    struct Node {
576        entity: Entity,
577        children: Vec<Node>,
578    }
579
580    impl Node {
581        fn new(entity: Entity) -> Self {
582            Self {
583                entity,
584                children: Vec::new(),
585            }
586        }
587
588        fn new_with(entity: Entity, children: Vec<Node>) -> Self {
589            Self { entity, children }
590        }
591    }
592
593    fn get_hierarchy(world: &World, entity: Entity) -> Node {
594        Node {
595            entity,
596            children: world
597                .entity(entity)
598                .get::<Children>()
599                .map_or_else(Default::default, |c| {
600                    c.iter().map(|e| get_hierarchy(world, e)).collect()
601                }),
602        }
603    }
604
605    #[test]
606    fn hierarchy() {
607        let mut world = World::new();
608        let root = world.spawn_empty().id();
609        let child1 = world.spawn(ChildOf(root)).id();
610        let grandchild = world.spawn(ChildOf(child1)).id();
611        let child2 = world.spawn(ChildOf(root)).id();
612
613        // Spawn
614        let hierarchy = get_hierarchy(&world, root);
615        assert_eq!(
616            hierarchy,
617            Node::new_with(
618                root,
619                vec![
620                    Node::new_with(child1, vec![Node::new(grandchild)]),
621                    Node::new(child2)
622                ]
623            )
624        );
625
626        // Removal
627        world.entity_mut(child1).remove::<ChildOf>();
628        let hierarchy = get_hierarchy(&world, root);
629        assert_eq!(hierarchy, Node::new_with(root, vec![Node::new(child2)]));
630
631        // Insert
632        world.entity_mut(child1).insert(ChildOf(root));
633        let hierarchy = get_hierarchy(&world, root);
634        assert_eq!(
635            hierarchy,
636            Node::new_with(
637                root,
638                vec![
639                    Node::new(child2),
640                    Node::new_with(child1, vec![Node::new(grandchild)])
641                ]
642            )
643        );
644
645        // Recursive Despawn
646        world.entity_mut(root).despawn();
647        assert!(world.get_entity(root).is_err());
648        assert!(world.get_entity(child1).is_err());
649        assert!(world.get_entity(child2).is_err());
650        assert!(world.get_entity(grandchild).is_err());
651    }
652
653    #[test]
654    fn with_children() {
655        let mut world = World::new();
656        let mut child1 = Entity::PLACEHOLDER;
657        let mut child2 = Entity::PLACEHOLDER;
658        let root = world
659            .spawn_empty()
660            .with_children(|p| {
661                child1 = p.spawn_empty().id();
662                child2 = p.spawn_empty().id();
663            })
664            .id();
665
666        let hierarchy = get_hierarchy(&world, root);
667        assert_eq!(
668            hierarchy,
669            Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
670        );
671    }
672
673    #[test]
674    fn add_children() {
675        let mut world = World::new();
676        let child1 = world.spawn_empty().id();
677        let child2 = world.spawn_empty().id();
678        let root = world.spawn_empty().add_children(&[child1, child2]).id();
679
680        let hierarchy = get_hierarchy(&world, root);
681        assert_eq!(
682            hierarchy,
683            Node::new_with(root, vec![Node::new(child1), Node::new(child2)])
684        );
685    }
686
687    #[test]
688    fn insert_children() {
689        let mut world = World::new();
690        let child1 = world.spawn_empty().id();
691        let child2 = world.spawn_empty().id();
692        let child3 = world.spawn_empty().id();
693        let child4 = world.spawn_empty().id();
694
695        let mut entity_world_mut = world.spawn_empty();
696
697        let first_children = entity_world_mut.add_children(&[child1, child2]);
698
699        let root = first_children.insert_children(1, &[child3, child4]).id();
700
701        let hierarchy = get_hierarchy(&world, root);
702        assert_eq!(
703            hierarchy,
704            Node::new_with(
705                root,
706                vec![
707                    Node::new(child1),
708                    Node::new(child3),
709                    Node::new(child4),
710                    Node::new(child2)
711                ]
712            )
713        );
714    }
715
716    #[test]
717    fn insert_child() {
718        let mut world = World::new();
719        let child1 = world.spawn_empty().id();
720        let child2 = world.spawn_empty().id();
721        let child3 = world.spawn_empty().id();
722
723        let mut entity_world_mut = world.spawn_empty();
724
725        let first_children = entity_world_mut.add_children(&[child1, child2]);
726
727        let root = first_children.insert_child(1, child3).id();
728
729        let hierarchy = get_hierarchy(&world, root);
730        assert_eq!(
731            hierarchy,
732            Node::new_with(
733                root,
734                vec![Node::new(child1), Node::new(child3), Node::new(child2)]
735            )
736        );
737    }
738
739    // regression test for https://github.com/bevyengine/bevy/pull/19134
740    #[test]
741    fn insert_children_index_bound() {
742        let mut world = World::new();
743        let child1 = world.spawn_empty().id();
744        let child2 = world.spawn_empty().id();
745        let child3 = world.spawn_empty().id();
746        let child4 = world.spawn_empty().id();
747
748        let mut entity_world_mut = world.spawn_empty();
749
750        let first_children = entity_world_mut.add_children(&[child1, child2]).id();
751        let hierarchy = get_hierarchy(&world, first_children);
752        assert_eq!(
753            hierarchy,
754            Node::new_with(first_children, vec![Node::new(child1), Node::new(child2)])
755        );
756
757        let root = world
758            .entity_mut(first_children)
759            .insert_children(usize::MAX, &[child3, child4])
760            .id();
761        let hierarchy = get_hierarchy(&world, root);
762        assert_eq!(
763            hierarchy,
764            Node::new_with(
765                root,
766                vec![
767                    Node::new(child1),
768                    Node::new(child2),
769                    Node::new(child3),
770                    Node::new(child4),
771                ]
772            )
773        );
774    }
775
776    #[test]
777    fn detach_children() {
778        let mut world = World::new();
779        let child1 = world.spawn_empty().id();
780        let child2 = world.spawn_empty().id();
781        let child3 = world.spawn_empty().id();
782        let child4 = world.spawn_empty().id();
783
784        let mut root = world.spawn_empty();
785        root.add_children(&[child1, child2, child3, child4]);
786        root.detach_children(&[child2, child3]);
787        let root = root.id();
788
789        let hierarchy = get_hierarchy(&world, root);
790        assert_eq!(
791            hierarchy,
792            Node::new_with(root, vec![Node::new(child1), Node::new(child4)])
793        );
794    }
795
796    #[test]
797    fn detach_child() {
798        let mut world = World::new();
799        let child1 = world.spawn_empty().id();
800        let child2 = world.spawn_empty().id();
801        let child3 = world.spawn_empty().id();
802
803        let mut root = world.spawn_empty();
804        root.add_children(&[child1, child2, child3]);
805        root.detach_child(child2);
806        let root = root.id();
807
808        let hierarchy = get_hierarchy(&world, root);
809        assert_eq!(
810            hierarchy,
811            Node::new_with(root, vec![Node::new(child1), Node::new(child3)])
812        );
813    }
814
815    #[test]
816    fn self_parenting_invalid() {
817        let mut world = World::new();
818        let id = world.spawn_empty().id();
819        world.entity_mut(id).insert(ChildOf(id));
820        assert!(
821            world.entity(id).get::<ChildOf>().is_none(),
822            "invalid ChildOf relationships should self-remove"
823        );
824    }
825
826    #[test]
827    fn missing_parent_invalid() {
828        let mut world = World::new();
829        let parent = world.spawn_empty().id();
830        world.entity_mut(parent).despawn();
831        let id = world.spawn(ChildOf(parent)).id();
832        assert!(
833            world.entity(id).get::<ChildOf>().is_none(),
834            "invalid ChildOf relationships should self-remove"
835        );
836    }
837
838    #[test]
839    fn reinsert_same_parent() {
840        let mut world = World::new();
841        let parent = world.spawn_empty().id();
842        let id = world.spawn(ChildOf(parent)).id();
843        world.entity_mut(id).insert(ChildOf(parent));
844        assert_eq!(
845            Some(&ChildOf(parent)),
846            world.entity(id).get::<ChildOf>(),
847            "ChildOf should still be there"
848        );
849    }
850
851    #[test]
852    fn spawn_children() {
853        let mut world = World::new();
854        let id = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
855        assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 2,);
856    }
857
858    #[test]
859    fn spawn_many_children() {
860        let mut world = World::new();
861
862        // ensure an empty set can be mentioned
863        world.spawn(children![]);
864
865        // 12 children should result in a flat tuple
866        let id = world
867            .spawn(children![(), (), (), (), (), (), (), (), (), (), (), ()])
868            .id();
869
870        assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 12,);
871
872        // 13 will start nesting, but should nonetheless produce a flat hierarchy
873        let id = world
874            .spawn(children![
875                (),
876                (),
877                (),
878                (),
879                (),
880                (),
881                (),
882                (),
883                (),
884                (),
885                (),
886                (),
887                (),
888            ])
889            .id();
890
891        assert_eq!(world.entity(id).get::<Children>().unwrap().len(), 13,);
892    }
893
894    #[test]
895    fn replace_children() {
896        let mut world = World::new();
897        let parent = world.spawn(Children::spawn((Spawn(()), Spawn(())))).id();
898        let &[child_a, child_b] = &world.entity(parent).get::<Children>().unwrap().0[..] else {
899            panic!("Tried to spawn 2 children on an entity and didn't get 2 children");
900        };
901
902        let child_c = world.spawn_empty().id();
903
904        world
905            .entity_mut(parent)
906            .replace_children(&[child_a, child_c]);
907
908        let children = world.entity(parent).get::<Children>().unwrap();
909
910        assert!(children.contains(&child_a));
911        assert!(children.contains(&child_c));
912        assert!(!children.contains(&child_b));
913
914        assert_eq!(
915            world.entity(child_a).get::<ChildOf>().unwrap(),
916            &ChildOf(parent)
917        );
918        assert_eq!(
919            world.entity(child_c).get::<ChildOf>().unwrap(),
920            &ChildOf(parent)
921        );
922        assert!(world.entity(child_b).get::<ChildOf>().is_none());
923    }
924
925    #[test]
926    fn replace_children_with_nothing() {
927        let mut world = World::new();
928        let parent = world.spawn_empty().id();
929        let child_a = world.spawn_empty().id();
930        let child_b = world.spawn_empty().id();
931
932        world.entity_mut(parent).add_children(&[child_a, child_b]);
933
934        assert_eq!(world.entity(parent).get::<Children>().unwrap().len(), 2);
935
936        world.entity_mut(parent).replace_children(&[]);
937
938        assert!(world.entity(child_a).get::<ChildOf>().is_none());
939        assert!(world.entity(child_b).get::<ChildOf>().is_none());
940    }
941
942    #[test]
943    fn insert_same_child_twice() {
944        let mut world = World::new();
945
946        let parent = world.spawn_empty().id();
947        let child = world.spawn_empty().id();
948
949        world.entity_mut(parent).add_child(child);
950        world.entity_mut(parent).add_child(child);
951
952        let children = world.get::<Children>(parent).unwrap();
953        assert_eq!(children.0, [child]);
954        assert_eq!(
955            world.entity(child).get::<ChildOf>().unwrap(),
956            &ChildOf(parent)
957        );
958    }
959
960    #[test]
961    fn replace_with_difference() {
962        let mut world = World::new();
963
964        let parent = world.spawn_empty().id();
965        let child_a = world.spawn_empty().id();
966        let child_b = world.spawn_empty().id();
967        let child_c = world.spawn_empty().id();
968        let child_d = world.spawn_empty().id();
969
970        // Test inserting new relations
971        world.entity_mut(parent).replace_children_with_difference(
972            &[],
973            &[child_a, child_b],
974            &[child_a, child_b],
975        );
976
977        assert_eq!(
978            world.entity(child_a).get::<ChildOf>().unwrap(),
979            &ChildOf(parent)
980        );
981        assert_eq!(
982            world.entity(child_b).get::<ChildOf>().unwrap(),
983            &ChildOf(parent)
984        );
985        assert_eq!(
986            world.entity(parent).get::<Children>().unwrap().0,
987            [child_a, child_b]
988        );
989
990        // Test replacing relations and changing order
991        world.entity_mut(parent).replace_children_with_difference(
992            &[child_b],
993            &[child_d, child_c, child_a],
994            &[child_c, child_d],
995        );
996        assert_eq!(
997            world.entity(child_a).get::<ChildOf>().unwrap(),
998            &ChildOf(parent)
999        );
1000        assert_eq!(
1001            world.entity(child_c).get::<ChildOf>().unwrap(),
1002            &ChildOf(parent)
1003        );
1004        assert_eq!(
1005            world.entity(child_d).get::<ChildOf>().unwrap(),
1006            &ChildOf(parent)
1007        );
1008        assert_eq!(
1009            world.entity(parent).get::<Children>().unwrap().0,
1010            [child_d, child_c, child_a]
1011        );
1012        assert!(!world.entity(child_b).contains::<ChildOf>());
1013
1014        // Test removing relationships
1015        world.entity_mut(parent).replace_children_with_difference(
1016            &[child_a, child_d, child_c],
1017            &[],
1018            &[],
1019        );
1020        assert!(!world.entity(parent).contains::<Children>());
1021        assert!(!world.entity(child_a).contains::<ChildOf>());
1022        assert!(!world.entity(child_b).contains::<ChildOf>());
1023        assert!(!world.entity(child_c).contains::<ChildOf>());
1024        assert!(!world.entity(child_d).contains::<ChildOf>());
1025    }
1026
1027    #[test]
1028    fn replace_with_difference_on_empty() {
1029        let mut world = World::new();
1030
1031        let parent = world.spawn_empty().id();
1032        let child_a = world.spawn_empty().id();
1033
1034        world
1035            .entity_mut(parent)
1036            .replace_children_with_difference(&[child_a], &[], &[]);
1037
1038        assert!(!world.entity(parent).contains::<Children>());
1039        assert!(!world.entity(child_a).contains::<ChildOf>());
1040    }
1041
1042    #[test]
1043    fn replace_with_difference_totally_new_children() {
1044        let mut world = World::new();
1045
1046        let parent = world.spawn_empty().id();
1047        let child_a = world.spawn_empty().id();
1048        let child_b = world.spawn_empty().id();
1049        let child_c = world.spawn_empty().id();
1050        let child_d = world.spawn_empty().id();
1051
1052        // Test inserting new relations
1053        world.entity_mut(parent).replace_children_with_difference(
1054            &[],
1055            &[child_a, child_b],
1056            &[child_a, child_b],
1057        );
1058
1059        assert_eq!(
1060            world.entity(child_a).get::<ChildOf>().unwrap(),
1061            &ChildOf(parent)
1062        );
1063        assert_eq!(
1064            world.entity(child_b).get::<ChildOf>().unwrap(),
1065            &ChildOf(parent)
1066        );
1067        assert_eq!(
1068            world.entity(parent).get::<Children>().unwrap().0,
1069            [child_a, child_b]
1070        );
1071
1072        // Test replacing relations and changing order
1073        world.entity_mut(parent).replace_children_with_difference(
1074            &[child_b, child_a],
1075            &[child_d, child_c],
1076            &[child_c, child_d],
1077        );
1078        assert_eq!(
1079            world.entity(child_c).get::<ChildOf>().unwrap(),
1080            &ChildOf(parent)
1081        );
1082        assert_eq!(
1083            world.entity(child_d).get::<ChildOf>().unwrap(),
1084            &ChildOf(parent)
1085        );
1086        assert_eq!(
1087            world.entity(parent).get::<Children>().unwrap().0,
1088            [child_d, child_c]
1089        );
1090        assert!(!world.entity(child_a).contains::<ChildOf>());
1091        assert!(!world.entity(child_b).contains::<ChildOf>());
1092    }
1093
1094    #[test]
1095    fn replace_children_order() {
1096        let mut world = World::new();
1097
1098        let parent = world.spawn_empty().id();
1099        let child_a = world.spawn_empty().id();
1100        let child_b = world.spawn_empty().id();
1101        let child_c = world.spawn_empty().id();
1102        let child_d = world.spawn_empty().id();
1103
1104        let initial_order = [child_a, child_b, child_c, child_d];
1105        world.entity_mut(parent).add_children(&initial_order);
1106
1107        assert_eq!(
1108            world.entity_mut(parent).get::<Children>().unwrap().0,
1109            initial_order
1110        );
1111
1112        let new_order = [child_d, child_b, child_a, child_c];
1113        world.entity_mut(parent).replace_children(&new_order);
1114
1115        assert_eq!(world.entity(parent).get::<Children>().unwrap().0, new_order);
1116    }
1117
1118    #[test]
1119    #[should_panic]
1120    #[cfg_attr(
1121        not(debug_assertions),
1122        ignore = "we don't check invariants if debug assertions are off"
1123    )]
1124    fn replace_diff_invariant_overlapping_unrelate_with_relate() {
1125        let mut world = World::new();
1126
1127        let parent = world.spawn_empty().id();
1128        let child_a = world.spawn_empty().id();
1129
1130        world
1131            .entity_mut(parent)
1132            .replace_children_with_difference(&[], &[child_a], &[child_a]);
1133
1134        // This should panic
1135        world
1136            .entity_mut(parent)
1137            .replace_children_with_difference(&[child_a], &[child_a], &[]);
1138    }
1139
1140    #[test]
1141    #[should_panic]
1142    #[cfg_attr(
1143        not(debug_assertions),
1144        ignore = "we don't check invariants if debug assertions are off"
1145    )]
1146    fn replace_diff_invariant_overlapping_unrelate_with_newly() {
1147        let mut world = World::new();
1148
1149        let parent = world.spawn_empty().id();
1150        let child_a = world.spawn_empty().id();
1151        let child_b = world.spawn_empty().id();
1152
1153        world
1154            .entity_mut(parent)
1155            .replace_children_with_difference(&[], &[child_a], &[child_a]);
1156
1157        // This should panic
1158        world.entity_mut(parent).replace_children_with_difference(
1159            &[child_b],
1160            &[child_a, child_b],
1161            &[child_b],
1162        );
1163    }
1164
1165    #[test]
1166    #[should_panic]
1167    #[cfg_attr(
1168        not(debug_assertions),
1169        ignore = "we don't check invariants if debug assertions are off"
1170    )]
1171    fn replace_diff_invariant_newly_not_subset() {
1172        let mut world = World::new();
1173
1174        let parent = world.spawn_empty().id();
1175        let child_a = world.spawn_empty().id();
1176        let child_b = world.spawn_empty().id();
1177
1178        // This should panic
1179        world.entity_mut(parent).replace_children_with_difference(
1180            &[],
1181            &[child_a, child_b],
1182            &[child_a],
1183        );
1184    }
1185
1186    #[test]
1187    fn child_replace_hook_skip() {
1188        let mut world = World::new();
1189        let parent = world.spawn_empty().id();
1190        let other = world.spawn_empty().id();
1191        let child = world.spawn(ChildOf(parent)).id();
1192        world
1193            .entity_mut(child)
1194            .insert_with_relationship_hook_mode(ChildOf(other), RelationshipHookMode::Skip);
1195        assert_eq!(
1196            &**world.entity(parent).get::<Children>().unwrap(),
1197            &[child],
1198            "Children should still have the old value, as on_insert/on_replace didn't run"
1199        );
1200    }
1201}