@@ -77,10 +77,15 @@ fn remove_children(parent: Entity, children: &[Entity], world: &mut World) {
77
77
}
78
78
push_events ( world, events) ;
79
79
80
- if let Some ( mut parent_children) = world. get_mut :: < Children > ( parent) {
80
+ let mut parent = world. entity_mut ( parent) ;
81
+ if let Some ( mut parent_children) = parent. get_mut :: < Children > ( ) {
81
82
parent_children
82
83
. 0
83
84
. retain ( |parent_child| !children. contains ( parent_child) ) ;
85
+
86
+ if parent_children. is_empty ( ) {
87
+ parent. remove :: < Children > ( ) ;
88
+ }
84
89
}
85
90
}
86
91
@@ -258,12 +263,26 @@ pub trait BuildChildren {
258
263
/// ```
259
264
fn add_children < T > ( & mut self , f : impl FnOnce ( & mut ChildBuilder ) -> T ) -> T ;
260
265
/// Pushes children to the back of the builder's children
266
+ ///
267
+ /// If the children were previously children of another parent, that parent's [`Children`] component
268
+ /// will have those children removed from its list. Removing all children from a parent causes its
269
+ /// [`Children`] component to be removed from the entity.
261
270
fn push_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
262
271
/// Inserts children at the given index
272
+ ///
273
+ /// If the children were previously children of another parent, that parent's [`Children`] component
274
+ /// will have those children removed from its list. Removing all children from a parent causes its
275
+ /// [`Children`] component to be removed from the entity.
263
276
fn insert_children ( & mut self , index : usize , children : & [ Entity ] ) -> & mut Self ;
264
277
/// Removes the given children
278
+ ///
279
+ /// Removing all children from a parent causes its [`Children`] component to be removed from the entity.
265
280
fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
266
281
/// Adds a single child
282
+ ///
283
+ /// If the children were previously children of another parent, that parent's [`Children`] component
284
+ /// will have those children removed from its list. Removing all children from a parent causes its
285
+ /// [`Children`] component to be removed from the entity.
267
286
fn add_child ( & mut self , child : Entity ) -> & mut Self ;
268
287
}
269
288
@@ -672,6 +691,96 @@ mod tests {
672
691
assert ! ( world. get:: <Parent >( child4) . is_none( ) ) ;
673
692
}
674
693
694
+ /// Tests what happens when all children are removed from a parent using world functions
695
+ #[ test]
696
+ fn children_removed_when_empty_world ( ) {
697
+ let mut world = World :: default ( ) ;
698
+ let entities = world
699
+ . spawn_batch ( vec ! [ ( C ( 1 ) , ) , ( C ( 2 ) , ) , ( C ( 3 ) , ) ] )
700
+ . collect :: < Vec < Entity > > ( ) ;
701
+
702
+ let parent1 = entities[ 0 ] ;
703
+ let parent2 = entities[ 1 ] ;
704
+ let child = entities[ 2 ] ;
705
+
706
+ // push child into parent1
707
+ world. entity_mut ( parent1) . push_children ( & [ child] ) ;
708
+ assert_eq ! (
709
+ world. get:: <Children >( parent1) . unwrap( ) . 0 . as_slice( ) ,
710
+ & [ child]
711
+ ) ;
712
+
713
+ // move only child from parent1 with `push_children`
714
+ world. entity_mut ( parent2) . push_children ( & [ child] ) ;
715
+ assert ! ( world. get:: <Children >( parent1) . is_none( ) ) ;
716
+
717
+ // move only child from parent2 with `insert_children`
718
+ world. entity_mut ( parent1) . insert_children ( 0 , & [ child] ) ;
719
+ assert ! ( world. get:: <Children >( parent2) . is_none( ) ) ;
720
+
721
+ // remove only child from parent1 with `remove_children`
722
+ world. entity_mut ( parent1) . remove_children ( & [ child] ) ;
723
+ assert ! ( world. get:: <Children >( parent1) . is_none( ) ) ;
724
+ }
725
+
726
+ /// Tests what happens when all children are removed form a parent using commands
727
+ #[ test]
728
+ fn children_removed_when_empty_commands ( ) {
729
+ let mut world = World :: default ( ) ;
730
+ let entities = world
731
+ . spawn_batch ( vec ! [ ( C ( 1 ) , ) , ( C ( 2 ) , ) , ( C ( 3 ) , ) ] )
732
+ . collect :: < Vec < Entity > > ( ) ;
733
+
734
+ let parent1 = entities[ 0 ] ;
735
+ let parent2 = entities[ 1 ] ;
736
+ let child = entities[ 2 ] ;
737
+
738
+ let mut queue = CommandQueue :: default ( ) ;
739
+
740
+ // push child into parent1
741
+ {
742
+ let mut commands = Commands :: new ( & mut queue, & world) ;
743
+ commands. entity ( parent1) . push_children ( & [ child] ) ;
744
+ queue. apply ( & mut world) ;
745
+ }
746
+ assert_eq ! (
747
+ world. get:: <Children >( parent1) . unwrap( ) . 0 . as_slice( ) ,
748
+ & [ child]
749
+ ) ;
750
+
751
+ // move only child from parent1 with `push_children`
752
+ {
753
+ let mut commands = Commands :: new ( & mut queue, & world) ;
754
+ commands. entity ( parent2) . push_children ( & [ child] ) ;
755
+ queue. apply ( & mut world) ;
756
+ }
757
+ assert ! ( world. get:: <Children >( parent1) . is_none( ) ) ;
758
+
759
+ // move only child from parent2 with `insert_children`
760
+ {
761
+ let mut commands = Commands :: new ( & mut queue, & world) ;
762
+ commands. entity ( parent1) . insert_children ( 0 , & [ child] ) ;
763
+ queue. apply ( & mut world) ;
764
+ }
765
+ assert ! ( world. get:: <Children >( parent2) . is_none( ) ) ;
766
+
767
+ // move only child from parent1 with `add_child`
768
+ {
769
+ let mut commands = Commands :: new ( & mut queue, & world) ;
770
+ commands. entity ( parent2) . add_child ( child) ;
771
+ queue. apply ( & mut world) ;
772
+ }
773
+ assert ! ( world. get:: <Children >( parent1) . is_none( ) ) ;
774
+
775
+ // remove only child from parent2 with `remove_children`
776
+ {
777
+ let mut commands = Commands :: new ( & mut queue, & world) ;
778
+ commands. entity ( parent2) . remove_children ( & [ child] ) ;
779
+ queue. apply ( & mut world) ;
780
+ }
781
+ assert ! ( world. get:: <Children >( parent2) . is_none( ) ) ;
782
+ }
783
+
675
784
#[ test]
676
785
fn regression_push_children_same_archetype ( ) {
677
786
let mut world = World :: new ( ) ;
0 commit comments