From 770cc21912613e641ac9bc8d798433bf6529df5d Mon Sep 17 00:00:00 2001 From: Gabriel Bourgeois Date: Mon, 5 Sep 2022 09:53:22 -0400 Subject: [PATCH 1/4] Clean up taffy nodes when UI node entities are removed --- crates/bevy_ui/src/flex/mod.rs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index 9e98e1f01d7f5..5e01dabf10373 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -5,7 +5,7 @@ use bevy_ecs::{ entity::Entity, event::EventReader, query::{Changed, With, Without, WorldQuery}, - system::{Query, Res, ResMut, Resource}, + system::{Query, RemovedComponents, Res, ResMut, Resource}, }; use bevy_hierarchy::{Children, Parent}; use bevy_log::warn; @@ -172,6 +172,14 @@ without UI components as a child of an entity with UI components, results may be } } + pub fn remove_entities(&mut self, entities: impl Iterator) { + for entity in entities { + if let Some(node) = self.entity_to_taffy.remove(&entity) { + self.taffy.remove(node); + } + } + } + pub fn get_layout(&self, entity: Entity) -> Result<&taffy::layout::Layout, FlexError> { if let Some(taffy_node) = self.entity_to_taffy.get(&entity) { self.taffy @@ -208,6 +216,7 @@ pub fn flex_node_system( >, children_query: Query<(Entity, &Children), (With, Changed)>, mut node_transform_query: Query<(Entity, &mut Node, &mut Transform, Option<&Parent>)>, + removed_nodes: RemovedComponents, ) { // update window root nodes for window in windows.iter() { @@ -244,7 +253,8 @@ pub fn flex_node_system( flex_surface.upsert_leaf(entity, style, *calculated_size, scale_factor); } - // TODO: handle removed nodes + // clean up removed nodes + flex_surface.remove_entities(removed_nodes.iter()); // update window children (for now assuming all Nodes live in the primary window) if let Some(primary_window) = windows.get_primary() { From 82a1744917f170c39360d97e2288483b52593b99 Mon Sep 17 00:00:00 2001 From: Gabriel Bourgeois Date: Mon, 5 Sep 2022 10:20:14 -0400 Subject: [PATCH 2/4] Minor refactor and add missing documentation --- crates/bevy_ui/src/flex/mod.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index 5e01dabf10373..94e6ac54c6cb5 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -172,8 +172,9 @@ without UI components as a child of an entity with UI components, results may be } } - pub fn remove_entities(&mut self, entities: impl Iterator) { - for entity in entities { + /// Removes each entity from the internal map and then removes their associated node from taffy + pub fn remove_entities(&mut self, entities: impl IntoIterator) { + for entity in entities.into_iter() { if let Some(node) = self.entity_to_taffy.remove(&entity) { self.taffy.remove(node); } From ad4bb13a48577167fe8c54346948b6efa5bdee40 Mon Sep 17 00:00:00 2001 From: Gabriel Bourgeois Date: Mon, 5 Sep 2022 10:34:50 -0400 Subject: [PATCH 3/4] Minor refactor of iterator --- crates/bevy_ui/src/flex/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index 94e6ac54c6cb5..327f0d4662c3c 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -174,7 +174,7 @@ without UI components as a child of an entity with UI components, results may be /// Removes each entity from the internal map and then removes their associated node from taffy pub fn remove_entities(&mut self, entities: impl IntoIterator) { - for entity in entities.into_iter() { + for entity in entities { if let Some(node) = self.entity_to_taffy.remove(&entity) { self.taffy.remove(node); } From 101347a97079529e962861160fa3e37f7beb2b5d Mon Sep 17 00:00:00 2001 From: Gabriel Bourgeois Date: Mon, 5 Sep 2022 12:56:52 -0400 Subject: [PATCH 4/4] Add IntoIterator implementation for RemovedComponents --- crates/bevy_ecs/src/system/system_param.rs | 9 +++++++++ crates/bevy_ui/src/flex/mod.rs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/crates/bevy_ecs/src/system/system_param.rs b/crates/bevy_ecs/src/system/system_param.rs index 8762bd64c4255..fa6ad3f26fb7b 100644 --- a/crates/bevy_ecs/src/system/system_param.rs +++ b/crates/bevy_ecs/src/system/system_param.rs @@ -780,6 +780,15 @@ impl<'a, T: Component> RemovedComponents<'a, T> { } } +impl<'a, T: Component> IntoIterator for &'a RemovedComponents<'a, T> { + type Item = Entity; + type IntoIter = std::iter::Cloned>; + + fn into_iter(self) -> Self::IntoIter { + self.iter() + } +} + // SAFETY: Only reads World components unsafe impl ReadOnlySystemParamFetch for RemovedComponentsState {} diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index 327f0d4662c3c..633d45aff5919 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -255,7 +255,7 @@ pub fn flex_node_system( } // clean up removed nodes - flex_surface.remove_entities(removed_nodes.iter()); + flex_surface.remove_entities(&removed_nodes); // update window children (for now assuming all Nodes live in the primary window) if let Some(primary_window) = windows.get_primary() {