Phase 9: Keyed widgets (9.1 + 9.2)
9.1: Add content_hash field to Element, computed during VDOM evaluation from type_name + properties + children content_hashes via DefaultHasher. 9.2: Assign stable iced::widget::Id to text_input and scrollable widgets so Iced preserves widget state (cursor position, scroll offset) across frames. Ids are cached in a thread_local HashMap to avoid leaks. 9.3 skipped: iced::Element is not Clone and contains Box<dyn Widget>, making element-level caching impractical without unsafe lifetime hacks.
This commit is contained in:
@@ -7,6 +7,7 @@ pub mod style;
|
||||
pub mod types;
|
||||
|
||||
use std::borrow::Cow;
|
||||
use std::hash::{Hash, Hasher};
|
||||
pub use rhei::RheiContext;
|
||||
use style::StyleSheet as SS;
|
||||
pub use types::{ComponentDef, Document, Element, Interner, InterpError};
|
||||
@@ -476,6 +477,7 @@ impl Interpreter {
|
||||
vcomp.children = Self::evaluate_vdom_incr(
|
||||
&comp_child_refs, variables, components, rhei, stylesheet, &child_ancestors, dirty_set,
|
||||
);
|
||||
vcomp.content_hash = Self::compute_content_hash(&vcomp);
|
||||
output.push(vcomp);
|
||||
|
||||
for (k, old) in old_vals.into_iter().rev() {
|
||||
@@ -509,6 +511,7 @@ impl Interpreter {
|
||||
vnode.children = Self::evaluate_vdom_incr(
|
||||
&child_refs, variables, components, rhei, stylesheet, &child_ancestors, dirty_set,
|
||||
);
|
||||
vnode.content_hash = Self::compute_content_hash(&vnode);
|
||||
output.push(vnode);
|
||||
}
|
||||
}
|
||||
@@ -518,6 +521,20 @@ impl Interpreter {
|
||||
output
|
||||
}
|
||||
|
||||
fn compute_content_hash(el: &Element) -> u64 {
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
let mut h = DefaultHasher::new();
|
||||
el.type_name.hash(&mut h);
|
||||
for (k, v) in &el.properties {
|
||||
k.hash(&mut h);
|
||||
v.hash(&mut h);
|
||||
}
|
||||
for child in &el.children {
|
||||
child.content_hash.hash(&mut h);
|
||||
}
|
||||
h.finish()
|
||||
}
|
||||
|
||||
fn build_ancestor_chain<'a>(ancestors: &[AncestorInfo], el: &Element) -> Vec<AncestorInfo> {
|
||||
let mut chain = ancestors.to_vec();
|
||||
let id = el.id().map(String::from);
|
||||
|
||||
Reference in New Issue
Block a user