Phase 3.4-3.7: evaluate_vdom_incr with dirty_set propagation, tests for ReactiveTracker

This commit is contained in:
Glint Dev
2026-07-21 20:40:23 +03:00
parent d8d3f57a21
commit 4a6dea6dd8
3 changed files with 41 additions and 22 deletions

View File

@@ -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<Element<'a>> {
Self::evaluate_vdom_incr(templates, variables, components, rhei, stylesheet, ancestors, &HashSet::new())
}
pub fn evaluate_vdom_incr<'a>(
templates: &[Element<'a>],
variables: &mut HashMap<String, Value>,
components: &HashMap<String, ComponentDef<'a>>,
rhei: &RheiContext,
stylesheet: &SS,
ancestors: &[AncestorInfo],
dirty_set: &HashSet<ElementId>,
) -> Vec<Element<'a>> {
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);
}

View File

@@ -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]