tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 499HTML 245JavaScript 8Markdown 71218 Definiciones

Remove `cache_mut`, `needs_measure` and `measure_node` methods from `LayoutTree` trait (#431)

* Remove the measure_node and needs_measure methods from the LayoutTree trait

* Remove cache_mut method from the LayoutTree trait

* Update release notes

384b60bdadb6ac33f2117cc571e519d738885587 · por Nico Burns · (hace 3 años) · padre 77a309162 · ver el árbol en este commit

Delta semántico · 22

src/compute/leaf.rs

src/compute/mod.rs

src/node.rs

src/tree.rs

5 archivos · +87 −137

diff --git a/RELEASES.md b/RELEASES.md
index e826e4359..f163070fb 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -5,7 +5,7 @@
 ### Removed
 
 - `layout_flexbox()` has been removed from the prelude. Use `FlexboxAlgorithm::perform_layout()` instead.
-- The following methods have been removed from the `LayoutTree` trait: `parent`, `is_childless`, `layout`, and `mark_dirty`. These no longer need to be implemented in custom implementation of `LayoutTree`.
+- The following methods have been removed from the `LayoutTree` trait: `parent`, `is_childless`, `layout`, `measure_node`, `needs_measure`, `cache_mut` and `mark_dirty`. These no longer need to be implemented in custom implementation of `LayoutTree`.
 
 ### Changes
 
diff --git a/src/compute/leaf.rs b/src/compute/leaf.rs
index 4ee8373a2..cf92d5701 100644
--- a/src/compute/leaf.rs
+++ b/src/compute/leaf.rs
@@ -1,55 +1,52 @@
 //! Computes size using styles and measure functions
 
-use crate::compute::LayoutAlgorithm;
 use crate::geometry::{Point, Size};
 use crate::layout::{SizeAndBaselines, SizingMode};
 use crate::math::MaybeMath;
+use crate::node::Taffy;
 use crate::resolve::{MaybeResolve, ResolveOrZero};
 use crate::style::AvailableSpace;
 use crate::sys::f32_max;
-use crate::tree::{LayoutTree, NodeId};
+use crate::tree::NodeId;
 
 #[cfg(feature = "debug")]
 use crate::debug::NODE_LOGGER;
 
-/// The public interface to Taffy's leaf node algorithm implementation
-pub(crate) struct LeafAlgorithm;
-impl LayoutAlgorithm for LeafAlgorithm {
-    const NAME: &'static str = "LEAF";
-
-    fn perform_layout(
-        tree: &mut impl LayoutTree,
-        node: NodeId,
-        known_dimensions: Size<Option<f32>>,
-        parent_size: Size<Option<f32>>,
-        available_space: Size<AvailableSpace>,
-        sizing_mode: SizingMode,
-    ) -> SizeAndBaselines {
-        compute(tree, node, known_dimensions, parent_size, available_space, sizing_mode)
-    }
+/// Perform full layout on a leaf node
+pub(crate) fn perform_layout(
+    tree: &mut Taffy,
+    node: NodeId,
+    known_dimensions: Size<Option<f32>>,
+    parent_size: Size<Option<f32>>,
+    available_space: Size<AvailableSpace>,
+    sizing_mode: SizingMode,
+) -> SizeAndBaselines {
+    compute(tree, node, known_dimensions, parent_size, available_space, sizing_mode)
+}
 
-    fn measure_size(
-        tree: &mut impl LayoutTree,
-        node: NodeId,
-        known_dimensions: Size<Option<f32>>,
-        parent_size: Size<Option<f32>>,
-        available_space: Size<AvailableSpace>,
-        sizing_mode: SizingMode,
-    ) -> Size<f32> {
-        compute(tree, node, known_dimensions, parent_size, available_space, sizing_mode).size
-    }
+/// Measure a leaf node's size
+pub(crate) fn measure_size(
+    tree: &mut Taffy,
+    node: NodeId,
+    known_dimensions: Size<Option<f32>>,
+    parent_size: Size<Option<f32>>,
+    available_space: Size<AvailableSpace>,
+    sizing_mode: SizingMode,
+) -> Size<f32> {
+    compute(tree, node, known_dimensions, parent_size, available_space, sizing_mode).size
 }
 
 /// Compute the size of a leaf node (node with no children)
 pub(crate) fn compute(
-    tree: &mut impl LayoutTree,
+    tree: &mut Taffy,
     node: NodeId,
     known_dimensions: Size<Option<f32>>,
     parent_size: Size<Option<f32>>,
     available_space: Size<AvailableSpace>,
     sizing_mode: SizingMode,
 ) -> SizeAndBaselines {
-    let style = tree.style(node);
+    let key = node.into();
+    let style = tree.style(node).unwrap();
 
     // Resolve node's preferred/min/max sizes (width/heights) against the available space (percentages resolve to pixel values)
     // For ContentSize mode, we pretend that the node has no size styles as these should be ignored.
@@ -94,7 +91,7 @@ pub(crate) fn compute(
         return SizeAndBaselines { size, first_baselines: Point::NONE };
     };
 
-    if tree.needs_measure(node) {
+    if tree.nodes[key].needs_measure {
         // Compute available space
         let available_space = Size {
             width: available_space
@@ -110,7 +107,7 @@ pub(crate) fn compute(
         };
 
         // Measure node
-        let measured_size = tree.measure_node(node, known_dimensions, available_space);
+        let measured_size = tree.measure_funcs[key].measure(known_dimensions, available_space);
 
         let measured_size = Size {
             width: measured_size.width,
diff --git a/src/compute/mod.rs b/src/compute/mod.rs
index b37c0e73d..bb8fd5e3b 100644
--- a/src/compute/mod.rs
+++ b/src/compute/mod.rs
@@ -23,7 +23,6 @@ use self::flexbox::FlexboxAlgorithm;
 
 #[cfg(feature = "grid")]
 use self::grid::CssGridAlgorithm;
-use self::leaf::LeafAlgorithm;
 
 #[cfg(any(feature = "debug", feature = "profile"))]
 use crate::debug::NODE_LOGGER;
@@ -35,7 +34,7 @@ pub fn compute_layout(
     available_space: Size<AvailableSpace>,
 ) -> Result<(), TaffyError> {
     // Recursively compute node layout
-    let size_and_baselines = GenericAlgorithm::perform_layout(
+    let size_and_baselines = perform_node_layout(
         taffy,
         root,
         Size::NONE,
@@ -81,55 +80,34 @@ pub(crate) trait LayoutAlgorithm {
     ) -> SizeAndBaselines;
 }
 
-/// The public interface to a generic algorithm that abstracts over all of Taffy's algorithms
-/// and applies the correct one based on the `Display` style
-pub struct GenericAlgorithm;
-impl LayoutAlgorithm for GenericAlgorithm {
-    const NAME: &'static str = "GENERIC";
-
-    fn perform_layout(
-        tree: &mut impl LayoutTree,
-        node: NodeId,
-        known_dimensions: Size<Option<f32>>,
-        parent_size: Size<Option<f32>>,
-        available_space: Size<AvailableSpace>,
-        sizing_mode: SizingMode,
-    ) -> SizeAndBaselines {
-        compute_node_layout(
-            tree,
-            node,
-            known_dimensions,
-            parent_size,
-            available_space,
-            RunMode::PeformLayout,
-            sizing_mode,
-        )
-    }
+/// Perform full layout on a node. Chooses which algorithm to use based on the `display` property.
+pub(crate) fn perform_node_layout(
+    tree: &mut Taffy,
+    node: NodeId,
+    known_dimensions: Size<Option<f32>>,
+    parent_size: Size<Option<f32>>,
+    available_space: Size<AvailableSpace>,
+    sizing_mode: SizingMode,
+) -> SizeAndBaselines {
+    compute_node_layout(tree, node, known_dimensions, parent_size, available_space, RunMode::PeformLayout, sizing_mode)
+}
 
-    fn measure_size(
-        tree: &mut impl LayoutTree,
-        node: NodeId,
-        known_dimensions: Size<Option<f32>>,
-        parent_size: Size<Option<f32>>,
-        available_space: Size<AvailableSpace>,
-        sizing_mode: SizingMode,
-    ) -> Size<f32> {
-        compute_node_layout(
-            tree,
-            node,
-            known_dimensions,
-            parent_size,
-            available_space,
-            RunMode::ComputeSize,
-            sizing_mode,
-        )
+/// Measure a node's size. Chooses which algorithm to use based on the `display` property.
+pub(crate) fn measure_node_size(
+    tree: &mut Taffy,
+    node: NodeId,
+    known_dimensions: Size<Option<f32>>,
+    parent_size: Size<Option<f32>>,
+    available_space: Size<AvailableSpace>,
+    sizing_mode: SizingMode,
+) -> Size<f32> {
+    compute_node_layout(tree, node, known_dimensions, parent_size, available_space, RunMode::ComputeSize, sizing_mode)
         .size
-    }
 }
 
 /// Updates the stored layout of the provided `node` and its children
 fn compute_node_layout(
-    tree: &mut impl LayoutTree,
+    tree: &mut Taffy,
     node: NodeId,
     known_dimensions: Size<Option<f32>>,
     parent_size: Size<Option<f32>>,
@@ -142,8 +120,11 @@ fn compute_node_layout(
     #[cfg(feature = "debug")]
     println!();
 
+    let node_key = node.into();
+    let has_children = !tree.children[node_key].is_empty();
+
     // First we check if we have a cached result for the given input
-    let cache_run_mode = if tree.child_count(node) == 0 { RunMode::PeformLayout } else { run_mode };
+    let cache_run_mode = if !has_children { RunMode::PeformLayout } else { run_mode };
     if let Some(cached_size_and_baselines) =
         compute_from_cache(tree, node, known_dimensions, available_space, cache_run_mode)
     {
@@ -178,15 +159,12 @@ fn compute_node_layout(
                 Algorithm::perform_layout(tree, node, known_dimensions, parent_size, available_space, sizing_mode)
             }
             RunMode::ComputeSize => {
-                let size =
-                    Algorithm::measure_size(tree, node, known_dimensions, parent_size, available_space, sizing_mode);
-                SizeAndBaselines { size, first_baselines: Point::NONE }
+                Algorithm::measure_size(tree, node, known_dimensions, parent_size, available_space, sizing_mode).into()
             }
         }
     }
 
-    let display_mode = tree.style(node).display;
-    let has_children = tree.child_count(node) != 0;
+    let display_mode = tree.nodes[node_key].style.display;
     let computed_size_and_baselines = match (display_mode, has_children) {
         (Display::None, _) => perform_computations::<HiddenAlgorithm>(
             tree,
@@ -217,20 +195,19 @@ fn compute_node_layout(
             run_mode,
             sizing_mode,
         ),
-        (_, false) => perform_computations::<LeafAlgorithm>(
-            tree,
-            node,
-            known_dimensions,
-            parent_size,
-            available_space,
-            run_mode,
-            sizing_mode,
-        ),
+        (_, false) => match run_mode {
+            RunMode::PeformLayout => {
+                leaf::perform_layout(tree, node, known_dimensions, parent_size, available_space, sizing_mode)
+            }
+            RunMode::ComputeSize => {
+                leaf::measure_size(tree, node, known_dimensions, parent_size, available_space, sizing_mode).into()
+            }
+        },
     };
 
     // Cache result
     let cache_slot = compute_cache_slot(known_dimensions, available_space);
-    *tree.cache_mut(node, cache_slot) = Some(Cache {
+    tree.nodes[node_key].size_cache[cache_slot] = Some(Cache {
         known_dimensions,
         available_space,
         run_mode: cache_run_mode,
@@ -312,14 +289,15 @@ fn compute_cache_slot(known_dimensions: Size<Option<f32>>, available_space: Size
 /// Try to get the computation result from the cache.
 #[inline]
 fn compute_from_cache(
-    tree: &mut impl LayoutTree,
+    tree: &mut Taffy,
     node: NodeId,
     known_dimensions: Size<Option<f32>>,
     available_space: Size<AvailableSpace>,
     run_mode: RunMode,
 ) -> Option<SizeAndBaselines> {
+    let node_key = node.into();
     for idx in 0..CACHE_SIZE {
-        let entry = tree.cache_mut(node, idx);
+        let entry = tree.nodes[node_key].size_cache[idx];
         if let Some(entry) = entry {
             // Cached ComputeSize results are not valid if we are running in PerformLayout mode
             if entry.run_mode == RunMode::ComputeSize && run_mode == RunMode::PeformLayout {
diff --git a/src/node.rs b/src/node.rs
index 8d1da7248..1e68c1094 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -3,11 +3,11 @@
 //! Layouts are composed of multiple nodes, which live in a tree-like data structure.
 use slotmap::{DefaultKey, SlotMap, SparseSecondaryMap};
 
-use crate::compute::{GenericAlgorithm, LayoutAlgorithm};
+use crate::compute::{measure_node_size, perform_node_layout};
 use crate::data::NodeData;
 use crate::error::{TaffyError, TaffyResult};
 use crate::geometry::Size;
-use crate::layout::{Cache, Layout, SizeAndBaselines, SizingMode};
+use crate::layout::{Layout, SizeAndBaselines, SizingMode};
 use crate::prelude::LayoutTree;
 use crate::style::{AvailableSpace, Style};
 #[cfg(any(feature = "std", feature = "alloc"))]
@@ -31,6 +31,18 @@ pub enum MeasureFunc {
     Boxed(Box<dyn Measurable>),
 }
 
+impl MeasureFunc {
+    /// Call the measure function to measure to the node
+    #[inline(always)]
+    pub fn measure(&self, known_dimensions: Size<Option<f32>>, available_space: Size<AvailableSpace>) -> Size<f32> {
+        match self {
+            MeasureFunc::Raw(measure) => measure(known_dimensions, available_space),
+            #[cfg(any(feature = "std", feature = "alloc"))]
+            MeasureFunc::Boxed(measure) => (measure as &dyn Fn(_, _) -> _)(known_dimensions, available_space),
+        }
+    }
+}
+
 /// Global configuration values for a Taffy instance
 pub(crate) struct TaffyConfig {
     /// Whether to round layout values
@@ -104,29 +116,6 @@ impl LayoutTree for Taffy {
         &mut self.nodes[node.into()].layout
     }
 
-    fn measure_node(
-        &self,
-        node: NodeId,
-        known_dimensions: Size<Option<f32>>,
-        available_space: Size<AvailableSpace>,
-    ) -> Size<f32> {
-        match &self.measure_funcs[node.into()] {
-            MeasureFunc::Raw(measure) => measure(known_dimensions, available_space),
-
-            #[cfg(any(feature = "std", feature = "alloc"))]
-            MeasureFunc::Boxed(measure) => (measure as &dyn Fn(_, _) -> _)(known_dimensions, available_space),
-        }
-    }
-
-    fn needs_measure(&self, node: NodeId) -> bool {
-        let node = node.into();
-        self.nodes[node].needs_measure && self.measure_funcs.get(node).is_some()
-    }
-
-    fn cache_mut(&mut self, node: NodeId, index: usize) -> &mut Option<Cache> {
-        &mut self.nodes[node.into()].size_cache[index]
-    }
-
     #[inline(always)]
     fn child(&self, node: NodeId, id: usize) -> NodeId {
         self.children[node.into()][id]
@@ -141,7 +130,7 @@ impl LayoutTree for Taffy {
         available_space: Size<AvailableSpace>,
         sizing_mode: SizingMode,
     ) -> Size<f32> {
-        GenericAlgorithm::measure_size(self, node, known_dimensions, parent_size, available_space, sizing_mode)
+        measure_node_size(self, node, known_dimensions, parent_size, available_space, sizing_mode)
     }
 
     #[inline(always)]
@@ -153,7 +142,7 @@ impl LayoutTree for Taffy {
         available_space: Size<AvailableSpace>,
         sizing_mode: SizingMode,
     ) -> SizeAndBaselines {
-        GenericAlgorithm::perform_layout(self, node, known_dimensions, parent_size, available_space, sizing_mode)
+        perform_node_layout(self, node, known_dimensions, parent_size, available_space, sizing_mode)
     }
 }
 
diff --git a/src/tree.rs b/src/tree.rs
index 1b49e7244..fa7b8f182 100644
--- a/src/tree.rs
+++ b/src/tree.rs
@@ -1,6 +1,6 @@
 //! The baseline requirements of any UI Tree so Taffy can efficiently calculate the layout
 use crate::{
-    layout::{Cache, Layout, SizeAndBaselines, SizingMode},
+    layout::{Layout, SizeAndBaselines, SizingMode},
     prelude::*,
 };
 use slotmap::{DefaultKey, Key, KeyData};
@@ -77,20 +77,6 @@ pub trait LayoutTree {
     /// Modify the node's output layout
     fn layout_mut(&mut self, node: NodeId) -> &mut Layout;
 
-    /// Measure a node. Taffy uses this to force reflows of things like text and overflowing content.
-    fn measure_node(
-        &self,
-        node: NodeId,
-        known_dimensions: Size<Option<f32>>,
-        available_space: Size<AvailableSpace>,
-    ) -> Size<f32>;
-
-    /// Node needs to be measured
-    fn needs_measure(&self, node: NodeId) -> bool;
-
-    /// Get a cache entry for this Node by index
-    fn cache_mut(&mut self, node: NodeId, index: usize) -> &mut Option<Cache>;
-
     /// Compute the size of the node given the specified constraints
     fn measure_child_size(
         &mut self,