WIP: moving to CbIdx as serializable event system

This commit is contained in:
Jonathan Kelley committed 2021-02-27 11:43:28 -05:00
1 parent e4b1f6ea0d
commit e840f472fa
9 files changed
+160 -200

No files matched your search

+49 -23
View File
@@ -37,7 +37,7 @@ use fxhash::{FxHashMap, FxHashSet};
use generational_arena::Index;
use crate::{
changelist::{Edit, EditList, EditMachine},
changelist::{CbIdx, Edit, EditList, EditMachine},
innerlude::{Attribute, Listener, Scope, VElement, VNode, VText},
virtual_dom::LifecycleEvent,
};
@@ -61,16 +61,20 @@ pub struct DiffMachine<'a> {
immediate_queue: Vec<Index>,
diffed: FxHashSet<Index>,
need_to_diff: FxHashSet<Index>,
// Current scopes we're comparing
current_idx: Option<generational_arena::Index>,
}
impl<'a> DiffMachine<'a> {
pub fn new(bump: &'a Bump) -> Self {
log::debug!("starsting diff machine");
log::debug!("starting diff machine");
Self {
change_list: EditMachine::new(bump),
immediate_queue: Vec::new(),
diffed: FxHashSet::default(),
need_to_diff: FxHashSet::default(),
current_idx: None,
}
}
@@ -78,8 +82,17 @@ impl<'a> DiffMachine<'a> {
self.change_list.emitter
}
pub fn diff_node(&mut self, old: &VNode<'a>, new: &VNode<'a>) {
pub fn diff_node(
&mut self,
old: &VNode<'a>,
new: &VNode<'a>,
scope: Option<generational_arena::Index>,
) {
log::debug!("Diffing nodes");
// Set it while diffing
// Reset it when finished diffing
self.current_idx = scope;
/*
For each valid case, we "commit traversal", meaning we save this current position in the tree.
Then, we diff and queue an edit event (via chagelist). s single trees - when components show up, we save that traversal and then re-enter later.
@@ -222,6 +235,7 @@ impl<'a> DiffMachine<'a> {
todo!("Suspended components not currently available")
}
}
self.current_idx = None;
}
// Diff event listeners between `old` and `new`.
@@ -237,16 +251,20 @@ impl<'a> DiffMachine<'a> {
}
'outer1: for new_l in new {
unsafe {
// Safety relies on removing `new_l` from the registry manually at
// the end of its lifetime. This happens below in the `'outer2`
// loop, and elsewhere in diffing when removing old dom trees.
// registry.add(new_l);
}
// unsafe {
// Safety relies on removing `new_l` from the registry manually at
// the end of its lifetime. This happens below in the `'outer2`
// loop, and elsewhere in diffing when removing old dom trees.
// registry.add(new_l);
// }
for old_l in old {
for (l_idx, old_l) in old.iter().enumerate() {
if new_l.event == old_l.event {
self.change_list.update_event_listener(new_l);
let event_type = new_l.event;
if let Some(scope) = self.current_idx {
let cb = CbIdx::from_gi_index(scope, l_idx);
self.change_list.update_event_listener(event_type, cb);
}
continue 'outer1;
}
}
@@ -507,7 +525,7 @@ impl<'a> DiffMachine<'a> {
self.change_list.go_to_sibling(i);
self.diff_node(old, new);
self.diff_node(old, new, self.current_idx);
shared_prefix_count += 1;
}
@@ -705,7 +723,7 @@ impl<'a> DiffMachine<'a> {
// [... parent]
self.change_list.go_down_to_temp_child(temp);
// [... parent last]
self.diff_node(&old[old_index], last);
self.diff_node(&old[old_index], last, self.current_idx);
if new_index_is_in_lis.contains(&last_index) {
// Don't move it, since it is already where it needs to be.
@@ -758,7 +776,7 @@ impl<'a> DiffMachine<'a> {
// [... parent new_child]
}
self.diff_node(&old[old_index], new_child);
self.diff_node(&old[old_index], new_child, self.current_idx);
}
}
@@ -789,8 +807,7 @@ impl<'a> DiffMachine<'a> {
for (i, (old_child, new_child)) in old.iter().zip(new.iter()).enumerate() {
self.change_list.go_to_sibling(new_shared_suffix_start + i);
self.diff_node(old_child, new_child);
self.diff_node(old_child, new_child, self.current_idx);
}
// [... parent]
@@ -818,7 +835,7 @@ impl<'a> DiffMachine<'a> {
// [... parent prev_child]
self.change_list.go_to_sibling(i);
// [... parent this_child]
self.diff_node(old_child, new_child);
self.diff_node(old_child, new_child, self.current_idx);
}
match old.len().cmp(&new.len()) {
@@ -880,12 +897,21 @@ impl<'a> DiffMachine<'a> {
self.change_list.create_element(tag_name);
}
for l in listeners {
// unsafe {
// registry.add(l);
// }
self.change_list.new_event_listener(l);
}
listeners.iter().enumerate().for_each(|(id, listener)| {
if let Some(index) = self.current_idx {
self.change_list
.new_event_listener(listener.event, CbIdx::from_gi_index(index, id));
} else {
// Don't panic
// Used for testing
log::trace!("Failed to set listener, create was not called in the context of the virtual dom");
}
});
// for l in listeners {
// unsafe {
// registry.add(l);
// }
// }
for attr in attributes {
self.change_list