From 7e24dffaa3f5dd61ce32aecf52487e2644abaf65 Mon Sep 17 00:00:00 2001 From: ickshonpe Date: Mon, 3 Apr 2023 19:43:28 +0100 Subject: [PATCH 01/60] changes: * Added new components "TaffyNode" and "TaffyParent" * Added `insert_node` method to `FlexSurface` * Added `make_measure` function to `flex` module. * `flex_node_system` stores taffy nodes keys in the "TaffyNode" and "TaffyParent" components instead of looking them up using the `entity_to_taffy` map. --- crates/bevy_ui/src/flex/mod.rs | 205 +++++++++++++++++++++------------ 1 file changed, 129 insertions(+), 76 deletions(-) diff --git a/crates/bevy_ui/src/flex/mod.rs b/crates/bevy_ui/src/flex/mod.rs index 62ab50196e5ee..287d4bb623c56 100644 --- a/crates/bevy_ui/src/flex/mod.rs +++ b/crates/bevy_ui/src/flex/mod.rs @@ -1,13 +1,15 @@ mod convert; use crate::{CalculatedSize, Node, Style, UiScale}; +use bevy_core_pipeline::core_2d::graph::input::VIEW_ENTITY; use bevy_ecs::{ change_detection::DetectChanges, entity::Entity, event::EventReader, + prelude::Component, query::{Changed, ReadOnlyWorldQuery, With, Without}, removal_detection::RemovedComponents, - system::{Query, Res, ResMut, Resource}, + system::{Commands, Query, Res, ResMut, Resource}, }; use bevy_hierarchy::{Children, Parent}; use bevy_log::warn; @@ -22,6 +24,16 @@ use taffy::{ Taffy, }; +#[derive(Component, Copy, Clone)] +pub struct TaffyNode { + key: taffy::node::Node, +} + +#[derive(Component, Copy, Clone)] +pub struct TaffyParent { + key: taffy::node::Node, +} + pub struct LayoutContext { pub scale_factor: f64, pub physical_size: Vec2, @@ -78,73 +90,62 @@ impl Default for FlexSurface { } impl FlexSurface { - pub fn upsert_node(&mut self, entity: Entity, style: &Style, context: &LayoutContext) { - let mut added = false; - let taffy = &mut self.taffy; - let taffy_node = self.entity_to_taffy.entry(entity).or_insert_with(|| { - added = true; - taffy.new_leaf(convert::from_style(context, style)).unwrap() - }); + pub fn insert_node( + &mut self, + entity: Entity, + style: &Style, + calculated_size: Option<&CalculatedSize>, + context: &LayoutContext, + ) -> taffy::node::Node { + let style = convert::from_style(context, style); + let taffy_node = if let Some(calculated_size) = calculated_size { + let measure = make_measure(*calculated_size, context.scale_factor); + self.taffy.new_leaf_with_measure(style, measure).unwrap() + } else { + self.taffy.new_leaf(style).unwrap() + }; + self.entity_to_taffy.insert(entity, taffy_node); + taffy_node + } - if !added { - self.taffy - .set_style(*taffy_node, convert::from_style(context, style)) - .unwrap(); - } + pub fn upsert_node( + &mut self, + taffy_node: taffy::node::Node, + style: &Style, + context: &LayoutContext, + ) { + self.taffy + .set_style(taffy_node, convert::from_style(context, style)) + .unwrap(); } pub fn upsert_leaf( &mut self, - entity: Entity, + taffy_node: taffy::node::Node, style: &Style, calculated_size: CalculatedSize, context: &LayoutContext, ) { - let taffy = &mut self.taffy; let taffy_style = convert::from_style(context, style); - let scale_factor = context.scale_factor; - let measure = taffy::node::MeasureFunc::Boxed(Box::new( - move |constraints: Size>, _available: Size| { - let mut size = Size { - width: (scale_factor * calculated_size.size.x as f64) as f32, - height: (scale_factor * calculated_size.size.y as f64) as f32, - }; - match (constraints.width, constraints.height) { - (None, None) => {} - (Some(width), None) => { - if calculated_size.preserve_aspect_ratio { - size.height = width * size.height / size.width; - } - size.width = width; - } - (None, Some(height)) => { - if calculated_size.preserve_aspect_ratio { - size.width = height * size.width / size.height; - } - size.height = height; - } - (Some(width), Some(height)) => { - size.width = width; - size.height = height; - } - } - size - }, - )); - if let Some(taffy_node) = self.entity_to_taffy.get(&entity) { - self.taffy.set_style(*taffy_node, taffy_style).unwrap(); - self.taffy.set_measure(*taffy_node, Some(measure)).unwrap(); - } else { - let taffy_node = taffy.new_leaf_with_measure(taffy_style, measure).unwrap(); - self.entity_to_taffy.insert(entity, taffy_node); - } + let measure = make_measure(calculated_size, context.scale_factor); + self.taffy.set_style(taffy_node, taffy_style).unwrap(); + self.taffy.set_measure(taffy_node, Some(measure)).unwrap(); } - pub fn update_children(&mut self, entity: Entity, children: &Children) { + pub fn update_children( + &mut self, + entity: Entity, + children: &Children, + commands: &mut Commands, + ) { + let taffy_parent = self.entity_to_taffy.get(&entity).unwrap(); let mut taffy_children = Vec::with_capacity(children.len()); for child in children { if let Some(taffy_node) = self.entity_to_taffy.get(child) { taffy_children.push(*taffy_node); + commands + .entity(*child) + .insert(TaffyParent { key: *taffy_parent }); } else { warn!( "Unstyled child in a UI entity hierarchy. You are using an entity \ @@ -153,9 +154,8 @@ without UI components as a child of an entity with UI components, results may be } } - let taffy_node = self.entity_to_taffy.get(&entity).unwrap(); self.taffy - .set_children(*taffy_node, &taffy_children) + .set_children(*taffy_parent, &taffy_children) .unwrap(); } @@ -195,12 +195,17 @@ without UI components as a child of an entity with UI components, results may be &mut self, parent_window: Entity, children: impl Iterator, - ) { - let taffy_node = self.window_nodes.get(&parent_window).unwrap(); + commands: &mut Commands, + ) -> taffy::node::Node { + let window_node = *self.window_nodes.get(&parent_window).unwrap(); let child_nodes = children - .map(|e| *self.entity_to_taffy.get(&e).unwrap()) + .map(|e| { + commands.entity(e).insert(TaffyParent { key: window_node }); + *self.entity_to_taffy.get(&e).unwrap() + }) .collect::>(); - self.taffy.set_children(*taffy_node, &child_nodes).unwrap(); + self.taffy.set_children(window_node, &child_nodes).unwrap(); + window_node } pub fn compute_window_layouts(&mut self) { @@ -250,16 +255,21 @@ pub fn flex_node_system( mut resize_events: EventReader, mut flex_surface: ResMut, root_node_query: Query, Without)>, - node_query: Query<(Entity, &Style, Option<&CalculatedSize>), (With, Changed