fix: switch to future based diffing

this commit removes the old manual fiber implementation in favor of a
traditional recursion based approach. This should make the diffing
algorithm easier to work on and eliminate various stack-based bugs in.
This commit is contained in:
Jonathan Kelley committed 2022-01-30 17:47:58 -05:00
1 parent 3edf3e367f
commit 3bb5c8142c
9 files changed
+1268 -322

No files matched your search

+18 -41
View File
@@ -175,6 +175,7 @@ impl Debug for VNode<'_> {
.field("key", &el.key)
.field("attrs", &el.attributes)
.field("children", &el.children)
.field("id", &el.id)
.finish(),
VNode::Text(t) => write!(s, "VNode::VText {{ text: {} }}", t.text),
VNode::Placeholder(t) => write!(s, "VNode::VPlaceholder {{ id: {:?} }}", t.id),
@@ -365,9 +366,7 @@ pub struct EventHandler<'bump, T = ()> {
impl<'a, T> Default for EventHandler<'a, T> {
fn default() -> Self {
Self {
callback: RefCell::new(None),
}
Self { callback: RefCell::new(None) }
}
}
@@ -441,10 +440,7 @@ pub struct NodeFactory<'a> {
impl<'a> NodeFactory<'a> {
pub fn new(scope: &'a ScopeState) -> NodeFactory<'a> {
NodeFactory {
scope,
bump: &scope.wip_frame().bump,
}
NodeFactory { scope, bump: &scope.wip_frame().bump }
}
#[inline]
@@ -454,11 +450,10 @@ impl<'a> NodeFactory<'a> {
/// Directly pass in text blocks without the need to use the format_args macro.
pub fn static_text(&self, text: &'static str) -> VNode<'a> {
VNode::Text(self.bump.alloc(VText {
id: empty_cell(),
text,
is_static: true,
}))
VNode::Text(
self.bump
.alloc(VText { id: empty_cell(), text, is_static: true }),
)
}
/// Parses a lazy text Arguments and returns a string and a flag indicating if the text is 'static
@@ -481,11 +476,7 @@ impl<'a> NodeFactory<'a> {
pub fn text(&self, args: Arguments) -> VNode<'a> {
let (text, is_static) = self.raw_text(args);
VNode::Text(self.bump.alloc(VText {
text,
is_static,
id: empty_cell(),
}))
VNode::Text(self.bump.alloc(VText { text, is_static, id: empty_cell() }))
}
pub fn element(
@@ -543,13 +534,7 @@ impl<'a> NodeFactory<'a> {
is_volatile: bool,
) -> Attribute<'a> {
let (value, is_static) = self.raw_text(val);
Attribute {
name,
value,
is_static,
namespace,
is_volatile,
}
Attribute { name, value, is_static, namespace, is_volatile }
}
pub fn component<P>(
@@ -591,11 +576,7 @@ impl<'a> NodeFactory<'a> {
}
pub fn listener(self, event: &'static str, callback: InternalHandler<'a>) -> Listener<'a> {
Listener {
event,
mounted_node: Cell::new(None),
callback,
}
Listener { event, mounted_node: Cell::new(None), callback }
}
pub fn fragment_root<'b, 'c>(
@@ -611,10 +592,10 @@ impl<'a> NodeFactory<'a> {
if nodes.is_empty() {
VNode::Placeholder(self.bump.alloc(VPlaceholder { id: empty_cell() }))
} else {
VNode::Fragment(self.bump.alloc(VFragment {
children: nodes.into_bump_slice(),
key: None,
}))
VNode::Fragment(
self.bump
.alloc(VFragment { children: nodes.into_bump_slice(), key: None }),
)
}
}
@@ -650,10 +631,7 @@ impl<'a> NodeFactory<'a> {
);
}
VNode::Fragment(self.bump.alloc(VFragment {
children,
key: None,
}))
VNode::Fragment(self.bump.alloc(VFragment { children, key: None }))
}
}
@@ -676,10 +654,9 @@ impl<'a> NodeFactory<'a> {
} else {
let children = nodes.into_bump_slice();
Some(VNode::Fragment(self.bump.alloc(VFragment {
children,
key: None,
})))
Some(VNode::Fragment(
self.bump.alloc(VFragment { children, key: None }),
))
}
}