wip: it works?
This commit is contained in:
1 parent
082765f687
commit
778baffb10
3 files changed
+103
-238
No files matched your search
Vendored
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
{
|
{
|
||||||
"rust-analyzer.inlayHints.enable": false
|
"rust-analyzer.inlayHints.enable": true
|
||||||
}
|
}
|
||||||
+92
-237
@@ -188,6 +188,10 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
DiffInstruction::Mount { and } => {
|
DiffInstruction::Mount { and } => {
|
||||||
self.mount(and);
|
self.mount(and);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DiffInstruction::PrepareMoveNode { node } => {
|
||||||
|
//
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -224,6 +228,12 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
let root = self.find_first_element(other_node).direct_id();
|
let root = self.find_first_element(other_node).direct_id();
|
||||||
self.mutations.insert_before(root, nodes_created as u32);
|
self.mutations.insert_before(root, nodes_created as u32);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MountType::InsertAfterFlush { other_node } => {
|
||||||
|
self.stack.push_nodes_created(0);
|
||||||
|
let root = self.find_last_element(other_node).direct_id();
|
||||||
|
self.mutations.insert_after(root, nodes_created as u32);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -693,94 +703,72 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
//
|
//
|
||||||
// `shared_prefix_count` is the count of how many nodes at the start of
|
// `shared_prefix_count` is the count of how many nodes at the start of
|
||||||
// `new` and `old` share the same keys.
|
// `new` and `old` share the same keys.
|
||||||
//
|
let (left_offset, right_offset) = match self.diff_keyed_ends(old, new) {
|
||||||
// TODO: just inline this
|
Some(count) => count,
|
||||||
let shared_prefix_count = match self.diff_keyed_prefix(old, new) {
|
None => return,
|
||||||
KeyedPrefixResult::Finished => return,
|
|
||||||
KeyedPrefixResult::MoreWorkToDo(count) => count,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Next, we find out how many of the nodes at the end of the children have
|
|
||||||
// the same key. We do _not_ diff them yet, since we want to emit the change
|
|
||||||
// list instructions such that they can be applied in a single pass over the
|
|
||||||
// DOM. Instead, we just save this information for later.
|
|
||||||
//
|
|
||||||
// `shared_suffix_count` is the count of how many nodes at the end of `new`
|
|
||||||
// and `old` share the same keys.
|
|
||||||
let shared_suffix_count = old[shared_prefix_count..]
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.zip(new[shared_prefix_count..].iter().rev())
|
|
||||||
.take_while(|&(old, new)| old.key() == new.key())
|
|
||||||
.count();
|
|
||||||
|
|
||||||
let old_shared_suffix_start = old.len() - shared_suffix_count;
|
|
||||||
let new_shared_suffix_start = new.len() - shared_suffix_count;
|
|
||||||
|
|
||||||
// Ok, we now hopefully have a smaller range of children in the middle
|
// Ok, we now hopefully have a smaller range of children in the middle
|
||||||
// within which to re-order nodes with the same keys, remove old nodes with
|
// within which to re-order nodes with the same keys, remove old nodes with
|
||||||
// now-unused keys, and create new nodes with fresh keys.
|
// now-unused keys, and create new nodes with fresh keys.
|
||||||
self.diff_keyed_middle(
|
self.diff_keyed_middle(
|
||||||
&old[shared_prefix_count..old_shared_suffix_start],
|
&old[left_offset..(old.len() - right_offset)],
|
||||||
&new[shared_prefix_count..new_shared_suffix_start],
|
&new[left_offset..(new.len() - right_offset)],
|
||||||
shared_prefix_count,
|
|
||||||
shared_suffix_count,
|
|
||||||
old_shared_suffix_start,
|
|
||||||
);
|
);
|
||||||
|
|
||||||
// Finally, diff the nodes at the end of `old` and `new` that share keys.
|
|
||||||
let old_suffix = &old[old_shared_suffix_start..];
|
|
||||||
let new_suffix = &new[new_shared_suffix_start..];
|
|
||||||
debug_assert_eq!(old_suffix.len(), new_suffix.len());
|
|
||||||
if !old_suffix.is_empty() {
|
|
||||||
self.diff_keyed_suffix(old_suffix, new_suffix, new_shared_suffix_start)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Diff the prefix of children in `new` and `old` that share the same keys in
|
/// Diff both ends of the children that share keys.
|
||||||
// the same order.
|
///
|
||||||
//
|
/// Returns a left offset and right offset of that indicates a smaller section to pass onto the middle diffing.
|
||||||
// The stack is empty upon entry.
|
///
|
||||||
fn diff_keyed_prefix(
|
/// If there is no offset, then this function returns None and the diffing is complete.
|
||||||
|
fn diff_keyed_ends(
|
||||||
&mut self,
|
&mut self,
|
||||||
old: &'bump [VNode<'bump>],
|
old: &'bump [VNode<'bump>],
|
||||||
new: &'bump [VNode<'bump>],
|
new: &'bump [VNode<'bump>],
|
||||||
) -> KeyedPrefixResult {
|
) -> Option<(usize, usize)> {
|
||||||
let mut shared_prefix_count = 0;
|
let mut left_offset = 0;
|
||||||
|
|
||||||
for (old, new) in old.iter().zip(new.iter()) {
|
for (old, new) in old.iter().zip(new.iter()) {
|
||||||
// abort early if we finally run into nodes with different keys
|
// abort early if we finally run into nodes with different keys
|
||||||
if old.key() != new.key() {
|
if old.key() != new.key() {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self.diff_node(old, new);
|
self.stack.push(DiffInstruction::DiffNode { old, new });
|
||||||
shared_prefix_count += 1;
|
left_offset += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If that was all of the old children, then create and append the remaining
|
// If that was all of the old children, then create and append the remaining
|
||||||
// new children and we're finished.
|
// new children and we're finished.
|
||||||
if shared_prefix_count == old.len() {
|
if left_offset == old.len() {
|
||||||
// Load the last element
|
self.stack.create_children(
|
||||||
let last_node = self.find_last_element(new.last().unwrap()).direct_id();
|
&new[left_offset..],
|
||||||
self.mutations.push_root(last_node);
|
MountType::InsertAfter {
|
||||||
|
other_node: old.last().unwrap(),
|
||||||
// Create the new children and insert them after
|
},
|
||||||
//
|
);
|
||||||
todo!();
|
return None;
|
||||||
// let meta = self.create_children(&new[shared_prefix_count..]);
|
|
||||||
// self.mutations.insert_after(meta.added_to_stack);
|
|
||||||
|
|
||||||
return KeyedPrefixResult::Finished;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// And if that was all of the new children, then remove all of the remaining
|
// And if that was all of the new children, then remove all of the remaining
|
||||||
// old children and we're finished.
|
// old children and we're finished.
|
||||||
if shared_prefix_count == new.len() {
|
if left_offset == new.len() {
|
||||||
self.remove_nodes(&old[shared_prefix_count..]);
|
self.remove_nodes(&old[left_offset..]);
|
||||||
return KeyedPrefixResult::Finished;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyedPrefixResult::MoreWorkToDo(shared_prefix_count)
|
// if the shared prefix is less than either length, then we need to walk backwards
|
||||||
|
let mut right_offset = 0;
|
||||||
|
for (old, new) in old.iter().rev().zip(new.iter().rev()) {
|
||||||
|
// abort early if we finally run into nodes with different keys
|
||||||
|
if old.key() != new.key() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
self.diff_node(old, new);
|
||||||
|
right_offset += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Some((left_offset, right_offset))
|
||||||
}
|
}
|
||||||
|
|
||||||
// The most-general, expensive code path for keyed children diffing.
|
// The most-general, expensive code path for keyed children diffing.
|
||||||
@@ -796,14 +784,7 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
// This function will load the appropriate nodes onto the stack and do diffing in place.
|
// This function will load the appropriate nodes onto the stack and do diffing in place.
|
||||||
//
|
//
|
||||||
// Upon exit from this function, it will be restored to that same state.
|
// Upon exit from this function, it will be restored to that same state.
|
||||||
fn diff_keyed_middle(
|
fn diff_keyed_middle(&mut self, old: &'bump [VNode<'bump>], new: &'bump [VNode<'bump>]) {
|
||||||
&mut self,
|
|
||||||
old: &'bump [VNode<'bump>],
|
|
||||||
mut new: &'bump [VNode<'bump>],
|
|
||||||
shared_prefix_count: usize,
|
|
||||||
shared_suffix_count: usize,
|
|
||||||
old_shared_suffix_start: usize,
|
|
||||||
) {
|
|
||||||
/*
|
/*
|
||||||
1. Map the old keys into a numerical ordering based on indicies.
|
1. Map the old keys into a numerical ordering based on indicies.
|
||||||
2. Create a map of old key to its index
|
2. Create a map of old key to its index
|
||||||
@@ -841,39 +822,30 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
.collect::<FxHashMap<_, _>>();
|
.collect::<FxHashMap<_, _>>();
|
||||||
|
|
||||||
let mut shared_keys = FxHashSet::default();
|
let mut shared_keys = FxHashSet::default();
|
||||||
let mut to_add = FxHashSet::default();
|
|
||||||
|
|
||||||
// 3. Map each new key to the old key, carrying over the old index.
|
// 3. Map each new key to the old key, carrying over the old index.
|
||||||
let new_index_to_old_index = new
|
let new_index_to_old_index = new
|
||||||
.iter()
|
.iter()
|
||||||
.map(|n| {
|
.map(|node| {
|
||||||
let key = n.key().unwrap();
|
let key = node.key().unwrap();
|
||||||
if let Some(&index) = old_key_to_old_index.get(&key) {
|
if let Some(&index) = old_key_to_old_index.get(&key) {
|
||||||
shared_keys.insert(key);
|
shared_keys.insert(key);
|
||||||
index
|
index
|
||||||
} else {
|
} else {
|
||||||
to_add.insert(key);
|
|
||||||
u32::MAX as usize
|
u32::MAX as usize
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
// If none of the old keys are reused by the new children, then we
|
// If none of the old keys are reused by the new children, then we remove all the remaining old children and
|
||||||
// remove all the remaining old children and create the new children
|
// create the new children afresh.
|
||||||
// afresh.
|
if shared_keys.is_empty() {
|
||||||
if shared_suffix_count == 0 && shared_keys.is_empty() {
|
|
||||||
self.replace_and_create_many_with_many(old, new);
|
self.replace_and_create_many_with_many(old, new);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Compute the LIS of this list
|
// 4. Compute the LIS of this list
|
||||||
|
// TODO: investigate if we can go without the hashset here, I can't quite tell from the LIS crate
|
||||||
// The longest increasing subsequence within `new_index_to_old_index`. This
|
|
||||||
// is the longest sequence on DOM nodes in `old` that are relatively ordered
|
|
||||||
// correctly within `new`. We will leave these nodes in place in the DOM,
|
|
||||||
// and only move nodes that are not part of the LIS. This results in the
|
|
||||||
// maximum number of DOM nodes left in place, AKA the minimum number of DOM
|
|
||||||
// nodes moved.
|
|
||||||
let mut new_index_is_in_lis = FxHashSet::default();
|
let mut new_index_is_in_lis = FxHashSet::default();
|
||||||
new_index_is_in_lis.reserve(new_index_to_old_index.len());
|
new_index_is_in_lis.reserve(new_index_to_old_index.len());
|
||||||
|
|
||||||
@@ -888,141 +860,50 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
&mut starts,
|
&mut starts,
|
||||||
);
|
);
|
||||||
|
|
||||||
// use the old nodes to navigate the new nodes
|
// REMEMBER: we're generating instructions. we cannot rely on anything stack related to be consistent.
|
||||||
let mut lis_in_order = new_index_is_in_lis.into_iter().collect::<Vec<_>>();
|
|
||||||
lis_in_order.sort_unstable();
|
|
||||||
|
|
||||||
// we walk front to back, creating the head node
|
// walk the new list, creating nodes or diffing them. if we hit an LIS, then we call "insert before"
|
||||||
// diff the shared, in-place nodes first
|
let mut last_lis = 0;
|
||||||
// this makes sure we can rely on their first/last nodes being correct later on
|
|
||||||
for id in &lis_in_order {
|
|
||||||
let new_node = &new[*id];
|
|
||||||
let key = new_node.key().unwrap();
|
|
||||||
let old_index = old_key_to_old_index.get(&key).unwrap();
|
|
||||||
let old_node = &old[*old_index];
|
|
||||||
self.diff_node(old_node, new_node);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return the old node from the key
|
self.stack.push_nodes_created(0);
|
||||||
let load_old_node_from_lsi = |key| -> &VNode {
|
for (idx, new_node) in new.into_iter().enumerate().rev() {
|
||||||
let old_index = old_key_to_old_index.get(key).unwrap();
|
let old_index = new_index_to_old_index[idx];
|
||||||
let old_node = &old[*old_index];
|
|
||||||
old_node
|
|
||||||
};
|
|
||||||
|
|
||||||
let mut root = None;
|
if old_index == u32::MAX as usize {
|
||||||
let mut new_iter = new.iter().enumerate();
|
self.stack.create_node(new_node, MountType::Absorb);
|
||||||
for lis_id in &lis_in_order {
|
|
||||||
eprintln!("tracking {:?}", lis_id);
|
|
||||||
// this is the next milestone node we are working up to
|
|
||||||
let new_anchor = &new[*lis_id];
|
|
||||||
root = Some(new_anchor);
|
|
||||||
|
|
||||||
// let anchor_el = self.find_first_element(new_anchor);
|
|
||||||
// self.mutations.push_root(anchor_el.direct_id());
|
|
||||||
// // let mut pushed = false;
|
|
||||||
|
|
||||||
'inner: loop {
|
|
||||||
let (next_id, next_new) = new_iter.next().unwrap();
|
|
||||||
if next_id == *lis_id {
|
|
||||||
// we've reached the milestone, break this loop so we can step to the next milestone
|
|
||||||
// remember: we already diffed this node
|
|
||||||
eprintln!("breaking {:?}", next_id);
|
|
||||||
break 'inner;
|
|
||||||
} else {
|
|
||||||
let key = next_new.key().unwrap();
|
|
||||||
eprintln!("found key {:?}", key);
|
|
||||||
if shared_keys.contains(&key) {
|
|
||||||
eprintln!("key is contained {:?}", key);
|
|
||||||
shared_keys.remove(key);
|
|
||||||
// diff the two nodes
|
|
||||||
let old_node = load_old_node_from_lsi(key);
|
|
||||||
self.diff_node(old_node, next_new);
|
|
||||||
|
|
||||||
// now move all the nodes into the right spot
|
|
||||||
for child in RealChildIterator::new(next_new, self.vdom) {
|
|
||||||
let el = child.direct_id();
|
|
||||||
self.mutations.push_root(el);
|
|
||||||
todo!();
|
|
||||||
// self.mutations.insert_before(1);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.stack.create_node(
|
|
||||||
next_new,
|
|
||||||
MountType::InsertBefore {
|
|
||||||
other_node: new_anchor,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.mutations.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
let final_lis_node = root.unwrap();
|
|
||||||
let final_el_node = self.find_last_element(final_lis_node);
|
|
||||||
let final_el = final_el_node.direct_id();
|
|
||||||
self.mutations.push_root(final_el);
|
|
||||||
|
|
||||||
let mut last_iter = new.iter().rev().enumerate();
|
|
||||||
let last_key = final_lis_node.key().unwrap();
|
|
||||||
loop {
|
|
||||||
let (last_id, last_node) = last_iter.next().unwrap();
|
|
||||||
let key = last_node.key().unwrap();
|
|
||||||
|
|
||||||
eprintln!("checking final nodes {:?}", key);
|
|
||||||
|
|
||||||
if last_key == key {
|
|
||||||
eprintln!("breaking final nodes");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if shared_keys.contains(&key) {
|
|
||||||
eprintln!("key is contained {:?}", key);
|
|
||||||
shared_keys.remove(key);
|
|
||||||
// diff the two nodes
|
|
||||||
let old_node = load_old_node_from_lsi(key);
|
|
||||||
self.diff_node(old_node, last_node);
|
|
||||||
|
|
||||||
// now move all the nodes into the right spot
|
|
||||||
for child in RealChildIterator::new(last_node, self.vdom) {
|
|
||||||
let el = child.direct_id();
|
|
||||||
self.mutations.push_root(el);
|
|
||||||
// self.mutations.insert_after(1);
|
|
||||||
todo!();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
eprintln!("key is not contained {:?}", key);
|
// diff / move
|
||||||
// new node needs to be created
|
if let Some(new_index) = new_index_is_in_lis.get(&idx) {
|
||||||
// insert it before the current milestone
|
// take all the nodes on the stack and insert them before this one
|
||||||
todo!();
|
self.stack.push(DiffInstruction::Mount {
|
||||||
// let meta = self.create_vnode(last_node);
|
and: MountType::InsertAfterFlush {
|
||||||
// self.mutations.insert_after(meta.added_to_stack);
|
other_node: new_node,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
self.stack.push(DiffInstruction::DiffNode {
|
||||||
|
new: new_node,
|
||||||
|
old: &old[old_index],
|
||||||
|
});
|
||||||
|
last_lis = *new_index;
|
||||||
|
} else {
|
||||||
|
// this is not an LIS node, we need to diff it and move it
|
||||||
|
self.stack
|
||||||
|
.push(DiffInstruction::PrepareMoveNode { node: new_node });
|
||||||
|
self.stack.push(DiffInstruction::DiffNode {
|
||||||
|
new: new_node,
|
||||||
|
old: &old[old_index],
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.mutations.pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Diff the suffix of keyed children that share the same keys in the same order.
|
// There will be nodes left on top of the stack. They need to be inserted before the final
|
||||||
//
|
let last_node = &old[last_lis];
|
||||||
// The parent must be on the change list stack when we enter this function:
|
self.stack.push(DiffInstruction::Mount {
|
||||||
//
|
and: MountType::InsertBefore {
|
||||||
// [... parent]
|
other_node: last_node,
|
||||||
//
|
},
|
||||||
// When this function exits, the change list stack remains the same.
|
});
|
||||||
fn diff_keyed_suffix(
|
|
||||||
&mut self,
|
|
||||||
old: &'bump [VNode<'bump>],
|
|
||||||
new: &'bump [VNode<'bump>],
|
|
||||||
new_shared_suffix_start: usize,
|
|
||||||
) {
|
|
||||||
debug_assert_eq!(old.len(), new.len());
|
|
||||||
debug_assert!(!old.is_empty());
|
|
||||||
|
|
||||||
for (old_child, new_child) in old.iter().zip(new.iter()) {
|
|
||||||
self.diff_node(old_child, new_child);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// =====================
|
// =====================
|
||||||
@@ -1075,14 +956,6 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_many_with_many(&mut self, old: &'bump [VNode<'bump>], new: &'bump [VNode<'bump>]) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replace_one_with_many(&mut self, old: &'bump VNode<'bump>, new: &'bump [VNode<'bump>]) {
|
|
||||||
self.stack.create_children(new, MountType::Replace { old });
|
|
||||||
}
|
|
||||||
|
|
||||||
fn replace_and_create_many_with_one(
|
fn replace_and_create_many_with_one(
|
||||||
&mut self,
|
&mut self,
|
||||||
old: &'bump [VNode<'bump>],
|
old: &'bump [VNode<'bump>],
|
||||||
@@ -1230,15 +1103,6 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn replace_node_with_node(
|
|
||||||
&mut self,
|
|
||||||
old_node: &'bump VNode<'bump>,
|
|
||||||
new_node: &'bump VNode<'bump>,
|
|
||||||
) {
|
|
||||||
self.stack
|
|
||||||
.create_node(new_node, MountType::Replace { old: old_node });
|
|
||||||
}
|
|
||||||
|
|
||||||
fn fix_listener<'a>(&mut self, listener: &'a Listener<'a>) {
|
fn fix_listener<'a>(&mut self, listener: &'a Listener<'a>) {
|
||||||
let scope_id = self.stack.current_scope();
|
let scope_id = self.stack.current_scope();
|
||||||
if let Some(scope_id) = scope_id {
|
if let Some(scope_id) = scope_id {
|
||||||
@@ -1249,12 +1113,3 @@ impl<'bump> DiffMachine<'bump> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
enum KeyedPrefixResult {
|
|
||||||
// Fast path: we finished diffing all the children just by looking at the
|
|
||||||
// prefix of shared keys!
|
|
||||||
Finished,
|
|
||||||
// There is more diffing work to do. Here is a count of how many children at
|
|
||||||
// the beginning of `new` and `old` we already processed.
|
|
||||||
MoreWorkToDo(usize),
|
|
||||||
}
|
|
||||||
@@ -18,6 +18,11 @@ pub enum DiffInstruction<'a> {
|
|||||||
node: &'a VNode<'a>,
|
node: &'a VNode<'a>,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/// pushes the node elements onto the stack for use in mount
|
||||||
|
PrepareMoveNode {
|
||||||
|
node: &'a VNode<'a>,
|
||||||
|
},
|
||||||
|
|
||||||
Mount {
|
Mount {
|
||||||
and: MountType<'a>,
|
and: MountType<'a>,
|
||||||
},
|
},
|
||||||
@@ -34,6 +39,7 @@ pub enum MountType<'a> {
|
|||||||
Replace { old: &'a VNode<'a> },
|
Replace { old: &'a VNode<'a> },
|
||||||
ReplaceByElementId { el: ElementId },
|
ReplaceByElementId { el: ElementId },
|
||||||
InsertAfter { other_node: &'a VNode<'a> },
|
InsertAfter { other_node: &'a VNode<'a> },
|
||||||
|
InsertAfterFlush { other_node: &'a VNode<'a> },
|
||||||
InsertBefore { other_node: &'a VNode<'a> },
|
InsertBefore { other_node: &'a VNode<'a> },
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,6 +80,10 @@ impl<'bump> DiffStack<'bump> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn push_nodes_created(&mut self, count: usize) {
|
||||||
|
self.nodes_created_stack.push(count);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn create_node(&mut self, node: &'bump VNode<'bump>, and: MountType<'bump>) {
|
pub fn create_node(&mut self, node: &'bump VNode<'bump>, and: MountType<'bump>) {
|
||||||
self.nodes_created_stack.push(0);
|
self.nodes_created_stack.push(0);
|
||||||
self.instructions.push(DiffInstruction::Mount { and });
|
self.instructions.push(DiffInstruction::Mount { and });
|
||||||
|
|||||||
Reference in new issue
Block a user