Phase 3.4-3.7: evaluate_vdom_incr with dirty_set propagation, tests for ReactiveTracker
This commit is contained in:
@@ -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,
|
&self.doc.roots,
|
||||||
&mut self.doc.variables,
|
&mut self.doc.variables,
|
||||||
&self.doc.components,
|
&self.doc.components,
|
||||||
&self.rhei,
|
&self.rhei,
|
||||||
&self.doc.stylesheet,
|
&self.doc.stylesheet,
|
||||||
&[],
|
&[],
|
||||||
|
&dirty_set,
|
||||||
);
|
);
|
||||||
|
|
||||||
iced::Task::none()
|
iced::Task::none()
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use reader::Reader;
|
|||||||
use rhei::RHEI_PREFIX;
|
use rhei::RHEI_PREFIX;
|
||||||
use style::{AncestorInfo, ComputedStyle, StructuralContext};
|
use style::{AncestorInfo, ComputedStyle, StructuralContext};
|
||||||
pub use types::Value;
|
pub use types::Value;
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
pub struct Interpreter;
|
pub struct Interpreter;
|
||||||
|
|
||||||
@@ -326,6 +326,18 @@ impl Interpreter {
|
|||||||
rhei: &RheiContext,
|
rhei: &RheiContext,
|
||||||
stylesheet: &SS,
|
stylesheet: &SS,
|
||||||
ancestors: &[AncestorInfo],
|
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>> {
|
) -> Vec<Element<'a>> {
|
||||||
let mut output = Vec::with_capacity(templates.len());
|
let mut output = Vec::with_capacity(templates.len());
|
||||||
|
|
||||||
@@ -376,8 +388,8 @@ impl Interpreter {
|
|||||||
active_branch.push(child.clone());
|
active_branch.push(child.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
output.extend(Self::evaluate_vdom(
|
output.extend(Self::evaluate_vdom_incr(
|
||||||
&active_branch, variables, components, rhei, stylesheet, ancestors,
|
&active_branch, variables, components, rhei, stylesheet, ancestors, dirty_set,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -400,8 +412,8 @@ impl Interpreter {
|
|||||||
for item in items {
|
for item in items {
|
||||||
let old_val = variables.insert(var_name.to_string(), Value::Str(CompactString::new(item)));
|
let old_val = variables.insert(var_name.to_string(), Value::Str(CompactString::new(item)));
|
||||||
|
|
||||||
output.extend(Self::evaluate_vdom(
|
output.extend(Self::evaluate_vdom_incr(
|
||||||
&el.children, variables, components, rhei, stylesheet, ancestors,
|
&el.children, variables, components, rhei, stylesheet, ancestors, dirty_set,
|
||||||
));
|
));
|
||||||
|
|
||||||
if let Some(old) = old_val {
|
if let Some(old) = old_val {
|
||||||
@@ -442,8 +454,8 @@ impl Interpreter {
|
|||||||
vcomp.computed_style = ComputedStyle::compute(&vcomp.properties, &matched_sheets);
|
vcomp.computed_style = ComputedStyle::compute(&vcomp.properties, &matched_sheets);
|
||||||
|
|
||||||
let child_ancestors = Self::build_ancestor_chain(ancestors, &vcomp);
|
let child_ancestors = Self::build_ancestor_chain(ancestors, &vcomp);
|
||||||
vcomp.children = Self::evaluate_vdom(
|
vcomp.children = Self::evaluate_vdom_incr(
|
||||||
&comp.children, variables, components, rhei, stylesheet, &child_ancestors,
|
&comp.children, variables, components, rhei, stylesheet, &child_ancestors, dirty_set,
|
||||||
);
|
);
|
||||||
output.push(vcomp);
|
output.push(vcomp);
|
||||||
|
|
||||||
@@ -474,8 +486,8 @@ impl Interpreter {
|
|||||||
vnode.computed_style = ComputedStyle::compute(&vnode.properties, &matched_sheets);
|
vnode.computed_style = ComputedStyle::compute(&vnode.properties, &matched_sheets);
|
||||||
|
|
||||||
let child_ancestors = Self::build_ancestor_chain(ancestors, &vnode);
|
let child_ancestors = Self::build_ancestor_chain(ancestors, &vnode);
|
||||||
vnode.children = Self::evaluate_vdom(
|
vnode.children = Self::evaluate_vdom_incr(
|
||||||
&el.children, variables, components, rhei, stylesheet, &child_ancestors,
|
&el.children, variables, components, rhei, stylesheet, &child_ancestors, dirty_set,
|
||||||
);
|
);
|
||||||
output.push(vnode);
|
output.push(vnode);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -111,13 +111,15 @@ mod tests {
|
|||||||
tracker.add_dependency(e2, "volume");
|
tracker.add_dependency(e2, "volume");
|
||||||
tracker.add_dependency(e2, "brightness");
|
tracker.add_dependency(e2, "brightness");
|
||||||
|
|
||||||
let affected = tracker.on_variable_changed("volume");
|
tracker.on_variable_changed("volume");
|
||||||
assert!(affected.contains(&e1));
|
let dirty = tracker.take_dirty_set();
|
||||||
assert!(affected.contains(&e2));
|
assert!(dirty.contains(&e1));
|
||||||
|
assert!(dirty.contains(&e2));
|
||||||
|
|
||||||
let affected = tracker.on_variable_changed("brightness");
|
tracker.on_variable_changed("brightness");
|
||||||
assert!(!affected.contains(&e1));
|
let dirty = tracker.take_dirty_set();
|
||||||
assert!(affected.contains(&e2));
|
assert!(!dirty.contains(&e1));
|
||||||
|
assert!(dirty.contains(&e2));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -127,11 +129,13 @@ mod tests {
|
|||||||
|
|
||||||
tracker.scan_value(e1, "Hello $name, you are $age years old");
|
tracker.scan_value(e1, "Hello $name, you are $age years old");
|
||||||
|
|
||||||
let affected = tracker.on_variable_changed("name");
|
tracker.on_variable_changed("name");
|
||||||
assert!(affected.contains(&e1));
|
let dirty = tracker.take_dirty_set();
|
||||||
|
assert!(dirty.contains(&e1));
|
||||||
|
|
||||||
let affected = tracker.on_variable_changed("age");
|
tracker.on_variable_changed("age");
|
||||||
assert!(affected.contains(&e1));
|
let dirty = tracker.take_dirty_set();
|
||||||
|
assert!(dirty.contains(&e1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -140,8 +144,9 @@ mod tests {
|
|||||||
let e1 = tracker.alloc_id();
|
let e1 = tracker.alloc_id();
|
||||||
|
|
||||||
tracker.scan_value(e1, "Hello world");
|
tracker.scan_value(e1, "Hello world");
|
||||||
let affected = tracker.on_variable_changed("name");
|
tracker.on_variable_changed("name");
|
||||||
assert!(!affected.contains(&e1));
|
let dirty = tracker.take_dirty_set();
|
||||||
|
assert!(!dirty.contains(&e1));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user