mirror of
https://github.com/bevyengine/bevy
synced 2024-11-22 04:33:37 +00:00
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).
This commit is contained in:
parent
43f83d5e7c
commit
30940e5cb4
1 changed files with 14 additions and 7 deletions
|
@ -19,7 +19,7 @@ use bevy_transform::components::Transform;
|
|||
use bevy_utils::{default, EntityHashMap, HashMap, HashSet};
|
||||
use bevy_window::{PrimaryWindow, Window, WindowScaleFactorChanged};
|
||||
use std::fmt;
|
||||
use taffy::Taffy;
|
||||
use taffy::{tree::LayoutTree, Taffy};
|
||||
use thiserror::Error;
|
||||
|
||||
pub struct LayoutContext {
|
||||
|
@ -169,12 +169,19 @@ without UI components as a child of an entity with UI components, results may be
|
|||
.iter()
|
||||
.find(|n| n.user_root_node == node)
|
||||
.cloned()
|
||||
.unwrap_or_else(|| RootNodePair {
|
||||
implicit_viewport_node: self
|
||||
.taffy
|
||||
.new_with_children(viewport_style.clone(), &[node])
|
||||
.unwrap(),
|
||||
user_root_node: node,
|
||||
.unwrap_or_else(|| {
|
||||
if let Some(previous_parent) = self.taffy.parent(node) {
|
||||
// remove the root node from the previous implicit node's children
|
||||
self.taffy.remove_child(previous_parent, node).unwrap();
|
||||
}
|
||||
|
||||
RootNodePair {
|
||||
implicit_viewport_node: self
|
||||
.taffy
|
||||
.new_with_children(viewport_style.clone(), &[node])
|
||||
.unwrap(),
|
||||
user_root_node: node,
|
||||
}
|
||||
});
|
||||
new_roots.push(root_node);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue