From 795a54a2e427bc7f2b37e636d50aa300977a42a1 Mon Sep 17 00:00:00 2001 From: Jonathan Kelley Date: Sat, 5 Jun 2021 23:38:51 -0400 Subject: [PATCH] wip: new approach at direct access to vdom This commit starts the process of merging scope arena with the diff machine to give the diffing algorithm mutable access to components. React and Preact mutate the dom as they diff it which makes their implementations simpler and cleaner. The goal here is to give access of scopes to the diffing machine which can mutate the underyling representation during diffing. --- packages/core/src/diff.rs | 6 ++++-- packages/core/src/virtual_dom.rs | 21 +++++++++++---------- 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/packages/core/src/diff.rs b/packages/core/src/diff.rs index d13793d6f..88c2b3331 100644 --- a/packages/core/src/diff.rs +++ b/packages/core/src/diff.rs @@ -32,7 +32,7 @@ //! //! More info on how to improve this diffing algorithm: //! - https://hacks.mozilla.org/2019/03/fast-bump-allocated-virtual-doms-with-rust-and-wasm/ -use crate::innerlude::*; +use crate::{arena::ScopeArena, innerlude::*}; use bumpalo::Bump; use fxhash::{FxHashMap, FxHashSet}; use generational_arena::Arena; @@ -62,6 +62,7 @@ pub struct DiffMachine<'a> { pub change_list: EditMachine<'a>, pub diffed: FxHashSet, pub lifecycle_events: VecDeque>, + pub vdom: ScopeArena, } pub enum LifeCycleEvent<'a> { Mount { @@ -97,8 +98,9 @@ fn get_id() -> u32 { } impl<'a> DiffMachine<'a> { - pub fn new() -> Self { + pub fn new(vdom: ScopeArena) -> Self { Self { + vdom, create_diffs: true, lifecycle_events: VecDeque::new(), change_list: EditMachine::new(), diff --git a/packages/core/src/virtual_dom.rs b/packages/core/src/virtual_dom.rs index b84e79101..34adc4335 100644 --- a/packages/core/src/virtual_dom.rs +++ b/packages/core/src/virtual_dom.rs @@ -175,20 +175,21 @@ impl VirtualDom { /// Performs a *full* rebuild of the virtual dom, returning every edit required to generate the actual dom rom scratch /// Currently this doesn't do what we want it to do pub fn rebuild<'s>(&'s mut self) -> Result> { - let mut diff_machine = DiffMachine::new(); + todo!() + // let mut diff_machine = DiffMachine::new(); - // Schedule an update and then immediately call it on the root component - // This is akin to a hook being called from a listener and requring a re-render - // Instead, this is done on top-level component + // // Schedule an update and then immediately call it on the root component + // // This is akin to a hook being called from a listener and requring a re-render + // // Instead, this is done on top-level component - let base = self.components.try_get(self.base_scope)?; + // let base = self.components.try_get(self.base_scope)?; - let update = &base.event_channel; - update(); + // let update = &base.event_channel; + // update(); - self.progress_completely(&mut diff_machine)?; + // self.progress_completely(&mut diff_machine)?; - Ok(diff_machine.consume()) + // Ok(diff_machine.consume()) } pub fn base_scope(&self) -> &Scope { @@ -248,7 +249,7 @@ impl VirtualDom { self.components.try_get_mut(id)?.call_listener(event)?; - let mut diff_machine = DiffMachine::new(); + let mut diff_machine = DiffMachine::new(self.components.clone()); self.progress_completely(&mut diff_machine)?; Ok(diff_machine.consume())