tawasuyu

tawasuyu/taffy

A high performance rust-powered UI layout library

Rust 788HTML 740Markdown 12TOML 62536 Definiciones

Better short circuit leaf nodes

17315d147a4cb1a72b50638e78de9bac5068fdee · por Emil Sjölander · (hace 7 años) · padre 8acbcdb83 · ver el árbol en este commit

Delta semántico · 8

src/algo.rs

src/node.rs

tests/node.rs

3 archivos · +39 −29

diff --git a/src/algo.rs b/src/algo.rs
index 9790897ff..acd9b0e17 100644
--- a/src/algo.rs
+++ b/src/algo.rs
@@ -137,6 +137,8 @@ fn compute_internal(
     parent_size: Size<Number>,
     perform_layout: bool,
 ) -> Result<ComputeResult> {
+    node.is_dirty = false;
+
     // First we check if we have a result for the given input
     {
         if let Some(cache) = &node.layout_cache {
@@ -164,19 +166,6 @@ fn compute_internal(
         }
     }
 
-    // If this is a leaf node we can skip a lot of this function in some cases
-    if node.children.is_empty() {
-        if node_size.width.is_defined() && node_size.height.is_defined() {
-            return Ok(ComputeResult { size: node_size.map(|s| s.or_else(0.0)), children: vec![] });
-        }
-
-        if let Some(ref measure) = node.measure {
-            let result = ComputeResult { size: measure(node_size)?, children: vec![] };
-            node.layout_cache = Some(result::Cache { node_size, parent_size, perform_layout, result: result.clone() });
-            return Ok(result);
-        }
-    }
-
     // Define some general constants we will need for the remainder
     // of the algorithm.
 
@@ -204,6 +193,27 @@ fn compute_internal(
     let mut container_size = Size { width: 0.0, height: 0.0 };
     let mut inner_container_size = Size { width: 0.0, height: 0.0 };
 
+    // If this is a leaf node we can skip a lot of this function in some cases
+    if node.children.is_empty() {
+        if node_size.width.is_defined() && node_size.height.is_defined() {
+            return Ok(ComputeResult { size: node_size.map(|s| s.or_else(0.0)), children: vec![] });
+        }
+
+        if let Some(ref measure) = node.measure {
+            let result = ComputeResult { size: measure(node_size)?, children: vec![] };
+            node.layout_cache = Some(result::Cache { node_size, parent_size, perform_layout, result: result.clone() });
+            return Ok(result);
+        }
+
+        return Ok(ComputeResult {
+            size: Size {
+                width: node_size.width.or_else(0.0) + padding_border.horizontal(),
+                height: node_size.height.or_else(0.0) + padding_border.vertical(),
+            },
+            children: vec![],
+        });
+    }
+
     // 9.2. Line Length Determination
 
     // 1. Generate anonymous flex items as described in §4 Flex Items.
diff --git a/src/node.rs b/src/node.rs
index 0ca027b07..e9369b1a7 100644
--- a/src/node.rs
+++ b/src/node.rs
@@ -20,6 +20,7 @@ pub(crate) struct InternalNode {
     pub(crate) children: Vec<Rc<RefCell<InternalNode>>>,
     pub(crate) measure: Option<MeasureFunc>,
     pub(crate) layout_cache: Option<Cache>,
+    pub(crate) is_dirty: bool,
 }
 
 pub struct Node(Rc<RefCell<InternalNode>>);
@@ -32,6 +33,7 @@ impl Node {
             children: Vec::with_capacity(0),
             measure,
             layout_cache: None,
+            is_dirty: true,
         })))
     }
 
@@ -42,6 +44,7 @@ impl Node {
             children: Vec::with_capacity(children.len()),
             measure: None,
             layout_cache: None,
+            is_dirty: true,
         })));
 
         for child in children {
@@ -126,6 +129,7 @@ impl Node {
     pub fn mark_dirty(&mut self) {
         let mut node = self.0.borrow_mut();
         node.layout_cache = None;
+        node.is_dirty = true;
 
         for parent in &node.parents {
             if let Some(parent) = parent.upgrade() {
@@ -134,12 +138,8 @@ impl Node {
         }
     }
 
-    pub fn is_dirty(&mut self) -> bool {
-        if let Some(_) = self.0.borrow().layout_cache {
-            false
-        } else {
-            true
-        }
+    pub fn dirty(&self) -> bool {
+        self.0.borrow().is_dirty
     }
 
     pub fn compute_layout(&self, size: Size<Number>) -> Result<Layout> {
diff --git a/tests/node.rs b/tests/node.rs
index a113c1a6e..1f29dddaf 100644
--- a/tests/node.rs
+++ b/tests/node.rs
@@ -103,24 +103,24 @@ mod node {
     #[test]
     fn mark_dirty() {
         let mut child1 = Node::new(Style::default(), vec![]);
-        let mut child2 = Node::new(Style::default(), vec![]);
+        let child2 = Node::new(Style::default(), vec![]);
         let mut node = Node::new(Style::default(), vec![&child1, &child2]);
 
         node.compute_layout(stretch::geometry::Size::undefined()).unwrap();
 
-        assert_eq!(child1.is_dirty(), false);
-        assert_eq!(child2.is_dirty(), false);
-        assert_eq!(node.is_dirty(), false);
+        assert_eq!(child1.dirty(), false);
+        assert_eq!(child2.dirty(), false);
+        assert_eq!(node.dirty(), false);
 
         node.mark_dirty();
-        assert_eq!(child1.is_dirty(), false);
-        assert_eq!(child2.is_dirty(), false);
-        assert_eq!(node.is_dirty(), true);
+        assert_eq!(child1.dirty(), false);
+        assert_eq!(child2.dirty(), false);
+        assert_eq!(node.dirty(), true);
 
         node.compute_layout(stretch::geometry::Size::undefined()).unwrap();
         child1.mark_dirty();
-        assert_eq!(child1.is_dirty(), true);
-        assert_eq!(child2.is_dirty(), false);
-        assert_eq!(node.is_dirty(), true);
+        assert_eq!(child1.dirty(), true);
+        assert_eq!(child2.dirty(), false);
+        assert_eq!(node.dirty(), true);
     }
 }