Skip to content

Commit 30940e5

Browse files
authored
fix occasional crash moving ui root nodes (#11371)
# Objective fix an occasional crash when moving ui root nodes between cameras. occasionally, updating the TargetCamera of a ui element and then removing the element causes a crash. i believe that is because when we assign a child in taffy, the old parent doesn't remove that child from it's children, so we have: ``` user: create root node N1, camera A -> layout::set_camera_children(A) : - create implicit node A1 - assign 1 as child -> taffy.children[A1] = [N1], taffy.parents[1] = A1 user: move root node N1 to camera B -> layout::set_camera_children(B) : - create implicit node B1 - assign 1 as child -> taffy.children[A1] = [N1], taffy.children[B1] = [N1], taffy.parents[1] = B1 -> layout::set_camera_children(A) : - remove implicit node A1 (which still has N1 as a child) -> -> taffy sets parent[N1] = None *** -> taffy.children[B1] = [N1], taffy.parents[1] = None user: remove N1 -> layout::remove_entities(N1) - since parent[N1] is None, it's not removed from B1 -> taffy.children[B1] = [N1], taffy.parents[1] is removed -> layout::set_camera_children(B) - remove implicit node B1 - taffy crash accessing taffy.parents[N1] ``` ## Solution we can work around this by making sure to remove the child from the old parent if one exists (this pr). i think a better fix may be for taffy to check in `Taffy::remove` and only set the child's parent to None if it is currently equal to the node being removed but i'm not sure if there's an explicit assumption we're violating here (@nicoburns).
1 parent 43f83d5 commit 30940e5

File tree

1 file changed

+14
-7
lines changed
  • crates/bevy_ui/src/layout

1 file changed

+14
-7
lines changed

crates/bevy_ui/src/layout/mod.rs

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use bevy_transform::components::Transform;
1919
use bevy_utils::{default, EntityHashMap, HashMap, HashSet};
2020
use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
2121
use std::fmt;
22-
use taffy::Taffy;
22+
use taffy::{tree::LayoutTree, Taffy};
2323
use thiserror::Error;
2424

2525
pub struct LayoutContext {
@@ -169,12 +169,19 @@ without UI components as a child of an entity with UI components, results may be
169169
.iter()
170170
.find(|n| n.user_root_node == node)
171171
.cloned()
172-
.unwrap_or_else(|| RootNodePair {
173-
implicit_viewport_node: self
174-
.taffy
175-
.new_with_children(viewport_style.clone(), &[node])
176-
.unwrap(),
177-
user_root_node: node,
172+
.unwrap_or_else(|| {
173+
if let Some(previous_parent) = self.taffy.parent(node) {
174+
// remove the root node from the previous implicit node's children
175+
self.taffy.remove_child(previous_parent, node).unwrap();
176+
}
177+
178+
RootNodePair {
179+
implicit_viewport_node: self
180+
.taffy
181+
.new_with_children(viewport_style.clone(), &[node])
182+
.unwrap(),
183+
user_root_node: node,
184+
}
178185
});
179186
new_roots.push(root_node);
180187
}

0 commit comments

Comments
 (0)