Skip to content

Commit 3c19def

Browse files
committed
chore: get create working and simplify dynamic nodes
1 parent 16a521a commit 3c19def

File tree

16 files changed

+170
-175
lines changed

16 files changed

+170
-175
lines changed

examples/router.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fn app(cx: Scope) -> Element {
3030
}
3131

3232
fn BlogPost(cx: Scope) -> Element {
33-
let post = dioxus_router::use_route(&cx).last_segment()?;
33+
let post = dioxus_router::use_route(&cx).last_segment().unwrap();
3434

3535
cx.render(rsx! {
3636
div {
@@ -46,7 +46,7 @@ struct Query {
4646
}
4747

4848
fn User(cx: Scope) -> Element {
49-
let post = dioxus_router::use_route(&cx).last_segment()?;
49+
let post = dioxus_router::use_route(&cx).last_segment().unwrap();
5050

5151
let query = dioxus_router::use_route(&cx)
5252
.query::<Query>()

examples/rsx_usage.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,13 +165,13 @@ fn app(cx: Scope) -> Element {
165165

166166
// Can pass in props directly as an expression
167167
{
168-
let props = TallerProps {a: "hello", children: Default::default()};
168+
let props = TallerProps {a: "hello", children: cx.render(rsx!(()))};
169169
rsx!(Taller { ..props })
170170
}
171171

172172
// Spreading can also be overridden manually
173173
Taller {
174-
..TallerProps { a: "ballin!", children: Default::default() },
174+
..TallerProps { a: "ballin!", children: cx.render(rsx!(()) )},
175175
a: "not ballin!"
176176
}
177177

packages/core/src/arena.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::{
22
factory::RenderReturn, nodes::VNode, virtual_dom::VirtualDom, AttributeValue, DynamicNode,
3-
ScopeId, VFragment,
3+
ScopeId,
44
};
55
use bumpalo::boxed::Box as BumpBox;
66

@@ -101,7 +101,7 @@ impl VirtualDom {
101101
for (idx, _) in node.template.roots.iter().enumerate() {
102102
match node.dynamic_root(idx) {
103103
Some(DynamicNode::Component(c)) => self.drop_scope(c.scope.get().unwrap()),
104-
Some(DynamicNode::Fragment(VFragment::NonEmpty(nodes))) => {
104+
Some(DynamicNode::Fragment(nodes)) => {
105105
for node in *nodes {
106106
self.drop_scope_inner(node);
107107
}

packages/core/src/create.rs

Lines changed: 24 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
use std::cell::Cell;
2+
13
use crate::factory::RenderReturn;
2-
use crate::innerlude::{VComponent, VFragment, VText};
4+
use crate::innerlude::{VComponent, VText};
35
use crate::mutations::Mutation;
46
use crate::mutations::Mutation::*;
57
use crate::nodes::VNode;
68
use crate::nodes::{DynamicNode, TemplateNode};
79
use crate::virtual_dom::VirtualDom;
8-
use crate::{AttributeValue, ScopeId, SuspenseContext, TemplateAttribute};
10+
use crate::{AttributeValue, ElementId, ScopeId, SuspenseContext, TemplateAttribute};
911

1012
impl<'b> VirtualDom {
1113
/// Create a new template [`VNode`] and write it to the [`Mutations`] buffer.
@@ -55,15 +57,14 @@ impl<'b> VirtualDom {
5557
1
5658
}
5759

58-
DynamicNode::Fragment(VFragment::Empty(slot)) => {
60+
DynamicNode::Placeholder(slot) => {
5961
let id = self.next_element(template, template.template.node_paths[*id]);
6062
slot.set(id);
6163
self.mutations.push(CreatePlaceholder { id });
6264
1
6365
}
6466

65-
DynamicNode::Fragment(VFragment::NonEmpty(_))
66-
| DynamicNode::Component { .. } => {
67+
DynamicNode::Fragment(_) | DynamicNode::Component { .. } => {
6768
self.create_dynamic_node(template, &template.dynamic_nodes[*id], *id)
6869
}
6970
}
@@ -309,7 +310,8 @@ impl<'b> VirtualDom {
309310
use DynamicNode::*;
310311
match node {
311312
Text(text) => self.create_dynamic_text(template, text, idx),
312-
Fragment(frag) => self.create_fragment(frag, template, idx),
313+
Fragment(frag) => self.create_fragment(frag),
314+
Placeholder(frag) => self.create_placeholder(frag, template, idx),
313315
Component(component) => self.create_component_node(template, component, idx),
314316
}
315317
}
@@ -340,34 +342,30 @@ impl<'b> VirtualDom {
340342
0
341343
}
342344

343-
pub(crate) fn create_fragment(
345+
pub(crate) fn create_placeholder(
344346
&mut self,
345-
frag: &'b VFragment<'b>,
347+
slot: &Cell<ElementId>,
346348
template: &'b VNode<'b>,
347349
idx: usize,
348350
) -> usize {
349-
match frag {
350-
VFragment::NonEmpty(nodes) => {
351-
nodes.iter().fold(0, |acc, child| acc + self.create(child))
352-
}
351+
// Allocate a dynamic element reference for this text node
352+
let id = self.next_element(template, template.template.node_paths[idx]);
353353

354-
VFragment::Empty(slot) => {
355-
// Allocate a dynamic element reference for this text node
356-
let id = self.next_element(template, template.template.node_paths[idx]);
354+
// Make sure the text node is assigned to the correct element
355+
slot.set(id);
357356

358-
// Make sure the text node is assigned to the correct element
359-
slot.set(id);
357+
// Assign the ID to the existing node in the template
358+
self.mutations.push(AssignId {
359+
path: &template.template.node_paths[idx][1..],
360+
id,
361+
});
360362

361-
// Assign the ID to the existing node in the template
362-
self.mutations.push(AssignId {
363-
path: &template.template.node_paths[idx][1..],
364-
id,
365-
});
363+
// Since the placeholder is already in the DOM, we don't create any new nodes
364+
0
365+
}
366366

367-
// Since the placeholder is already in the DOM, we don't create any new nodes
368-
0
369-
}
370-
}
367+
pub(crate) fn create_fragment(&mut self, nodes: &'b [VNode<'b>]) -> usize {
368+
nodes.iter().fold(0, |acc, child| acc + self.create(child))
371369
}
372370

373371
pub(super) fn create_component_node(

packages/core/src/diff.rs

Lines changed: 17 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::{
22
arena::ElementId,
33
factory::RenderReturn,
4-
innerlude::{DirtyScope, VComponent, VFragment, VText},
4+
innerlude::{DirtyScope, VComponent, VText},
55
mutations::Mutation,
66
nodes::{DynamicNode, VNode},
77
scopes::ScopeId,
@@ -10,7 +10,6 @@ use crate::{
1010
};
1111

1212
use fxhash::{FxHashMap, FxHashSet};
13-
use std::cell::Cell;
1413
use DynamicNode::*;
1514

1615
impl<'b> VirtualDom {
@@ -101,7 +100,7 @@ impl<'b> VirtualDom {
101100
{
102101
match (left_node, right_node) {
103102
(Text(left), Text(right)) => self.diff_vtext(left, right),
104-
(Fragment(left), Fragment(right)) => self.diff_vfragment(left, right),
103+
(Fragment(left), Fragment(right)) => self.diff_non_empty_fragment(left, right),
105104
(Component(left), Component(right)) => {
106105
self.diff_vcomponent(left, right, right_template, idx)
107106
}
@@ -231,49 +230,15 @@ impl<'b> VirtualDom {
231230
}
232231
}
233232

234-
fn diff_vfragment(&mut self, left: &'b VFragment<'b>, right: &'b VFragment<'b>) {
235-
use VFragment::*;
236-
match (left, right) {
237-
(Empty(l), Empty(r)) => r.set(l.get()),
238-
(Empty(l), NonEmpty(r)) => self.replace_placeholder_with_nodes(l, r),
239-
(NonEmpty(l), Empty(r)) => self.replace_nodes_with_placeholder(l, r),
240-
(NonEmpty(old), NonEmpty(new)) => self.diff_non_empty_fragment(new, old),
241-
}
242-
}
243-
244-
fn replace_placeholder_with_nodes(&mut self, l: &'b Cell<ElementId>, r: &'b [VNode<'b>]) {
245-
let m = self.create_children(r);
246-
let id = l.get();
247-
self.mutations.push(Mutation::ReplaceWith { id, m });
248-
self.reclaim(id);
249-
}
250-
251-
fn replace_nodes_with_placeholder(&mut self, l: &'b [VNode<'b>], r: &'b Cell<ElementId>) {
252-
// Create the placeholder first, ensuring we get a dedicated ID for the placeholder
253-
let placeholder = self.next_element(&l[0], &[]);
254-
r.set(placeholder);
255-
self.mutations
256-
.push(Mutation::CreatePlaceholder { id: placeholder });
257-
258-
// Remove the old nodes, except for onea
259-
let first = self.replace_inner(&l[0]);
260-
self.remove_nodes(&l[1..]);
261-
262-
self.mutations
263-
.push(Mutation::ReplaceWith { id: first, m: 1 });
264-
265-
self.try_reclaim(first);
266-
}
267-
268233
/// Remove all the top-level nodes, returning the firstmost root ElementId
269234
///
270235
/// All IDs will be garbage collected
271236
fn replace_inner(&mut self, node: &'b VNode<'b>) -> ElementId {
272237
let id = match node.dynamic_root(0) {
273238
None => node.root_ids[0].get(),
274239
Some(Text(t)) => t.id.get(),
275-
Some(Fragment(VFragment::Empty(e))) => e.get(),
276-
Some(Fragment(VFragment::NonEmpty(nodes))) => {
240+
Some(Placeholder(e)) => e.get(),
241+
Some(Fragment(nodes)) => {
277242
let id = self.replace_inner(&nodes[0]);
278243
self.remove_nodes(&nodes[1..]);
279244
id
@@ -317,10 +282,8 @@ impl<'b> VirtualDom {
317282
};
318283
}
319284
Text(t) => self.reclaim(t.id.get()),
320-
Fragment(VFragment::Empty(t)) => self.reclaim(t.get()),
321-
Fragment(VFragment::NonEmpty(nodes)) => {
322-
nodes.iter().for_each(|node| self.clean_up_node(node))
323-
}
285+
Placeholder(t) => self.reclaim(t.get()),
286+
Fragment(nodes) => nodes.iter().for_each(|node| self.clean_up_node(node)),
324287
};
325288
}
326289

@@ -351,12 +314,12 @@ impl<'b> VirtualDom {
351314
self.mutations.push(Mutation::Remove { id });
352315
self.reclaim(id);
353316
}
354-
Some(Fragment(VFragment::Empty(e))) => {
317+
Some(Placeholder(e)) => {
355318
let id = e.get();
356319
self.mutations.push(Mutation::Remove { id });
357320
self.reclaim(id);
358321
}
359-
Some(Fragment(VFragment::NonEmpty(nodes))) => self.remove_nodes(nodes),
322+
Some(Fragment(nodes)) => self.remove_nodes(nodes),
360323
Some(Component(comp)) => {
361324
let scope = comp.scope.get().unwrap();
362325
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
@@ -750,8 +713,8 @@ impl<'b> VirtualDom {
750713
for (idx, _) in node.template.roots.iter().enumerate() {
751714
let id = match node.dynamic_root(idx) {
752715
Some(Text(t)) => t.id.get(),
753-
Some(Fragment(VFragment::Empty(t))) => t.get(),
754-
Some(Fragment(VFragment::NonEmpty(t))) => return self.remove_nodes(t),
716+
Some(Placeholder(t)) => t.get(),
717+
Some(Fragment(t)) => return self.remove_nodes(t),
755718
Some(Component(comp)) => return self.remove_component(comp.scope.get().unwrap()),
756719
None => node.root_ids[idx].get(),
757720
};
@@ -793,12 +756,12 @@ impl<'b> VirtualDom {
793756
self.mutations.push(Mutation::PushRoot { id: t.id.get() });
794757
onstack += 1;
795758
}
796-
Some(Fragment(VFragment::Empty(t))) => {
759+
Some(Placeholder(t)) => {
797760
self.mutations.push(Mutation::PushRoot { id: t.get() });
798761
onstack += 1;
799762
}
800-
Some(Fragment(VFragment::NonEmpty(t))) => {
801-
for node in *t {
763+
Some(Fragment(nodes)) => {
764+
for node in *nodes {
802765
onstack += self.push_all_real_nodes(node);
803766
}
804767
}
@@ -842,8 +805,8 @@ impl<'b> VirtualDom {
842805
match node.dynamic_root(0) {
843806
None => node.root_ids[0].get(),
844807
Some(Text(t)) => t.id.get(),
845-
Some(Fragment(VFragment::NonEmpty(t))) => self.find_first_element(&t[0]),
846-
Some(Fragment(VFragment::Empty(t))) => t.get(),
808+
Some(Fragment(t)) => self.find_first_element(&t[0]),
809+
Some(Placeholder(t)) => t.get(),
847810
Some(Component(comp)) => {
848811
let scope = comp.scope.get().unwrap();
849812
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {
@@ -858,8 +821,8 @@ impl<'b> VirtualDom {
858821
match node.dynamic_root(node.template.roots.len() - 1) {
859822
None => node.root_ids.last().unwrap().get(),
860823
Some(Text(t)) => t.id.get(),
861-
Some(Fragment(VFragment::NonEmpty(t))) => self.find_last_element(t.last().unwrap()),
862-
Some(Fragment(VFragment::Empty(t))) => t.get(),
824+
Some(Fragment(t)) => self.find_last_element(t.last().unwrap()),
825+
Some(Placeholder(t)) => t.get(),
863826
Some(Component(comp)) => {
864827
let scope = comp.scope.get().unwrap();
865828
match unsafe { self.scopes[scope.0].root_node().extend_lifetime_ref() } {

packages/core/src/factory.rs

Lines changed: 18 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use std::future::Future;
1010
use crate::{
1111
any_props::{AnyProps, VProps},
1212
arena::ElementId,
13-
innerlude::{DynamicNode, EventHandler, VComponent, VFragment, VText},
13+
innerlude::{DynamicNode, EventHandler, VComponent, VText},
1414
Attribute, AttributeValue, Element, LazyNodes, Properties, Scope, ScopeState, VNode,
1515
};
1616

@@ -148,20 +148,28 @@ pub trait IntoDynNode<'a, A = ()> {
148148

149149
impl<'a> IntoDynNode<'a> for () {
150150
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
151-
DynamicNode::Fragment(VFragment::Empty(Cell::new(ElementId(0))))
151+
DynamicNode::placeholder()
152152
}
153153
}
154154
impl<'a> IntoDynNode<'a> for VNode<'a> {
155155
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
156-
DynamicNode::Fragment(VFragment::NonEmpty(_cx.bump().alloc([self])))
156+
DynamicNode::Fragment(_cx.bump().alloc([self]))
157+
}
158+
}
159+
impl<'a> IntoDynNode<'a> for Element<'a> {
160+
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
161+
match self {
162+
Ok(val) => val.into_vnode(_cx),
163+
_ => DynamicNode::placeholder(),
164+
}
157165
}
158166
}
159167

160168
impl<'a, T: IntoDynNode<'a>> IntoDynNode<'a> for Option<T> {
161169
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
162170
match self {
163171
Some(val) => val.into_vnode(_cx),
164-
None => DynamicNode::Fragment(VFragment::Empty(Cell::new(ElementId(0)))),
172+
None => DynamicNode::placeholder(),
165173
}
166174
}
167175
}
@@ -170,14 +178,14 @@ impl<'a> IntoDynNode<'a> for &Element<'a> {
170178
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
171179
match self.as_ref() {
172180
Ok(val) => val.clone().into_vnode(_cx),
173-
_ => DynamicNode::Fragment(VFragment::Empty(Cell::new(ElementId(0)))),
181+
_ => DynamicNode::placeholder(),
174182
}
175183
}
176184
}
177185

178186
impl<'a, 'b> IntoDynNode<'a> for LazyNodes<'a, 'b> {
179187
fn into_vnode(self, cx: &'a ScopeState) -> DynamicNode<'a> {
180-
DynamicNode::Fragment(VFragment::NonEmpty(cx.bump().alloc([self.call(cx)])))
188+
DynamicNode::Fragment(cx.bump().alloc([self.call(cx)]))
181189
}
182190
}
183191

@@ -201,14 +209,14 @@ impl<'b> IntoDynNode<'b> for Arguments<'_> {
201209

202210
impl<'a> IntoDynNode<'a> for &'a VNode<'a> {
203211
fn into_vnode(self, _cx: &'a ScopeState) -> DynamicNode<'a> {
204-
DynamicNode::Fragment(VFragment::NonEmpty(_cx.bump().alloc([VNode {
212+
DynamicNode::Fragment(_cx.bump().alloc([VNode {
205213
parent: self.parent,
206214
template: self.template,
207215
root_ids: self.root_ids,
208216
key: self.key,
209217
dynamic_nodes: self.dynamic_nodes,
210218
dynamic_attrs: self.dynamic_attrs,
211-
}])))
219+
}]))
212220
}
213221
}
214222

@@ -243,8 +251,8 @@ where
243251
let children = nodes.into_bump_slice();
244252

245253
match children.len() {
246-
0 => DynamicNode::Fragment(VFragment::Empty(Cell::new(ElementId(0)))),
247-
_ => DynamicNode::Fragment(VFragment::NonEmpty(children)),
254+
0 => DynamicNode::placeholder(),
255+
_ => DynamicNode::Fragment(children),
248256
}
249257
}
250258
}

0 commit comments

Comments
 (0)