Skip to content

Commit e44990a

Browse files
ld000lidong63
and
lidong63
committed
Add ReplaceChildren and ClearChildren EntityCommands (#6035)
# Objective Fixes #5859 ## Solution - Add `ClearChildren` and `ReplaceChildren` commands in the `crates/bevy_hierarchy/src/child_builder.rs` --- ## Changelog - Added `ClearChildren` and `ReplaceChildren` struct - Added `clear_children(&mut self) -> &mut Self` and `replace_children(&mut self, children: &[Entity]) -> &mut Self` function in `BuildChildren` trait - Changed `PushChildren` `write` function body to a `push_children ` function to reused in `ReplaceChildren` - Added `clear_children` function - Added `push_and_replace_children_commands` and `push_and_clear_children_commands` test Co-authored-by: ld000 <[email protected]> Co-authored-by: lidong63 <[email protected]>
1 parent d4e3fcd commit e44990a

File tree

1 file changed

+133
-0
lines changed

1 file changed

+133
-0
lines changed

crates/bevy_hierarchy/src/child_builder.rs

Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,14 @@ fn remove_children(parent: Entity, children: &[Entity], world: &mut World) {
140140
}
141141
}
142142

143+
fn clear_children(parent: Entity, world: &mut World) {
144+
if let Some(children) = world.entity_mut(parent).remove::<Children>() {
145+
for &child in &children.0 {
146+
world.entity_mut(child).remove::<Parent>();
147+
}
148+
}
149+
}
150+
143151
/// Command that adds a child to an entity
144152
#[derive(Debug)]
145153
pub struct AddChild {
@@ -196,6 +204,30 @@ impl Command for RemoveChildren {
196204
}
197205
}
198206

207+
/// Command that clear all children from an entity.
208+
pub struct ClearChildren {
209+
parent: Entity,
210+
}
211+
212+
impl Command for ClearChildren {
213+
fn write(self, world: &mut World) {
214+
clear_children(self.parent, world);
215+
}
216+
}
217+
218+
/// Command that clear all children from an entity. And replace with the given children.
219+
pub struct ReplaceChildren {
220+
parent: Entity,
221+
children: SmallVec<[Entity; 8]>,
222+
}
223+
224+
impl Command for ReplaceChildren {
225+
fn write(self, world: &mut World) {
226+
clear_children(self.parent, world);
227+
world.entity_mut(self.parent).push_children(&self.children);
228+
}
229+
}
230+
199231
/// Command that removes the parent of an entity, and removes that entity from the parent's [`Children`].
200232
pub struct RemoveParent {
201233
/// `Entity` whose parent must be removed.
@@ -268,6 +300,10 @@ pub trait BuildChildren {
268300
/// will have those children removed from its list. Removing all children from a parent causes its
269301
/// [`Children`] component to be removed from the entity.
270302
fn add_child(&mut self, child: Entity) -> &mut Self;
303+
/// Removes all children from this entity. The [`Children`] component will be removed if it exists, otherwise this does nothing.
304+
fn clear_children(&mut self) -> &mut Self;
305+
/// Removes all current children from this entity, replacing them with the specified list of entities.
306+
fn replace_children(&mut self, children: &[Entity]) -> &mut Self;
271307
/// Sets the parent of this entity.
272308
fn set_parent(&mut self, parent: Entity) -> &mut Self;
273309
/// Removes the parent of this entity.
@@ -325,6 +361,21 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> {
325361
self
326362
}
327363

364+
fn clear_children(&mut self) -> &mut Self {
365+
let parent = self.id();
366+
self.commands().add(ClearChildren { parent });
367+
self
368+
}
369+
370+
fn replace_children(&mut self, children: &[Entity]) -> &mut Self {
371+
let parent = self.id();
372+
self.commands().add(ReplaceChildren {
373+
children: SmallVec::from(children),
374+
parent,
375+
});
376+
self
377+
}
378+
328379
fn set_parent(&mut self, parent: Entity) -> &mut Self {
329380
let child = self.id();
330381
self.commands().add(AddChild { child, parent });
@@ -728,6 +779,88 @@ mod tests {
728779
assert!(world.get::<Parent>(child4).is_none());
729780
}
730781

782+
#[test]
783+
fn push_and_clear_children_commands() {
784+
let mut world = World::default();
785+
let entities = world
786+
.spawn_batch(vec![(C(1),), (C(2),), (C(3),), (C(4),), (C(5),)])
787+
.collect::<Vec<Entity>>();
788+
789+
let mut queue = CommandQueue::default();
790+
{
791+
let mut commands = Commands::new(&mut queue, &world);
792+
commands.entity(entities[0]).push_children(&entities[1..3]);
793+
}
794+
queue.apply(&mut world);
795+
796+
let parent = entities[0];
797+
let child1 = entities[1];
798+
let child2 = entities[2];
799+
800+
let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
801+
assert_eq!(
802+
world.get::<Children>(parent).unwrap().0.clone(),
803+
expected_children
804+
);
805+
assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
806+
assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
807+
808+
{
809+
let mut commands = Commands::new(&mut queue, &world);
810+
commands.entity(parent).clear_children();
811+
}
812+
queue.apply(&mut world);
813+
814+
assert!(world.get::<Children>(parent).is_none());
815+
816+
assert!(world.get::<Parent>(child1).is_none());
817+
assert!(world.get::<Parent>(child2).is_none());
818+
}
819+
820+
#[test]
821+
fn push_and_replace_children_commands() {
822+
let mut world = World::default();
823+
let entities = world
824+
.spawn_batch(vec![(C(1),), (C(2),), (C(3),), (C(4),), (C(5),)])
825+
.collect::<Vec<Entity>>();
826+
827+
let mut queue = CommandQueue::default();
828+
{
829+
let mut commands = Commands::new(&mut queue, &world);
830+
commands.entity(entities[0]).push_children(&entities[1..3]);
831+
}
832+
queue.apply(&mut world);
833+
834+
let parent = entities[0];
835+
let child1 = entities[1];
836+
let child2 = entities[2];
837+
let child4 = entities[4];
838+
839+
let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child2];
840+
assert_eq!(
841+
world.get::<Children>(parent).unwrap().0.clone(),
842+
expected_children
843+
);
844+
assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
845+
assert_eq!(*world.get::<Parent>(child2).unwrap(), Parent(parent));
846+
847+
let replace_children = [child1, child4];
848+
{
849+
let mut commands = Commands::new(&mut queue, &world);
850+
commands.entity(parent).replace_children(&replace_children);
851+
}
852+
queue.apply(&mut world);
853+
854+
let expected_children: SmallVec<[Entity; 8]> = smallvec![child1, child4];
855+
assert_eq!(
856+
world.get::<Children>(parent).unwrap().0.clone(),
857+
expected_children
858+
);
859+
assert_eq!(*world.get::<Parent>(child1).unwrap(), Parent(parent));
860+
assert_eq!(*world.get::<Parent>(child4).unwrap(), Parent(parent));
861+
assert!(world.get::<Parent>(child2).is_none());
862+
}
863+
731864
#[test]
732865
fn push_and_insert_and_remove_children_world() {
733866
let mut world = World::default();

0 commit comments

Comments
 (0)