gioser

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 1112HTML 1039Markdown 12TOML 94628 Definiciones

Trampoline child measurement/layout through the `LayoutTree` trait (#427)

* Add measure_child_size and perform_child_layout methods to LayoutTree trait

* Force inlining of methods on internal implementation of LayoutTree

* Use import instead of fully qualified path

325413cd16d8e81598b36d2129c717d4c53baaa9 · por Nico Burns · (hace 3 años) · padre 2ef49c4ae · ver el árbol en este commit

Delta semántico · 15

src/compute/flexbox.rs

src/compute/grid/alignment.rs

src/compute/grid/mod.rs

  • cambió por dentro fn compute pub

src/compute/grid/track_sizing.rs

src/compute/grid/types/grid_item.rs

src/node.rs

src/tree.rs

7 archivos · +83 −59

diff --git a/src/compute/flexbox.rs b/src/compute/flexbox.rs
index c72416232..eef31a4ba 100644
--- a/src/compute/flexbox.rs
+++ b/src/compute/flexbox.rs
@@ -2,7 +2,7 @@
 use core::f32;
 
 use crate::compute::common::alignment::compute_alignment_offset;
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
+use crate::compute::LayoutAlgorithm;
 use crate::geometry::{Point, Rect, Size};
 use crate::layout::{Layout, RunMode, SizeAndBaselines, SizingMode};
 use crate::math::MaybeMath;
@@ -382,14 +382,7 @@ fn compute_preliminary(
         let child = tree.child(node, order);
         if tree.style(child).display == Display::None {
             *tree.layout_mut(child) = Layout::with_order(order as u32);
-            GenericAlgorithm::perform_layout(
-                tree,
-                child,
-                Size::NONE,
-                Size::NONE,
-                Size::MAX_CONTENT,
-                SizingMode::InherentSize,
-            );
+            tree.perform_child_layout(child, Size::NONE, Size::NONE, Size::MAX_CONTENT, SizingMode::InherentSize);
         }
     }
 
@@ -661,15 +654,15 @@ fn determine_flex_base_size(
                 ckd
             };
 
-            break 'flex_basis GenericAlgorithm::measure_size(
-                tree,
-                child.node,
-                child_known_dimensions,
-                child_parent_size,
-                child_available_space,
-                SizingMode::ContentSize,
-            )
-            .main(dir);
+            break 'flex_basis tree
+                .measure_child_size(
+                    child.node,
+                    child_known_dimensions,
+                    child_parent_size,
+                    child_available_space,
+                    SizingMode::ContentSize,
+                )
+                .main(dir);
         };
 
         // Floor flex-basis by the padding_border_sum (floors inner_flex_basis at zero)
