From 7d57d7ac0c967a4ee6a11eb984fe06f09391f554 Mon Sep 17 00:00:00 2001 From: ira Date: Wed, 23 Nov 2022 00:27:28 +0000 Subject: [PATCH] Remove `BuildWorldChildren` impl from `WorldChildBuilder` (#6727) # Objective Remove an obscure and inconsistent bit of API. Simplify the `WorldChildBuilder` code. No idea why this even exists. An example of the removed API: ```rust world.spawn_empty().with_children(|parent| { parent.spawn_empty(); parent.push_children(&[some_entity]); // Does *not* add children to the parent. // It's actually identical to: parent.spawn_empty().push_children(&[some_entity]); }); world.spawn_empty().with_children(|parent| { // This just panics. parent.push_children(&[some_entity]); }); ``` This exists only on `WorldChildBuilder`; `ChildBuilder` does not have this API. Yeet. ## Migration Guide Hierarchy editing methods such as `with_children` and `push_children` have been removed from `WorldChildBuilder`. You can edit the hierarchy via `EntityMut` instead. Co-authored-by: devil-ira --- crates/bevy_hierarchy/src/child_builder.rs | 96 +++------------------- 1 file changed, 10 insertions(+), 86 deletions(-) diff --git a/crates/bevy_hierarchy/src/child_builder.rs b/crates/bevy_hierarchy/src/child_builder.rs index a5c5d6708a667..8e6309e481a66 100644 --- a/crates/bevy_hierarchy/src/child_builder.rs +++ b/crates/bevy_hierarchy/src/child_builder.rs @@ -389,21 +389,18 @@ impl<'w, 's, 'a> BuildChildren for EntityCommands<'w, 's, 'a> { #[derive(Debug)] pub struct WorldChildBuilder<'w> { world: &'w mut World, - current_entity: Option, - parent_entities: Vec, + parent: Entity, } impl<'w> WorldChildBuilder<'w> { /// Spawns an entity with the given bundle and inserts it into the children defined by the [`WorldChildBuilder`] pub fn spawn(&mut self, bundle: impl Bundle + Send + Sync + 'static) -> EntityMut<'_> { - let parent_entity = self.parent_entity(); - let entity = self.world.spawn((bundle, Parent(parent_entity))).id(); - push_child_unchecked(self.world, parent_entity, entity); - self.current_entity = Some(entity); + let entity = self.world.spawn((bundle, Parent(self.parent))).id(); + push_child_unchecked(self.world, self.parent, entity); if let Some(mut added) = self.world.get_resource_mut::>() { added.send(HierarchyEvent::ChildAdded { child: entity, - parent: parent_entity, + parent: self.parent, }); } self.world.entity_mut(entity) @@ -420,14 +417,12 @@ impl<'w> WorldChildBuilder<'w> { /// Spawns an [`Entity`] with no components and inserts it into the children defined by the [`WorldChildBuilder`] which adds the [`Parent`] component to it. pub fn spawn_empty(&mut self) -> EntityMut<'_> { - let parent_entity = self.parent_entity(); - let entity = self.world.spawn(Parent(parent_entity)).id(); - push_child_unchecked(self.world, parent_entity, entity); - self.current_entity = Some(entity); + let entity = self.world.spawn(Parent(self.parent)).id(); + push_child_unchecked(self.world, self.parent, entity); if let Some(mut added) = self.world.get_resource_mut::>() { added.send(HierarchyEvent::ChildAdded { child: entity, - parent: parent_entity, + parent: self.parent, }); } self.world.entity_mut(entity) @@ -435,10 +430,7 @@ impl<'w> WorldChildBuilder<'w> { /// Returns the parent entity of this [`WorldChildBuilder`] pub fn parent_entity(&self) -> Entity { - self.parent_entities - .last() - .cloned() - .expect("There should always be a parent at this point.") + self.parent } } @@ -456,14 +448,9 @@ pub trait BuildWorldChildren { impl<'w> BuildWorldChildren for EntityMut<'w> { fn with_children(&mut self, spawn_children: impl FnOnce(&mut WorldChildBuilder)) -> &mut Self { - let entity = self.id(); + let parent = self.id(); self.world_scope(|world| { - let mut builder = WorldChildBuilder { - current_entity: None, - parent_entities: vec![entity], - world, - }; - spawn_children(&mut builder); + spawn_children(&mut WorldChildBuilder { world, parent }); }); self } @@ -509,69 +496,6 @@ impl<'w> BuildWorldChildren for EntityMut<'w> { } } -impl<'w> BuildWorldChildren for WorldChildBuilder<'w> { - fn with_children( - &mut self, - spawn_children: impl FnOnce(&mut WorldChildBuilder<'w>), - ) -> &mut Self { - let current_entity = self - .current_entity - .expect("Cannot add children without a parent. Try creating an entity first."); - self.parent_entities.push(current_entity); - self.current_entity = None; - - spawn_children(self); - - self.current_entity = self.parent_entities.pop(); - self - } - - fn push_children(&mut self, children: &[Entity]) -> &mut Self { - let parent = self - .current_entity - .expect("Cannot add children without a parent. Try creating an entity first."); - update_old_parents(self.world, parent, children); - if let Some(mut children_component) = self.world.get_mut::(parent) { - children_component - .0 - .retain(|value| !children.contains(value)); - children_component.0.extend(children.iter().cloned()); - } else { - self.world - .entity_mut(parent) - .insert(Children::from_entities(children)); - } - self - } - - fn insert_children(&mut self, index: usize, children: &[Entity]) -> &mut Self { - let parent = self - .current_entity - .expect("Cannot add children without a parent. Try creating an entity first."); - update_old_parents(self.world, parent, children); - if let Some(mut children_component) = self.world.get_mut::(parent) { - children_component - .0 - .retain(|value| !children.contains(value)); - children_component.0.insert_from_slice(index, children); - } else { - self.world - .entity_mut(parent) - .insert(Children::from_entities(children)); - } - self - } - - fn remove_children(&mut self, children: &[Entity]) -> &mut Self { - let parent = self - .current_entity - .expect("Cannot remove children without a parent. Try creating an entity first."); - - remove_children(parent, children, self.world); - self - } -} - #[cfg(test)] mod tests { use super::{BuildChildren, BuildWorldChildren};