@@ -46,11 +46,6 @@ pub struct PushChildren {
46
46
children : SmallVec < [ Entity ; 8 ] > ,
47
47
}
48
48
49
- pub struct ChildBuilder < ' a , ' b > {
50
- commands : & ' b mut Commands < ' a > ,
51
- push_children : PushChildren ,
52
- }
53
-
54
49
impl Command for PushChildren {
55
50
fn write ( self : Box < Self > , world : & mut World ) {
56
51
for child in self . children . iter ( ) {
@@ -77,6 +72,46 @@ impl Command for PushChildren {
77
72
}
78
73
}
79
74
75
+ pub struct RemoveChildren {
76
+ parent : Entity ,
77
+ children : SmallVec < [ Entity ; 8 ] > ,
78
+ }
79
+
80
+ fn remove_children ( parent : Entity , children : & [ Entity ] , world : & mut World ) {
81
+ for child in children. iter ( ) {
82
+ let mut child = world. entity_mut ( * child) ;
83
+ let mut remove_parent = false ;
84
+ if let Some ( child_parent) = child. get_mut :: < Parent > ( ) {
85
+ if child_parent. 0 == parent {
86
+ remove_parent = true ;
87
+ }
88
+ }
89
+ if remove_parent {
90
+ if let Some ( parent) = child. remove :: < Parent > ( ) {
91
+ child. insert ( PreviousParent ( parent. 0 ) ) ;
92
+ }
93
+ }
94
+ }
95
+ // Remove the children from the parents.
96
+ if let Some ( mut parent_children) = world. get_mut :: < Children > ( parent) {
97
+ parent_children
98
+ . 0
99
+ . retain ( |parent_child| !children. contains ( parent_child) ) ;
100
+ }
101
+ }
102
+
103
+ impl Command for RemoveChildren {
104
+ fn write ( self : Box < Self > , world : & mut World ) {
105
+ // Remove any matching Parent components from the children
106
+ remove_children ( self . parent , & self . children , world) ;
107
+ }
108
+ }
109
+
110
+ pub struct ChildBuilder < ' a , ' b > {
111
+ commands : & ' b mut Commands < ' a > ,
112
+ push_children : PushChildren ,
113
+ }
114
+
80
115
impl < ' a , ' b > ChildBuilder < ' a , ' b > {
81
116
pub fn spawn_bundle ( & mut self , bundle : impl Bundle ) -> EntityCommands < ' a , ' _ > {
82
117
let e = self . commands . spawn_bundle ( bundle) ;
@@ -104,6 +139,7 @@ pub trait BuildChildren {
104
139
fn with_children ( & mut self , f : impl FnOnce ( & mut ChildBuilder ) ) -> & mut Self ;
105
140
fn push_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
106
141
fn insert_children ( & mut self , index : usize , children : & [ Entity ] ) -> & mut Self ;
142
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
107
143
}
108
144
109
145
impl < ' a , ' b > BuildChildren for EntityCommands < ' a , ' b > {
@@ -143,6 +179,15 @@ impl<'a, 'b> BuildChildren for EntityCommands<'a, 'b> {
143
179
} ) ;
144
180
self
145
181
}
182
+
183
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self {
184
+ let parent = self . id ( ) ;
185
+ self . commands ( ) . add ( RemoveChildren {
186
+ children : SmallVec :: from ( children) ,
187
+ parent,
188
+ } ) ;
189
+ self
190
+ }
146
191
}
147
192
148
193
#[ derive( Debug ) ]
@@ -202,6 +247,7 @@ pub trait BuildWorldChildren {
202
247
fn with_children ( & mut self , spawn_children : impl FnOnce ( & mut WorldChildBuilder ) ) -> & mut Self ;
203
248
fn push_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
204
249
fn insert_children ( & mut self , index : usize , children : & [ Entity ] ) -> & mut Self ;
250
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
205
251
}
206
252
207
253
impl < ' w > BuildWorldChildren for EntityMut < ' w > {
@@ -262,6 +308,33 @@ impl<'w> BuildWorldChildren for EntityMut<'w> {
262
308
}
263
309
self
264
310
}
311
+
312
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self {
313
+ let parent = self . id ( ) ;
314
+ // SAFE: This doesn't change the parent's location
315
+ let world = unsafe { self . world_mut ( ) } ;
316
+ for child in children. iter ( ) {
317
+ let mut child = world. entity_mut ( * child) ;
318
+ let mut remove_parent = false ;
319
+ if let Some ( child_parent) = child. get_mut :: < Parent > ( ) {
320
+ if child_parent. 0 == parent {
321
+ remove_parent = true ;
322
+ }
323
+ }
324
+ if remove_parent {
325
+ if let Some ( parent) = child. remove :: < Parent > ( ) {
326
+ child. insert ( PreviousParent ( parent. 0 ) ) ;
327
+ }
328
+ }
329
+ }
330
+ // Remove the children from the parents.
331
+ if let Some ( mut parent_children) = world. get_mut :: < Children > ( parent) {
332
+ parent_children
333
+ . 0
334
+ . retain ( |parent_child| !children. contains ( parent_child) ) ;
335
+ }
336
+ self
337
+ }
265
338
}
266
339
267
340
impl < ' w > BuildWorldChildren for WorldChildBuilder < ' w > {
@@ -321,6 +394,15 @@ impl<'w> BuildWorldChildren for WorldChildBuilder<'w> {
321
394
}
322
395
self
323
396
}
397
+
398
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self {
399
+ let parent = self
400
+ . current_entity
401
+ . expect ( "Cannot remove children without a parent. Try creating an entity first." ) ;
402
+
403
+ remove_children ( parent, children, self . world ) ;
404
+ self
405
+ }
324
406
}
325
407
326
408
#[ cfg( test) ]
@@ -367,7 +449,7 @@ mod tests {
367
449
}
368
450
369
451
#[ test]
370
- fn push_and_insert_children_commands ( ) {
452
+ fn push_and_insert_and_remove_children_commands ( ) {
371
453
let mut world = World :: default ( ) ;
372
454
373
455
let entities = world
@@ -425,10 +507,33 @@ mod tests {
425
507
* world. get:: <PreviousParent >( child4) . unwrap( ) ,
426
508
PreviousParent ( parent)
427
509
) ;
510
+
511
+ let remove_children = [ child1, child4] ;
512
+ {
513
+ let mut commands = Commands :: new ( & mut queue, & world) ;
514
+ commands. entity ( parent) . remove_children ( & remove_children) ;
515
+ }
516
+ queue. apply ( & mut world) ;
517
+
518
+ let expected_children: SmallVec < [ Entity ; 8 ] > = smallvec ! [ child3, child2] ;
519
+ assert_eq ! (
520
+ world. get:: <Children >( parent) . unwrap( ) . 0 . clone( ) ,
521
+ expected_children
522
+ ) ;
523
+ assert ! ( world. get:: <Parent >( child1) . is_none( ) ) ;
524
+ assert ! ( world. get:: <Parent >( child4) . is_none( ) ) ;
525
+ assert_eq ! (
526
+ * world. get:: <PreviousParent >( child1) . unwrap( ) ,
527
+ PreviousParent ( parent)
528
+ ) ;
529
+ assert_eq ! (
530
+ * world. get:: <PreviousParent >( child4) . unwrap( ) ,
531
+ PreviousParent ( parent)
532
+ ) ;
428
533
}
429
534
430
535
#[ test]
431
- fn push_and_insert_children_world ( ) {
536
+ fn push_and_insert_and_remove_children_world ( ) {
432
537
let mut world = World :: default ( ) ;
433
538
434
539
let entities = world
@@ -476,5 +581,23 @@ mod tests {
476
581
* world. get:: <PreviousParent >( child4) . unwrap( ) ,
477
582
PreviousParent ( parent)
478
583
) ;
584
+
585
+ let remove_children = [ child1, child4] ;
586
+ world. entity_mut ( parent) . remove_children ( & remove_children) ;
587
+ let expected_children: SmallVec < [ Entity ; 8 ] > = smallvec ! [ child3, child2] ;
588
+ assert_eq ! (
589
+ world. get:: <Children >( parent) . unwrap( ) . 0 . clone( ) ,
590
+ expected_children
591
+ ) ;
592
+ assert ! ( world. get:: <Parent >( child1) . is_none( ) ) ;
593
+ assert ! ( world. get:: <Parent >( child4) . is_none( ) ) ;
594
+ assert_eq ! (
595
+ * world. get:: <PreviousParent >( child1) . unwrap( ) ,
596
+ PreviousParent ( parent)
597
+ ) ;
598
+ assert_eq ! (
599
+ * world. get:: <PreviousParent >( child4) . unwrap( ) ,
600
+ PreviousParent ( parent)
601
+ ) ;
479
602
}
480
603
}
0 commit comments