@@ -708,8 +701,7 @@ fn determine_flex_base_size(
             let child_parent_size = Size::NONE.with_cross(dir, cross_axis_parent_size);
             let child_available_space = Size::MIN_CONTENT.with_cross(dir, cross_axis_available_space);
 
-            GenericAlgorithm::measure_size(
-                tree,
+            tree.measure_child_size(
                 child.node,
                 Size::NONE,
                 child_parent_size,
@@ -904,15 +896,15 @@ fn determine_container_main_size(
                             _ => {
                                 // Either the min- or max- content size depending on which constraint we are sizing under.
                                 // TODO: Optimise by using already computed values where available
-                                let content_main_size = GenericAlgorithm::measure_size(
-                                    tree,
-                                    item.node,
-                                    Size::NONE,
-                                    constants.node_inner_size,
-                                    Size { width: main_axis_available_space, height: main_axis_available_space },
-                                    SizingMode::InherentSize,
-                                )
-                                .main(constants.dir)
+                                let content_main_size = tree
+                                    .measure_child_size(
+                                        item.node,
+                                        Size::NONE,
+                                        constants.node_inner_size,
+                                        Size { width: main_axis_available_space, height: main_axis_available_space },
+                                        SizingMode::InherentSize,
+                                    )
+                                    .main(constants.dir)
                                     + item.margin.main_axis_sum(constants.dir);
 
                                 // This is somewhat bizarre in that it's asymetrical depending whether the flex container is a column or a row.
@@ -1223,8 +1215,7 @@ fn determine_hypothetical_cross_size(
             .maybe_max(padding_border_sum);
 
         let child_inner_cross = child_cross.unwrap_or_else(|| {
-            GenericAlgorithm::measure_size(
-                tree,
+            tree.measure_child_size(
                 child.node,
                 Size {
                     width: if constants.is_row { child.target_size.width.into() } else { child_cross },
@@ -1278,8 +1269,7 @@ fn calculate_children_base_lines(
                 continue;
             }
 
-            let measured_size_and_baselines = GenericAlgorithm::perform_layout(
-                tree,
+            let measured_size_and_baselines = tree.perform_child_layout(
                 child.node,
                 Size {
                     width: if constants.is_row {
@@ -1714,8 +1704,7 @@ fn calculate_flex_item(
     node_inner_size: Size<Option<f32>>,
     direction: FlexDirection,
 ) {
-    let preliminary_size_and_baselines = GenericAlgorithm::perform_layout(
-        tree,
+    let preliminary_size_and_baselines = tree.perform_child_layout(
         item.node,
         item.target_size.map(|s| s.into()),
         node_inner_size,
@@ -1900,8 +1889,7 @@ fn perform_absolute_layout_on_absolute_children(tree: &mut impl LayoutTree, node
             known_dimensions = known_dimensions.maybe_apply_aspect_ratio(aspect_ratio).maybe_clamp(min_size, max_size);
         }
 
-        let measured_size_and_baselines = GenericAlgorithm::perform_layout(
-            tree,
+        let measured_size_and_baselines = tree.perform_child_layout(
             child,
             known_dimensions,
             constants.node_inner_size,
diff --git a/src/compute/grid/alignment.rs b/src/compute/grid/alignment.rs
index 0b85fb792..14a60bafe 100644
--- a/src/compute/grid/alignment.rs
+++ b/src/compute/grid/alignment.rs
@@ -2,7 +2,6 @@
 use super::types::GridTrack;
 use crate::axis::InBothAbsAxis;
 use crate::compute::common::alignment::compute_alignment_offset;
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
 use crate::geometry::{Line, Point, Rect, Size};
 use crate::layout::{Layout, SizingMode};
 use crate::math::MaybeMath;
@@ -189,8 +188,7 @@ pub(super) fn align_and_position_item(
     let Size { width, height } = Size { width, height }.maybe_clamp(min_size, max_size);
 
     // Layout node
-    let measured_size_and_baselines = GenericAlgorithm::perform_layout(
-        tree,
+    let measured_size_and_baselines = tree.perform_child_layout(
         node,
         Size { width, height },
         grid_area_size.map(Option::Some),
diff --git a/src/compute/grid/mod.rs b/src/compute/grid/mod.rs
index 09a91eb09..490a96310 100644
--- a/src/compute/grid/mod.rs
+++ b/src/compute/grid/mod.rs
@@ -24,7 +24,7 @@ pub(crate) use types::{GridCoordinate, GridLine, OriginZeroLine};
 #[cfg(feature = "debug")]
 use crate::debug::NODE_LOGGER;
 
-use super::{GenericAlgorithm, LayoutAlgorithm};
+use super::LayoutAlgorithm;
 
 mod alignment;
 mod explicit_grid;
@@ -453,14 +453,7 @@ pub fn compute(
         // Position hidden child
         if child_style.display == Display::None {
             *tree.layout_mut(child) = Layout::with_order(order);
-            GenericAlgorithm::perform_layout(
-                tree,
-                child,
-                Size::NONE,
-                Size::NONE,
-                Size::MAX_CONTENT,
-                SizingMode::InherentSize,
-            );
+            tree.perform_child_layout(child, Size::NONE, Size::NONE, Size::MAX_CONTENT, SizingMode::InherentSize);
             order += 1;
             return;
         }
diff --git a/src/compute/grid/track_sizing.rs b/src/compute/grid/track_sizing.rs
index a1fa6db78..cfd415487 100644
--- a/src/compute/grid/track_sizing.rs
+++ b/src/compute/grid/track_sizing.rs
@@ -2,7 +2,6 @@
 //! <https://www.w3.org/TR/css-grid-1/#layout-algorithm>
 use super::types::{GridItem, GridTrack, TrackCounts};
 use crate::axis::AbstractAxis;
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
 use crate::geometry::Size;
 use crate::layout::SizingMode;
 use crate::math::MaybeMath;
@@ -470,8 +469,7 @@ fn resolve_item_baselines(
 
         // Compute the baselines of all items in the row
         for item in row_items.iter_mut() {
-            let measured_size_and_baselines = GenericAlgorithm::perform_layout(
-                tree,
+            let measured_size_and_baselines = tree.perform_child_layout(
                 item.node,
                 Size::NONE,
                 inner_node_size,
diff --git a/src/compute/grid/types/grid_item.rs b/src/compute/grid/types/grid_item.rs
index 513038d2f..cd9fb8234 100644
--- a/src/compute/grid/types/grid_item.rs
+++ b/src/compute/grid/types/grid_item.rs
@@ -2,7 +2,6 @@
 use super::GridTrack;
 use crate::axis::AbstractAxis;
 use crate::compute::grid::OriginZeroLine;
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
 use crate::geometry::{Line, Rect, Size};
 use crate::layout::SizingMode;
 use crate::math::MaybeMath;
@@ -328,8 +327,7 @@ impl GridItem {
         inner_node_size: Size<Option<f32>>,
     ) -> f32 {
         let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
-        GenericAlgorithm::measure_size(
-            tree,
+        tree.measure_child_size(
             self.node,
             known_dimensions,
             available_space,
@@ -367,8 +365,7 @@ impl GridItem {
         inner_node_size: Size<Option<f32>>,
     ) -> f32 {
         let known_dimensions = self.known_dimensions(tree, inner_node_size, available_space);
-        GenericAlgorithm::measure_size(
-            tree,
+        tree.measure_child_size(
             self.node,
             known_dimensions,
             available_space,
diff --git a/src/node.rs b/src/node.rs
index 854c76e41..430aa7153 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -6,9 +6,10 @@ use slotmap::{DefaultKey, SlotMap, SparseSecondaryMap};
 /// A node in a layout.
 pub type Node = slotmap::DefaultKey;
 
+use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
 use crate::error::{TaffyError, TaffyResult};
 use crate::geometry::Size;
-use crate::layout::{Cache, Layout};
+use crate::layout::{Cache, Layout, SizeAndBaselines, SizingMode};
 use crate::prelude::LayoutTree;
 use crate::style::{AvailableSpace, Style};
 #[cfg(any(feature = "std", feature = "alloc"))]
@@ -75,18 +76,22 @@ impl Default for Taffy {
 impl LayoutTree for Taffy {
     type ChildIter<'a> = core::slice::Iter<'a, DefaultKey>;
 
+    #[inline(always)]
     fn children(&self, node: Node) -> Self::ChildIter<'_> {
         self.children[node].iter()
     }
 
+    #[inline(always)]
     fn child_count(&self, node: Node) -> usize {
         self.children[node].len()
     }
 
+    #[inline(always)]
     fn style(&self, node: Node) -> &Style {
         &self.nodes[node].style
     }
 
+    #[inline(always)]
     fn layout_mut(&mut self, node: Node) -> &mut Layout {
         &mut self.nodes[node].layout
     }
@@ -113,9 +118,34 @@ impl LayoutTree for Taffy {
         &mut self.nodes[node].size_cache[index]
     }
 
+    #[inline(always)]
     fn child(&self, node: Node, id: usize) -> Node {
         self.children[node][id]
     }
+
+    #[inline(always)]
+    fn measure_child_size(
+        &mut self,
+        node: Node,
+        known_dimensions: Size<Option<f32>>,
+        parent_size: Size<Option<f32>>,
+        available_space: Size<AvailableSpace>,
+        sizing_mode: SizingMode,
+    ) -> Size<f32> {
+        GenericAlgorithm::measure_size(self, node, known_dimensions, parent_size, available_space, sizing_mode)
+    }
+
+    #[inline(always)]
+    fn perform_child_layout(
+        &mut self,
+        node: Node,
+        known_dimensions: Size<Option<f32>>,
+        parent_size: Size<Option<f32>>,
+        available_space: Size<AvailableSpace>,
+        sizing_mode: SizingMode,
+    ) -> SizeAndBaselines {
+        GenericAlgorithm::perform_layout(self, node, known_dimensions, parent_size, available_space, sizing_mode)
+    }
 }
 
 #[allow(clippy::iter_cloned_collect)] // due to no-std support, we need to use `iter_cloned` instead of `collect`
diff --git a/src/tree.rs b/src/tree.rs
index 47bb7fbd5..0b015045c 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -3,7 +3,7 @@
 use slotmap::DefaultKey;
 
 use crate::{
-    layout::{Cache, Layout},
+    layout::{Cache, Layout, SizeAndBaselines, SizingMode},
     prelude::*,
 };
 
@@ -48,4 +48,24 @@ pub trait LayoutTree {
 
     /// Get a cache entry for this Node by index
     fn cache_mut(&mut self, node: Node, index: usize) -> &mut Option<Cache>;
+
+    /// Compute the size of the node given the specified constraints
+    fn measure_child_size(
+        &mut self,
+        node: Node,
+        known_dimensions: Size<Option<f32>>,
+        parent_size: Size<Option<f32>>,
+        available_space: Size<AvailableSpace>,
+        sizing_mode: SizingMode,
+    ) -> Size<f32>;
+
+    /// Perform a full layout on the node given the specified constraints
+    fn perform_child_layout(
+        &mut self,
+        node: Node,
+        known_dimensions: Size<Option<f32>>,
+        parent_size: Size<Option<f32>>,
+        available_space: Size<AvailableSpace>,
+        sizing_mode: SizingMode,
+    ) -> SizeAndBaselines;
 }