From 7021ee77dee82c26dde88ba3cc40c14e55c092e8 Mon Sep 17 00:00:00 2001 From: JaySpruce Date: Sun, 13 Apr 2025 17:26:58 -0500 Subject: [PATCH] add `remove_children` / `remove_related` --- crates/bevy_ecs/src/hierarchy.rs | 30 +++++++++++++++++++ .../src/relationship/related_methods.rs | 26 ++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/crates/bevy_ecs/src/hierarchy.rs b/crates/bevy_ecs/src/hierarchy.rs index 91b1cc78cbac8..6711d2ff8518e 100644 --- a/crates/bevy_ecs/src/hierarchy.rs +++ b/crates/bevy_ecs/src/hierarchy.rs @@ -290,6 +290,11 @@ impl<'w> EntityWorldMut<'w> { self.add_related::(&[child]) } + /// Removes the relationship between this entity and the given entities. + pub fn remove_children(&mut self, children: &[Entity]) -> &mut Self { + self.remove_related::(children) + } + /// Replaces all the related children with a new set of children. pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self { self.replace_related::(children) @@ -372,6 +377,11 @@ impl<'a> EntityCommands<'a> { self.add_related::(&[child]) } + /// Removes the relationship between this entity and the given entities. + pub fn remove_children(&mut self, children: &[Entity]) -> &mut Self { + self.remove_related::(children) + } + /// Replaces the children on this entity with a new list of children. pub fn replace_children(&mut self, children: &[Entity]) -> &mut Self { self.replace_related::(children) @@ -643,6 +653,26 @@ mod tests { ); } + #[test] + fn remove_children() { + let mut world = World::new(); + let child1 = world.spawn_empty().id(); + let child2 = world.spawn_empty().id(); + let child3 = world.spawn_empty().id(); + let child4 = world.spawn_empty().id(); + + let mut root = world.spawn_empty(); + root.add_children(&[child1, child2, child3, child4]); + root.remove_children(&[child2, child3]); + let root = root.id(); + + let hierarchy = get_hierarchy(&world, root); + assert_eq!( + hierarchy, + Node::new_with(root, vec![Node::new(child1), Node::new(child4)]) + ); + } + #[test] fn self_parenting_invalid() { let mut world = World::new(); diff --git a/crates/bevy_ecs/src/relationship/related_methods.rs b/crates/bevy_ecs/src/relationship/related_methods.rs index 3674a1cba471b..fc18dfed44711 100644 --- a/crates/bevy_ecs/src/relationship/related_methods.rs +++ b/crates/bevy_ecs/src/relationship/related_methods.rs @@ -105,6 +105,23 @@ impl<'w> EntityWorldMut<'w> { self } + /// Removes the relation `R` between this entity and the given entities. + pub fn remove_related(&mut self, related: &[Entity]) -> &mut Self { + let id = self.id(); + self.world_scope(|world| { + for related in related { + if world + .get::(*related) + .is_some_and(|relationship| relationship.get() == id) + { + world.entity_mut(*related).remove::(); + } + } + }); + + self + } + /// Replaces all the related entities with a new set of entities. pub fn replace_related(&mut self, related: &[Entity]) -> &mut Self { type Collection = @@ -383,6 +400,15 @@ impl<'a> EntityCommands<'a> { self.add_related::(&[entity]) } + /// Removes the relation `R` between this entity and the given entities. + pub fn remove_related(&mut self, related: &[Entity]) -> &mut Self { + let related: Box<[Entity]> = related.into(); + + self.queue(move |mut entity: EntityWorldMut| { + entity.remove_related::(&related); + }) + } + /// Replaces all the related entities with the given set of new related entities. pub fn replace_related(&mut self, related: &[Entity]) -> &mut Self { let related: Box<[Entity]> = related.into();