ソースを参照

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.
Jonathan Kelley 4 年 前
コミット
795a54a
2 ファイル変更15 行追加12 行削除
  1. 4 2
      packages/core/src/diff.rs
  2. 11 10
      packages/core/src/virtual_dom.rs

+ 4 - 2
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<ScopeIdx>,
     pub lifecycle_events: VecDeque<LifeCycleEvent<'a>>,
+    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(),

+ 11 - 10
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<EditList<'s>> {
-        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())