@@ -40,11 +40,6 @@ pub struct PushChildren {
40
40
children : SmallVec < [ Entity ; 8 ] > ,
41
41
}
42
42
43
- pub struct ChildBuilder < ' w , ' s , ' a > {
44
- commands : & ' a mut Commands < ' w , ' s > ,
45
- push_children : PushChildren ,
46
- }
47
-
48
43
impl Command for PushChildren {
49
44
fn write ( self , world : & mut World ) {
50
45
for child in self . children . iter ( ) {
@@ -71,6 +66,46 @@ impl Command for PushChildren {
71
66
}
72
67
}
73
68
69
+ pub struct RemoveChildren {
70
+ parent : Entity ,
71
+ children : SmallVec < [ Entity ; 8 ] > ,
72
+ }
73
+
74
+ fn remove_children ( parent : Entity , children : & [ Entity ] , world : & mut World ) {
75
+ for child in children. iter ( ) {
76
+ let mut child = world. entity_mut ( * child) ;
77
+ let mut remove_parent = false ;
78
+ if let Some ( child_parent) = child. get_mut :: < Parent > ( ) {
79
+ if child_parent. 0 == parent {
80
+ remove_parent = true ;
81
+ }
82
+ }
83
+ if remove_parent {
84
+ if let Some ( parent) = child. remove :: < Parent > ( ) {
85
+ child. insert ( PreviousParent ( parent. 0 ) ) ;
86
+ }
87
+ }
88
+ }
89
+ // Remove the children from the parents.
90
+ if let Some ( mut parent_children) = world. get_mut :: < Children > ( parent) {
91
+ parent_children
92
+ . 0
93
+ . retain ( |parent_child| !children. contains ( parent_child) ) ;
94
+ }
95
+ }
96
+
97
+ impl Command for RemoveChildren {
98
+ fn write ( self , world : & mut World ) {
99
+ // Remove any matching Parent components from the children
100
+ remove_children ( self . parent , & self . children , world) ;
101
+ }
102
+ }
103
+
104
+ pub struct ChildBuilder < ' w , ' s , ' a > {
105
+ commands : & ' a mut Commands < ' w , ' s > ,
106
+ push_children : PushChildren ,
107
+ }
108
+
74
109
impl < ' w , ' s , ' a > ChildBuilder < ' w , ' s , ' a > {
75
110
pub fn spawn_bundle ( & mut self , bundle : impl Bundle ) -> EntityCommands < ' w , ' s , ' _ > {
76
111
let e = self . commands . spawn_bundle ( bundle) ;
@@ -98,6 +133,7 @@ pub trait BuildChildren {
98
133
fn with_children ( & mut self , f : impl FnOnce ( & mut ChildBuilder ) ) -> & mut Self ;
99
134
fn push_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
100
135
fn insert_children ( & mut self , index : usize , children : & [ Entity ] ) -> & mut Self ;
136
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
101
137
}
102
138
103
139
impl < ' w , ' s , ' a > BuildChildren for EntityCommands < ' w , ' s , ' a > {
@@ -137,6 +173,15 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> {
137
173
} ) ;
138
174
self
139
175
}
176
+
177
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self {
178
+ let parent = self . id ( ) ;
179
+ self . commands ( ) . add ( RemoveChildren {
180
+ children : SmallVec :: from ( children) ,
181
+ parent,
182
+ } ) ;
183
+ self
184
+ }
140
185
}
141
186
142
187
#[ derive( Debug ) ]
@@ -196,6 +241,7 @@ pub trait BuildWorldChildren {
196
241
fn with_children ( & mut self , spawn_children : impl FnOnce ( & mut WorldChildBuilder ) ) -> & mut Self ;
197
242
fn push_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
198
243
fn insert_children ( & mut self , index : usize , children : & [ Entity ] ) -> & mut Self ;
244
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self ;
199
245
}
200
246
201
247
impl < ' w > BuildWorldChildren for EntityMut < ' w > {
@@ -260,6 +306,33 @@ impl<'w> BuildWorldChildren for EntityMut<'w> {
260
306
}
261
307
self
262
308
}
309
+
310
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self {
311
+ let parent = self . id ( ) ;
312
+ // SAFE: This doesn't change the parent's location
313
+ let world = unsafe { self . world_mut ( ) } ;
314
+ for child in children. iter ( ) {
315
+ let mut child = world. entity_mut ( * child) ;
316
+ let mut remove_parent = false ;
317
+ if let Some ( child_parent) = child. get_mut :: < Parent > ( ) {
318
+ if child_parent. 0 == parent {
319
+ remove_parent = true ;
320
+ }
321
+ }
322
+ if remove_parent {
323
+ if let Some ( parent) = child. remove :: < Parent > ( ) {
324
+ child. insert ( PreviousParent ( parent. 0 ) ) ;
325
+ }
326
+ }
327
+ }
328
+ // Remove the children from the parents.
329
+ if let Some ( mut parent_children) = world. get_mut :: < Children > ( parent) {
330
+ parent_children
331
+ . 0
332
+ . retain ( |parent_child| !children. contains ( parent_child) ) ;
333
+ }
334
+ self
335
+ }
263
336
}
264
337
265
338
impl < ' w > BuildWorldChildren for WorldChildBuilder < ' w > {
@@ -319,6 +392,15 @@ impl<'w> BuildWorldChildren for WorldChildBuilder<'w> {
319
392
}
320
393
self
321
394
}
395
+
396
+ fn remove_children ( & mut self , children : & [ Entity ] ) -> & mut Self {
397
+ let parent = self
398
+ . current_entity
399
+ . expect ( "Cannot remove children without a parent. Try creating an entity first." ) ;
400
+
401
+ remove_children ( parent, children, self . world ) ;
402
+ self
403
+ }
322
404
}
323
405
324
406
#[ cfg( test) ]
@@ -369,7 +451,7 @@ mod tests {
369
451
}
370
452
371
453
#[ test]
372
- fn push_and_insert_children_commands ( ) {
454
+ fn push_and_insert_and_remove_children_commands ( ) {
373
455
let mut world = World :: default ( ) ;
374
456
375
457
let entities = world
@@ -427,10 +509,33 @@ mod tests {
427
509
* world. get:: <PreviousParent >( child4) . unwrap( ) ,
428
510
PreviousParent ( parent)
429
511
) ;
512
+
513
+ let remove_children = [ child1, child4] ;
514
+ {
515
+ let mut commands = Commands :: new ( & mut queue, & world) ;
516
+ commands. entity ( parent) . remove_children ( & remove_children) ;
517
+ }
518
+ queue. apply ( & mut world) ;
519
+
520
+ let expected_children: SmallVec < [ Entity ; 8 ] > = smallvec ! [ child3, child2] ;
521
+ assert_eq ! (
522
+ world. get:: <Children >( parent) . unwrap( ) . 0 . clone( ) ,
523
+ expected_children
524
+ ) ;
525
+ assert ! ( world. get:: <Parent >( child1) . is_none( ) ) ;
526
+ assert ! ( world. get:: <Parent >( child4) . is_none( ) ) ;
527
+ assert_eq ! (
528
+ * world. get:: <PreviousParent >( child1) . unwrap( ) ,
529
+ PreviousParent ( parent)
530
+ ) ;
531
+ assert_eq ! (
532
+ * world. get:: <PreviousParent >( child4) . unwrap( ) ,
533
+ PreviousParent ( parent)
534
+ ) ;
430
535
}
431
536
432
537
#[ test]
433
- fn push_and_insert_children_world ( ) {
538
+ fn push_and_insert_and_remove_children_world ( ) {
434
539
let mut world = World :: default ( ) ;
435
540
436
541
let entities = world
@@ -478,6 +583,24 @@ mod tests {
478
583
* world. get:: <PreviousParent >( child4) . unwrap( ) ,
479
584
PreviousParent ( parent)
480
585
) ;
586
+
587
+ let remove_children = [ child1, child4] ;
588
+ world. entity_mut ( parent) . remove_children ( & remove_children) ;
589
+ let expected_children: SmallVec < [ Entity ; 8 ] > = smallvec ! [ child3, child2] ;
590
+ assert_eq ! (
591
+ world. get:: <Children >( parent) . unwrap( ) . 0 . clone( ) ,
592
+ expected_children
593
+ ) ;
594
+ assert ! ( world. get:: <Parent >( child1) . is_none( ) ) ;
595
+ assert ! ( world. get:: <Parent >( child4) . is_none( ) ) ;
596
+ assert_eq ! (
597
+ * world. get:: <PreviousParent >( child1) . unwrap( ) ,
598
+ PreviousParent ( parent)
599
+ ) ;
600
+ assert_eq ! (
601
+ * world. get:: <PreviousParent >( child4) . unwrap( ) ,
602
+ PreviousParent ( parent)
603
+ ) ;
481
604
}
482
605
483
606
#[ test]
0 commit comments