diff --git a/src/app.rs b/src/app.rs index f5e6a83..b0f600f 100644 --- a/src/app.rs +++ b/src/app.rs @@ -54,13 +54,15 @@ impl GlintApp { _ => {} } - self.vdom_roots = Interpreter::evaluate_vdom( + let dirty_set = self.doc.tracker.take_dirty_set(); + self.vdom_roots = Interpreter::evaluate_vdom_incr( &self.doc.roots, &mut self.doc.variables, &self.doc.components, &self.rhei, &self.doc.stylesheet, &[], + &dirty_set, ); iced::Task::none() diff --git a/src/interpreter/mod.rs b/src/interpreter/mod.rs index bbe8438..3bb2ed3 100644 --- a/src/interpreter/mod.rs +++ b/src/interpreter/mod.rs @@ -18,7 +18,7 @@ use reader::Reader; use rhei::RHEI_PREFIX; use style::{AncestorInfo, ComputedStyle, StructuralContext}; pub use types::Value; -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; pub struct Interpreter; @@ -326,6 +326,18 @@ impl Interpreter { rhei: &RheiContext, stylesheet: &SS, ancestors: &[AncestorInfo], +) -> Vec> { + Self::evaluate_vdom_incr(templates, variables, components, rhei, stylesheet, ancestors, &HashSet::new()) + } + + pub fn evaluate_vdom_incr<'a>( + templates: &[Element<'a>], + variables: &mut HashMap, + components: &HashMap>, + rhei: &RheiContext, + stylesheet: &SS, + ancestors: &[AncestorInfo], + dirty_set: &HashSet, ) -> Vec> { let mut output = Vec::with_capacity(templates.len()); @@ -376,8 +388,8 @@ impl Interpreter { active_branch.push(child.clone()); } } - output.extend(Self::evaluate_vdom( - &active_branch, variables, components, rhei, stylesheet, ancestors, + output.extend(Self::evaluate_vdom_incr( + &active_branch, variables, components, rhei, stylesheet, ancestors, dirty_set, )); } @@ -400,8 +412,8 @@ impl Interpreter { for item in items { let old_val = variables.insert(var_name.to_string(), Value::Str(CompactString::new(item))); - output.extend(Self::evaluate_vdom( - &el.children, variables, components, rhei, stylesheet, ancestors, + output.extend(Self::evaluate_vdom_incr( + &el.children, variables, components, rhei, stylesheet, ancestors, dirty_set, )); if let Some(old) = old_val { @@ -442,8 +454,8 @@ impl Interpreter { vcomp.computed_style = ComputedStyle::compute(&vcomp.properties, &matched_sheets); let child_ancestors = Self::build_ancestor_chain(ancestors, &vcomp); - vcomp.children = Self::evaluate_vdom( - &comp.children, variables, components, rhei, stylesheet, &child_ancestors, + vcomp.children = Self::evaluate_vdom_incr( + &comp.children, variables, components, rhei, stylesheet, &child_ancestors, dirty_set, ); output.push(vcomp); @@ -474,8 +486,8 @@ impl Interpreter { vnode.computed_style = ComputedStyle::compute(&vnode.properties, &matched_sheets); let child_ancestors = Self::build_ancestor_chain(ancestors, &vnode); - vnode.children = Self::evaluate_vdom( - &el.children, variables, components, rhei, stylesheet, &child_ancestors, + vnode.children = Self::evaluate_vdom_incr( + &el.children, variables, components, rhei, stylesheet, &child_ancestors, dirty_set, ); output.push(vnode); } diff --git a/src/interpreter/reactive.rs b/src/interpreter/reactive.rs index d171f3a..86b112e 100644 --- a/src/interpreter/reactive.rs +++ b/src/interpreter/reactive.rs @@ -111,13 +111,15 @@ mod tests { tracker.add_dependency(e2, "volume"); tracker.add_dependency(e2, "brightness"); - let affected = tracker.on_variable_changed("volume"); - assert!(affected.contains(&e1)); - assert!(affected.contains(&e2)); + tracker.on_variable_changed("volume"); + let dirty = tracker.take_dirty_set(); + assert!(dirty.contains(&e1)); + assert!(dirty.contains(&e2)); - let affected = tracker.on_variable_changed("brightness"); - assert!(!affected.contains(&e1)); - assert!(affected.contains(&e2)); + tracker.on_variable_changed("brightness"); + let dirty = tracker.take_dirty_set(); + assert!(!dirty.contains(&e1)); + assert!(dirty.contains(&e2)); } #[test] @@ -127,11 +129,13 @@ mod tests { tracker.scan_value(e1, "Hello $name, you are $age years old"); - let affected = tracker.on_variable_changed("name"); - assert!(affected.contains(&e1)); + tracker.on_variable_changed("name"); + let dirty = tracker.take_dirty_set(); + assert!(dirty.contains(&e1)); - let affected = tracker.on_variable_changed("age"); - assert!(affected.contains(&e1)); + tracker.on_variable_changed("age"); + let dirty = tracker.take_dirty_set(); + assert!(dirty.contains(&e1)); } #[test] @@ -140,8 +144,9 @@ mod tests { let e1 = tracker.alloc_id(); tracker.scan_value(e1, "Hello world"); - let affected = tracker.on_variable_changed("name"); - assert!(!affected.contains(&e1)); + tracker.on_variable_changed("name"); + let dirty = tracker.take_dirty_set(); + assert!(!dirty.contains(&e1)); } #[test]