wip: queue mods
This commit is contained in:
1 parent
ea7ab5f765
commit
66319cf6e2
4 files changed
+76
-26
No files matched your search
@@ -18,5 +18,17 @@ fn app(cx: Scope) -> Element {
|
|||||||
onclick: move |_| val.set("invalid"),
|
onclick: move |_| val.set("invalid"),
|
||||||
"Set an invalid number"
|
"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}"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
+53
-25
@@ -45,37 +45,53 @@ impl VirtualDom {
|
|||||||
|
|
||||||
// Walk the roots, creating nodes and assigning IDs
|
// Walk the roots, creating nodes and assigning IDs
|
||||||
// todo: adjust dynamic nodes to be in the order of roots and then leaves (ie BFS)
|
// todo: adjust dynamic nodes to be in the order of roots and then leaves (ie BFS)
|
||||||
let mut dynamic_attrs = template
|
let mut dynamic_attrs = template.template.attr_paths.iter().enumerate().peekable();
|
||||||
.template
|
let mut dynamic_nodes = template.template.node_paths.iter().enumerate().peekable();
|
||||||
.attr_paths
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.rev()
|
|
||||||
.peekable();
|
|
||||||
let mut dynamic_nodes = template
|
|
||||||
.template
|
|
||||||
.node_paths
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.rev()
|
|
||||||
.peekable();
|
|
||||||
|
|
||||||
let cur_scope = self.scope_stack.last().copied().unwrap();
|
let cur_scope = self.scope_stack.last().copied().unwrap();
|
||||||
|
|
||||||
println!("creating template: {:#?}", template);
|
println!("creating template: {:#?}", template);
|
||||||
|
|
||||||
let mut on_stack = 0;
|
let mut on_stack = 0;
|
||||||
for (root_idx, root) in template.template.roots.iter().enumerate().rev() {
|
for (root_idx, root) in template.template.roots.iter().enumerate() {
|
||||||
mutations.push(LoadTemplate {
|
|
||||||
name: template.template.id,
|
|
||||||
index: root_idx,
|
|
||||||
});
|
|
||||||
|
|
||||||
on_stack += match root {
|
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) => {
|
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
|
// We're on top of a node that has a dynamic child for a descendant
|
||||||
// Skip any node that's a root
|
// Skip any node that's a root
|
||||||
while let Some((idx, path)) =
|
while let Some((idx, path)) =
|
||||||
@@ -133,12 +157,16 @@ impl VirtualDom {
|
|||||||
let node = &template.dynamic_nodes[idx];
|
let node = &template.dynamic_nodes[idx];
|
||||||
let m = self.create_dynamic_node(mutations, template, node, idx);
|
let m = self.create_dynamic_node(mutations, template, node, idx);
|
||||||
if m > 0 {
|
if m > 0 {
|
||||||
mutations.push(ReplacePlaceholder {
|
queued_changes.push(ReplacePlaceholder {
|
||||||
m,
|
m,
|
||||||
path: &path[1..],
|
path: &path[1..],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for change in queued_changes.into_iter().rev() {
|
||||||
|
mutations.push(change);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
on_stack
|
on_stack
|
||||||
@@ -156,8 +184,8 @@ impl VirtualDom {
|
|||||||
let id = self.next_element(template);
|
let id = self.next_element(template);
|
||||||
mutations.push(CreatePlaceholder { id })
|
mutations.push(CreatePlaceholder { id })
|
||||||
}
|
}
|
||||||
TemplateNode::Text(value) => mutations.push(CreateTextNode { value }),
|
TemplateNode::Text(value) => mutations.push(CreateStaticText { value }),
|
||||||
TemplateNode::DynamicText { .. } => mutations.push(CreateTextNode {
|
TemplateNode::DynamicText { .. } => mutations.push(CreateStaticText {
|
||||||
value: "placeholder",
|
value: "placeholder",
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|||||||
@@ -60,9 +60,12 @@ pub enum Mutation<'a> {
|
|||||||
CreatePlaceholder {
|
CreatePlaceholder {
|
||||||
id: ElementId,
|
id: ElementId,
|
||||||
},
|
},
|
||||||
|
CreateStaticText {
|
||||||
|
value: &'a str,
|
||||||
|
},
|
||||||
CreateTextNode {
|
CreateTextNode {
|
||||||
value: &'a str,
|
value: &'a str,
|
||||||
|
id: ElementId,
|
||||||
},
|
},
|
||||||
HydrateText {
|
HydrateText {
|
||||||
path: &'static [u8],
|
path: &'static [u8],
|
||||||
|
|||||||
@@ -124,6 +124,10 @@ export class Interpreter {
|
|||||||
node.remove();
|
node.remove();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
CreateRawText(text) {
|
||||||
|
const node = document.createTextNode(text);
|
||||||
|
this.stack.push(node);
|
||||||
|
}
|
||||||
CreateTextNode(text, root) {
|
CreateTextNode(text, root) {
|
||||||
const node = document.createTextNode(text);
|
const node = document.createTextNode(text);
|
||||||
this.nodes[root] = node;
|
this.nodes[root] = node;
|
||||||
@@ -271,6 +275,9 @@ export class Interpreter {
|
|||||||
case "CreateTextNode":
|
case "CreateTextNode":
|
||||||
this.CreateTextNode(edit.value);
|
this.CreateTextNode(edit.value);
|
||||||
break;
|
break;
|
||||||
|
case "CreateStaticText":
|
||||||
|
this.CreateTextNode(edit.value);
|
||||||
|
break;
|
||||||
case "HydrateText":
|
case "HydrateText":
|
||||||
this.HydrateText(edit.path, edit.value, edit.id);
|
this.HydrateText(edit.path, edit.value, edit.id);
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in new issue
Block a user