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);
}
}