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 push_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 Some(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 PushChild {
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 PushChild {
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 PushChildren {
196    parent: Entity,
197    children: SmallVec<[Entity; 8]>,
198}
199
200impl Command for PushChildren {
201    fn apply(self, world: &mut World) {
202        world.entity_mut(self.parent).push_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).push_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::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    push_children: PushChildren,
280}
281
282impl ChildBuilder<'_> {
283    /// Spawns an entity with the given bundle and inserts it into the parent entity's [`Children`].
284    /// Also adds [`Parent`] component to the created entity.
285    pub fn spawn(&mut self, bundle: impl Bundle) -> EntityCommands {
286        let e = self.commands.spawn(bundle);
287        self.push_children.children.push(e.id());
288        e
289    }
290
291    /// Spawns an [`Entity`] with no components and inserts it into the parent entity's [`Children`].
292    /// Also adds [`Parent`] component to the created entity.
293    pub fn spawn_empty(&mut self) -> EntityCommands {
294        let e = self.commands.spawn_empty();
295        self.push_children.children.push(e.id());
296        e
297    }
298
299    /// Returns the parent entity of this [`ChildBuilder`].
300    pub fn parent_entity(&self) -> Entity {
301        self.push_children.parent
302    }
303
304    /// Adds a command to be executed, like [`Commands::add`].
305    pub fn add_command<C: Command>(&mut self, command: C) -> &mut Self {
306        self.commands.add(command);
307        self
308    }
309}
310
311/// Trait for removing, adding and replacing children and parents of an entity.
312pub trait BuildChildren {
313    /// Takes a closure which builds children for this entity using [`ChildBuilder`].
314    fn with_children(&mut self, f: impl FnOnce(&mut ChildBuilder)) -> &mut Self;
315    /// Pushes children to the back of the builder's children. For any entities that are
316    /// already a child of this one, this method does nothing.
317    ///
318    /// If the children were previously children of another parent, that parent's [`Children`] component
319    /// will have those children removed from its list. Removing all children from a parent causes its
320    /// [`Children`] component to be removed from the entity.
321    ///
322    /// # Panics
323    ///
324    /// Panics if any of the children are the same as the parent.
325    fn push_children(&mut self, children: &[Entity]) -> &mut Self;
326    /// Inserts children at the given index.
327    ///
328    /// If the children were previously children of another parent, that parent's [`Children`] component
329    /// will have those children removed from its list. Removing all children from a parent causes its
330    /// [`Children`] component to be removed from the entity.
331    ///
332    /// # Panics
333    ///
334    /// Panics if any of the children are the same as the parent.
335    fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self;
336    /// Removes the given children
337    ///
338    /// Removing all children from a parent causes its [`Children`] component to be removed from the entity.
339    fn remove_children(&mut self, children: &[Entity]) -> &mut Self;
340    /// Adds a single child.
341    ///
342    /// If the children were previously children of another parent, that parent's [`Children`] component
343    /// will have those children removed from its list. Removing all children from a parent causes its
344    /// [`Children`] component to be removed from the entity.
345    ///
346    /// # Panics
347    ///
348    /// Panics if the child is the same as the parent.
349    fn add_child(&mut self, child: Entity) -> &mut Self;
350    /// Removes all children from this entity. The [`Children`] component will be removed if it exists, otherwise this does nothing.
351    fn clear_children(&mut self) -> &mut Self;
352    /// Removes all current children from this entity, replacing them with the specified list of entities.
353    ///
354    /// The removed children will have their [`Parent`] component removed.
355    ///
356    /// # Panics
357    ///
358    /// Panics if any of the children are the same as the parent.
359    fn replace_children(&mut self, children: &[Entity]) -> &mut Self;
360    /// Sets the parent of this entity.
361    ///
362    /// If this entity already had a parent, the parent's [`Children`] component will have this
363    /// child removed from its list. Removing all children from a parent causes its [`Children`]
364    /// component to be removed from the entity.
365    ///
366    /// # Panics
367    ///
368    /// Panics if the parent is the same as the child.
369    fn set_parent(&mut self, parent: Entity) -> &mut Self;
370    /// Removes the [`Parent`] of this entity.
371    ///
372    /// Also removes this entity from its parent's [`Children`] component. Removing all children from a parent causes
373    /// its [`Children`] component to be removed from the entity.
374    fn remove_parent(&mut self) -> &mut Self;
375}
376
377impl BuildChildren for EntityCommands<'_> {
378    fn with_children(&mut self, spawn_children: impl FnOnce(&mut ChildBuilder)) -> &mut Self {
379        let parent = self.id();
380        let mut builder = ChildBuilder {
381            commands: self.commands(),
382            push_children: PushChildren {
383                children: SmallVec::default(),
384                parent,
385            },
386        };
387
388        spawn_children(&mut builder);
389        let children = builder.push_children;
390        if children.children.contains(&parent) {
391            panic!("Entity cannot be a child of itself.");
392        }
393        self.commands().add(children);
394        self
395    }
396
397    fn push_children(&mut self, children: &[Entity]) -> &mut Self {
398        let parent = self.id();
399        if children.contains(&parent) {
400            panic!("Cannot push entity as a child of itself.");
401        }
402        self.commands().add(PushChildren {
403            children: SmallVec::from(children),
404            parent,
405        });
406        self
407    }
408
409    fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
410        let parent = self.id();
411        if children.contains(&parent) {
412            panic!("Cannot insert entity as a child of itself.");
413        }
414        self.commands().add(InsertChildren {
415            children: SmallVec::from(children),
416            index,
417            parent,
418        });
419        self
420    }
421
422    fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
423        let parent = self.id();
424        self.commands().add(RemoveChildren {
425            children: SmallVec::from(children),
426            parent,
427        });
428        self
429    }
430
431    fn add_child(&mut self, child: Entity) -> &mut Self {
432        let parent = self.id();
433        if child == parent {
434            panic!("Cannot add entity as a child of itself.");
435        }
436        self.commands().add(PushChild { child, parent });
437        self
438    }
439
440    fn clear_children(&mut self) -> &mut Self {
441        let parent = self.id();
442        self.commands().add(ClearChildren { parent });
443        self
444    }
445
446    fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
447        let parent = self.id();
448        if children.contains(&parent) {
449            panic!("Cannot replace entity as a child of itself.");
450        }
451        self.commands().add(ReplaceChildren {
452            children: SmallVec::from(children),
453            parent,
454        });
455        self
456    }
457
458    fn set_parent(&mut self, parent: Entity) -> &mut Self {
459        let child = self.id();
460        if child == parent {
461            panic!("Cannot set parent to itself");
462        }
463        self.commands().add(PushChild { child, parent });
464        self
465    }
466
467    fn remove_parent(&mut self) -> &mut Self {
468        let child = self.id();
469        self.commands().add(RemoveParent { child });
470        self
471    }
472}
473
474/// Struct for adding children to an entity directly through the [`World`] for use in exclusive systems.
475#[derive(Debug)]
476pub struct WorldChildBuilder<'w> {
477    world: &'w mut World,
478    parent: Entity,
479}
480
481impl<'w> WorldChildBuilder<'w> {
482    /// Spawns an entity with the given bundle and inserts it into the parent entity's [`Children`].
483    /// Also adds [`Parent`] component to the created entity.
484    pub fn spawn(&mut self, bundle: impl Bundle) -> EntityWorldMut<'_> {
485        let entity = self.world.spawn((bundle, Parent(self.parent))).id();
486        push_child_unchecked(self.world, self.parent, entity);
487        push_events(
488            self.world,
489            [HierarchyEvent::ChildAdded {
490                child: entity,
491                parent: self.parent,
492            }],
493        );
494        self.world.entity_mut(entity)
495    }
496
497    /// Spawns an [`Entity`] with no components and inserts it into the parent entity's [`Children`].
498    /// Also adds [`Parent`] component to the created entity.
499    pub fn spawn_empty(&mut self) -> EntityWorldMut<'_> {
500        let entity = self.world.spawn(Parent(self.parent)).id();
501        push_child_unchecked(self.world, self.parent, entity);
502        push_events(
503            self.world,
504            [HierarchyEvent::ChildAdded {
505                child: entity,
506                parent: self.parent,
507            }],
508        );
509        self.world.entity_mut(entity)
510    }
511
512    /// Returns the parent entity of this [`WorldChildBuilder`].
513    pub fn parent_entity(&self) -> Entity {
514        self.parent
515    }
516}
517
518/// Trait that defines adding, changing and children and parents of an entity directly through the [`World`].
519pub trait BuildWorldChildren {
520    /// Takes a closure which builds children for this entity using [`WorldChildBuilder`].
521    fn with_children(&mut self, spawn_children: impl FnOnce(&mut WorldChildBuilder)) -> &mut Self;
522
523    /// Adds a single child.
524    ///
525    /// If the children were previously children of another parent, that parent's [`Children`] component
526    /// will have those children removed from its list. Removing all children from a parent causes its
527    /// [`Children`] component to be removed from the entity.
528    ///
529    /// # Panics
530    ///
531    /// Panics if the child is the same as the parent.
532    fn add_child(&mut self, child: Entity) -> &mut Self;
533
534    /// Pushes children to the back of the builder's children. For any entities that are
535    /// already a child of this one, this method does nothing.
536    ///
537    /// If the children were previously children of another parent, that parent's [`Children`] component
538    /// will have those children removed from its list. Removing all children from a parent causes its
539    /// [`Children`] component to be removed from the entity.
540    ///
541    /// # Panics
542    ///
543    /// Panics if any of the children are the same as the parent.
544    fn push_children(&mut self, children: &[Entity]) -> &mut Self;
545    /// Inserts children at the given index.
546    ///
547    /// If the children were previously children of another parent, that parent's [`Children`] component
548    /// will have those children removed from its list. Removing all children from a parent causes its
549    /// [`Children`] component to be removed from the entity.
550    ///
551    /// # Panics
552    ///
553    /// Panics if any of the children are the same as the parent.
554    fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self;
555    /// Removes the given children
556    ///
557    /// Removing all children from a parent causes its [`Children`] component to be removed from the entity.
558    fn remove_children(&mut self, children: &[Entity]) -> &mut Self;
559
560    /// Sets the parent of this entity.
561    ///
562    /// If this entity already had a parent, the parent's [`Children`] component will have this
563    /// child removed from its list. Removing all children from a parent causes its [`Children`]
564    /// component to be removed from the entity.
565    ///
566    /// # Panics
567    ///
568    /// Panics if the parent is the same as the child.
569    fn set_parent(&mut self, parent: Entity) -> &mut Self;
570
571    /// Removes the [`Parent`] of this entity.
572    ///
573    /// Also removes this entity from its parent's [`Children`] component. Removing all children from a parent causes
574    /// its [`Children`] component to be removed from the entity.
575    fn remove_parent(&mut self) -> &mut Self;
576    /// Removes all children from this entity. The [`Children`] component will be removed if it exists, otherwise this does nothing.
577    fn clear_children(&mut self) -> &mut Self;
578    /// Removes all current children from this entity, replacing them with the specified list of entities.
579    ///
580    /// The removed children will have their [`Parent`] component removed.
581    ///
582    /// # Panics
583    ///
584    /// Panics if any of the children are the same as the parent.
585    fn replace_children(&mut self, children: &[Entity]) -> &mut Self;
586}
587
588impl<'w> BuildWorldChildren for EntityWorldMut<'w> {
589    fn with_children(&mut self, spawn_children: impl FnOnce(&mut WorldChildBuilder)) -> &mut Self {
590        let parent = self.id();
591        self.world_scope(|world| {
592            spawn_children(&mut WorldChildBuilder { world, parent });
593        });
594        self
595    }
596
597    fn add_child(&mut self, child: Entity) -> &mut Self {
598        let parent = self.id();
599        if child == parent {
600            panic!("Cannot add entity as a child of itself.");
601        }
602        self.world_scope(|world| {
603            update_old_parent(world, child, parent);
604        });
605        if let Some(mut children_component) = self.get_mut::<Children>() {
606            children_component.0.retain(|value| child != *value);
607            children_component.0.push(child);
608        } else {
609            self.insert(Children::from_entities(&[child]));
610        }
611        self
612    }
613
614    fn push_children(&mut self, children: &[Entity]) -> &mut Self {
615        if children.is_empty() {
616            return self;
617        }
618
619        let parent = self.id();
620        if children.contains(&parent) {
621            panic!("Cannot push entity as a child of itself.");
622        }
623        self.world_scope(|world| {
624            update_old_parents(world, parent, children);
625        });
626        if let Some(mut children_component) = self.get_mut::<Children>() {
627            children_component
628                .0
629                .retain(|value| !children.contains(value));
630            children_component.0.extend(children.iter().cloned());
631        } else {
632            self.insert(Children::from_entities(children));
633        }
634        self
635    }
636
637    fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self {
638        let parent = self.id();
639        if children.contains(&parent) {
640            panic!("Cannot insert entity as a child of itself.");
641        }
642        self.world_scope(|world| {
643            update_old_parents(world, parent, children);
644        });
645        if let Some(mut children_component) = self.get_mut::<Children>() {
646            children_component
647                .0
648                .retain(|value| !children.contains(value));
649            children_component.0.insert_from_slice(index, children);
650        } else {
651            self.insert(Children::from_entities(children));
652        }
653        self
654    }
655
656    fn remove_children(&mut self, children: &[Entity]) -> &mut Self {
657        let parent = self.id();
658        self.world_scope(|world| {
659            remove_children(parent, children, world);
660        });
661        self
662    }
663
664    fn set_parent(&mut self, parent: Entity) -> &mut Self {
665        let child = self.id();
666        self.world_scope(|world| {
667            world.entity_mut(parent).add_child(child);
668        });
669        self
670    }
671
672    fn remove_parent(&mut self) -> &mut Self {
673        let child = self.id();
674        if let Some(parent) = self.take::<Parent>().map(|p| p.get()) {
675            self.world_scope(|world| {
676                remove_from_children(world, parent, child);
677                push_events(world, [HierarchyEvent::ChildRemoved { child, parent }]);
678            });
679        }
680        self
681    }
682
683    fn clear_children(&mut self) -> &mut Self {
684        let parent = self.id();
685        self.world_scope(|world| {
686            clear_children(parent, world);
687        });
688        self
689    }
690
691    fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
692        self.clear_children().push_children(children)
693    }
694}
695
696#[cfg(test)]
697mod tests {
698    use super::{BuildChildren, BuildWorldChildren};
699    use crate::{
700        components::{Children, Parent},
701        HierarchyEvent::{self, ChildAdded, ChildMoved, ChildRemoved},
702    };
703    use smallvec::{smallvec, SmallVec};
704
705    use bevy_ecs::{
706        component::Component,
707        entity::Entity,
708        event::Events,
709        system::Commands,
710        world::{CommandQueue, World},
711    };
712
713    /// Assert the (non)existence and state of the child's [`Parent`] component.
714    fn assert_parent(world: &World, child: Entity, parent: Option<Entity>) {
715        assert_eq!(world.get::<Parent>(child).map(|p| p.get()), parent);
716    }
717
718    /// Assert the (non)existence and state of the parent's [`Children`] component.
719    fn assert_children(world: &World, parent: Entity, children: Option<&[Entity]>) {
720        assert_eq!(world.get::<Children>(parent).map(|c| &**c), children);
721    }
722
723    /// Used to omit a number of events that are not relevant to a particular test.
724    fn omit_events(world: &mut World, number: usize) {
725        let mut events_resource = world.resource_mut::<Events<HierarchyEvent>>();
726        let mut events: Vec<_> = events_resource.drain().collect();
727        events_resource.extend(events.drain(number..));
728    }
729
730    fn assert_events(world: &mut World, expected_events: &[HierarchyEvent]) {
731        let events: Vec<_> = world
732            .resource_mut::<Events<HierarchyEvent>>()
733            .drain()
734            .collect();
735        assert_eq!(events, expected_events);
736    }
737
738    #[test]
739    fn add_child() {
740        let world = &mut World::new();
741        world.insert_resource(Events::<HierarchyEvent>::default());
742
743        let [a, b, c, d] = std::array::from_fn(|_| world.spawn_empty().id());
744
745        world.entity_mut(a).add_child(b);
746
747        assert_parent(world, b, Some(a));
748        assert_children(world, a, Some(&[b]));
749        assert_events(
750            world,
751            &[ChildAdded {
752                child: b,
753                parent: a,
754            }],
755        );
756
757        world.entity_mut(a).add_child(c);
758
759        assert_children(world, a, Some(&[b, c]));
760        assert_parent(world, c, Some(a));
761        assert_events(
762            world,
763            &[ChildAdded {
764                child: c,
765                parent: a,
766            }],
767        );
768        // Children component should be removed when it's empty.
769        world.entity_mut(d).add_child(b).add_child(c);
770        assert_children(world, a, None);
771    }
772
773    #[test]
774    fn set_parent() {
775        let world = &mut World::new();
776        world.insert_resource(Events::<HierarchyEvent>::default());
777
778        let [a, b, c] = std::array::from_fn(|_| world.spawn_empty().id());
779
780        world.entity_mut(a).set_parent(b);
781
782        assert_parent(world, a, Some(b));
783        assert_children(world, b, Some(&[a]));
784        assert_events(
785            world,
786            &[ChildAdded {
787                child: a,
788                parent: b,
789            }],
790        );
791
792        world.entity_mut(a).set_parent(c);
793
794        assert_parent(world, a, Some(c));
795        assert_children(world, b, None);
796        assert_children(world, c, Some(&[a]));
797        assert_events(
798            world,
799            &[ChildMoved {
800                child: a,
801                previous_parent: b,
802                new_parent: c,
803            }],
804        );
805    }
806
807    // regression test for https://github.com/bevyengine/bevy/pull/8346
808    #[test]
809    fn set_parent_of_orphan() {
810        let world = &mut World::new();
811
812        let [a, b, c] = std::array::from_fn(|_| world.spawn_empty().id());
813        world.entity_mut(a).set_parent(b);
814        assert_parent(world, a, Some(b));
815        assert_children(world, b, Some(&[a]));
816
817        world.entity_mut(b).despawn();
818        world.entity_mut(a).set_parent(c);
819
820        assert_parent(world, a, Some(c));
821        assert_children(world, c, Some(&[a]));
822    }
823
824    #[test]
825    fn remove_parent() {
826        let world = &mut World::new();
827        world.insert_resource(Events::<HierarchyEvent>::default());
828
829        let [a, b, c] = std::array::from_fn(|_| world.spawn_empty().id());
830
831        world.entity_mut(a).push_children(&[b, c]);
832        world.entity_mut(b).remove_parent();
833
834        assert_parent(world, b, None);
835        assert_parent(world, c, Some(a));
836        assert_children(world, a, Some(&[c]));
837        omit_events(world, 2); // Omit ChildAdded events.
838        assert_events(
839            world,
840            &[ChildRemoved {
841                child: b,
842                parent: a,
843            }],
844        );
845
846        world.entity_mut(c).remove_parent();
847        assert_parent(world, c, None);
848        assert_children(world, a, None);
849        assert_events(
850            world,
851            &[ChildRemoved {
852                child: c,
853                parent: a,
854            }],
855        );
856    }
857
858    #[allow(dead_code)]
859    #[derive(Component)]
860    struct C(u32);
861
862    #[test]
863    fn build_children() {
864        let mut world = World::default();
865        let mut queue = CommandQueue::default();
866        let mut commands = Commands::new(&mut queue, &world);
867
868        let parent = commands.spawn(C(1)).id();
869        let mut children = Vec::new();
870        commands.entity(parent).with_children(|parent| {
871            children.extend([
872                parent.spawn(C(2)).id(),
873                parent.spawn(C(3)).id(),
874                parent.spawn(C(4)).id(),
875            ]);
876        });
877
878        queue.apply(&mut world);
879        assert_eq!(
880            world.get::<Children>(parent).unwrap().0.as_slice(),
881            children.as_slice(),
882        );
883        assert_eq!(*world.get::<Parent>(children[0]).unwrap(), Parent(parent));
884        assert_eq!(*world.get::<Parent>(children[1]).unwrap(), Parent(parent));
885
886        assert_eq!(*world.get::<Parent>(children[0]).unwrap(), Parent(parent));
887        assert_eq!(*world.get::<Parent>(children[1]).unwrap(), Parent(parent));
888    }
889
890    #[test]
891    fn push_and_insert_and_remove_children_commands() {
892        let mut world = World::default();
893        let entities = world
894            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
895            .collect::<Vec<Entity>>();
896
897        let mut queue = CommandQueue::default();
898        {
899            let mut commands = Commands::new(&mut queue, &world);
900            commands.entity(entities[0]).push_children(&entities[1..3]);
901        }
902        queue.apply(&mut world);
903
904        let parent = entities[0];
905        let child1 = entities[1];
906        let child2 = entities[2];
907        let child3 = entities[3];
908        let child4 = entities[4];
909
910        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
911        assert_eq!(
912            world.get::<Children>(parent).unwrap().0.clone(),
913            expected_children
914        );
915        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
916        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
917
918        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
919        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
920
921        {
922            let mut commands = Commands::new(&mut queue, &world);
923            commands.entity(parent).insert_children(1, &entities[3..]);
924        }
925        queue.apply(&mut world);
926
927        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child3, child4, child2];
928        assert_eq!(
929            world.get::<Children>(parent).unwrap().0.clone(),
930            expected_children
931        );
932        assert_eq!(*world.get::<Parent>(child3).unwrap(), Parent(parent));
933        assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
934
935        let remove_children = [child1, child4];
936        {
937            let mut commands = Commands::new(&mut queue, &world);
938            commands.entity(parent).remove_children(&remove_children);
939        }
940        queue.apply(&mut world);
941
942        let expected_children: SmallVec<[Entity; 8]> = smallvec![child3, child2];
943        assert_eq!(
944            world.get::<Children>(parent).unwrap().0.clone(),
945            expected_children
946        );
947        assert!(world.get::<Parent>(child1).is_none());
948        assert!(world.get::<Parent>(child4).is_none());
949    }
950
951    #[test]
952    fn push_and_clear_children_commands() {
953        let mut world = World::default();
954        let entities = world
955            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
956            .collect::<Vec<Entity>>();
957
958        let mut queue = CommandQueue::default();
959        {
960            let mut commands = Commands::new(&mut queue, &world);
961            commands.entity(entities[0]).push_children(&entities[1..3]);
962        }
963        queue.apply(&mut world);
964
965        let parent = entities[0];
966        let child1 = entities[1];
967        let child2 = entities[2];
968
969        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
970        assert_eq!(
971            world.get::<Children>(parent).unwrap().0.clone(),
972            expected_children
973        );
974        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
975        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
976
977        {
978            let mut commands = Commands::new(&mut queue, &world);
979            commands.entity(parent).clear_children();
980        }
981        queue.apply(&mut world);
982
983        assert!(world.get::<Children>(parent).is_none());
984
985        assert!(world.get::<Parent>(child1).is_none());
986        assert!(world.get::<Parent>(child2).is_none());
987    }
988
989    #[test]
990    fn push_and_replace_children_commands() {
991        let mut world = World::default();
992        let entities = world
993            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
994            .collect::<Vec<Entity>>();
995
996        let mut queue = CommandQueue::default();
997        {
998            let mut commands = Commands::new(&mut queue, &world);
999            commands.entity(entities[0]).push_children(&entities[1..3]);
1000        }
1001        queue.apply(&mut world);
1002
1003        let parent = entities[0];
1004        let child1 = entities[1];
1005        let child2 = entities[2];
1006        let child4 = entities[4];
1007
1008        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
1009        assert_eq!(
1010            world.get::<Children>(parent).unwrap().0.clone(),
1011            expected_children
1012        );
1013        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1014        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1015
1016        let replace_children = [child1, child4];
1017        {
1018            let mut commands = Commands::new(&mut queue, &world);
1019            commands.entity(parent).replace_children(&replace_children);
1020        }
1021        queue.apply(&mut world);
1022
1023        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child4];
1024        assert_eq!(
1025            world.get::<Children>(parent).unwrap().0.clone(),
1026            expected_children
1027        );
1028        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1029        assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
1030        assert!(world.get::<Parent>(child2).is_none());
1031    }
1032
1033    #[test]
1034    fn push_and_insert_and_remove_children_world() {
1035        let mut world = World::default();
1036        let entities = world
1037            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
1038            .collect::<Vec<Entity>>();
1039
1040        world.entity_mut(entities[0]).push_children(&entities[1..3]);
1041
1042        let parent = entities[0];
1043        let child1 = entities[1];
1044        let child2 = entities[2];
1045        let child3 = entities[3];
1046        let child4 = entities[4];
1047
1048        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
1049        assert_eq!(
1050            world.get::<Children>(parent).unwrap().0.clone(),
1051            expected_children
1052        );
1053        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1054        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1055
1056        world.entity_mut(parent).insert_children(1, &entities[3..]);
1057        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child3, child4, child2];
1058        assert_eq!(
1059            world.get::<Children>(parent).unwrap().0.clone(),
1060            expected_children
1061        );
1062        assert_eq!(*world.get::<Parent>(child3).unwrap(), Parent(parent));
1063        assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
1064
1065        let remove_children = [child1, child4];
1066        world.entity_mut(parent).remove_children(&remove_children);
1067        let expected_children: SmallVec<[Entity; 8]> = smallvec![child3, child2];
1068        assert_eq!(
1069            world.get::<Children>(parent).unwrap().0.clone(),
1070            expected_children
1071        );
1072        assert!(world.get::<Parent>(child1).is_none());
1073        assert!(world.get::<Parent>(child4).is_none());
1074    }
1075
1076    #[test]
1077    fn push_and_insert_and_clear_children_world() {
1078        let mut world = World::default();
1079        let entities = world
1080            .spawn_batch(vec![C(1), C(2), C(3)])
1081            .collect::<Vec<Entity>>();
1082
1083        world.entity_mut(entities[0]).push_children(&entities[1..3]);
1084
1085        let parent = entities[0];
1086        let child1 = entities[1];
1087        let child2 = entities[2];
1088
1089        let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
1090        assert_eq!(
1091            world.get::<Children>(parent).unwrap().0.clone(),
1092            expected_children
1093        );
1094        assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
1095        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1096
1097        world.entity_mut(parent).clear_children();
1098        assert!(world.get::<Children>(parent).is_none());
1099        assert!(world.get::<Parent>(child1).is_none());
1100        assert!(world.get::<Parent>(child2).is_none());
1101    }
1102
1103    #[test]
1104    fn push_and_replace_children_world() {
1105        let mut world = World::default();
1106        let entities = world
1107            .spawn_batch(vec![C(1), C(2), C(3), C(4), C(5)])
1108            .collect::<Vec<Entity>>();
1109
1110        world.entity_mut(entities[0]).push_children(&entities[1..3]);
1111
1112        let parent = entities[0];
1113        let child1 = entities[1];
1114        let child2 = entities[2];
1115        let child3 = entities[3];
1116        let child4 = entities[4];
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).replace_children(&entities[2..]);
1127        let expected_children: SmallVec<[Entity; 8]> = smallvec![child2, child3, child4];
1128        assert_eq!(
1129            world.get::<Children>(parent).unwrap().0.clone(),
1130            expected_children
1131        );
1132        assert!(world.get::<Parent>(child1).is_none());
1133        assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
1134        assert_eq!(*world.get::<Parent>(child3).unwrap(), Parent(parent));
1135        assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
1136    }
1137
1138    /// Tests what happens when all children are removed from a parent using world functions
1139    #[test]
1140    fn children_removed_when_empty_world() {
1141        let mut world = World::default();
1142        let entities = world
1143            .spawn_batch(vec![C(1), C(2), C(3)])
1144            .collect::<Vec<Entity>>();
1145
1146        let parent1 = entities[0];
1147        let parent2 = entities[1];
1148        let child = entities[2];
1149
1150        // push child into parent1
1151        world.entity_mut(parent1).push_children(&[child]);
1152        assert_eq!(
1153            world.get::<Children>(parent1).unwrap().0.as_slice(),
1154            &[child]
1155        );
1156
1157        // move only child from parent1 with `push_children`
1158        world.entity_mut(parent2).push_children(&[child]);
1159        assert!(world.get::<Children>(parent1).is_none());
1160
1161        // move only child from parent2 with `insert_children`
1162        world.entity_mut(parent1).insert_children(0, &[child]);
1163        assert!(world.get::<Children>(parent2).is_none());
1164
1165        // remove only child from parent1 with `remove_children`
1166        world.entity_mut(parent1).remove_children(&[child]);
1167        assert!(world.get::<Children>(parent1).is_none());
1168    }
1169
1170    /// Tests what happens when all children are removed form a parent using commands
1171    #[test]
1172    fn children_removed_when_empty_commands() {
1173        let mut world = World::default();
1174        let entities = world
1175            .spawn_batch(vec![C(1), C(2), C(3)])
1176            .collect::<Vec<Entity>>();
1177
1178        let parent1 = entities[0];
1179        let parent2 = entities[1];
1180        let child = entities[2];
1181
1182        let mut queue = CommandQueue::default();
1183
1184        // push child into parent1
1185        {
1186            let mut commands = Commands::new(&mut queue, &world);
1187            commands.entity(parent1).push_children(&[child]);
1188            queue.apply(&mut world);
1189        }
1190        assert_eq!(
1191            world.get::<Children>(parent1).unwrap().0.as_slice(),
1192            &[child]
1193        );
1194
1195        // move only child from parent1 with `push_children`
1196        {
1197            let mut commands = Commands::new(&mut queue, &world);
1198            commands.entity(parent2).push_children(&[child]);
1199            queue.apply(&mut world);
1200        }
1201        assert!(world.get::<Children>(parent1).is_none());
1202
1203        // move only child from parent2 with `insert_children`
1204        {
1205            let mut commands = Commands::new(&mut queue, &world);
1206            commands.entity(parent1).insert_children(0, &[child]);
1207            queue.apply(&mut world);
1208        }
1209        assert!(world.get::<Children>(parent2).is_none());
1210
1211        // move only child from parent1 with `add_child`
1212        {
1213            let mut commands = Commands::new(&mut queue, &world);
1214            commands.entity(parent2).add_child(child);
1215            queue.apply(&mut world);
1216        }
1217        assert!(world.get::<Children>(parent1).is_none());
1218
1219        // remove only child from parent2 with `remove_children`
1220        {
1221            let mut commands = Commands::new(&mut queue, &world);
1222            commands.entity(parent2).remove_children(&[child]);
1223            queue.apply(&mut world);
1224        }
1225        assert!(world.get::<Children>(parent2).is_none());
1226    }
1227
1228    #[test]
1229    fn regression_push_children_same_archetype() {
1230        let mut world = World::new();
1231        let child = world.spawn_empty().id();
1232        world.spawn_empty().push_children(&[child]);
1233    }
1234
1235    #[test]
1236    fn push_children_idempotent() {
1237        let mut world = World::new();
1238        let child = world.spawn_empty().id();
1239        let parent = world
1240            .spawn_empty()
1241            .push_children(&[child])
1242            .push_children(&[child])
1243            .id();
1244
1245        let mut query = world.query::<&Children>();
1246        let children = query.get(&world, parent).unwrap();
1247        assert_eq!(**children, [child]);
1248    }
1249
1250    #[test]
1251    fn push_children_does_not_insert_empty_children() {
1252        let mut world = World::new();
1253        let parent = world.spawn_empty().push_children(&[]).id();
1254
1255        let mut query = world.query::<&Children>();
1256        let children = query.get(&world, parent);
1257        assert!(children.is_err());
1258    }
1259}