wip: queue mods

This commit is contained in:
Jonathan Kelley 2022-11-16 01:13:39 -08:00
parent ea7ab5f765
commit 66319cf6e2
4 changed files with 76 additions and 26 deletions

View file

@ -18,5 +18,17 @@ fn app(cx: Scope) -> Element {
onclick: move |_| val.set("invalid"),
"Set an invalid number"
}
(0..5).map(|i| rsx! {
demo_c { x: i }
})
})
}
#[inline_props]
fn demo_c(cx: Scope, x: i32) -> Element {
cx.render(rsx! {
h1 {
"asdasdasdasd {x}"
}
})
}

View file

@ -45,37 +45,53 @@ impl VirtualDom {
// Walk the roots, creating nodes and assigning IDs
// todo: adjust dynamic nodes to be in the order of roots and then leaves (ie BFS)
let mut dynamic_attrs = template
.template
.attr_paths
.iter()
.enumerate()
.rev()
.peekable();
let mut dynamic_nodes = template
.template
.node_paths
.iter()
.enumerate()
.rev()
.peekable();
let mut dynamic_attrs = template.template.attr_paths.iter().enumerate().peekable();
let mut dynamic_nodes = template.template.node_paths.iter().enumerate().peekable();
let cur_scope = self.scope_stack.last().copied().unwrap();
println!("creating template: {:#?}", template);
let mut on_stack = 0;
for (root_idx, root) in template.template.roots.iter().enumerate().rev() {
mutations.push(LoadTemplate {
name: template.template.id,
index: root_idx,
});
for (root_idx, root) in template.template.roots.iter().enumerate() {
on_stack += match root {
TemplateNode::Element { .. } | TemplateNode::Text(_) => 1,
TemplateNode::Element { .. } | TemplateNode::Text(_) => {
mutations.push(LoadTemplate {
name: template.template.id,
index: root_idx,
});
1
}
TemplateNode::DynamicText(id) | TemplateNode::Dynamic(id) => {
self.create_dynamic_node(mutations, template, &template.dynamic_nodes[*id], *id)
let dynamic_node = &template.dynamic_nodes[*id];
match dynamic_node {
DynamicNode::Fragment { .. } | DynamicNode::Component { .. } => self
.create_dynamic_node(
mutations,
template,
&template.dynamic_nodes[*id],
*id,
),
DynamicNode::Text {
id: slot, value, ..
} => {
let id = self.next_element(template);
slot.set(id);
mutations.push(CreateTextNode {
value: value.clone(),
id,
});
1
}
DynamicNode::Placeholder(id) => {
let id = self.next_element(template);
mutations.push(CreatePlaceholder { id });
1
}
}
// self.create_dynamic_node(mutations, template, &template.dynamic_nodes[*id], *id)
}
};
@ -125,6 +141,14 @@ impl VirtualDom {
}
}
// todo:
//
// we walk the roots front to back when creating nodes, bur want to fill in the dynamic nodes
// back to front. This is because the indices would shift around because the paths become invalid
//
// We could easily implement this without the vec by walking the indicies forward
let mut queued_changes = vec![];
// We're on top of a node that has a dynamic child for a descendant
// Skip any node that's a root
while let Some((idx, path)) =
@ -133,12 +157,16 @@ impl VirtualDom {
let node = &template.dynamic_nodes[idx];
let m = self.create_dynamic_node(mutations, template, node, idx);
if m > 0 {
mutations.push(ReplacePlaceholder {
queued_changes.push(ReplacePlaceholder {
m,
path: &path[1..],
});
}
}
for change in queued_changes.into_iter().rev() {
mutations.push(change);
}
}
on_stack
@ -156,8 +184,8 @@ impl VirtualDom {
let id = self.next_element(template);
mutations.push(CreatePlaceholder { id })
}
TemplateNode::Text(value) => mutations.push(CreateTextNode { value }),
TemplateNode::DynamicText { .. } => mutations.push(CreateTextNode {
TemplateNode::Text(value) => mutations.push(CreateStaticText { value }),
TemplateNode::DynamicText { .. } => mutations.push(CreateStaticText {
value: "placeholder",
}),

View file

@ -60,9 +60,12 @@ pub enum Mutation<'a> {
CreatePlaceholder {
id: ElementId,
},
CreateStaticText {
value: &'a str,
},
CreateTextNode {
value: &'a str,
id: ElementId,
},
HydrateText {
path: &'static [u8],

View file

@ -124,6 +124,10 @@ export class Interpreter {
node.remove();
}
}
CreateRawText(text) {
const node = document.createTextNode(text);
this.stack.push(node);
}
CreateTextNode(text, root) {
const node = document.createTextNode(text);
this.nodes[root] = node;
@ -271,6 +275,9 @@ export class Interpreter {
case "CreateTextNode":
this.CreateTextNode(edit.value);
break;
case "CreateStaticText":
this.CreateTextNode(edit.value);
break;
case "HydrateText":
this.HydrateText(edit.path, edit.value, edit.id);
break;