Sfoglia il codice sorgente

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 anni fa
parent
commit
795a54a
2 ha cambiato i file con 15 aggiunte e 12 eliminazioni
  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())