bevy_hierarchy/
child_builder.rs

1use crate::{Children, HierarchyEvent, Parent};
2use bevy_ecs::{
3    bundle::Bundle,
4    entity::Entity,
5    prelude::Events,
6    system::{Commands, EntityCommands},
7    world::{Command, EntityWorldMut, World},
8};
9use smallvec::{smallvec, SmallVec};
10
11// Do not use `world.send_event_batch` as it prints error message when the Events are not available in the world,
12// even though it's a valid use case to execute commands on a world without events. Loading a GLTF file for example
13fn push_events(world: &mut World, events: impl IntoIterator<Item = HierarchyEvent>) {
14    if let Some(mut moved) = world.get_resource_mut::<Events<HierarchyEvent>>() {
15        moved.extend(events);
16    }
17}
18
19/// Adds `child` to `parent`'s [`Children`], without checking if it is already present there.
20///
21/// This might cause unexpected results when removing duplicate children.
22fn add_child_unchecked(world: &mut World, parent: Entity, child: Entity) {
23    let mut parent = world.entity_mut(parent);
24    if let Some(mut children) = parent.get_mut::<Children>() {
25        children.0.push(child);
26    } else {
27        parent.insert(Children(smallvec![child]));
28    }
29}
30
31/// Sets [`Parent`] of the `child` to `new_parent`. Inserts [`Parent`] if `child` doesn't have one.
32fn update_parent(world: &mut World, child: Entity, new_parent: Entity) -> Option<Entity> {
33    let mut child = world.entity_mut(child);
34    if let Some(mut parent) = child.get_mut::<Parent>() {
35        let previous = parent.0;
36        *parent = Parent(new_parent);
37        Some(previous)
38    } else {
39        child.insert(Parent(new_parent));
40        None
41    }
42}
43
44/// Remove child from the parent's [`Children`] component.
45///
46/// Removes the [`Children`] component from the parent if it's empty.
47fn remove_from_children(world: &mut World, parent: Entity, child: Entity) {
48    let Ok(mut parent) = world.get_entity_mut(parent) else {
49        return;
50    };
51    let Some(mut children) = parent.get_mut::<Children>() else {
52        return;
53    };
54    children.0.retain(|x| *x != child);
55    if children.is_empty() {
56        parent.remove::<Children>();
57    }
58}
59
60/// Update the [`Parent`] component of the `child`.
61/// Removes the `child` from the previous parent's [`Children`].
62///
63/// Does not update the new parents [`Children`] component.
64///
65/// Does nothing if `child` was already a child of `parent`.
66///
67/// Sends [`HierarchyEvent`]'s.
68fn update_old_parent(world: &mut World, child: Entity, parent: Entity) {
69    let previous = update_parent(world, child, parent);
70    if let Some(previous_parent) = previous {
71        // Do nothing if the child was already parented to this entity.
72        if previous_parent == parent {
73            return;
74        }
75        remove_from_children(world, previous_parent, child);
76
77        push_events(
78            world,
79            [HierarchyEvent::ChildMoved {
80                child,
81                previous_parent,
82                new_parent: parent,
83            }],
84        );
85    } else {
86        push_events(world, [HierarchyEvent::ChildAdded { child, parent }]);
87    }
88}
89
90/// Update the [`Parent`] components of the `children`.
91/// Removes the `children` from their previous parent's [`Children`].
92///
93/// Does not update the new parents [`Children`] component.
94///
95/// Does nothing for a child if it was already a child of `parent`.
96///
97/// Sends [`HierarchyEvent`]'s.
98fn update_old_parents(world: &mut World, parent: Entity, children: &[Entity]) {
99    let mut events: SmallVec<[HierarchyEvent; 8]> = SmallVec::with_capacity(children.len());
100    for &child in children {
101        if let Some(previous) = update_parent(world, child, parent) {
102            // Do nothing if the entity already has the correct parent.
103            if parent == previous {
104                continue;
105            }
106
107            remove_from_children(world, previous, child);
108            events.push(HierarchyEvent::ChildMoved {
109                child,
110                previous_parent: previous,
111                new_parent: parent,
112            });
113        } else {
114            events.push(HierarchyEvent::ChildAdded { child, parent });
115        }
116    }
117    push_events(world, events);
118}
119
120/// Removes entities in `children` from `parent`'s [`Children`], removing the component if it ends up empty.
121/// Also removes [`Parent`] component from `children`.
122fn remove_children(parent: Entity, children: &[Entity], world: &mut World) {
123    let mut events: SmallVec<[HierarchyEvent; 8]> = SmallVec::new();
124    if let Some(parent_children) = world.get::<Children>(parent) {
125        for &child in children {
126            if parent_children.contains(&child) {
127                events.push(HierarchyEvent::ChildRemoved { child, parent });
128            }
129        }
130    } else {
131        return;
132    }
133    for event in &events {
134        if let &HierarchyEvent::ChildRemoved { child, .. } = event {
135            world.entity_mut(child).remove::<Parent>();
136        }
137    }
138    push_events(world, events);
139
140    let mut parent = world.entity_mut(parent);
141    if let Some(mut parent_children) = parent.get_mut::<Children>() {
142        parent_children
143            .0
144            .retain(|parent_child| !children.contains(parent_child));
145
146        if parent_children.is_empty() {
147            parent.remove::<Children>();
148        }
149    }
150}
151
152/// Removes all children from `parent` by removing its [`Children`] component, as well as removing
153/// [`Parent`] component from its children.
154fn clear_children(parent: Entity, world: &mut World) {
155    if let Some(children) = world.entity_mut(parent).take::<Children>() {
156        for &child in &children.0 {
157            world.entity_mut(child).remove::<Parent>();
158        }
159    }
160}
161
162/// Command that adds a child to an entity.
163#[derive(Debug)]
164pub struct AddChild {
165    /// Parent entity to add the child to.
166    pub parent: Entity,
167    /// Child entity to add.
168    pub child: Entity,
169}
170
171impl Command for AddChild {
172    fn apply(self, world: &mut World) {
173        world.entity_mut(self.parent).add_child(self.child);
174    }
175}
176
177/// Command that inserts a child at a given index of a parent's children, shifting following children back.
178#[derive(Debug)]
179pub struct InsertChildren {
180    parent: Entity,
181    children: SmallVec<[Entity; 8]>,
182    index: usize,
183}
184
185impl Command for InsertChildren {
186    fn apply(self, world: &mut World) {
187        world
188            .entity_mut(self.parent)
189            .insert_children(self.index, &self.children);
190    }
191}
192
193/// Command that pushes children to the end of the entity's [`Children`].
194#[derive(Debug)]
195pub struct AddChildren {
196    parent: Entity,
197    children: SmallVec<[Entity; 8]>,
198}
199
200impl Command for AddChildren {
201    fn apply(self, world: &mut World) {
202        world.entity_mut(self.parent).add_children(&self.children);
203    }
204}
205
206/// Command that removes children from an entity, and removes these children's parent.
207pub struct RemoveChildren {
208    parent: Entity,
209    children: SmallVec<[Entity; 8]>,
210}
211
212impl Command for RemoveChildren {
213    fn apply(self, world: &mut World) {
214        remove_children(self.parent, &self.children, world);
215    }
216}
217
218/// Command that clears all children from an entity and removes [`Parent`] component from those
219/// children.
220pub struct ClearChildren {
221    parent: Entity,
222}
223
224impl Command for ClearChildren {
225    fn apply(self, world: &mut World) {
226        clear_children(self.parent, world);
227    }
228}
229
230/// Command that clear all children from an entity, replacing them with the given children.
231pub struct ReplaceChildren {
232    parent: Entity,
233    children: SmallVec<[Entity; 8]>,
234}
235
236impl Command for ReplaceChildren {
237    fn apply(self, world: &mut World) {
238        clear_children(self.parent, world);
239        world.entity_mut(self.parent).add_children(&self.children);
240    }
241}
242
243/// Command that removes the parent of an entity, and removes that entity from the parent's [`Children`].
244pub struct RemoveParent {
245    /// `Entity` whose parent must be removed.
246    pub child: Entity,
247}
248
249impl Command for RemoveParent {
250    fn apply(self, world: &mut World) {
251        world.entity_mut(self.child).remove_parent();
252    }
253}
254
255/// Struct for building children entities and adding them to a parent entity.
256///
257/// # Example
258///
259/// This example creates three entities, a parent and two children.
260///
261/// ```
262/// # use bevy_ecs::bundle::Bundle;
263/// # use bevy_ecs::system::Commands;
264/// # use bevy_hierarchy::{ChildBuild, BuildChildren};
265/// # #[derive(Bundle)]
266/// # struct MyBundle {}
267/// # #[derive(Bundle)]
268/// # struct MyChildBundle {}
269/// #
270/// # fn test(mut commands: Commands) {
271/// commands.spawn(MyBundle {}).with_children(|child_builder| {
272///     child_builder.spawn(MyChildBundle {});
273///     child_builder.spawn(MyChildBundle {});
274/// });
275/// # }
276/// ```
277pub struct ChildBuilder<'a> {
278    commands: Commands<'a, 'a>,
279    add_children: AddChildren,
280}
281
282/// Trait for building children entities and adding them to a parent entity. This is used in
283/// implementations of [`BuildChildren`] as a bound on the [`Builder`](BuildChildren::Builder)
284/// associated type. The closure passed to [`BuildChildren::with_children`] accepts an
285/// implementation of `ChildBuild` so that children can be spawned via [`ChildBuild::spawn`].
286pub trait ChildBuild {
287    /// Spawn output type. Both [`spawn`](Self::spawn) and [`spawn_empty`](Self::spawn_empty) return
288    /// an implementation of this type so that children can be operated on via method-chaining.
289    /// Implementations of `ChildBuild` reborrow `self` when spawning entities (see
290    /// [`Commands::spawn_empty`] and [`World::get_entity_mut`]). Lifetime `'a` corresponds to this
291    /// reborrowed self, and `Self` outlives it.
292    type SpawnOutput<'a>: BuildChildren
293    where
294        Self: 'a;
295
296    /// Spawns an entity with the given bundle and inserts it into the parent entity's [`Children`].
297    /// Also adds [`Parent`] component to the created entity.
298    fn spawn(&mut self, bundle: impl Bundle) -> Self::SpawnOutput<'_>;
299
300    /// Spawns an [`Entity`] with no components and inserts it into the parent entity's [`Children`].
301    /// Also adds [`Parent`] component to the created entity.
302    fn spawn_empty(&mut self) -> Self::SpawnOutput<'_>;
303
304    /// Returns the parent entity.
305    fn parent_entity(&self) -> Entity;
306
307    /// Adds a command to be executed, like [`Commands::queue`].
308    fn enqueue_command<C: Command>(&mut self, command: C) -> &mut Self;
309}
310
311impl ChildBuild for ChildBuilder<'_> {
312    type SpawnOutput<'a>
313        = EntityCommands<'a>
314    where
315        Self: 'a;
316
317    fn spawn(&mut self, bundle: impl Bundle) -> EntityCommands {
318        let e = self.commands.spawn(bundle);
319        self.add_children.children.push(e.id());
320        e
321    }
322
323    fn spawn_empty(&mut self) -> EntityCommands {
324        let e = self.commands.spawn_empty();
325        self.add_children.children.push(e.id());
326        e
327    }
328
329    fn parent_entity(&self) -> Entity {
330        self.add_children.parent
331    }
332
333    fn enqueue_command<C: Command>(&mut self, command: C) -> &mut Self {
334        self.commands.queue(command);
335        self
336    }
337}
338
339/// Trait for removing, adding and replacing children and parents of an entity.
340pub trait BuildChildren {
341    /// Child builder type.
342    type Builder<'a>: ChildBuild;
343
344    /// Takes a closure which builds children for this entity using [`ChildBuild`].
345    ///
346    /// For convenient spawning of a single child, you can use [`with_child`].
347    ///
348    /// [`with_child`]: BuildChildren::with_child
349    fn with_children(&mut self, f: impl FnOnce(&mut Self::Builder<'_>)) -> &mut Self;
350
351    /// Spawns the passed bundle and adds it to this entity as a child.
352    ///
353    /// For efficient spawning of multiple children, use [`with_children`].
354    ///
355    /// [`with_children`]: BuildChildren::with_children
356    fn with_child<B: Bundle>(&mut self, bundle: B) -> &mut Self;
357
358    /// Pushes children to the back of the builder's children. For any entities that are
359    /// already a child of this one, this method does nothing.
360    ///
361    /// If the children were previously children of another parent, that parent's [`Children`] component
362    /// will have those children removed from its list. Removing all children from a parent causes its
363    /// [`Children`] component to be removed from the entity.
364    ///
365    /// # Panics
366    ///
367    /// Panics if any of the children are the same as the parent.
368    fn add_children(&mut self, children: &[Entity]) -> &mut Self;
369
370    /// Inserts children at the given index.
371    ///
372    /// If the children were previously children of another parent, that parent's [`Children`] component
373    /// will have those children removed from its list. Removing all children from a parent causes its
374    /// [`Children`] component to be removed from the entity.
375    ///
376    /// # Panics
377    ///
378    /// Panics if any of the children are the same as the parent.
379    fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self;
380
381    /// Removes the given children
382    ///
383    /// Removing all children from a parent causes its [`Children`] component to be removed from the entity.
384    fn remove_children(&mut self, children: &[Entity]) -> &mut Self;
385
386    /// Adds a single child.
387    ///
388    /// If the children were previously children of another parent, that parent's [`Children`] component
389    /// will have those children removed from its list. Removing all children from a parent causes its
390    /// [`Children`] component to be removed from the entity.
391    ///
392    /// # Panics
393    ///
394    /// Panics if the child is the same as the parent.
395    fn add_child(&mut self, child: Entity) -> &mut Self;
396
397    /// Removes all children from this entity. The [`Children`] component will be removed if it exists, otherwise this does nothing.
398    fn clear_children(&mut self) -> &mut Self;
399
400    /// Removes all current children from this entity, replacing them with the specified list of entities.
401    ///
402    /// The removed children will have their [`Parent`] component removed.
403    ///
404    /// # Panics
405    ///
406    /// Panics if any of the children are the same as the parent.
407    fn replace_children(&mut self, children: &[Entity]) -> &mut Self;
408
409    /// Sets the parent of this entity.
410    ///
411    /// If this entity already had a parent, the parent's [`Children`] component will have this
412    /// child removed from its list. Removing all children from a parent causes its [`Children`]
413    /// component to be removed from the entity.
414    ///
415    /// # Panics
416    ///
417    /// Panics if the parent is the same as the child.
418    fn set_parent(&mut self, parent: Entity) -> &mut Self;
419
420    /// Removes the [`Parent`] of this entity.
421    ///
422    /// Also removes this entity from its parent's [`Children`] component. Removing all children from a parent causes
423    /// its [`Children`] component to be removed from the entity.
424    fn remove_parent(&mut self) -> &mut Self;
425}
426
427impl BuildChildren for EntityCommands<'_> {
428    type Builder<'a> = ChildBuilder<'a>;
429
430    fn with_children(&mut self, spawn_children: impl FnOnce(&mut Self::Builder<'_>)) -> &mut Self {
431        let parent = self.id();
432        let mut builder = ChildBuilder {
433            commands: self.commands(),
434            add_children: AddChildren {
435                children: SmallVec::default(),
436                parent,
437            },
438        };
439
440        spawn_children(&mut builder);
441        let children = builder.add_children;
442        if children.children.contains(&parent) {
443            panic!("Entity cannot be a child of itself.");
444        }
445        self.commands().queue(children);
446        self
447    }
448
449    fn with_child<B: Bundle>(&mut self, bundle: B) -> &mut Self {
450        let parent = self.id();
451        let child = self.commands().spawn(bundle).id();
452        self.commands().queue(AddChild { parent, child });
453        self
454    }
455
456    fn add_children(&mut self, children: &[Entity]) -> &mut Self {
457        let parent = self.id();
458        if children.contains(&parent) {
459            panic!("Cannot push entity as a child of itself.");
460        }
461        self.commands().queue(AddChildren {
462            children: SmallVec::from(children),
463            parent,
464        });
465        self
466    }
467
468    fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
469        let parent = self.id();
470        if children.contains(&parent) {
471            panic!("Cannot insert entity as a child of itself.");
472        }
473        self.commands().queue(InsertChildren {
474            children: SmallVec::from(children),
475            index,
476            parent,
477        });
478        self
479    }
480
481    fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
482        let parent = self.id();
483        self.commands().queue(RemoveChildren {
484            children: SmallVec::from(children),
485            parent,
486        });
487        self
488    }
489
490    fn add_child(&mut self, child: Entity) -> &mut Self {
491        let parent = self.id();
492        if child == parent {
493            panic!("Cannot add entity as a child of itself.");
494        }
495        self.commands().queue(AddChild { child, parent });
496        self
497    }
498
499    fn clear_children(&mut self) -> &mut Self {
500        let parent = self.id();
501        self.commands().queue(ClearChildren { parent });
502        self
503    }
504
505    fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
506        let parent = self.id();
507        if children.contains(&parent) {
508            panic!("Cannot replace entity as a child of itself.");
509        }
510        self.commands().queue(ReplaceChildren {
511            children: SmallVec::from(children),
512            parent,
513        });
514        self
515    }
516
517    fn set_parent(&mut self, parent: Entity) -> &mut Self {
518        let child = self.id();
519        if child == parent {
520            panic!("Cannot set parent to itself");
521        }
522        self.commands().queue(AddChild { child, parent });
523        self
524    }
525
526    fn remove_parent(&mut self) -> &mut Self {
527        let child = self.id();
528        self.commands().queue(RemoveParent { child });
529        self
530    }
531}
532
533/// Struct for adding children to an entity directly through the [`World`] for use in exclusive systems.
534#[derive(Debug)]
535pub struct WorldChildBuilder<'w> {
536    world: &'w mut World,
537    parent: Entity,
538}
539
540impl ChildBuild for WorldChildBuilder<'_> {
541    type SpawnOutput<'a>
542        = EntityWorldMut<'a>
543    where
544        Self: 'a;
545
546    fn spawn(&mut self, bundle: impl Bundle) -> EntityWorldMut {
547        let entity = self.world.spawn((bundle, Parent(self.parent))).id();
548        add_child_unchecked(self.world, self.parent, entity);
549        push_events(
550            self.world,
551            [HierarchyEvent::ChildAdded {
552                child: entity,
553                parent: self.parent,
554            }],
555        );
556        self.world.entity_mut(entity)
557    }
558
559    fn spawn_empty(&mut self) -> EntityWorldMut {
560        let entity = self.world.spawn(Parent(self.parent)).id();
561        add_child_unchecked(self.world, self.parent, entity);
562        push_events(
563            self.world,
564            [HierarchyEvent::ChildAdded {
565                child: entity,
566                parent: self.parent,
567            }],
568        );
569        self.world.entity_mut(entity)
570    }
571
572    fn parent_entity(&self) -> Entity {
573        self.parent
574    }
575
576    fn enqueue_command<C: Command>(&mut self, command: C) -> &mut Self {
577        command.apply(self.world);
578        self
579    }
580}
581
582impl BuildChildren for EntityWorldMut<'_> {
583    type Builder<'a> = WorldChildBuilder<'a>;
584
585    fn with_children(&mut self, spawn_children: impl FnOnce(&mut WorldChildBuilder)) -> &mut Self {
586        let parent = self.id();
587        self.world_scope(|world| {
588            spawn_children(&mut WorldChildBuilder { world, parent });
589        });
590        self
591    }
592
593    fn with_child<B: Bundle>(&mut self, bundle: B) -> &mut Self {
594        let parent = self.id();
595        let child = self.world_scope(|world| world.spawn((bundle, Parent(parent))).id());
596        if let Some(mut children_component) = self.get_mut::<Children>() {
597            children_component.0.retain(|value| child != *value);
598            children_component.0.push(child);
599        } else {
600            self.insert(Children::from_entities(&[child]));
601        }
602        self
603    }
604
605    fn add_child(&mut self, child: Entity) -> &mut Self {
606        let parent = self.id();
607        if child == parent {
608            panic!("Cannot add entity as a child of itself.");
609        }
610        self.world_scope(|world| {
611            update_old_parent(world, child, parent);
612        });
613        if let Some(mut children_component) = self.get_mut::<Children>() {
614            children_component.0.retain(|value| child != *value);
615            children_component.0.push(child);
616        } else {
617            self.insert(Children::from_entities(&[child]));
618        }
619        self
620    }
621
622    fn add_children(&mut self, children: &[Entity]) -> &mut Self {
623        if children.is_empty() {
624            return self;
625        }
626
627        let parent = self.id();
628        if children.contains(&parent) {
629            panic!("Cannot push entity as a child of itself.");
630        }
631        self.world_scope(|world| {
632            update_old_parents(world, parent, children);
633        });
634        if let Some(mut children_component) = self.get_mut::<Children>() {
635            children_component
636                .0
637                .retain(|value| !children.contains(value));
638            children_component.0.extend(children.iter().cloned());
639        } else {
640            self.insert(Children::from_entities(children));
641        }
642        self
643    }
644
645    fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
646        let parent = self.id();
647        if children.contains(&parent) {
648            panic!("Cannot insert entity as a child of itself.");
649        }
650        self.world_scope(|world| {
651            update_old_parents(world, parent, children);
652        });
653        if let Some(mut children_component) = self.get_mut::<Children>() {
654            children_component
655                .0
656                .retain(|value| !children.contains(value));
657            children_component.0.insert_from_slice(index, children);
658        } else {
659            self.insert(Children::from_entities(children));
660        }
661        self
662    }
663
664    fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
665        let parent = self.id();
666        self.world_scope(|world| {
667            remove_children(parent, children, world);
668        });
669        self
670    }
671
672    fn set_parent(&mut self, parent: Entity) -> &mut Self {
673        let child = self.id();
674        self.world_scope(|world| {
675            world.entity_mut(parent).add_child(child);
676        });
677        self
678    }
679
680    fn remove_parent(&mut self) -> &mut Self {
681        let child = self.id();
682        if let Some(parent) = self.take::<Parent>().map(|p| p.get()) {
683            self.world_scope(|world| {
684                remove_from_children(world, parent, child);
685                push_events(world, [HierarchyEvent::ChildRemoved { child, parent }]);
686            });
687        }
688        self
689    }
690
691    fn clear_children(&mut self) -> &mut Self {
692        let parent = self.id();
693        self.world_scope(|world| {
694            clear_children(parent, world);
695        });
696        self
697    }
698
699    fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
700        self.clear_children().add_children(children)
701    }
702}
703
704#[cfg(test)]
705mod tests {
706    use super::{BuildChildren, ChildBuild};
707    use crate::{
708        components::{Children, Parent},
709        HierarchyEvent::{self, ChildAdded, ChildMoved, ChildRemoved},
710    };
711    use smallvec::{smallvec, SmallVec};
712
713    use bevy_ecs::{
714        component::Component,
715        entity::Entity,
716        event::Events,
717        system::Commands,
718        world::{CommandQueue, World},
719    };
720
721    /// Assert the (non)existence and state of the child's [`Parent`] component.
722    fn assert_parent(world: &World, child: Entity, parent: Option<Entity>) {
723        assert_eq!(world.get::<Parent>(child).map(Parent::get), parent);
724    }
725
726    /// Assert the (non)existence and state of the parent's [`Children`] component.
727    fn assert_children(world: &World, parent: Entity, children: Option<&[Entity]>) {
728        assert_eq!(world.get::<Children>(parent).map(|c| &**c), children);
729    }
730
731    /// Assert the number of children in the parent's [`Children`] component if it exists.
732    fn assert_num_children(world: &World, parent: Entity, num_children: usize) {
733        assert_eq!(
734            world.get::<Children>(parent).map(|c| c.len()).unwrap_or(0),
735            num_children
736        );
737    }
738
739    /// Used to omit a number of events that are not relevant to a particular test.
740    fn omit_events(world: &mut World, number: usize) {
741        let mut events_resource = world.resource_mut::<Events<HierarchyEvent>>();
742        let mut events: Vec<_> = events_resource.drain().collect();
743        events_resource.extend(events.drain(number..));
744    }
745
746    fn assert_events(world: &mut World, expected_events: &[HierarchyEvent]) {
747        let events: Vec<_> = world
748            .resource_mut::<Events<HierarchyEvent>>()
749            .drain()
750            .collect();
751        assert_eq!(events, expected_events);
752    }
753
754    #[test]
755    fn add_child() {
756        let world = &mut World::new();
757        world.insert_resource(Events::<HierarchyEvent>::default());
758
759        let [a, b, c, d] = core::array::from_fn(|_| world.spawn_empty().id());
760
761        world.entity_mut(a).add_child(b);
762
763        assert_parent(world, b, Some(a));
764        assert_children(world, a, Some(&[b]));
765        assert_events(
766            world,
767            &[ChildAdded {
768                child: b,
769                parent: a,
770            }],
771        );
772
773        world.entity_mut(a).add_child(c);
774
775        assert_children(world, a, Some(&[b, c]));
776        assert_parent(world, c, Some(a));
777        assert_events(
778            world,
779            &[ChildAdded {
780                child: c,
781                parent: a,
782            }],
783        );
784        // Children component should be removed when it's empty.
785        world.entity_mut(d).add_child(b).add_child(c);
786        assert_children(world, a, None);
787    }
788
789    #[test]
790    fn set_parent() {
791        let world = &mut World::new();
792        world.insert_resource(Events::<HierarchyEvent>::default());
793
794        let [a, b, c] = core::array::from_fn(|_| world.spawn_empty().id());
795
796        world.entity_mut(a).set_parent(b);
797
798        assert_parent(world, a, Some(b));
799        assert_children(world, b, Some(&[a]));
800        assert_events(
801            world,
802            &[ChildAdded {
803                child: a,
804                parent: b,
805            }],
806        );
807
808        world.entity_mut(a).set_parent(c);
809
810        assert_parent(world, a, Some(c));
811        assert_children(world, b, None);
812        assert_children(world, c, Some(&[a]));
813        assert_events(
814            world,
815            &[ChildMoved {
816                child: a,
817                previous_parent: b,
818                new_parent: c,
819            }],
820        );
821    }
822
823    // regression test for https://github.com/bevyengine/bevy/pull/8346
824    #[test]
825    fn set_parent_of_orphan() {
826        let world = &mut World::new();
827
828        let [a, b, c] = core::array::from_fn(|_| world.spawn_empty().id());
829        world.entity_mut(a).set_parent(b);
830        assert_parent(world, a, Some(b));
831        assert_children(world, b, Some(&[a]));
832
833        world.entity_mut(b).despawn();
834        world.entity_mut(a).set_parent(c);
835
836        assert_parent(world, a, Some(c));
837        assert_children(world, c, Some(&[a]));
838    }
839
840    #[test]
841    fn remove_parent() {
842        let world = &mut World::new();
843        world.insert_resource(Events::<HierarchyEvent>::default());
844
845        let [a, b, c] = core::array::from_fn(|_| world.spawn_empty().id());
846
847        world.entity_mut(a).add_children(&[b, c]);
848        world.entity_mut(b).remove_parent();
849
850        assert_parent(world, b, None);
851        assert_parent(world, c, Some(a));
852        assert_children(world, a, Some(&[c]));
853        omit_events(world, 2); // Omit ChildAdded events.
854        assert_events(
855            world,
856            &[ChildRemoved {
857                child: b,
858                parent: a,
859            }],
860        );
861
862        world.entity_mut(c).remove_parent();
863        assert_parent(world, c, None);
864        assert_children(world, a, None);
865        assert_events(
866            world,
867            &[ChildRemoved {
868                child: c,
869                parent: a,
870            }],
871        );
872    }
873
874    #[allow(dead_code)]
875    #[derive(Component)]
876    struct C(u32);
877
878    #[test]
879    fn build_children() {
880        let mut world = World::default();
881        let mut queue = CommandQueue::default();
882        let mut commands = Commands::new(&mut queue, &world);
883
884        let parent = commands.spawn(C(1)).id();
885        let mut children = Vec::new();
886        commands.entity(parent).with_children(|parent| {
887            children.extend([
888                parent.spawn(C(2)).id(),
889                parent.spawn(C(3)).id(),
890                parent.spawn(C(4)).id(),
891            ]);
892        });
893
894        queue.apply(&mut world);
895        assert_eq!(
896            world.get::<Children>(parent).unwrap().0.as_slice(),
897            children.as_slice(),
898        );
899        assert_eq!(*world.get::<Parent>(children[0]).unwrap(), Parent(parent));
900        assert_eq!(*world.get::<Parent>(children[1]).unwrap(), Parent(parent));
901
902        assert_eq!(*world.get::<Parent>(children[0]).unwrap(), Parent(parent));
903        assert_eq!(*world.get::<Parent>(children[1]).unwrap(), Parent(parent));
904    }
905
906    #[test]
907    fn build_child() {
908        let mut world = World::default();
909        let mut queue = CommandQueue::default();
910        let mut commands = Commands::new(&mut queue, &world);
911
912        let parent = commands.spawn(C(1)).id();
913        commands.entity(parent).with_child(C(2));
914
915        queue.apply(&mut world);
916        assert_eq!(world.get::<Children>(parent).unwrap().0.len(), 1);
917    }
918
919    #[test]
920    fn push_and_insert_and_remove_children_commands() {
921        let mut world = World::default();
922        let entities = world
923            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
924            .collect::<Vec<Entity>>();
925
926        let mut queue = CommandQueue::default();
927        {
928            let mut commands = Commands::new(&mut queue, &world);
929            commands.entity(entities[0]).add_children(&entities[1..3]);
930        }
931        queue.apply(&mut world);
932
933        let parent = entities[0];
934        let child1 = entities[1];
935        let child2 = entities[2];
936        let child3 = entities[3];
937        let child4 = entities[4];
938
939        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
940        assert_eq!(
941            world.get::<Children>(parent).unwrap().0.clone(),
942            expected_children
943        );
944        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
945        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
946
947        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
948        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
949
950        {
951            let mut commands = Commands::new(&mut queue, &world);
952            commands.entity(parent).insert_children(1, &entities[3..]);
953        }
954        queue.apply(&mut world);
955
956        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child3, child4, child2];
957        assert_eq!(
958            world.get::<Children>(parent).unwrap().0.clone(),
959            expected_children
960        );
961        assert_eq!(*world.get::<Parent>(child3).unwrap(), Parent(parent));
962        assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
963
964        let remove_children = [child1, child4];
965        {
966            let mut commands = Commands::new(&mut queue, &world);
967            commands.entity(parent).remove_children(&remove_children);
968        }
969        queue.apply(&mut world);
970
971        let expected_children: SmallVec<[Entity; 8]> = smallvec![child3, child2];
972        assert_eq!(
973            world.get::<Children>(parent).unwrap().0.clone(),
974            expected_children
975        );
976        assert!(world.get::<Parent>(child1).is_none());
977        assert!(world.get::<Parent>(child4).is_none());
978    }
979
980    #[test]
981    fn push_and_clear_children_commands() {
982        let mut world = World::default();
983        let entities = world
984            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
985            .collect::<Vec<Entity>>();
986
987        let mut queue = CommandQueue::default();
988        {
989            let mut commands = Commands::new(&mut queue, &world);
990            commands.entity(entities[0]).add_children(&entities[1..3]);
991        }
992        queue.apply(&mut world);
993
994        let parent = entities[0];
995        let child1 = entities[1];
996        let child2 = entities[2];
997
998        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
999        assert_eq!(
1000            world.get::<Children>(parent).unwrap().0.clone(),
1001            expected_children
1002        );
1003        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1004        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1005
1006        {
1007            let mut commands = Commands::new(&mut queue, &world);
1008            commands.entity(parent).clear_children();
1009        }
1010        queue.apply(&mut world);
1011
1012        assert!(world.get::<Children>(parent).is_none());
1013
1014        assert!(world.get::<Parent>(child1).is_none());
1015        assert!(world.get::<Parent>(child2).is_none());
1016    }
1017
1018    #[test]
1019    fn push_and_replace_children_commands() {
1020        let mut world = World::default();
1021        let entities = world
1022            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
1023            .collect::<Vec<Entity>>();
1024
1025        let mut queue = CommandQueue::default();
1026        {
1027            let mut commands = Commands::new(&mut queue, &world);
1028            commands.entity(entities[0]).add_children(&entities[1..3]);
1029        }
1030        queue.apply(&mut world);
1031
1032        let parent = entities[0];
1033        let child1 = entities[1];
1034        let child2 = entities[2];
1035        let child4 = entities[4];
1036
1037        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
1038        assert_eq!(
1039            world.get::<Children>(parent).unwrap().0.clone(),
1040            expected_children
1041        );
1042        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1043        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1044
1045        let replace_children = [child1, child4];
1046        {
1047            let mut commands = Commands::new(&mut queue, &world);
1048            commands.entity(parent).replace_children(&replace_children);
1049        }
1050        queue.apply(&mut world);
1051
1052        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child4];
1053        assert_eq!(
1054            world.get::<Children>(parent).unwrap().0.clone(),
1055            expected_children
1056        );
1057        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1058        assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
1059        assert!(world.get::<Parent>(child2).is_none());
1060    }
1061
1062    #[test]
1063    fn push_and_insert_and_remove_children_world() {
1064        let mut world = World::default();
1065        let entities = world
1066            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
1067            .collect::<Vec<Entity>>();
1068
1069        world.entity_mut(entities[0]).add_children(&entities[1..3]);
1070
1071        let parent = entities[0];
1072        let child1 = entities[1];
1073        let child2 = entities[2];
1074        let child3 = entities[3];
1075        let child4 = entities[4];
1076
1077        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
1078        assert_eq!(
1079            world.get::<Children>(parent).unwrap().0.clone(),
1080            expected_children
1081        );
1082        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1083        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1084
1085        world.entity_mut(parent).insert_children(1, &entities[3..]);
1086        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child3, child4, child2];
1087        assert_eq!(
1088            world.get::<Children>(parent).unwrap().0.clone(),
1089            expected_children
1090        );
1091        assert_eq!(*world.get::<Parent>(child3).unwrap(), Parent(parent));
1092        assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
1093
1094        let remove_children = [child1, child4];
1095        world.entity_mut(parent).remove_children(&remove_children);
1096        let expected_children: SmallVec<[Entity; 8]> = smallvec![child3, child2];
1097        assert_eq!(
1098            world.get::<Children>(parent).unwrap().0.clone(),
1099            expected_children
1100        );
1101        assert!(world.get::<Parent>(child1).is_none());
1102        assert!(world.get::<Parent>(child4).is_none());
1103    }
1104
1105    #[test]
1106    fn push_and_insert_and_clear_children_world() {
1107        let mut world = World::default();
1108        let entities = world
1109            .spawn_batch(vec![C(1), C(2), C(3)])
1110            .collect::<Vec<Entity>>();
1111
1112        world.entity_mut(entities[0]).add_children(&entities[1..3]);
1113
1114        let parent = entities[0];
1115        let child1 = entities[1];
1116        let child2 = entities[2];
1117
1118        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
1119        assert_eq!(
1120            world.get::<Children>(parent).unwrap().0.clone(),
1121            expected_children
1122        );
1123        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1124        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1125
1126        world.entity_mut(parent).clear_children();
1127        assert!(world.get::<Children>(parent).is_none());
1128        assert!(world.get::<Parent>(child1).is_none());
1129        assert!(world.get::<Parent>(child2).is_none());
1130    }
1131
1132    #[test]
1133    fn push_and_replace_children_world() {
1134        let mut world = World::default();
1135        let entities = world
1136            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
1137            .collect::<Vec<Entity>>();
1138
1139        world.entity_mut(entities[0]).add_children(&entities[1..3]);
1140
1141        let parent = entities[0];
1142        let child1 = entities[1];
1143        let child2 = entities[2];
1144        let child3 = entities[3];
1145        let child4 = entities[4];
1146
1147        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
1148        assert_eq!(
1149            world.get::<Children>(parent).unwrap().0.clone(),
1150            expected_children
1151        );
1152        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1153        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1154
1155        world.entity_mut(parent).replace_children(&entities[2..]);
1156        let expected_children: SmallVec<[Entity; 8]> = smallvec![child2, child3, child4];
1157        assert_eq!(
1158            world.get::<Children>(parent).unwrap().0.clone(),
1159            expected_children
1160        );
1161        assert!(world.get::<Parent>(child1).is_none());
1162        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1163        assert_eq!(*world.get::<Parent>(child3).unwrap(), Parent(parent));
1164        assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
1165    }
1166
1167    /// Tests what happens when all children are removed from a parent using world functions
1168    #[test]
1169    fn children_removed_when_empty_world() {
1170        let mut world = World::default();
1171        let entities = world
1172            .spawn_batch(vec![C(1), C(2), C(3)])
1173            .collect::<Vec<Entity>>();
1174
1175        let parent1 = entities[0];
1176        let parent2 = entities[1];
1177        let child = entities[2];
1178
1179        // add child into parent1
1180        world.entity_mut(parent1).add_children(&[child]);
1181        assert_eq!(
1182            world.get::<Children>(parent1).unwrap().0.as_slice(),
1183            &[child]
1184        );
1185
1186        // move only child from parent1 with `add_children`
1187        world.entity_mut(parent2).add_children(&[child]);
1188        assert!(world.get::<Children>(parent1).is_none());
1189
1190        // move only child from parent2 with `insert_children`
1191        world.entity_mut(parent1).insert_children(0, &[child]);
1192        assert!(world.get::<Children>(parent2).is_none());
1193
1194        // remove only child from parent1 with `remove_children`
1195        world.entity_mut(parent1).remove_children(&[child]);
1196        assert!(world.get::<Children>(parent1).is_none());
1197    }
1198
1199    /// Tests what happens when all children are removed form a parent using commands
1200    #[test]
1201    fn children_removed_when_empty_commands() {
1202        let mut world = World::default();
1203        let entities = world
1204            .spawn_batch(vec![C(1), C(2), C(3)])
1205            .collect::<Vec<Entity>>();
1206
1207        let parent1 = entities[0];
1208        let parent2 = entities[1];
1209        let child = entities[2];
1210
1211        let mut queue = CommandQueue::default();
1212
1213        // add child into parent1
1214        {
1215            let mut commands = Commands::new(&mut queue, &world);
1216            commands.entity(parent1).add_children(&[child]);
1217            queue.apply(&mut world);
1218        }
1219        assert_eq!(
1220            world.get::<Children>(parent1).unwrap().0.as_slice(),
1221            &[child]
1222        );
1223
1224        // move only child from parent1 with `add_children`
1225        {
1226            let mut commands = Commands::new(&mut queue, &world);
1227            commands.entity(parent2).add_children(&[child]);
1228            queue.apply(&mut world);
1229        }
1230        assert!(world.get::<Children>(parent1).is_none());
1231
1232        // move only child from parent2 with `insert_children`
1233        {
1234            let mut commands = Commands::new(&mut queue, &world);
1235            commands.entity(parent1).insert_children(0, &[child]);
1236            queue.apply(&mut world);
1237        }
1238        assert!(world.get::<Children>(parent2).is_none());
1239
1240        // move only child from parent1 with `add_child`
1241        {
1242            let mut commands = Commands::new(&mut queue, &world);
1243            commands.entity(parent2).add_child(child);
1244            queue.apply(&mut world);
1245        }
1246        assert!(world.get::<Children>(parent1).is_none());
1247
1248        // remove only child from parent2 with `remove_children`
1249        {
1250            let mut commands = Commands::new(&mut queue, &world);
1251            commands.entity(parent2).remove_children(&[child]);
1252            queue.apply(&mut world);
1253        }
1254        assert!(world.get::<Children>(parent2).is_none());
1255    }
1256
1257    #[test]
1258    fn regression_add_children_same_archetype() {
1259        let mut world = World::new();
1260        let child = world.spawn_empty().id();
1261        world.spawn_empty().add_children(&[child]);
1262    }
1263
1264    #[test]
1265    fn add_children_idempotent() {
1266        let mut world = World::new();
1267        let child = world.spawn_empty().id();
1268        let parent = world
1269            .spawn_empty()
1270            .add_children(&[child])
1271            .add_children(&[child])
1272            .id();
1273
1274        let mut query = world.query::<&Children>();
1275        let children = query.get(&world, parent).unwrap();
1276        assert_eq!(**children, [child]);
1277    }
1278
1279    #[test]
1280    fn add_children_does_not_insert_empty_children() {
1281        let mut world = World::new();
1282        let parent = world.spawn_empty().add_children(&[]).id();
1283
1284        let mut query = world.query::<&Children>();
1285        let children = query.get(&world, parent);
1286        assert!(children.is_err());
1287    }
1288
1289    #[test]
1290    fn with_child() {
1291        let world = &mut World::new();
1292        world.insert_resource(Events::<HierarchyEvent>::default());
1293
1294        let a = world.spawn_empty().id();
1295        let b = ();
1296        let c = ();
1297        let d = ();
1298
1299        world.entity_mut(a).with_child(b);
1300
1301        assert_num_children(world, a, 1);
1302
1303        world.entity_mut(a).with_child(c).with_child(d);
1304
1305        assert_num_children(world, a, 3);
1306    }
1307}