From 66319cf6e2e43c5f1c9fcdd2bdf44f54ced442a2 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Wed, 16 Nov 2022 01:13:39 -0800 Subject: [PATCH] wip: queue mods --- examples/error_handle.rs | 12 ++++ packages/core/src/create.rs | 78 +++++++++++++++++-------- packages/core/src/mutations.rs | 5 +- packages/interpreter/src/interpreter.js | 7 +++ 4 files changed, 76 insertions(+), 26 deletions(-) diff --git a/examples/error_handle.rs b/examples/error_handle.rs index 1d5d82b6d..5c64915cd 100644 --- a/examples/error_handle.rs +++ b/examples/error_handle.rs @@ -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}" + } }) } diff --git a/packages/core/src/create.rs b/packages/core/src/create.rs index 9be9011d5..c255b7113 100644 --- a/packages/core/src/create.rs +++ b/packages/core/src/create.rs @@ -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", }), diff --git a/packages/core/src/mutations.rs b/packages/core/src/mutations.rs index 849611171..f03088250 100644 --- a/packages/core/src/mutations.rs +++ b/packages/core/src/mutations.rs @@ -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], diff --git a/packages/interpreter/src/interpreter.js b/packages/interpreter/src/interpreter.js index 220e2d1a2..1a2215383 100644 --- a/packages/interpreter/src/interpreter.js +++ b/packages/interpreter/src/interpreter.js @@ -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;