2.7 KiB
2.7 KiB
Reactivity Module: src/interpreter/reactive.rs
Dependency tracking system between variables and VDOM elements. Allows recalculation of only changed elements (Phase 3).
ElementId(u32)
Unique element identifier in the VDOM tree. Assigned by ReactiveTracker::alloc_id()
during template loading.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct ElementId(pub u32);
Used as:
- Key in
dirty_set: HashSet<ElementId> - Key in
dependencies: HashMap<ElementId, HashSet<String>> - Field in
Element::element_id(VDOM → tracker link) - Source for
iced::widget::Id(Phase 9.2:format!("ti:{}", id.0)) - Source for scrollable_id (
el.element_id.0 as u64)
ReactiveTracker
Dependency graph: variable → list of elements that reference it.
pub struct ReactiveTracker {
subscribers: HashMap<String, HashSet<ElementId>>,
dependencies: HashMap<ElementId, HashSet<String>>,
dirty_set: HashSet<ElementId>,
next_id: u32,
}
Fields:
subscribers— for each variable: which ElementIds depend on itdependencies— for each element: which variables it depends on (reverse mapping)dirty_set— elements to recalculate in the next framenext_id— counter foralloc_id()
Methods
| Method | Description |
|---|---|
new() |
Empty tracker |
alloc_id() -> ElementId |
Allocate a new ID, increment counter |
add_dependency(element, var_name) |
Register a dependency |
scan_value(element, value) |
Scan a string for $var and add dependencies |
on_variable_changed(name) |
Mark all dependent elements as dirty |
take_dirty_set() -> HashSet<ElementId> |
Take dirty_set and clear it |
is_dirty(id) -> bool |
Check if an element is marked dirty |
reset() |
Clear all data |
scan_value()
Parses a string for $var_name patterns:
"Hello $name, you are $age years old"
// → add_dependency(element, "name")
// → add_dependency(element, "age")
Used during template loading for each properties string containing $.
As a result, each element knows which variables it depends on.
Update cycle
Event → update() → on_variable_changed("var")
→ dirty_set = {element_A, element_B, ...}
→ take_dirty_set() → evaluate_vdom_incr(roots, &dirty_set)
→ for dirty_set elements: recalculate
→ for others: return as-is
Tests
| Test | What it checks |
|---|---|
test_basic_dependency_tracking |
Two elements, two variables, correct dirty_set |
test_scan_value |
Parse $var from a string |
test_scan_no_vars |
String without $ creates no dependencies |
test_take_dirty_set |
take_dirty_set() clears the internal set |
test_reset |
reset() clears everything |