gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 501HTML 254C 19JavaScript 81412 Definitions

Convert mutable layout getters to layout setters (#583)

* Convert get_unrounded_layout_mut to set_unrounded_layout

* Convert get_final_layout_mut to set_final_layout

7781c70241f7f572130c13106f2a869a9cf80885 · by Nico Burns · (2 years ago) · parent 1a077197b · browse the tree at this commit

Semantic delta · 31

examples/custom_layout_tree_owned.rs

examples/custom_layout_tree_vec.rs

src/compute/block.rs

src/compute/flexbox.rs

src/compute/grid/alignment.rs

src/compute/grid/mod.rs

src/compute/grid/types/grid_item.rs

src/compute/mod.rs

src/tree/mod.rs

src/tree/taffy_tree.rs

10 files · +133 −90

diff --git a/examples/custom_layout_tree_owned.rs b/examples/custom_layout_tree_owned.rs
index 59a384a5e..29466091e 100644
--- a/examples/custom_layout_tree_owned.rs
+++ b/examples/custom_layout_tree_owned.rs
@@ -130,8 +130,8 @@ impl PartialLayoutTree for StatelessLayoutTree {
         unsafe { &node_from_id(node_id).style }
     }
 
-    fn get_unrounded_layout_mut(&mut self, node_id: NodeId) -> &mut Layout {
-        unsafe { &mut node_from_id_mut(node_id).unrounded_layout }
+    fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout) {
+        unsafe { node_from_id_mut(node_id).unrounded_layout = *layout };
     }
 
     fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache {
@@ -171,12 +171,16 @@ impl PartialLayoutTree for StatelessLayoutTree {
 }
 
 impl LayoutTree for StatelessLayoutTree {
+    fn get_unrounded_layout(&self, node_id: NodeId) -> &Layout {
+        unsafe { &node_from_id_mut(node_id).unrounded_layout }
+    }
+
     fn get_final_layout(&self, node_id: NodeId) -> &Layout {
         unsafe { &node_from_id(node_id).final_layout }
     }
 
-    fn get_final_layout_mut(&mut self, node_id: NodeId) -> &mut Layout {
-        unsafe { &mut node_from_id_mut(node_id).final_layout }
+    fn set_final_layout(&mut self, node_id: NodeId, layout: &Layout) {
+        unsafe { node_from_id_mut(node_id).final_layout = *layout }
     }
 }
 
diff --git a/examples/custom_layout_tree_vec.rs b/examples/custom_layout_tree_vec.rs
index 67b7ef94d..d089b455a 100644
--- a/examples/custom_layout_tree_vec.rs
+++ b/examples/custom_layout_tree_vec.rs
@@ -140,8 +140,8 @@ impl PartialLayoutTree for Tree {
         &self.node_from_id(node_id).style
     }
 
-    fn get_unrounded_layout_mut(&mut self, node_id: NodeId) -> &mut Layout {
-        &mut self.node_from_id_mut(node_id).unrounded_layout
+    fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout) {
+        self.node_from_id_mut(node_id).unrounded_layout = *layout;
     }
 
     fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache {
@@ -181,12 +181,16 @@ impl PartialLayoutTree for Tree {
 }
 
 impl LayoutTree for Tree {
+    fn get_unrounded_layout(&self, node_id: NodeId) -> &Layout {
+        &self.node_from_id(node_id).unrounded_layout
+    }
+
     fn get_final_layout(&self, node_id: NodeId) -> &Layout {
         &self.node_from_id(node_id).final_layout
     }
 
-    fn get_final_layout_mut(&mut self, node_id: NodeId) -> &mut Layout {
-        &mut self.node_from_id_mut(node_id).final_layout
+    fn set_final_layout(&mut self, node_id: NodeId, layout: &Layout) {
+        self.node_from_id_mut(node_id).final_layout = *layout;
     }
 }
 
diff --git a/src/compute/block.rs b/src/compute/block.rs
index 56e898f13..9544a56c1 100644
--- a/src/compute/block.rs
+++ b/src/compute/block.rs
@@ -213,7 +213,7 @@ fn compute_inner(tree: &mut impl PartialLayoutTree, node_id: NodeId, inputs: Lay
     for order in 0..len {
         let child = tree.get_child_id(node_id, order);
         if tree.get_style(child).display == Display::None {
-            *tree.get_unrounded_layout_mut(child) = Layout::with_order(order as u32);
+            tree.set_unrounded_layout(child, &Layout::with_order(order as u32));
             tree.perform_child_layout(
                 child,
                 Size::NONE,
@@ -428,16 +428,19 @@ fn perform_final_layout_on_in_flow_children(
                 height: if item.overflow.x == Overflow::Scroll { item.scrollbar_width } else { 0.0 },
             };
 
-            *tree.get_unrounded_layout_mut(item.node_id) = Layout {
-                order: item.order,
-                size: item_layout.size,
-                #[cfg(feature = "content_size")]
-                content_size: item_layout.content_size,
-                scrollbar_size,
-                location,
-                padding: item.padding,
-                border: item.border,
-            };
+            tree.set_unrounded_layout(
+                item.node_id,
+                &Layout {
+                    order: item.order,
+                    size: item_layout.size,
+                    #[cfg(feature = "content_size")]
+                    content_size: item_layout.content_size,
+                    scrollbar_size,
+                    location,
+                    padding: item.padding,
+                    border: item.border,
+                },
+            );
 
             #[cfg(feature = "content_size")]
             {
@@ -650,16 +653,19 @@ fn perform_absolute_layout_on_absolute_children(
         };
 
         let location = area_offset + item_offset;
-        *tree.get_unrounded_layout_mut(item.node_id) = Layout {
-            order: item.order,
-            size: final_size,
-            #[cfg(feature = "content_size")]
-            content_size: layout_output.content_size,
-            scrollbar_size,
-            location,
-            padding,
-            border,
-        };
+        tree.set_unrounded_layout(
+            item.node_id,
+            &Layout {
+                order: item.order,
+                size: final_size,
+                #[cfg(feature = "content_size")]
+                content_size: layout_output.content_size,
+                scrollbar_size,
+                location,
+                padding,
+                border,
+            },
+        );
 
         #[cfg(feature = "content_size")]
         {
diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index f2d610749..2e4720956 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -337,7 +337,7 @@ fn compute_preliminary(tree: &mut impl PartialLayoutTree, node: NodeId, inputs:
     for order in 0..len {
         let child = tree.get_child_id(node, order);
         if tree.get_style(child).display == Display::None {
-            *tree.get_unrounded_layout_mut(child) = Layout::with_order(order as u32);
+            tree.set_unrounded_layout(child, &Layout::with_order(order as u32));
             tree.perform_child_layout(
                 child,
                 Size::NONE,
@@ -1767,16 +1767,19 @@ fn calculate_flex_item(
         height: if item.overflow.x == Overflow::Scroll { item.scrollbar_width } else { 0.0 },
     };
 
-    *tree.get_unrounded_layout_mut(item.node) = Layout {
-        order: item.order,
-        size,
-        #[cfg(feature = "content_size")]
-        content_size,
-        scrollbar_size,
-        location,
-        padding: item.padding,
-        border: item.border,
-    };
+    tree.set_unrounded_layout(
+        item.node,
+        &Layout {
+            order: item.order,
+            size,
+            #[cfg(feature = "content_size")]
+            content_size,
+            scrollbar_size,
+            location,
+            padding: item.padding,
+            border: item.border,
+        },
+    );
 
     *total_offset_main += item.offset_main + item.margin.main_axis_sum(direction) + size.main(direction);
 
@@ -2095,16 +2098,19 @@ fn perform_absolute_layout_on_absolute_children(
             width: if overflow.y == Overflow::Scroll { scrollbar_width } else { 0.0 },
             height: if overflow.x == Overflow::Scroll { scrollbar_width } else { 0.0 },
         };
-        *tree.get_unrounded_layout_mut(child) = Layout {
-            order: order as u32,
-            size: final_size,
-            #[cfg(feature = "content_size")]
-            content_size: layout_output.content_size,
-            scrollbar_size,
-            location,
-            padding,
-            border,
-        };
+        tree.set_unrounded_layout(
+            child,
+            &Layout {
+                order: order as u32,
+                size: final_size,
+                #[cfg(feature = "content_size")]
+                content_size: layout_output.content_size,
+                scrollbar_size,
+                location,
+                padding,
+                border,
+            },
+        );
 
         #[cfg(feature = "content_size")]
         {
diff --git a/src/compute/grid/alignment.rs b/src/compute/grid/alignment.rs
index 3b0974a0d..84579182d 100644
--- a/src/compute/grid/alignment.rs
+++ b/src/compute/grid/alignment.rs
@@ -60,7 +60,7 @@ pub(super) fn align_and_position_item(
     grid_area: Rect<f32>,
     container_alignment_styles: InBothAbsAxis<Option<AlignItems>>,
     baseline_shim: f32,
-) -> Size<f32> {
+) -> (Size<f32>, f32, f32) {
     let grid_area_size = Size { width: grid_area.right - grid_area.left, height: grid_area.bottom - grid_area.top };
 
     let style = tree.get_style(node);
@@ -209,16 +209,19 @@ pub(super) fn align_and_position_item(
         height: if overflow.x == Overflow::Scroll { scrollbar_width } else { 0.0 },
     };
 
-    *tree.get_unrounded_layout_mut(node) = Layout {
-        order,
-        location: Point { x, y },
-        size: Size { width, height },
-        #[cfg(feature = "content_size")]
-        content_size: layout_output.content_size,
-        scrollbar_size,
-        padding,
-        border,
-    };
+    tree.set_unrounded_layout(
+        node,
+        &Layout {
+            order,
+            location: Point { x, y },
+            size: Size { width, height },
+            #[cfg(feature = "content_size")]
+            content_size: layout_output.content_size,
+            scrollbar_size,
+            padding,
+            border,
+        },
+    );
 
     #[cfg(feature = "content_size")]
     let contribution =
@@ -226,7 +229,7 @@ pub(super) fn align_and_position_item(
     #[cfg(not(feature = "content_size"))]
     let contribution = Size::ZERO;
 
-    contribution
+    (contribution, y, height)
 }
 
 /// Align and size a grid item along a single axis
diff --git a/src/compute/grid/mod.rs b/src/compute/grid/mod.rs
index 5c73159f6..8d0008e27 100644
--- a/src/compute/grid/mod.rs
+++ b/src/compute/grid/mod.rs
@@ -408,7 +408,7 @@ pub fn compute_grid_layout(tree: &mut impl PartialLayoutTree, node: NodeId, inpu
     let container_alignment_styles = InBothAbsAxis { horizontal: style.justify_items, vertical: style.align_items };
 
     // Position in-flow children (stored in items vector)
-    for (index, item) in items.iter().enumerate() {
+    for (index, item) in items.iter_mut().enumerate() {
         let grid_area = Rect {
             top: rows[item.row_indexes.start as usize + 1].offset,
             bottom: rows[item.row_indexes.end as usize].offset,
@@ -416,7 +416,7 @@ pub fn compute_grid_layout(tree: &mut impl PartialLayoutTree, node: NodeId, inpu
             right: columns[item.column_indexes.end as usize].offset,
         };
         #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
-        let content_size_contribution = align_and_position_item(
+        let (content_size_contribution, y_position, height) = align_and_position_item(
             tree,
             item.node,
             index as u32,
@@ -424,6 +424,9 @@ pub fn compute_grid_layout(tree: &mut impl PartialLayoutTree, node: NodeId, inpu
             container_alignment_styles,
             item.baseline_shim,
         );
+        item.y_position = y_position;
+        item.height = height;
+
         #[cfg(feature = "content_size")]
         {
             item_content_size_contribution = item_content_size_contribution.f32_max(content_size_contribution);
@@ -438,7 +441,7 @@ pub fn compute_grid_layout(tree: &mut impl PartialLayoutTree, node: NodeId, inpu
 
         // Position hidden child
         if child_style.display == Display::None {
-            *tree.get_unrounded_layout_mut(child) = Layout::with_order(order);
+            tree.set_unrounded_layout(child, &Layout::with_order(order));
             tree.perform_child_layout(
                 child,
                 Size::NONE,
@@ -486,7 +489,7 @@ pub fn compute_grid_layout(tree: &mut impl PartialLayoutTree, node: NodeId, inpu
             };
             // TODO: Baseline alignment support for absolutely positioned items (should check if is actuallty specified)
             #[cfg_attr(not(feature = "content_size"), allow(unused_variables))]
-            let content_size_contribution =
+            let (content_size_contribution, _, _) =
                 align_and_position_item(tree, child, order, grid_area, container_alignment_styles, 0.0);
             #[cfg(feature = "content_size")]
             {
@@ -522,8 +525,7 @@ pub fn compute_grid_layout(tree: &mut impl PartialLayoutTree, node: NodeId, inpu
             &first_row_items[0]
         };
 
-        let layout = tree.get_unrounded_layout_mut(item.node);
-        layout.location.y + item.baseline.unwrap_or(layout.size.height)
+        item.y_position + item.baseline.unwrap_or(item.height)
     };
 
     LayoutOutput::from_sizes_and_baselines(
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index 86c4a1284..df6646388 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -77,6 +77,11 @@ pub(in super::super) struct GridItem {
     pub minimum_contribution_cache: Size<Option<f32>>,
     /// Cache for the max-content size
     pub max_content_contribution_cache: Size<Option<f32>>,
+
+    /// Final y position. Used to compute baseline alignment for the container.
+    pub y_position: f32,
+    /// Final height. Used to compute baseline alignment for the container.
+    pub height: f32,
 }
 
 impl GridItem {
@@ -115,6 +120,8 @@ impl GridItem {
             min_content_contribution_cache: Size::NONE,
             max_content_contribution_cache: Size::NONE,
             minimum_contribution_cache: Size::NONE,
+            y_position: 0.0,
+            height: 0.0,
         }
     }
 
diff --git a/src/compute/mod.rs b/src/compute/mod.rs
index 7864f6d9e..267fdf4e0 100644
--- a/src/compute/mod.rs
+++ b/src/compute/mod.rs
@@ -52,17 +52,19 @@ pub fn compute_layout(tree: &mut impl PartialLayoutTree, root: NodeId, available
         height: if style.overflow.x == Overflow::Scroll { style.scrollbar_width } else { 0.0 },
     };
 
-    let layout = Layout {
-        order: 0,
-        location: Point::ZERO,
-        size: output.size,
-        #[cfg(feature = "content_size")]
-        content_size: output.content_size,
-        scrollbar_size,
-        padding,
-        border,
-    };
-    *tree.get_unrounded_layout_mut(root) = layout;
+    tree.set_unrounded_layout(
+        root,
+        &Layout {
+            order: 0,
+            location: Point::ZERO,
+            size: output.size,
+            #[cfg(feature = "content_size")]
+            content_size: output.content_size,
+            scrollbar_size,
+            padding,
+            border,
+        },
+    );
 }
 
 /// Updates the stored layout of the provided `node` and its children
@@ -115,8 +117,8 @@ pub fn round_layout(tree: &mut impl LayoutTree, node_id: NodeId) {
 
     /// Recursive function to apply rounding to all descendents
     fn round_layout_inner(tree: &mut impl LayoutTree, node_id: NodeId, cumulative_x: f32, cumulative_y: f32) {
-        let unrounded_layout = *tree.get_unrounded_layout_mut(node_id);
-        let layout = tree.get_final_layout_mut(node_id);
+        let unrounded_layout = *tree.get_unrounded_layout(node_id);
+        let mut layout = unrounded_layout;
 
         let cumulative_x = cumulative_x + unrounded_layout.location.x;
         let cumulative_y = cumulative_y + unrounded_layout.location.y;
@@ -141,7 +143,9 @@ pub fn round_layout(tree: &mut impl LayoutTree, node_id: NodeId) {
             - round(cumulative_y + unrounded_layout.size.height - unrounded_layout.padding.bottom);
 
         #[cfg(feature = "content_size")]
-        round_content_size(layout, unrounded_layout.content_size, cumulative_x, cumulative_y);
+        round_content_size(&mut layout, unrounded_layout.content_size, cumulative_x, cumulative_y);
+
+        tree.set_final_layout(node_id, &layout);
 
         let child_count = tree.child_count(node_id);
         for index in 0..child_count {
@@ -170,7 +174,7 @@ pub fn round_layout(tree: &mut impl LayoutTree, node_id: NodeId) {
 pub fn compute_hidden_layout(tree: &mut impl PartialLayoutTree, node: NodeId) -> LayoutOutput {
     // Clear cache and set zeroed-out layout for the node
     tree.get_cache_mut(node).clear();
-    *tree.get_unrounded_layout_mut(node) = Layout::with_order(0);
+    tree.set_unrounded_layout(node, &Layout::with_order(0));
 
     // Perform hidden layout on all children
     for index in 0..tree.child_count(node) {
diff --git a/src/tree/mod.rs b/src/tree/mod.rs
index f3de1cc9a..dd2e37613 100644
--- a/src/tree/mod.rs
+++ b/src/tree/mod.rs
@@ -40,8 +40,8 @@ pub trait PartialLayoutTree {
     /// Get a reference to the [`Style`] for this node.
     fn get_style(&self, node_id: NodeId) -> &Style;
 
-    /// Get a mutable reference to the node's unrounded layout
-    fn get_unrounded_layout_mut(&mut self, node_id: NodeId) -> &mut Layout;
+    /// Set the node's unrounded layout
+    fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout);
 
     /// Get a mutable reference to the [`Cache`] for this node.
     fn get_cache_mut(&mut self, node_id: NodeId) -> &mut Cache;
@@ -53,10 +53,12 @@ pub trait PartialLayoutTree {
 /// Extends [`PartialLayoutTree`] with an additional guarantee: that the child/children methods can be used to recurse
 /// infinitely down the tree. Enables Taffy's rounding and debug printing methods to be used.
 pub trait LayoutTree: PartialLayoutTree {
+    /// Get the node's unrounded layout
+    fn get_unrounded_layout(&self, node_id: NodeId) -> &Layout;
     /// Get a reference to the node's final layout
     fn get_final_layout(&self, node_id: NodeId) -> &Layout;
     /// Get a mutable reference to the node's final layout
-    fn get_final_layout_mut(&mut self, node_id: NodeId) -> &mut Layout;
+    fn set_final_layout(&mut self, node_id: NodeId, layout: &Layout);
 }
 
 /// A private trait which allows us to add extra convenience methods to types which implement
diff --git a/src/tree/taffy_tree.rs b/src/tree/taffy_tree.rs
index 4692944ff..2764cd9ac 100644
--- a/src/tree/taffy_tree.rs
+++ b/src/tree/taffy_tree.rs
@@ -153,8 +153,8 @@ where
     }
 
     #[inline(always)]
-    fn get_unrounded_layout_mut(&mut self, node: NodeId) -> &mut Layout {
-        &mut self.taffy.nodes[node.into()].unrounded_layout
+    fn set_unrounded_layout(&mut self, node_id: NodeId, layout: &Layout) {
+        self.taffy.nodes[node_id.into()].unrounded_layout = *layout;
     }
 
     #[inline(always)]
@@ -212,14 +212,19 @@ impl<'t, NodeContext, MeasureFunction> LayoutTree for TaffyView<'t, NodeContext,
 where
     MeasureFunction: FnMut(Size<Option<f32>>, Size<AvailableSpace>, NodeId, Option<&mut NodeContext>) -> Size<f32>,
 {
+    #[inline(always)]
+    fn get_unrounded_layout(&self, node: NodeId) -> &Layout {
+        &self.taffy.nodes[node.into()].unrounded_layout
+    }
+
     #[inline(always)]
     fn get_final_layout(&self, node: NodeId) -> &Layout {
         &self.taffy.nodes[node.into()].final_layout
     }
 
     #[inline(always)]
-    fn get_final_layout_mut(&mut self, node: NodeId) -> &mut Layout {
-        &mut self.taffy.nodes[node.into()].final_layout
+    fn set_final_layout(&mut self, node_id: NodeId, layout: &Layout) {
+        self.taffy.nodes[node_id.into()].final_layout = *layout;
     }
 }