Browse Source

WIP make ECS work with reactive system

Evan Almloff 2 years ago
parent
commit
1587b41829

+ 1 - 1
packages/native-core/Cargo.toml

@@ -20,7 +20,7 @@ smallvec = "1.6"
 rustc-hash = "1.1.0"
 rustc-hash = "1.1.0"
 anymap = "1.0.0-beta.2"
 anymap = "1.0.0-beta.2"
 slab = "0.4"
 slab = "0.4"
-parking_lot = "0.12.1"
+parking_lot = { version = "0.12.1", features = ["send_guard"] }
 crossbeam-deque = "0.8.2"
 crossbeam-deque = "0.8.2"
 dashmap = "5.4.0"
 dashmap = "5.4.0"
 hashbrown = { version = "0.13.2", features = ["raw"] }
 hashbrown = { version = "0.13.2", features = ["raw"] }

+ 0 - 2
packages/native-core/src/lib.rs

@@ -5,7 +5,6 @@ pub use node_ref::NodeMask;
 pub use passes::AnyMapLike;
 pub use passes::AnyMapLike;
 pub use passes::{Dependancy, Pass, TypeErasedPass};
 pub use passes::{Dependancy, Pass, TypeErasedPass};
 use rustc_hash::FxHasher;
 use rustc_hash::FxHasher;
-pub use state::State;
 pub use tree::NodeId;
 pub use tree::NodeId;
 
 
 pub mod layout_attributes;
 pub mod layout_attributes;
@@ -13,7 +12,6 @@ pub mod node;
 pub mod node_ref;
 pub mod node_ref;
 mod passes;
 mod passes;
 pub mod real_dom;
 pub mod real_dom;
-pub mod state;
 pub mod tree;
 pub mod tree;
 pub mod utils;
 pub mod utils;
 
 

+ 7 - 19
packages/native-core/src/node.rs

@@ -1,17 +1,8 @@
-use crate::{state::State, tree::NodeId};
+use crate::tree::NodeId;
 use dioxus_core::{AnyValue, BorrowedAttributeValue, ElementId};
 use dioxus_core::{AnyValue, BorrowedAttributeValue, ElementId};
 use rustc_hash::{FxHashMap, FxHashSet};
 use rustc_hash::{FxHashMap, FxHashSet};
 use std::fmt::Debug;
 use std::fmt::Debug;
 
 
-/// The node is stored client side and stores only basic data about the node.
-#[derive(Debug, Clone)]
-pub struct Node<S: State<V>, V: FromAnyValue = ()> {
-    /// The transformed state of the node.
-    pub state: S,
-    /// The raw data for the node
-    pub node_data: NodeData<V>,
-}
-
 #[derive(Debug, Clone)]
 #[derive(Debug, Clone)]
 pub struct NodeData<V: FromAnyValue = ()> {
 pub struct NodeData<V: FromAnyValue = ()> {
     /// The id of the node
     /// The id of the node
@@ -38,21 +29,18 @@ pub enum NodeType<V: FromAnyValue = ()> {
     Placeholder,
     Placeholder,
 }
 }
 
 
-impl<S: State<V>, V: FromAnyValue> Node<S, V> {
+impl<V: FromAnyValue> NodeData<V> {
     pub(crate) fn new(node_type: NodeType<V>) -> Self {
     pub(crate) fn new(node_type: NodeType<V>) -> Self {
-        Node {
-            state: S::default(),
-            node_data: NodeData {
-                element_id: None,
-                node_type,
-                node_id: NodeId(0),
-            },
+        NodeData {
+            element_id: None,
+            node_type,
+            node_id: NodeId(0),
         }
         }
     }
     }
 
 
     /// get the mounted id of the node
     /// get the mounted id of the node
     pub fn mounted_id(&self) -> Option<ElementId> {
     pub fn mounted_id(&self) -> Option<ElementId> {
-        self.node_data.element_id
+        self.element_id
     }
     }
 }
 }
 
 

+ 37 - 1
packages/native-core/src/node_ref.rs

@@ -1,11 +1,47 @@
+use std::cmp::Ordering;
+
 use dioxus_core::ElementId;
 use dioxus_core::ElementId;
 
 
 use crate::{
 use crate::{
     node::{ElementNode, FromAnyValue, NodeData, NodeType, OwnedAttributeView},
     node::{ElementNode, FromAnyValue, NodeData, NodeType, OwnedAttributeView},
-    state::union_ordered_iter,
     NodeId,
     NodeId,
 };
 };
 
 
+/// Join two sorted iterators
+pub(crate) fn union_ordered_iter<'a>(
+    s_iter: impl Iterator<Item = &'a str>,
+    o_iter: impl Iterator<Item = &'a str>,
+    new_len_guess: usize,
+) -> Vec<String> {
+    let mut s_peekable = s_iter.peekable();
+    let mut o_peekable = o_iter.peekable();
+    let mut v = Vec::with_capacity(new_len_guess);
+    while let Some(s_i) = s_peekable.peek() {
+        while let Some(o_i) = o_peekable.peek() {
+            match o_i.cmp(s_i) {
+                Ordering::Greater => {
+                    break;
+                }
+                Ordering::Less => {
+                    v.push(o_peekable.next().unwrap().to_string());
+                }
+                Ordering::Equal => {
+                    o_peekable.next();
+                    break;
+                }
+            }
+        }
+        v.push(s_peekable.next().unwrap().to_string());
+    }
+    for o_i in o_peekable {
+        v.push(o_i.to_string());
+    }
+    for w in v.windows(2) {
+        debug_assert!(w[1] > w[0]);
+    }
+    v
+}
+
 /// A view into a [VNode] with limited access.
 /// A view into a [VNode] with limited access.
 #[derive(Debug)]
 #[derive(Debug)]
 pub struct NodeView<'a, V: FromAnyValue = ()> {
 pub struct NodeView<'a, V: FromAnyValue = ()> {

+ 173 - 193
packages/native-core/src/passes.rs

@@ -1,18 +1,115 @@
 use anymap::AnyMap;
 use anymap::AnyMap;
+use parking_lot::RwLock;
 use rustc_hash::FxHashSet;
 use rustc_hash::FxHashSet;
-use std::any::{Any, TypeId};
+use std::any::{self, Any, TypeId};
 use std::collections::BTreeMap;
 use std::collections::BTreeMap;
+use std::marker::PhantomData;
 use std::sync::Arc;
 use std::sync::Arc;
 
 
-use crate::node::{FromAnyValue, Node};
+use crate::node::{FromAnyValue, NodeData};
 use crate::node_ref::NodeView;
 use crate::node_ref::NodeView;
-use crate::state::State;
-use crate::tree::TreeViewMut;
-use crate::tree::{Tree, TreeView};
+use crate::real_dom::RealDom;
+use crate::tree::{Node, TreeStateView};
 use crate::{FxDashMap, FxDashSet, SendAnyMap};
 use crate::{FxDashMap, FxDashSet, SendAnyMap};
 use crate::{NodeId, NodeMask};
 use crate::{NodeId, NodeMask};
 
 
-pub trait Pass<V: FromAnyValue = ()>: Any {
+#[derive(Default)]
+struct DirtyNodes {
+    passes_dirty: Vec<u64>,
+}
+
+impl DirtyNodes {
+    pub fn add_node(&mut self, node_id: NodeId) {
+        let node_id = node_id.0;
+        let index = node_id / 64;
+        let bit = node_id % 64;
+        let encoded = 1 << bit;
+        if let Some(passes) = self.passes_dirty.get_mut(index) {
+            *passes |= encoded;
+        } else {
+            self.passes_dirty.resize(index + 1, 0);
+            self.passes_dirty[index] |= encoded;
+        }
+    }
+
+    pub fn is_empty(&self) -> bool {
+        self.passes_dirty.iter().all(|dirty| *dirty == 0)
+    }
+
+    pub fn pop(&mut self) -> Option<NodeId> {
+        let index = self.passes_dirty.iter().position(|dirty| *dirty != 0)?;
+        let passes = self.passes_dirty[index];
+        let node_id = passes.trailing_zeros();
+        let encoded = 1 << node_id;
+        self.passes_dirty[index] &= !encoded;
+        Some(NodeId((index * 64) + node_id as usize))
+    }
+}
+
+#[derive(Default, Clone)]
+pub struct DirtyNodeStates {
+    dirty: Arc<RwLock<BTreeMap<u16, FxDashMap<TypeId, DirtyNodes>>>>,
+}
+
+impl DirtyNodeStates {
+    pub fn insert(&self, pass_id: TypeId, node_id: NodeId, height: u16) {
+        let mut dirty = self.dirty.write();
+        if let Some(dirty) = dirty.get_mut(&height) {
+            if let Some(mut entry) = dirty.get_mut(&pass_id) {
+                entry.add_node(node_id);
+            } else {
+                let mut entry = DirtyNodes::default();
+                entry.add_node(node_id);
+                dirty.insert(pass_id, entry);
+            }
+        } else {
+            let mut entry = DirtyNodes::default();
+            entry.add_node(node_id);
+            let hm = FxDashMap::default();
+            hm.insert(pass_id, entry);
+            dirty.insert(height, hm);
+        }
+    }
+
+    fn pop_front(&self, pass_id: TypeId) -> Option<(u16, NodeId)> {
+        let dirty_read = self.dirty.read();
+        let (&height, values) = dirty_read
+            .iter()
+            .find(|(_, values)| values.contains_key(&pass_id))?;
+        let mut dirty = values.get_mut(&pass_id)?;
+        let node_id = dirty.pop()?;
+        if dirty.is_empty() {
+            values.remove(&pass_id);
+        }
+        if values.is_empty() {
+            let mut dirty_write = self.dirty.write();
+            dirty_write.remove(&height);
+        }
+
+        Some((height, node_id))
+    }
+
+    fn pop_back(&self, pass_id: TypeId) -> Option<(u16, NodeId)> {
+        let dirty_read = self.dirty.read();
+        let (&height, values) = dirty_read
+            .iter()
+            .rev()
+            .find(|(_, values)| values.contains_key(&pass_id))?;
+        let mut dirty = values.get_mut(&pass_id)?;
+        let node_id = dirty.pop()?;
+        if dirty.is_empty() {
+            values.remove(&pass_id);
+        }
+        if values.is_empty() {
+            let mut dirty_write = self.dirty.write();
+            dirty_write.remove(&height);
+        }
+
+        Some((height, node_id))
+    }
+}
+
+pub trait Pass<V: FromAnyValue + Send = ()>: Any {
     /// This is a tuple of (T: Any, ..)
     /// This is a tuple of (T: Any, ..)
     type ParentDependencies: Dependancy;
     type ParentDependencies: Dependancy;
     /// This is a tuple of (T: Any, ..)
     /// This is a tuple of (T: Any, ..)
@@ -26,23 +123,21 @@ pub trait Pass<V: FromAnyValue = ()>: Any {
         node_view: NodeView<V>,
         node_view: NodeView<V>,
         node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
         node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
         parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
         parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-        children: Option<
-            impl Iterator<Item = <Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
-        >,
+        children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
         context: &SendAnyMap,
         context: &SendAnyMap,
     ) -> bool;
     ) -> bool;
 
 
     fn validate() {
     fn validate() {
         // no type can be a child and parent dependency
         // no type can be a child and parent dependency
-        for type_id in Self::parent_type_ids() {
-            for type_id2 in Self::child_type_ids() {
+        for type_id in Self::parent_type_ids().into_iter().copied() {
+            for type_id2 in Self::child_type_ids().into_iter().copied() {
                 if type_id == type_id2 {
                 if type_id == type_id2 {
                     panic!("type cannot be both a parent and child dependency");
                     panic!("type cannot be both a parent and child dependency");
                 }
                 }
             }
             }
         }
         }
         // this type should not be a node dependency
         // this type should not be a node dependency
-        for type_id in Self::node_type_ids() {
+        for type_id in Self::node_type_ids().into_iter().copied() {
             if type_id == TypeId::of::<Self>() {
             if type_id == TypeId::of::<Self>() {
                 panic!("The current type cannot be a node dependency");
                 panic!("The current type cannot be a node dependency");
             }
             }
@@ -58,85 +153,74 @@ pub trait Pass<V: FromAnyValue = ()>: Any {
         }
         }
     }
     }
 
 
-    fn to_type_erased<T: AnyMapLike + State<V>>() -> TypeErasedPass<T, V>
+    fn to_type_erased() -> TypeErasedPass<V>
     where
     where
         Self: Sized,
         Self: Sized,
     {
     {
         Self::validate();
         Self::validate();
         TypeErasedPass {
         TypeErasedPass {
             this_type_id: TypeId::of::<Self>(),
             this_type_id: TypeId::of::<Self>(),
-            combined_dependancy_type_ids: Self::all_dependanices().into_iter().collect(),
+            combined_dependancy_type_ids: Self::all_dependanices().into_iter().copied().collect(),
             parent_dependant: !Self::parent_type_ids().is_empty(),
             parent_dependant: !Self::parent_type_ids().is_empty(),
             child_dependant: !Self::child_type_ids().is_empty(),
             child_dependant: !Self::child_type_ids().is_empty(),
             dependants: FxHashSet::default(),
             dependants: FxHashSet::default(),
             mask: Self::NODE_MASK,
             mask: Self::NODE_MASK,
             pass_direction: Self::pass_direction(),
             pass_direction: Self::pass_direction(),
             pass: Box::new(
             pass: Box::new(
-                |node_id: NodeId, any_map: &mut Tree<Node<T, V>>, context: &SendAnyMap| {
-                    let (current_node, parent, children) = any_map
-                        .node_parent_children_mut(node_id)
-                        .expect("tried to run pass on node that does not exist");
-                    let current_node_raw = current_node as *mut Node<T, V>;
-                    let node = Self::NodeDependencies::borrow_elements_from(&current_node.state)
-                        .expect("tried to get a pass that does not exist");
-                    let parent = parent.map(|parent| {
-                        Self::ParentDependencies::borrow_elements_from(&parent.state)
-                            .expect("tried to get a pass that does not exist")
-                    });
-                    let children = children.map(|children| {
-                        children.map(|child| {
-                            Self::ChildDependencies::borrow_elements_from(&child.state)
-                                .expect("tried to get a pass that does not exist")
-                        })
-                    });
-                    // safety: we have varified the pass is valid in the is_valid function
-                    let myself: &mut Self = unsafe {
-                        (*current_node_raw)
-                            .state
-                            .get_mut()
-                            .expect("tried to get a pass that does not exist")
-                    };
+                |node_id: NodeId, tree: &mut TreeStateView, context: &SendAnyMap| {
+                    debug_assert!(!Self::NodeDependencies::type_ids()
+                        .into_iter()
+                        .any(|id| *id == TypeId::of::<Self>()));
+                    // get all of the states from the tree view
+                    // Safety: No node has itself as a parent or child.
+                    let node_raw = tree.get_mut::<Self>(node_id).unwrap() as *mut Self;
+                    let node_data = tree.get_single::<NodeData<V>>(node_id).unwrap();
+                    let node = tree.get::<Self::NodeDependencies>(node_id).unwrap();
+                    let children = tree.children::<Self::ChildDependencies>(node_id);
+                    let parent = tree.parent::<Self::ParentDependencies>(node_id);
+                    let myself = unsafe { &mut *node_raw };
+
                     myself.pass(
                     myself.pass(
-                        NodeView::new(&current_node.node_data, Self::NODE_MASK),
+                        NodeView::new(&node_data, Self::NODE_MASK),
                         node,
                         node,
                         parent,
                         parent,
                         children,
                         children,
                         context,
                         context,
                     )
                     )
                 },
                 },
-            )
-                as Box<dyn Fn(NodeId, &mut Tree<Node<T, V>>, &SendAnyMap) -> bool + Send + Sync>,
+            ) as PassCallback,
+            phantom: PhantomData,
         }
         }
     }
     }
 
 
-    fn parent_type_ids() -> Vec<TypeId> {
+    fn parent_type_ids() -> Box<[TypeId]> {
         Self::ParentDependencies::type_ids()
         Self::ParentDependencies::type_ids()
     }
     }
 
 
-    fn child_type_ids() -> Vec<TypeId> {
+    fn child_type_ids() -> Box<[TypeId]> {
         Self::ChildDependencies::type_ids()
         Self::ChildDependencies::type_ids()
     }
     }
 
 
-    fn node_type_ids() -> Vec<TypeId> {
+    fn node_type_ids() -> Box<[TypeId]> {
         Self::NodeDependencies::type_ids()
         Self::NodeDependencies::type_ids()
     }
     }
 
 
-    fn all_dependanices() -> Vec<TypeId> {
-        let mut dependencies = Self::parent_type_ids();
-        dependencies.extend(Self::child_type_ids());
-        dependencies.extend(Self::node_type_ids());
-        dependencies
+    fn all_dependanices() -> Box<[TypeId]> {
+        let mut dependencies = Self::parent_type_ids().to_vec();
+        dependencies.extend(Self::child_type_ids().into_iter());
+        dependencies.extend(Self::node_type_ids().into_iter());
+        dependencies.into_boxed_slice()
     }
     }
 
 
     fn pass_direction() -> PassDirection {
     fn pass_direction() -> PassDirection {
         if Self::child_type_ids()
         if Self::child_type_ids()
             .into_iter()
             .into_iter()
-            .any(|type_id| type_id == TypeId::of::<Self>())
+            .any(|type_id| *type_id == TypeId::of::<Self>())
         {
         {
             PassDirection::ChildToParent
             PassDirection::ChildToParent
         } else if Self::parent_type_ids()
         } else if Self::parent_type_ids()
             .into_iter()
             .into_iter()
-            .any(|type_id| type_id == TypeId::of::<Self>())
+            .any(|type_id| *type_id == TypeId::of::<Self>())
         {
         {
             PassDirection::ParentToChild
             PassDirection::ParentToChild
         } else {
         } else {
@@ -145,63 +229,57 @@ pub trait Pass<V: FromAnyValue = ()>: Any {
     }
     }
 }
 }
 
 
-pub struct TypeErasedPass<T: AnyMapLike + State<V>, V: FromAnyValue = ()> {
+pub struct TypeErasedPass<V: FromAnyValue + Send = ()> {
     pub(crate) this_type_id: TypeId,
     pub(crate) this_type_id: TypeId,
     pub(crate) parent_dependant: bool,
     pub(crate) parent_dependant: bool,
     pub(crate) child_dependant: bool,
     pub(crate) child_dependant: bool,
     pub(crate) combined_dependancy_type_ids: FxHashSet<TypeId>,
     pub(crate) combined_dependancy_type_ids: FxHashSet<TypeId>,
     pub(crate) dependants: FxHashSet<TypeId>,
     pub(crate) dependants: FxHashSet<TypeId>,
     pub(crate) mask: NodeMask,
     pub(crate) mask: NodeMask,
-    pass: PassCallback<T, V>,
+    pass: PassCallback,
     pub(crate) pass_direction: PassDirection,
     pub(crate) pass_direction: PassDirection,
+    phantom: PhantomData<V>,
 }
 }
 
 
-impl<T: AnyMapLike + State<V>, V: FromAnyValue> TypeErasedPass<T, V> {
+impl<V: FromAnyValue + Send> TypeErasedPass<V> {
     fn resolve(
     fn resolve(
         &self,
         &self,
-        tree: &mut Tree<Node<T, V>>,
-        mut dirty: DirtyNodes,
-        dirty_states: &DirtyNodeStates,
+        mut tree: TreeStateView,
+        dirty: &DirtyNodeStates,
         nodes_updated: &FxDashSet<NodeId>,
         nodes_updated: &FxDashSet<NodeId>,
         ctx: &SendAnyMap,
         ctx: &SendAnyMap,
     ) {
     ) {
         match self.pass_direction {
         match self.pass_direction {
             PassDirection::ParentToChild => {
             PassDirection::ParentToChild => {
-                while let Some(id) = dirty.pop_front() {
-                    if (self.pass)(id, tree, ctx) {
+                while let Some((height, id)) = dirty.pop_front(self.this_type_id) {
+                    if (self.pass)(id, &mut tree, ctx) {
                         nodes_updated.insert(id);
                         nodes_updated.insert(id);
                         for id in tree.children_ids(id).unwrap() {
                         for id in tree.children_ids(id).unwrap() {
                             for dependant in &self.dependants {
                             for dependant in &self.dependants {
-                                dirty_states.insert(*dependant, *id);
+                                dirty.insert(*dependant, id, height + 1);
                             }
                             }
-
-                            let height = tree.height(*id).unwrap();
-                            dirty.insert(height, *id);
                         }
                         }
                     }
                     }
                 }
                 }
             }
             }
             PassDirection::ChildToParent => {
             PassDirection::ChildToParent => {
-                while let Some(id) = dirty.pop_back() {
-                    if (self.pass)(id, tree, ctx) {
+                while let Some((height, id)) = dirty.pop_back(self.this_type_id) {
+                    if (self.pass)(id, &mut tree, ctx) {
                         nodes_updated.insert(id);
                         nodes_updated.insert(id);
                         if let Some(id) = tree.parent_id(id) {
                         if let Some(id) = tree.parent_id(id) {
                             for dependant in &self.dependants {
                             for dependant in &self.dependants {
-                                dirty_states.insert(*dependant, id);
+                                dirty.insert(*dependant, id, height - 1);
                             }
                             }
-
-                            let height = tree.height(id).unwrap();
-                            dirty.insert(height, id);
                         }
                         }
                     }
                     }
                 }
                 }
             }
             }
             PassDirection::AnyOrder => {
             PassDirection::AnyOrder => {
-                while let Some(id) = dirty.pop_back() {
-                    if (self.pass)(id, tree, ctx) {
+                while let Some((height, id)) = dirty.pop_back(self.this_type_id) {
+                    if (self.pass)(id, &mut tree, ctx) {
                         nodes_updated.insert(id);
                         nodes_updated.insert(id);
                         for dependant in &self.dependants {
                         for dependant in &self.dependants {
-                            dirty_states.insert(*dependant, id);
+                            dirty.insert(*dependant, id, height);
                         }
                         }
                     }
                     }
                 }
                 }
@@ -217,30 +295,20 @@ pub enum PassDirection {
     AnyOrder,
     AnyOrder,
 }
 }
 
 
-type PassCallback<T, V> =
-    Box<dyn Fn(NodeId, &mut Tree<Node<T, V>>, &SendAnyMap) -> bool + Send + Sync>;
+type PassCallback = Box<dyn Fn(NodeId, &mut TreeStateView, &SendAnyMap) -> bool + Send + Sync>;
 
 
-pub trait AnyMapLike {
-    fn get<T: Any>(&self) -> Option<&T>;
-    fn get_mut<T: Any>(&mut self) -> Option<&mut T>;
+pub trait AnyMapLike<'a> {
+    fn get<T: Any>(self) -> Option<&'a T>;
 }
 }
 
 
-impl AnyMapLike for AnyMap {
-    fn get<T: Any>(&self) -> Option<&T> {
+impl<'a> AnyMapLike<'a> for &'a AnyMap {
+    fn get<T: Any>(self) -> Option<&'a T> {
         self.get()
         self.get()
     }
     }
-
-    fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
-        self.get_mut()
-    }
 }
 }
 
 
-impl AnyMapLike for SendAnyMap {
-    fn get<T: Any>(&self) -> Option<&T> {
-        todo!()
-    }
-
-    fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
+impl<'a> AnyMapLike<'a> for &'a SendAnyMap {
+    fn get<T: Any>(self) -> Option<&'a T> {
         todo!()
         todo!()
     }
     }
 }
 }
@@ -250,8 +318,10 @@ pub trait Dependancy {
     where
     where
         Self: 'a;
         Self: 'a;
 
 
-    fn borrow_elements_from<T: AnyMapLike>(map: &T) -> Option<Self::ElementBorrowed<'_>>;
-    fn type_ids() -> Vec<TypeId>;
+    fn borrow_elements_from<'a, T: AnyMapLike<'a> + Copy>(
+        map: T,
+    ) -> Option<Self::ElementBorrowed<'a>>;
+    fn type_ids() -> Box<[TypeId]>;
 }
 }
 
 
 macro_rules! impl_dependancy {
 macro_rules! impl_dependancy {
@@ -260,12 +330,12 @@ macro_rules! impl_dependancy {
             type ElementBorrowed<'a> = ($(&'a $t,)*) where Self: 'a;
             type ElementBorrowed<'a> = ($(&'a $t,)*) where Self: 'a;
 
 
             #[allow(unused_variables, clippy::unused_unit, non_snake_case)]
             #[allow(unused_variables, clippy::unused_unit, non_snake_case)]
-            fn borrow_elements_from<T: AnyMapLike>(map: &T) -> Option<Self::ElementBorrowed<'_>> {
+            fn borrow_elements_from<'a, T: AnyMapLike<'a> + Copy>(map: T) -> Option<Self::ElementBorrowed<'a>> {
                 Some(($(map.get::<$t>()?,)*))
                 Some(($(map.get::<$t>()?,)*))
             }
             }
 
 
-            fn type_ids() -> Vec<TypeId> {
-                vec![$(TypeId::of::<$t>()),*]
+            fn type_ids() -> Box<[TypeId]> {
+                Box::new([$(TypeId::of::<$t>()),*])
             }
             }
         }
         }
     };
     };
@@ -289,96 +359,12 @@ impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
 impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
 impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
 impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
 impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
 
 
-#[derive(Debug, Clone, PartialEq, Eq, Default)]
-pub struct DirtyNodes {
-    map: BTreeMap<u16, FxHashSet<NodeId>>,
-}
-
-impl DirtyNodes {
-    fn add_node(&mut self, node_id: NodeId) {
-        let node_id = node_id.0;
-        let index = node_id / 64;
-        let bit = node_id % 64;
-        let encoded = 1 << bit;
-        if let Some(passes) = self.passes_dirty.get_mut(index) {
-            *passes |= encoded;
-        } else {
-            self.passes_dirty.resize(index + 1, 0);
-            self.passes_dirty[index] |= encoded;
-        }
-    }
-
-    fn is_empty(&self) -> bool {
-        self.passes_dirty.iter().all(|dirty| *dirty == 0)
-    }
-
-    fn pop(&mut self) -> Option<NodeId> {
-        let index = self.passes_dirty.iter().position(|dirty| *dirty != 0)?;
-        let passes = self.passes_dirty[index];
-        let node_id = passes.trailing_zeros();
-        let encoded = 1 << node_id;
-        self.passes_dirty[index] &= !encoded;
-        Some(NodeId((index * 64) + node_id as usize))
-    }
-}
-
-#[derive(Default)]
-pub struct DirtyNodeStates {
-    dirty: FxDashMap<NodeId, FxHashSet<TypeId>>,
-}
-
-impl DirtyNodeStates {
-    pub fn insert(&self, pass_id: TypeId, node_id: NodeId) {
-        if let Some(mut dirty) = self.dirty.get_mut(&node_id) {
-            dirty.insert(pass_id);
-        } else {
-            let mut v = FxHashSet::default();
-            v.insert(pass_id);
-            self.dirty.insert(node_id, v);
-        }
-    }
-
-    fn all_dirty<T>(&self, pass_id: TypeId, dirty_nodes: &mut DirtyNodes, tree: &impl TreeView<T>) {
-        for entry in self.dirty.iter() {
-            let node_id = entry.key();
-            let dirty = entry.value();
-            if dirty.contains(&pass_id) {
-                dirty_nodes.insert(tree.height(*node_id).unwrap(), *node_id);
-            }
-        }
-        if values.is_empty() {
-            self.dirty.remove(&height);
-        }
-
-        Some((height, node_id))
-    }
-
-    fn pop_back(&mut self, pass_id: PassId) -> Option<(u16, NodeId)> {
-        let (&height, values) = self
-            .dirty
-            .iter_mut()
-            .rev()
-            .find(|(_, values)| values.contains_key(&pass_id))?;
-        let dirty = values.get_mut(&pass_id)?;
-        let node_id = dirty.pop()?;
-        if dirty.is_empty() {
-            values.remove(&pass_id);
-        }
-        if values.is_empty() {
-            self.dirty.remove(&height);
-        }
-
-        Some((height, node_id))
-    }
-}
-
-pub fn resolve_passes<T: AnyMapLike + State<V> + Send, V: FromAnyValue + Send>(
-    tree: &mut Tree<Node<T, V>>,
+pub fn resolve_passes<V: FromAnyValue + Send + Sync>(
+    tree: &mut RealDom<V>,
     dirty_nodes: DirtyNodeStates,
     dirty_nodes: DirtyNodeStates,
-    passes: &[TypeErasedPass<T, V>],
     ctx: SendAnyMap,
     ctx: SendAnyMap,
 ) -> FxDashSet<NodeId> {
 ) -> FxDashSet<NodeId> {
-    let dirty_states = Arc::new(dirty_nodes);
+    let passes = &tree.passes;
     let mut resolved_passes: FxHashSet<TypeId> = FxHashSet::default();
     let mut resolved_passes: FxHashSet<TypeId> = FxHashSet::default();
     let mut resolving = Vec::new();
     let mut resolving = Vec::new();
     let nodes_updated = Arc::new(FxDashSet::default());
     let nodes_updated = Arc::new(FxDashSet::default());
@@ -399,21 +385,15 @@ pub fn resolve_passes<T: AnyMapLike + State<V> + Send, V: FromAnyValue + Send>(
                     pass_indexes_remaining.remove(i);
                     pass_indexes_remaining.remove(i);
                     resolving.push(pass_id);
                     resolving.push(pass_id);
                     currently_in_use.insert(pass.this_type_id);
                     currently_in_use.insert(pass.this_type_id);
-                    // this is safe because each pass only has mutable access to the member associated with this_type_id and we have verified that the pass does not overlap with any other pass currently running
-                    let tree_unbounded_mut = unsafe { &mut *(tree as *mut _) };
-                    let dirty_states = dirty_states.clone();
+                    let tree_view = tree.tree.state_views(
+                        [pass.this_type_id],
+                        pass.combined_dependancy_type_ids.iter().copied(),
+                    );
+                    let dirty_nodes = dirty_nodes.clone();
                     let nodes_updated = nodes_updated.clone();
                     let nodes_updated = nodes_updated.clone();
                     let ctx = ctx.clone();
                     let ctx = ctx.clone();
                     s.spawn(move || {
                     s.spawn(move || {
-                        let mut dirty = DirtyNodes::default();
-                        dirty_states.all_dirty(pass_id, &mut dirty, tree_unbounded_mut);
-                        pass.resolve(
-                            tree_unbounded_mut,
-                            dirty,
-                            &dirty_states,
-                            &nodes_updated,
-                            &ctx,
-                        );
+                        pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
                     });
                     });
                 } else {
                 } else {
                     i += 1;
                     i += 1;

+ 162 - 190
packages/native-core/src/real_dom.rs

@@ -1,15 +1,14 @@
 use dioxus_core::{BorrowedAttributeValue, ElementId, Mutations, TemplateNode};
 use dioxus_core::{BorrowedAttributeValue, ElementId, Mutations, TemplateNode};
+use parking_lot::{MappedRwLockReadGuard, MappedRwLockWriteGuard};
 use rustc_hash::{FxHashMap, FxHashSet};
 use rustc_hash::{FxHashMap, FxHashSet};
-use std::ops::{Index, IndexMut};
+use std::any::Any;
 
 
 use crate::node::{
 use crate::node::{
-    ElementNode, FromAnyValue, Node, NodeData, NodeType, OwnedAttributeDiscription,
-    OwnedAttributeValue,
+    ElementNode, FromAnyValue, NodeData, NodeType, OwnedAttributeDiscription, OwnedAttributeValue,
 };
 };
 use crate::node_ref::{AttributeMask, NodeMask};
 use crate::node_ref::{AttributeMask, NodeMask};
 use crate::passes::{resolve_passes, DirtyNodeStates, TypeErasedPass};
 use crate::passes::{resolve_passes, DirtyNodeStates, TypeErasedPass};
-use crate::state::State;
-use crate::tree::{NodeId, Tree, TreeLike, TreeView, TreeViewMut};
+use crate::tree::{EntryBuilder, NodeId, Tree};
 use crate::{FxDashSet, SendAnyMap};
 use crate::{FxDashSet, SendAnyMap};
 
 
 /// A Dom that can sync with the VirtualDom mutations intended for use in lazy renderers.
 /// A Dom that can sync with the VirtualDom mutations intended for use in lazy renderers.
@@ -18,41 +17,36 @@ use crate::{FxDashSet, SendAnyMap};
 ///
 ///
 /// # Custom values
 /// # Custom values
 /// To allow custom values to be passed into attributes implement FromAnyValue on a type that can represent your custom value and specify the V generic to be that type. If you have many different custom values, it can be useful to use a enum type to represent the varients.
 /// To allow custom values to be passed into attributes implement FromAnyValue on a type that can represent your custom value and specify the V generic to be that type. If you have many different custom values, it can be useful to use a enum type to represent the varients.
-pub struct RealDom<S: State<V>, V: FromAnyValue = ()> {
-    tree: Tree<Node<S, V>>,
+pub struct RealDom<V: FromAnyValue + Send = ()> {
+    pub(crate) tree: Tree,
     /// a map from element id to real node id
     /// a map from element id to real node id
     node_id_mapping: Vec<Option<NodeId>>,
     node_id_mapping: Vec<Option<NodeId>>,
     nodes_listening: FxHashMap<String, FxHashSet<NodeId>>,
     nodes_listening: FxHashMap<String, FxHashSet<NodeId>>,
     stack: Vec<NodeId>,
     stack: Vec<NodeId>,
     templates: FxHashMap<String, Vec<NodeId>>,
     templates: FxHashMap<String, Vec<NodeId>>,
-    pub(crate) passes: Box<[TypeErasedPass<S, V>]>,
+    pub(crate) passes: Box<[TypeErasedPass<V>]>,
     pub(crate) nodes_updated: FxHashMap<NodeId, NodeMask>,
     pub(crate) nodes_updated: FxHashMap<NodeId, NodeMask>,
     passes_updated: DirtyNodeStates,
     passes_updated: DirtyNodeStates,
     parent_changed_nodes: FxHashSet<NodeId>,
     parent_changed_nodes: FxHashSet<NodeId>,
     child_changed_nodes: FxHashSet<NodeId>,
     child_changed_nodes: FxHashSet<NodeId>,
     nodes_created: FxHashSet<NodeId>,
     nodes_created: FxHashSet<NodeId>,
+    phantom: std::marker::PhantomData<V>,
 }
 }
 
 
-impl<S: State<V>, V: FromAnyValue> Default for RealDom<S, V> {
-    fn default() -> Self {
-        Self::new()
-    }
-}
-
-impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
-    pub fn new() -> RealDom<S, V> {
-        let mut root = Node::new(NodeType::Element(ElementNode {
+impl<V: FromAnyValue + Send + Sync> RealDom<V> {
+    pub fn new(mut passes: Box<[TypeErasedPass<V>]>) -> RealDom<V> {
+        let tree = Tree::new();
+        let root_id = tree.root();
+        let root = tree.get_node(root_id);
+        let mut root_node: NodeData<V> = NodeData::new(NodeType::Element(ElementNode {
             tag: "Root".to_string(),
             tag: "Root".to_string(),
             namespace: Some("Root".to_string()),
             namespace: Some("Root".to_string()),
             attributes: FxHashMap::default(),
             attributes: FxHashMap::default(),
             listeners: FxHashSet::default(),
             listeners: FxHashSet::default(),
         }));
         }));
-        root.node_data.element_id = Some(ElementId(0));
-        let mut tree = Tree::new(root);
-        let root_id = tree.root();
-        tree.get_mut(root_id).unwrap().node_data.node_id = root_id;
-
-        let mut passes = S::create_passes();
+        root_node.element_id = Some(ElementId(0));
+        root_node.node_id = root_id;
+        root.insert(root_node);
 
 
         // resolve dependants for each pass
         // resolve dependants for each pass
         for i in 1..passes.len() {
         for i in 1..passes.len() {
@@ -83,6 +77,7 @@ impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
             parent_changed_nodes: FxHashSet::default(),
             parent_changed_nodes: FxHashSet::default(),
             child_changed_nodes: FxHashSet::default(),
             child_changed_nodes: FxHashSet::default(),
             nodes_created: FxHashSet::default(),
             nodes_created: FxHashSet::default(),
+            phantom: std::marker::PhantomData,
         }
         }
     }
     }
 
 
@@ -107,9 +102,9 @@ impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
     }
     }
 
 
     fn set_element_id(&mut self, node_id: NodeId, element_id: ElementId) {
     fn set_element_id(&mut self, node_id: NodeId, element_id: ElementId) {
-        let node = self.tree.get_mut(node_id).unwrap();
-        let node_id = node.node_data.node_id;
-        node.node_data.element_id = Some(element_id);
+        let mut node = self.tree.write::<NodeData>(node_id).unwrap();
+        let node_id = node.node_id;
+        node.element_id = Some(element_id);
         if self.node_id_mapping.len() <= element_id.0 {
         if self.node_id_mapping.len() <= element_id.0 {
             self.node_id_mapping.resize(element_id.0 + 1, None);
             self.node_id_mapping.resize(element_id.0 + 1, None);
         }
         }
@@ -124,14 +119,21 @@ impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
         current
         current
     }
     }
 
 
-    fn create_node(&mut self, node: Node<S, V>, mark_dirty: bool) -> NodeId {
-        let node_id = self.tree.create_node(node);
-        let node = self.tree.get_mut(node_id).unwrap();
-        node.node_data.node_id = node_id;
+    fn create_node(
+        &mut self,
+        mut node: NodeData<V>,
+        id: Option<ElementId>,
+        mark_dirty: bool,
+    ) -> EntryBuilder<'_> {
+        let mut node_entry = self.tree.create_node();
+        let node_id = node_entry.id();
+        node.node_id = node_id;
+        node.element_id = id;
+        node_entry.insert(node);
         if mark_dirty {
         if mark_dirty {
             self.nodes_created.insert(node_id);
             self.nodes_created.insert(node_id);
         }
         }
-        node_id
+        node_entry
     }
     }
 
 
     fn add_child(&mut self, node_id: NodeId, child_id: NodeId) {
     fn add_child(&mut self, node_id: NodeId, child_id: NodeId) {
@@ -146,7 +148,7 @@ impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
                 attrs,
                 attrs,
                 children,
                 children,
             } => {
             } => {
-                let node = Node::new(NodeType::Element(ElementNode {
+                let node = NodeData::new(NodeType::Element(ElementNode {
                     tag: tag.to_string(),
                     tag: tag.to_string(),
                     namespace: namespace.map(|s| s.to_string()),
                     namespace: namespace.map(|s| s.to_string()),
                     attributes: attrs
                     attributes: attrs
@@ -169,22 +171,22 @@ impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
                         .collect(),
                         .collect(),
                     listeners: FxHashSet::default(),
                     listeners: FxHashSet::default(),
                 }));
                 }));
-                let node_id = self.create_node(node, true);
+                let node_id = self.create_node(node, None, true).id();
                 for child in *children {
                 for child in *children {
                     let child_id = self.create_template_node(child);
                     let child_id = self.create_template_node(child);
                     self.add_child(node_id, child_id);
                     self.add_child(node_id, child_id);
                 }
                 }
                 node_id
                 node_id
             }
             }
-            TemplateNode::Text { text } => {
-                self.create_node(Node::new(NodeType::Text(text.to_string())), true)
-            }
-            TemplateNode::Dynamic { .. } => {
-                self.create_node(Node::new(NodeType::Placeholder), true)
-            }
-            TemplateNode::DynamicText { .. } => {
-                self.create_node(Node::new(NodeType::Text(String::new())), true)
-            }
+            TemplateNode::Text { text } => self
+                .create_node(NodeData::new(NodeType::Text(text.to_string())), None, true)
+                .id(),
+            TemplateNode::Dynamic { .. } => self
+                .create_node(NodeData::new(NodeType::Placeholder), None, true)
+                .id(),
+            TemplateNode::DynamicText { .. } => self
+                .create_node(NodeData::new(NodeType::Text(String::new())), None, true)
+                .id(),
         }
         }
     }
     }
 
 
@@ -214,29 +216,26 @@ impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
                     self.set_element_id(self.load_child(path), id);
                     self.set_element_id(self.load_child(path), id);
                 }
                 }
                 CreatePlaceholder { id } => {
                 CreatePlaceholder { id } => {
-                    let node = Node::new(NodeType::Placeholder);
-                    let node_id = self.create_node(node, true);
+                    let node = NodeData::new(NodeType::Placeholder);
+                    let node_id = self.create_node(node, None, true).id();
                     self.set_element_id(node_id, id);
                     self.set_element_id(node_id, id);
                     self.stack.push(node_id);
                     self.stack.push(node_id);
                 }
                 }
                 CreateTextNode { value, id } => {
                 CreateTextNode { value, id } => {
-                    let node = Node::new(NodeType::Text(value.to_string()));
-                    let node_id = self.create_node(node, true);
-                    let node = self.tree.get_mut(node_id).unwrap();
-                    node.node_data.element_id = Some(id);
+                    let node_data = NodeData::new(NodeType::Text(value.to_string()));
+                    let node_id = self.create_node(node_data, None, true).id();
+                    self.set_element_id(node_id, id);
                     self.stack.push(node_id);
                     self.stack.push(node_id);
                 }
                 }
                 HydrateText { path, value, id } => {
                 HydrateText { path, value, id } => {
                     let node_id = self.load_child(path);
                     let node_id = self.load_child(path);
                     self.set_element_id(node_id, id);
                     self.set_element_id(node_id, id);
-                    let node = self.tree.get_mut(node_id).unwrap();
-                    if let NodeType::Text(text) = &mut node.node_data.node_type {
+                    let mut node = self.get_mut(node_id).unwrap();
+                    if let NodeTypeMut::Text(text) = node.node_type_mut() {
                         *text = value.to_string();
                         *text = value.to_string();
                     } else {
                     } else {
-                        node.node_data.node_type = NodeType::Text(value.to_string());
+                        node.set_type(NodeType::Text(value.to_string()));
                     }
                     }
-
-                    self.mark_dirty(node_id, NodeMask::new().with_text());
                 }
                 }
                 LoadTemplate { name, index, id } => {
                 LoadTemplate { name, index, id } => {
                     let template_id = self.templates[name][index];
                     let template_id = self.templates[name][index];
@@ -350,15 +349,14 @@ impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
 
 
     /// Find all nodes that are listening for an event, sorted by there height in the dom progressing starting at the bottom and progressing up.
     /// Find all nodes that are listening for an event, sorted by there height in the dom progressing starting at the bottom and progressing up.
     /// This can be useful to avoid creating duplicate events.
     /// This can be useful to avoid creating duplicate events.
-    pub fn get_listening_sorted(&self, event: &'static str) -> Vec<&Node<S, V>> {
+    pub fn get_listening_sorted(&self, event: &'static str) -> Vec<NodeId> {
         if let Some(nodes) = self.nodes_listening.get(event) {
         if let Some(nodes) = self.nodes_listening.get(event) {
-            let mut listening: Vec<_> = nodes.iter().map(|id| self.get(*id).unwrap()).collect();
-            listening.sort_by(|n1, n2| {
-                (self.tree.height(n1.node_data.node_id))
-                    .cmp(&self.tree.height(n2.node_data.node_id))
-                    .reverse()
-            });
-            listening
+            let mut listening: Vec<_> = nodes
+                .iter()
+                .map(|id| (*id, self.tree.height(*id).unwrap()))
+                .collect();
+            listening.sort_by(|(_, h1), (_, h2)| h1.cmp(h2).reverse());
+            listening.into_iter().map(|(id, _)| id).collect()
         } else {
         } else {
             Vec::new()
             Vec::new()
         }
         }
@@ -376,160 +374,94 @@ impl<S: State<V>, V: FromAnyValue> RealDom<S, V> {
     }
     }
 
 
     fn clone_node(&mut self, node_id: NodeId) -> NodeId {
     fn clone_node(&mut self, node_id: NodeId) -> NodeId {
-        let node = self.tree.get(node_id).unwrap();
-        let new_node = Node {
-            state: node.state.clone(),
-            node_data: node.node_data.clone(),
-        };
-        let new_id = self.create_node(new_node, true);
-
-        let self_ptr = self as *mut Self;
+        let node = self.get(node_id).unwrap();
+        let new_node = node.node_data().clone();
+        let new_id = self.create_node(new_node, None, true).id();
+
         for child in self.tree.children_ids(node_id).unwrap() {
         for child in self.tree.children_ids(node_id).unwrap() {
-            unsafe {
-                // this is safe because no node has itself as a child
-                let self_mut = &mut *self_ptr;
-                let child_id = self_mut.clone_node(*child);
-                self_mut.add_child(new_id, child_id);
-            }
+            let child_id = self.clone_node(child);
+            self.add_child(new_id, child_id);
         }
         }
         new_id
         new_id
     }
     }
 
 
+    fn root(&self) -> NodeId {
+        self.tree.root()
+    }
+
+    fn get(&self, id: NodeId) -> Option<NodeRef<'_, V>> {
+        self.tree.contains(id).then(|| NodeRef { id, dom: &self })
+    }
+
     pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<'_, V>> {
     pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<'_, V>> {
-        self.tree.get_mut(id).map(|node| NodeMut {
-            node: &mut node.node_data,
+        self.tree.contains(id).then(|| NodeMut {
+            id,
             dirty: NodeMask::new(),
             dirty: NodeMask::new(),
-            nodes_updated: &mut self.nodes_updated,
+            dom: self,
         })
         })
     }
     }
 
 
     /// WARNING: This escapes the reactive system that the real dom uses. Any changes made with this method will not trigger updates in states when [RealDom::update_state] is called.
     /// WARNING: This escapes the reactive system that the real dom uses. Any changes made with this method will not trigger updates in states when [RealDom::update_state] is called.
-    pub fn get_mut_raw(&mut self, id: NodeId) -> Option<&mut Node<S, V>> {
-        self.tree.get_mut(id)
+    pub fn get_mut_raw(&mut self, id: NodeId) -> Option<&mut NodeData<V>> {
+        self.tree.write(id)
     }
     }
-}
 
 
-impl<S: State<V> + Send, V: FromAnyValue + Send> RealDom<S, V> {
     /// Update the state of the dom, after appling some mutations. This will keep the nodes in the dom up to date with their VNode counterparts.
     /// Update the state of the dom, after appling some mutations. This will keep the nodes in the dom up to date with their VNode counterparts.
     pub fn update_state(
     pub fn update_state(
         &mut self,
         &mut self,
         ctx: SendAnyMap,
         ctx: SendAnyMap,
     ) -> (FxDashSet<NodeId>, FxHashMap<NodeId, NodeMask>) {
     ) -> (FxDashSet<NodeId>, FxHashMap<NodeId, NodeMask>) {
-        let passes = &self.passes;
         let dirty_nodes = std::mem::take(&mut self.passes_updated);
         let dirty_nodes = std::mem::take(&mut self.passes_updated);
         let nodes_updated = std::mem::take(&mut self.nodes_updated);
         let nodes_updated = std::mem::take(&mut self.nodes_updated);
         for (&node, mask) in &nodes_updated {
         for (&node, mask) in &nodes_updated {
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
-            if self.tree.contains(node) {
+            if let Some(height) = self.tree.height(node) {
                 for pass in &*self.passes {
                 for pass in &*self.passes {
                     if mask.overlaps(&pass.mask) {
                     if mask.overlaps(&pass.mask) {
-                        dirty_nodes.insert(pass.this_type_id, node);
+                        dirty_nodes.insert(pass.this_type_id, node, height);
                     }
                     }
                 }
                 }
             }
             }
         }
         }
         for node in std::mem::take(&mut self.child_changed_nodes) {
         for node in std::mem::take(&mut self.child_changed_nodes) {
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
-            if self.tree.contains(node) {
+            if let Some(height) = self.tree.height(node) {
                 for pass in &*self.passes {
                 for pass in &*self.passes {
                     if pass.child_dependant {
                     if pass.child_dependant {
-                        dirty_nodes.insert(pass.this_type_id, node);
+                        dirty_nodes.insert(pass.this_type_id, node, height);
                     }
                     }
                 }
                 }
             }
             }
         }
         }
         for node in std::mem::take(&mut self.parent_changed_nodes) {
         for node in std::mem::take(&mut self.parent_changed_nodes) {
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
-            if self.tree.contains(node) {
+            if let Some(height) = self.tree.height(node) {
                 for pass in &*self.passes {
                 for pass in &*self.passes {
                     if pass.parent_dependant {
                     if pass.parent_dependant {
-                        dirty_nodes.insert(pass.this_type_id, node);
+                        dirty_nodes.insert(pass.this_type_id, node, height);
                     }
                     }
                 }
                 }
             }
             }
         }
         }
         for node in std::mem::take(&mut self.nodes_created) {
         for node in std::mem::take(&mut self.nodes_created) {
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
             // remove any nodes that were created and then removed in the same mutations from the dirty nodes list
-            if self.tree.contains(node) {
+            if let Some(height) = self.tree.height(node) {
                 for pass in &*self.passes {
                 for pass in &*self.passes {
-                    dirty_nodes.insert(pass.this_type_id, node);
+                    dirty_nodes.insert(pass.this_type_id, node, height);
                 }
                 }
             }
             }
         }
         }
 
 
-        let tree = &mut self.tree;
-
-        (
-            resolve_passes(tree, dirty_nodes, passes, ctx),
-            nodes_updated,
-        )
-    }
-}
-
-impl<S: State<V>, V: FromAnyValue> TreeView<Node<S, V>> for RealDom<S, V> {
-    type Iterator<'a> = <Tree<Node<S, V>> as TreeView<Node<S, V>>>::Iterator<'a>;
-
-    fn root(&self) -> NodeId {
-        self.tree.root()
-    }
-
-    fn get(&self, id: NodeId) -> Option<&Node<S, V>> {
-        self.tree.get(id)
-    }
-
-    fn children(&self, id: NodeId) -> Option<Self::Iterator<'_>> {
-        self.tree.children(id)
+        (resolve_passes(self, dirty_nodes, ctx), nodes_updated)
     }
     }
 
 
-    fn children_ids(&self, id: NodeId) -> Option<&[NodeId]> {
-        self.tree.children_ids(id)
-    }
-
-    fn parent(&self, id: NodeId) -> Option<&Node<S, V>> {
-        self.tree.parent(id)
-    }
-
-    fn parent_id(&self, id: NodeId) -> Option<NodeId> {
-        self.tree.parent_id(id)
-    }
-
-    fn height(&self, id: NodeId) -> Option<u16> {
-        self.tree.height(id)
-    }
-
-    fn size(&self) -> usize {
-        self.tree.size()
-    }
-}
-
-impl<S: State<V>, V: FromAnyValue> TreeLike<Node<S, V>> for RealDom<S, V> {
-    fn create_node(&mut self, node: Node<S, V>) -> NodeId {
-        let id = self.tree.create_node(node);
-        self.tree.get_mut(id).unwrap().node_data.node_id = id;
-        self.nodes_created.insert(id);
-        id
-    }
-
-    fn add_child(&mut self, parent: NodeId, child: NodeId) {
-        // mark the parent's children changed
-        self.mark_child_changed(parent);
-        // mark the child's parent changed
-        self.mark_parent_added_or_removed(child);
-        self.tree.add_child(parent, child);
-    }
-
-    fn remove(&mut self, id: NodeId) -> Option<Node<S, V>> {
+    fn remove(&mut self, id: NodeId) {
         if let Some(parent_id) = self.tree.parent_id(id) {
         if let Some(parent_id) = self.tree.parent_id(id) {
             self.mark_child_changed(parent_id);
             self.mark_child_changed(parent_id);
         }
         }
         self.tree.remove(id)
         self.tree.remove(id)
     }
     }
 
 
-    fn remove_all_children(&mut self, id: NodeId) -> Vec<Node<S, V>> {
-        self.mark_child_changed(id);
-        self.tree.remove_all_children(id)
-    }
-
     fn replace(&mut self, old: NodeId, new: NodeId) {
     fn replace(&mut self, old: NodeId, new: NodeId) {
         if let Some(parent_id) = self.tree.parent_id(old) {
         if let Some(parent_id) = self.tree.parent_id(old) {
             self.mark_child_changed(parent_id);
             self.mark_child_changed(parent_id);
@@ -555,68 +487,108 @@ impl<S: State<V>, V: FromAnyValue> TreeLike<Node<S, V>> for RealDom<S, V> {
     }
     }
 }
 }
 
 
-impl<S: State<V> + Send, V: FromAnyValue> Index<ElementId> for RealDom<S, V> {
-    type Output = Node<S, V>;
-
-    fn index(&self, id: ElementId) -> &Self::Output {
-        self.tree.get(self.element_to_node_id(id)).unwrap()
-    }
+// impl<V: FromAnyValue> Index<ElementId> for RealDom<V> {
+//     type Output = Node<V>;
+
+//     fn index(&self, id: ElementId) -> &Self::Output {
+//         self.tree.get(self.element_to_node_id(id)).unwrap()
+//     }
+// }
+
+// impl<V: FromAnyValue> Index<NodeId> for RealDom<V> {
+//     type Output = Node<V>;
+
+//     fn index(&self, idx: NodeId) -> &Self::Output {
+//         self.tree.get(idx).unwrap()
+//     }
+// }
+
+// impl<V: FromAnyValue> IndexMut<ElementId> for RealDom<V> {
+//     fn index_mut(&mut self, id: ElementId) -> &mut Self::Output {
+//         self.tree.get_mut(self.element_to_node_id(id)).unwrap()
+//     }
+// }
+
+// impl<V: FromAnyValue> IndexMut<NodeId> for RealDom<V> {
+//     fn index_mut(&mut self, idx: NodeId) -> &mut Self::Output {
+//         self.tree.get_mut(idx).unwrap()
+//     }
+// }
+
+pub struct NodeRef<'a, V: FromAnyValue + Send = ()> {
+    id: NodeId,
+    dom: &'a RealDom<V>,
 }
 }
 
 
-impl<S: State<V> + Send, V: FromAnyValue> Index<NodeId> for RealDom<S, V> {
-    type Output = Node<S, V>;
-
-    fn index(&self, idx: NodeId) -> &Self::Output {
-        self.tree.get(idx).unwrap()
+impl<'a, V: FromAnyValue + Send> NodeRef<'a, V> {
+    pub fn node_data(&self) -> &NodeData<V> {
+        self.read().unwrap()
     }
     }
-}
 
 
-impl<S: State<V> + Send, V: FromAnyValue> IndexMut<ElementId> for RealDom<S, V> {
-    fn index_mut(&mut self, id: ElementId) -> &mut Self::Output {
-        self.tree.get_mut(self.element_to_node_id(id)).unwrap()
+    pub fn node_type(&self) -> &NodeType<V> {
+        &self.node_data().node_type
     }
     }
-}
 
 
-impl<S: State<V> + Send, V: FromAnyValue> IndexMut<NodeId> for RealDom<S, V> {
-    fn index_mut(&mut self, idx: NodeId) -> &mut Self::Output {
-        self.tree.get_mut(idx).unwrap()
+    pub fn read<T: Any>(&self) -> Option<&T> {
+        self.dom.tree.read(self.id)
     }
     }
 }
 }
 
 
-pub struct NodeMut<'a, V: FromAnyValue = ()> {
-    node: &'a mut NodeData<V>,
+pub struct NodeMut<'a, V: FromAnyValue + Send = ()> {
+    id: NodeId,
+    dom: &'a mut RealDom<V>,
     dirty: NodeMask,
     dirty: NodeMask,
-    nodes_updated: &'a mut FxHashMap<NodeId, NodeMask>,
 }
 }
 
 
-impl<'a, V: FromAnyValue> NodeMut<'a, V> {
+impl<'a, V: FromAnyValue + Send> NodeMut<'a, V> {
+    fn node_data(&self) -> &NodeData<V> {
+        self.read().unwrap()
+    }
+
+    fn node_data_mut(&mut self) -> &mut NodeData<V> {
+        self.dom.tree.write(self.id).unwrap()
+    }
+
     pub fn node_type(&self) -> &NodeType<V> {
     pub fn node_type(&self) -> &NodeType<V> {
-        &self.node.node_type
+        &self.node_data().node_type
     }
     }
 
 
     pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
     pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
-        match &mut self.node.node_type {
-            NodeType::Element(element) => NodeTypeMut::Element(ElementNodeMut {
-                element,
-                dirty: &mut self.dirty,
-            }),
+        let Self { id, dom, dirty } = self;
+        let node_type = &mut dom.tree.write::<NodeData<V>>(*id).unwrap().node_type;
+        match node_type {
+            NodeType::Element(element) => NodeTypeMut::Element(ElementNodeMut { element, dirty }),
             NodeType::Text(text) => {
             NodeType::Text(text) => {
-                self.dirty.set_text();
+                dirty.set_text();
                 NodeTypeMut::Text(text)
                 NodeTypeMut::Text(text)
             }
             }
             NodeType::Placeholder => NodeTypeMut::Placeholder,
             NodeType::Placeholder => NodeTypeMut::Placeholder,
         }
         }
     }
     }
+
+    pub fn set_type(&mut self, new: NodeType<V>) {
+        self.node_data_mut().node_type = new;
+        self.dirty = NodeMask::ALL;
+    }
+
+    pub fn read<T: Any>(&self) -> Option<&T> {
+        self.dom.tree.read(self.id)
+    }
+
+    pub fn write<T: Any>(&mut self) -> Option<&T> {
+        todo!("get_mut with mark as dirty")
+    }
 }
 }
 
 
-impl<V: FromAnyValue> Drop for NodeMut<'_, V> {
+impl<V: FromAnyValue + Send> Drop for NodeMut<'_, V> {
     fn drop(&mut self) {
     fn drop(&mut self) {
-        let node_id = self.node.node_id;
+        let node_id = self.node_data().node_id;
         let mask = std::mem::take(&mut self.dirty);
         let mask = std::mem::take(&mut self.dirty);
-        if let Some(node) = self.nodes_updated.get_mut(&node_id) {
+        let nodes_updated = &mut self.dom.nodes_updated;
+        if let Some(node) = nodes_updated.get_mut(&node_id) {
             *node = node.union(&mask);
             *node = node.union(&mask);
         } else {
         } else {
-            self.nodes_updated.insert(node_id, mask);
+            nodes_updated.insert(node_id, mask);
         }
         }
     }
     }
 }
 }

+ 0 - 46
packages/native-core/src/state.rs

@@ -1,46 +0,0 @@
-use crate::{
-    node::FromAnyValue,
-    passes::{AnyMapLike, TypeErasedPass},
-};
-use std::cmp::Ordering;
-
-/// Join two sorted iterators
-pub(crate) fn union_ordered_iter<'a>(
-    s_iter: impl Iterator<Item = &'a str>,
-    o_iter: impl Iterator<Item = &'a str>,
-    new_len_guess: usize,
-) -> Vec<String> {
-    let mut s_peekable = s_iter.peekable();
-    let mut o_peekable = o_iter.peekable();
-    let mut v = Vec::with_capacity(new_len_guess);
-    while let Some(s_i) = s_peekable.peek() {
-        while let Some(o_i) = o_peekable.peek() {
-            match o_i.cmp(s_i) {
-                Ordering::Greater => {
-                    break;
-                }
-                Ordering::Less => {
-                    v.push(o_peekable.next().unwrap().to_string());
-                }
-                Ordering::Equal => {
-                    o_peekable.next();
-                    break;
-                }
-            }
-        }
-        v.push(s_peekable.next().unwrap().to_string());
-    }
-    for o_i in o_peekable {
-        v.push(o_i.to_string());
-    }
-    for w in v.windows(2) {
-        debug_assert!(w[1] > w[0]);
-    }
-    v
-}
-
-/// Do not implement this trait. It is only meant to be derived and used through [crate::real_dom::RealDom].
-pub trait State<V: FromAnyValue = ()>: Default + Clone + AnyMapLike + 'static {
-    #[doc(hidden)]
-    fn create_passes() -> Box<[TypeErasedPass<Self, V>]>;
-}

+ 163 - 210
packages/native-core/src/tree.rs

@@ -7,17 +7,19 @@ use std::collections::VecDeque;
 use std::fmt::Debug;
 use std::fmt::Debug;
 use std::hash::BuildHasherDefault;
 use std::hash::BuildHasherDefault;
 
 
-#[derive(PartialEq, Eq, Clone, Copy, Debug)]
+use crate::{AnyMapLike, Dependancy};
+
+#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Hash)]
 pub struct NodeId(pub usize);
 pub struct NodeId(pub usize);
 
 
 #[derive(PartialEq, Eq, Clone, Debug)]
 #[derive(PartialEq, Eq, Clone, Debug)]
-pub struct Node {
+pub(crate) struct Node {
     parent: Option<NodeId>,
     parent: Option<NodeId>,
     children: Vec<NodeId>,
     children: Vec<NodeId>,
     height: u16,
     height: u16,
 }
 }
 
 
-pub struct NodeView<'a> {
+pub(crate) struct NodeView<'a> {
     tree: &'a Tree,
     tree: &'a Tree,
     id: NodeId,
     id: NodeId,
 }
 }
@@ -27,25 +29,21 @@ impl NodeView<'_> {
     where
     where
         T: Any,
         T: Any,
     {
     {
-        self.tree.nodes.get_slab_mut::<T>().insert(self.id, data);
+        self.tree.nodes.write_slab::<T>().insert(self.id, data);
     }
     }
 
 
-    pub fn get<T>(&self) -> MappedRwLockReadGuard<'_, T>
+    pub fn get<T>(&self) -> &T
     where
     where
         T: Any,
         T: Any,
     {
     {
-        MappedRwLockReadGuard::map(self.tree.nodes.get_slab::<T>(), |slab| {
-            slab.get(self.id).unwrap()
-        })
+        self.tree.nodes.read_slab::<T>().get(self.id).unwrap()
     }
     }
 
 
-    pub fn get_mut<T>(&self) -> MappedRwLockWriteGuard<'_, T>
+    pub fn get_mut<T>(&self) -> &mut T
     where
     where
         T: Any,
         T: Any,
     {
     {
-        MappedRwLockWriteGuard::map(self.tree.nodes.get_slab_mut::<T>(), |slab| {
-            slab.get_mut(self.id).unwrap()
-        })
+        self.tree.nodes.write_slab::<T>().get_mut(self.id).unwrap()
     }
     }
 
 
     pub fn height(&self) -> u16 {
     pub fn height(&self) -> u16 {
@@ -66,7 +64,7 @@ impl NodeView<'_> {
 }
 }
 
 
 #[derive(Debug)]
 #[derive(Debug)]
-pub struct Tree {
+pub(crate) struct Tree {
     nodes: AnySlab,
     nodes: AnySlab,
     root: NodeId,
     root: NodeId,
 }
 }
@@ -84,20 +82,20 @@ impl Tree {
         Self { nodes, root }
         Self { nodes, root }
     }
     }
 
 
-    fn node_slab(&self) -> MappedRwLockReadGuard<'_, SlabStorage<Node>> {
-        self.nodes.get_slab()
+    fn node_slab(&self) -> &SlabStorage<Node> {
+        self.nodes.read_slab()
     }
     }
 
 
-    pub fn get_node_data(&self, id: NodeId) -> MappedRwLockReadGuard<'_, Node> {
-        MappedRwLockReadGuard::map(self.node_slab(), |slab| slab.get(id).unwrap())
+    pub fn get_node_data(&self, id: NodeId) -> &Node {
+        self.node_slab().get(id).unwrap()
     }
     }
 
 
-    fn node_slab_mut(&self) -> MappedRwLockWriteGuard<'_, SlabStorage<Node>> {
-        self.nodes.get_slab_mut()
+    fn node_slab_mut(&self) -> &mut SlabStorage<Node> {
+        self.nodes.write_slab()
     }
     }
 
 
-    pub fn get_node_data_mut(&self, id: NodeId) -> MappedRwLockWriteGuard<'_, Node> {
-        MappedRwLockWriteGuard::map(self.node_slab_mut(), |slab| slab.get_mut(id).unwrap())
+    pub fn get_node_data_mut(&self, id: NodeId) -> &mut Node {
+        self.node_slab_mut().get_mut(id).unwrap()
     }
     }
 
 
     pub fn remove(&mut self, id: NodeId) {
     pub fn remove(&mut self, id: NodeId) {
@@ -131,7 +129,7 @@ impl Tree {
         }
         }
     }
     }
 
 
-    pub fn create_node(&mut self) -> Entry<'_> {
+    pub fn create_node(&mut self) -> EntryBuilder<'_> {
         let mut node = self.nodes.insert();
         let mut node = self.nodes.insert();
         node.insert(Node {
         node.insert(Node {
             parent: None,
             parent: None,
@@ -206,7 +204,7 @@ impl Tree {
         self.set_height(new_id, height);
         self.set_height(new_id, height);
     }
     }
 
 
-    pub fn insert<T: Any>(&mut self, id: NodeId, value: T) {
+    pub fn insert<T: Any + Send + Sync>(&mut self, id: NodeId, value: T) {
         self.nodes.add(id, value);
         self.nodes.add(id, value);
     }
     }
 
 
@@ -214,42 +212,60 @@ impl Tree {
         self.nodes.len()
         self.nodes.len()
     }
     }
 
 
-    pub fn state_view<T: Any>(&self) -> TreeStateView<'_, T> {
+    pub fn state_views(
+        &self,
+        immutable: impl IntoIterator<Item = TypeId>,
+        mutable: impl IntoIterator<Item = TypeId>,
+    ) -> TreeStateView<'_> {
         TreeStateView {
         TreeStateView {
             nodes_data: self.node_slab(),
             nodes_data: self.node_slab(),
-            nodes: self.nodes.get_slab(),
+            nodes: immutable
+                .into_iter()
+                .map(|id| (id, MaybeRead::Read(self.nodes.data.get(&id).unwrap())))
+                .chain(
+                    mutable
+                        .into_iter()
+                        .map(|id| (id, MaybeRead::Write(self.nodes.data.get_mut(&id).unwrap()))),
+                )
+                .collect(),
             root: self.root,
             root: self.root,
         }
         }
     }
     }
 
 
-    pub fn state_view_mut<T: Any>(&mut self) -> TreeStateViewMut<'_, T> {
-        TreeStateViewMut {
-            nodes_data: self.node_slab(),
-            nodes: self.nodes.get_slab_mut(),
-            root: self.root,
-        }
+    pub fn read<T: Any>(&self, id: NodeId) -> Option<&T> {
+        self.nodes.read_slab().get(id)
     }
     }
-}
 
 
-impl NodeDataView for Tree {
-    fn root(&self) -> NodeId {
+    pub fn write<T: Any>(&mut self, id: NodeId) -> Option<&mut T> {
+        self.nodes.write_slab().get_mut(id)
+    }
+
+    pub fn get_node(&self, id: NodeId) -> NodeView<'_> {
+        NodeView { tree: self, id }
+    }
+
+    pub fn contains(&self, id: NodeId) -> bool {
+        self.nodes.contains(id)
+    }
+
+    pub fn root(&self) -> NodeId {
         self.root
         self.root
     }
     }
 
 
-    fn parent_id(&self, id: NodeId) -> Option<NodeId> {
+    pub fn parent_id(&self, id: NodeId) -> Option<NodeId> {
         self.get_node_data(id).parent
         self.get_node_data(id).parent
     }
     }
 
 
-    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
+    pub fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
         Some(self.get_node_data(id).children.clone())
         Some(self.get_node_data(id).children.clone())
     }
     }
 
 
-    fn height(&self, id: NodeId) -> Option<u16> {
+    pub fn height(&self, id: NodeId) -> Option<u16> {
         Some(self.get_node_data(id).height)
         Some(self.get_node_data(id).height)
     }
     }
 }
 }
 
 
-pub trait NodeDataView {
+pub(crate) trait NodeDataView {
     fn root(&self) -> NodeId;
     fn root(&self) -> NodeId;
 
 
     fn parent_id(&self, id: NodeId) -> Option<NodeId>;
     fn parent_id(&self, id: NodeId) -> Option<NodeId>;
@@ -259,7 +275,7 @@ pub trait NodeDataView {
     fn height(&self, id: NodeId) -> Option<u16>;
     fn height(&self, id: NodeId) -> Option<u16>;
 }
 }
 
 
-pub trait TreeView<T>: Sized + NodeDataView {
+trait TreeView<T>: Sized + NodeDataView {
     fn get(&self, id: NodeId) -> Option<&T>;
     fn get(&self, id: NodeId) -> Option<&T>;
 
 
     fn get_unchecked(&self, id: NodeId) -> &T {
     fn get_unchecked(&self, id: NodeId) -> &T {
@@ -298,7 +314,7 @@ pub trait TreeView<T>: Sized + NodeDataView {
     }
     }
 }
 }
 
 
-pub trait TreeViewMut<T>: Sized + TreeView<T> {
+trait TreeViewMut<T>: Sized + TreeView<T> {
     fn get_mut(&mut self, id: NodeId) -> Option<&mut T>;
     fn get_mut(&mut self, id: NodeId) -> Option<&mut T>;
 
 
     unsafe fn get_mut_unchecked(&mut self, id: NodeId) -> &mut T {
     unsafe fn get_mut_unchecked(&mut self, id: NodeId) -> &mut T {
@@ -357,175 +373,91 @@ pub trait TreeViewMut<T>: Sized + TreeView<T> {
     }
     }
 }
 }
 
 
-pub trait TreeLike {
-    fn create_node(&mut self) -> Entry;
-
-    fn add_child(&mut self, parent: NodeId, child: NodeId);
-
-    fn remove(&mut self, id: NodeId);
-
-    fn replace(&mut self, old: NodeId, new: NodeId);
-
-    fn insert_before(&mut self, id: NodeId, new: NodeId);
-
-    fn insert_after(&mut self, id: NodeId, new: NodeId);
-}
-
-pub struct TreeStateView<'a, T> {
-    nodes_data: MappedRwLockReadGuard<'a, SlabStorage<Node>>,
-    nodes: MappedRwLockReadGuard<'a, SlabStorage<T>>,
-    root: NodeId,
+enum MaybeRead<'a> {
+    Read(&'a Box<dyn AnySlabStorageImpl>),
+    Write(&'a mut Box<dyn AnySlabStorageImpl>),
 }
 }
 
 
-pub struct TreeStateViewMut<'a, T> {
-    nodes_data: MappedRwLockReadGuard<'a, SlabStorage<Node>>,
-    nodes: MappedRwLockWriteGuard<'a, SlabStorage<T>>,
-    root: NodeId,
+#[derive(Clone, Copy)]
+struct TreeStateViewEntry<'a> {
+    view: &'a TreeStateView<'a>,
+    id: NodeId,
 }
 }
 
 
-impl<'a, T> NodeDataView for TreeStateView<'a, T> {
-    fn root(&self) -> NodeId {
-        self.root
-    }
-
-    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
-        self.nodes_data.get(id).map(|node| node.children.clone())
-    }
-
-    fn parent_id(&self, id: NodeId) -> Option<NodeId> {
-        self.nodes_data.get(id).and_then(|node| node.parent)
-    }
-
-    fn height(&self, id: NodeId) -> Option<u16> {
-        self.nodes_data.get(id).map(|n| n.height)
+impl<'a> AnyMapLike<'a> for TreeStateViewEntry<'a> {
+    fn get<T: Any>(self) -> Option<&'a T> {
+        self.view.get_slab().and_then(|slab| slab.get(self.id))
     }
     }
 }
 }
 
 
-impl<'a, T> TreeView<T> for TreeStateView<'a, T> {
-    fn get(&self, id: NodeId) -> Option<&T> {
-        self.nodes.get(id)
-    }
-
-    fn children(&self, id: NodeId) -> Option<Vec<&T>> {
-        let ids = self.children_ids(id);
-        ids.map(|ids| ids.iter().map(|id| self.get_unchecked(*id)).collect())
-    }
+pub struct TreeStateView<'a> {
+    nodes_data: &'a SlabStorage<Node>,
+    nodes: hashbrown::HashMap<TypeId, MaybeRead<'a>, BuildHasherDefault<FxHasher>>,
+    root: NodeId,
+}
 
 
-    fn parent(&self, id: NodeId) -> Option<&T> {
-        self.nodes_data
-            .get(id)
-            .and_then(|node| node.parent.map(|id| self.nodes.get(id).unwrap()))
+impl<'a> TreeStateView<'a> {
+    fn get_slab<T: Any>(&self) -> Option<&SlabStorage<T>> {
+        self.nodes
+            .get(&TypeId::of::<T>())
+            .and_then(|gaurd| match gaurd {
+                MaybeRead::Read(gaurd) => gaurd.as_any().downcast_ref::<SlabStorage<T>>(),
+                MaybeRead::Write(gaurd) => gaurd.as_any().downcast_ref::<SlabStorage<T>>(),
+            })
     }
     }
 
 
-    fn get_unchecked(&self, id: NodeId) -> &T {
-        unsafe { &self.nodes.get_unchecked(id) }
+    fn get_slab_mut<T: Any>(&mut self) -> Option<&mut SlabStorage<T>> {
+        self.nodes
+            .get_mut(&TypeId::of::<T>())
+            .and_then(|gaurd| match gaurd {
+                MaybeRead::Read(gaurd) => None,
+                MaybeRead::Write(gaurd) => gaurd.as_any_mut().downcast_mut::<SlabStorage<T>>(),
+            })
     }
     }
-}
 
 
-impl<'a, T> NodeDataView for TreeStateViewMut<'a, T> {
     fn root(&self) -> NodeId {
     fn root(&self) -> NodeId {
         self.root
         self.root
     }
     }
 
 
-    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
+    pub fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
         self.nodes_data.get(id).map(|node| node.children.clone())
         self.nodes_data.get(id).map(|node| node.children.clone())
     }
     }
 
 
-    fn parent_id(&self, id: NodeId) -> Option<NodeId> {
+    pub fn parent_id(&self, id: NodeId) -> Option<NodeId> {
         self.nodes_data.get(id).and_then(|node| node.parent)
         self.nodes_data.get(id).and_then(|node| node.parent)
     }
     }
 
 
-    fn height(&self, id: NodeId) -> Option<u16> {
+    pub fn height(&self, id: NodeId) -> Option<u16> {
         self.nodes_data.get(id).map(|n| n.height)
         self.nodes_data.get(id).map(|n| n.height)
     }
     }
-}
-
-impl<'a, T> TreeView<T> for TreeStateViewMut<'a, T> {
-    fn get(&self, id: NodeId) -> Option<&T> {
-        self.nodes.get(id)
-    }
-
-    fn children(&self, id: NodeId) -> Option<Vec<&T>> {
-        let ids = self.children_ids(id);
-        ids.map(|ids| ids.iter().map(|id| self.get_unchecked(*id)).collect())
-    }
-    fn parent(&self, id: NodeId) -> Option<&T> {
-        self.nodes_data
-            .get(id)
-            .and_then(|node| node.parent.map(|id| self.nodes.get(id).unwrap()))
-    }
-
-    fn get_unchecked(&self, id: NodeId) -> &T {
-        unsafe { &self.nodes.get_unchecked(id) }
-    }
-}
-
-impl<'a, T> TreeViewMut<T> for TreeStateViewMut<'a, T> {
-    fn get_mut(&mut self, id: NodeId) -> Option<&mut T> {
-        self.nodes.get_mut(id)
-    }
 
 
-    fn parent_mut(&mut self, id: NodeId) -> Option<&mut T> {
-        let parent_id = self.parent_id(id)?;
-        unsafe { Some(self.get_mut_unchecked(parent_id)) }
+    pub fn get<T: Dependancy>(&self, id: NodeId) -> Option<T::ElementBorrowed<'_>> {
+        T::borrow_elements_from(self.entry(id))
     }
     }
 
 
-    fn children_mut(&mut self, id: NodeId) -> Option<Vec<&mut T>> {
-        // Safety: No node has itself as a parent.
-        if let Some(children_ids) = self.children_ids(id) {
-            let children_ids = children_ids.to_vec();
-            unsafe {
-                self.nodes
-                    .get_many_mut_unchecked(children_ids.into_iter().rev().map(|id| id))
-            }
-        } else {
-            None
-        }
+    pub fn get_single<T: Any>(&self, id: NodeId) -> Option<&T> {
+        self.get_slab().and_then(|slab| slab.get(id))
     }
     }
 
 
-    unsafe fn get_mut_unchecked(&mut self, id: NodeId) -> &mut T {
-        unsafe { self.nodes.get_unchecked_mut(id) }
+    pub fn get_mut<T: Any>(&mut self, id: NodeId) -> Option<&mut T> {
+        self.get_slab_mut().and_then(|slab| slab.get_mut(id))
     }
     }
 
 
-    fn node_parent_mut(&mut self, id: NodeId) -> Option<(&mut T, Option<&mut T>)> {
-        if let Some(parent_id) = self.parent_id(id) {
-            self.nodes
-                .get2_mut(id, parent_id)
-                .map(|(node, parent)| (node, Some(parent)))
-        } else {
-            self.nodes.get_mut(id).map(|node| (node, None))
-        }
+    fn entry(&self, id: NodeId) -> TreeStateViewEntry<'_> {
+        TreeStateViewEntry { view: self, id }
     }
     }
 
 
-    fn node_parent_children_mut(
-        &mut self,
-        id: NodeId,
-    ) -> Option<(&mut T, Option<&mut T>, Option<Vec<&mut T>>)> {
-        // Safety: No node has itself as a parent.
-        let unbounded_self = unsafe { &mut *(self as *mut Self) };
-        self.node_parent_mut(id).map(move |(node, parent)| {
-            let children = unbounded_self.children_mut(id);
-            (node, parent, children)
+    pub fn children<T: Dependancy>(&self, id: NodeId) -> Option<Vec<T::ElementBorrowed<'_>>> {
+        let ids = self.children_ids(id);
+        ids.and_then(|ids| {
+            ids.iter()
+                .map(|id| T::borrow_elements_from(self.entry(*id)))
+                .collect()
         })
         })
     }
     }
 
 
-    fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Vec<&mut T>)> {
-        // Safety: No node will appear as a child twice
-        if let Some(children_ids) = self.children_ids(id) {
-            debug_assert!(!children_ids.iter().any(|child_id| *child_id == id));
-            let mut borrowed = unsafe {
-                let as_vec = children_ids.to_vec();
-                self.nodes
-                    .get_many_mut_unchecked(
-                        as_vec.into_iter().map(|id| id).chain(std::iter::once(id)),
-                    )
-                    .unwrap()
-            };
-            let node = borrowed.pop().unwrap();
-            Some((node, borrowed))
-        } else {
-            None
-        }
+    pub fn parent<T: Dependancy>(&self, id: NodeId) -> Option<T::ElementBorrowed<'_>> {
+        T::borrow_elements_from(self.entry(id))
     }
     }
 }
 }
 
 
@@ -727,7 +659,7 @@ fn get_node_children_mut() {
 }
 }
 
 
 #[derive(Debug)]
 #[derive(Debug)]
-struct SlabStorage<T> {
+pub(crate) struct SlabStorage<T> {
     data: Vec<Option<T>>,
     data: Vec<Option<T>>,
 }
 }
 
 
@@ -737,7 +669,7 @@ impl<T> Default for SlabStorage<T> {
     }
     }
 }
 }
 
 
-trait AnySlabStorageImpl: Any {
+trait AnySlabStorageImpl: Any + Send + Sync {
     fn remove(&mut self, id: NodeId);
     fn remove(&mut self, id: NodeId);
     fn as_any(&self) -> &dyn Any;
     fn as_any(&self) -> &dyn Any;
     fn as_any_mut(&mut self) -> &mut dyn Any;
     fn as_any_mut(&mut self) -> &mut dyn Any;
@@ -806,7 +738,7 @@ impl<T> SlabStorage<T> {
     }
     }
 }
 }
 
 
-impl<T: 'static> AnySlabStorageImpl for SlabStorage<T> {
+impl<T: 'static + Send + Sync> AnySlabStorageImpl for SlabStorage<T> {
     fn remove(&mut self, id: NodeId) {
     fn remove(&mut self, id: NodeId) {
         self.data[id.0].take();
         self.data[id.0].take();
     }
     }
@@ -820,12 +752,9 @@ impl<T: 'static> AnySlabStorageImpl for SlabStorage<T> {
     }
     }
 }
 }
 
 
-struct AnySlab {
-    data: hashbrown::HashMap<
-        TypeId,
-        RwLock<Box<dyn AnySlabStorageImpl>>,
-        BuildHasherDefault<FxHasher>,
-    >,
+pub(crate) struct AnySlab {
+    data: hashbrown::HashMap<TypeId, Box<dyn AnySlabStorageImpl>, BuildHasherDefault<FxHasher>>,
+    filled: Vec<bool>,
     free: VecDeque<NodeId>,
     free: VecDeque<NodeId>,
     len: usize,
     len: usize,
 }
 }
@@ -850,80 +779,104 @@ impl AnySlab {
     fn new() -> Self {
     fn new() -> Self {
         Self {
         Self {
             data: Default::default(),
             data: Default::default(),
+            filled: Default::default(),
             free: VecDeque::new(),
             free: VecDeque::new(),
             len: 0,
             len: 0,
         }
         }
     }
     }
 
 
-    fn try_get_slab<T: Any>(&self) -> Option<MappedRwLockReadGuard<'_, SlabStorage<T>>> {
+    fn try_read_slab<T: Any>(&self) -> Option<&SlabStorage<T>> {
         self.data
         self.data
             .get(&TypeId::of::<T>())
             .get(&TypeId::of::<T>())
-            .map(|x| RwLockReadGuard::map(x.read(), |x| x.as_any().downcast_ref().unwrap()))
+            .map(|x| x.as_any().downcast_ref().unwrap())
     }
     }
 
 
-    fn get_slab<T: Any>(&self) -> MappedRwLockReadGuard<'_, SlabStorage<T>> {
-        self.try_get_slab().unwrap()
+    fn read_slab<T: Any>(&self) -> &SlabStorage<T> {
+        self.try_read_slab().unwrap()
     }
     }
 
 
-    fn try_get_slab_mut<T: Any>(&self) -> Option<MappedRwLockWriteGuard<'_, SlabStorage<T>>> {
+    fn try_write_slab<T: Any>(&self) -> Option<&mut SlabStorage<T>> {
         self.data
         self.data
             .get(&TypeId::of::<T>())
             .get(&TypeId::of::<T>())
-            .map(|x| RwLockWriteGuard::map(x.write(), |x| x.as_any_mut().downcast_mut().unwrap()))
+            .map(|x| x.as_any_mut().downcast_mut().unwrap())
     }
     }
 
 
-    fn get_slab_mut<T: Any>(&self) -> MappedRwLockWriteGuard<'_, SlabStorage<T>> {
-        self.try_get_slab_mut().unwrap()
+    fn write_slab<T: Any>(&self) -> &mut SlabStorage<T> {
+        self.try_write_slab().unwrap()
     }
     }
 
 
-    fn get_or_insert_slab_mut<T: Any>(&mut self) -> MappedRwLockWriteGuard<'_, SlabStorage<T>> {
-        RwLockWriteGuard::map(
-            self.data
-                .entry(TypeId::of::<T>())
-                .or_insert_with(|| RwLock::new(Box::new(SlabStorage::<T>::default())))
-                .write(),
-            |x| x.as_any_mut().downcast_mut().unwrap(),
-        )
+    fn get_slab_mut_borrow<T: Any>(&mut self) -> &mut SlabStorage<T> {
+        self.data
+            .get_mut(&TypeId::of::<T>())
+            .unwrap()
+            .as_any_mut()
+            .downcast_mut()
+            .unwrap()
     }
     }
 
 
-    fn insert(&mut self) -> Entry<'_> {
+    fn get_or_insert_slab_mut<T: Any + Send + Sync>(&mut self) -> &mut SlabStorage<T> {
+        self.data
+            .entry(TypeId::of::<T>())
+            .or_insert_with(|| Box::new(SlabStorage::<T>::default()))
+            .as_any_mut()
+            .downcast_mut()
+            .unwrap()
+    }
+
+    fn insert(&mut self) -> EntryBuilder<'_> {
         let id = if let Some(id) = self.free.pop_front() {
         let id = if let Some(id) = self.free.pop_front() {
+            self.filled[id.0] = true;
             id
             id
         } else {
         } else {
             let id = self.len;
             let id = self.len;
+            self.filled.push(true);
             self.len += 1;
             self.len += 1;
             NodeId(id)
             NodeId(id)
         };
         };
-        Entry { id, inner: self }
+        EntryBuilder { id, inner: self }
     }
     }
 
 
-    fn add<T: Any>(&mut self, id: NodeId, value: T) {
+    fn add<T: Any + Send + Sync>(&mut self, id: NodeId, value: T) {
         self.get_or_insert_slab_mut().insert(id, value);
         self.get_or_insert_slab_mut().insert(id, value);
     }
     }
 
 
     fn remove(&mut self, id: NodeId) {
     fn remove(&mut self, id: NodeId) {
         for slab in self.data.values_mut() {
         for slab in self.data.values_mut() {
-            slab.write().remove(id);
+            slab.remove(id);
         }
         }
+        self.filled[id.0] = true;
         self.free.push_back(id);
         self.free.push_back(id);
     }
     }
 
 
     fn len(&self) -> usize {
     fn len(&self) -> usize {
         self.len - self.free.len()
         self.len - self.free.len()
     }
     }
+
+    fn contains(&self, id: NodeId) -> bool {
+        self.filled.get(id.0).copied().unwrap_or_default()
+    }
 }
 }
 
 
-pub struct Entry<'a> {
+pub struct EntryBuilder<'a> {
     id: NodeId,
     id: NodeId,
     inner: &'a mut AnySlab,
     inner: &'a mut AnySlab,
 }
 }
 
 
-impl Entry<'_> {
-    pub fn insert<T: Any>(&mut self, value: T) {
+impl EntryBuilder<'_> {
+    pub fn insert<T: Any + Send + Sync>(&mut self, value: T) {
         self.inner
         self.inner
             .get_or_insert_slab_mut::<T>()
             .get_or_insert_slab_mut::<T>()
             .insert(self.id, value);
             .insert(self.id, value);
     }
     }
 
 
+    pub fn get<T: Any>(&self) -> Option<&T> {
+        self.inner.read_slab().get(self.id)
+    }
+
+    pub fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
+        self.inner.write_slab().get_mut(self.id)
+    }
+
     pub fn remove(self) {
     pub fn remove(self) {
         self.inner.remove(self.id);
         self.inner.remove(self.id);
     }
     }
@@ -946,7 +899,7 @@ fn remove() {
 
 
     slab.remove(node1_id);
     slab.remove(node1_id);
 
 
-    assert!(slab.get_slab::<i32>().get(node1_id).is_none());
+    assert!(slab.read_slab::<i32>().get(node1_id).is_none());
     assert_eq!(slab.len(), 1);
     assert_eq!(slab.len(), 1);
 }
 }
 
 
@@ -966,7 +919,7 @@ fn get_many_mut_unchecked() {
     println!("ids: {:#?}", [parent, child, grandchild]);
     println!("ids: {:#?}", [parent, child, grandchild]);
 
 
     {
     {
-        let mut i32_slab = slab.get_slab_mut::<i32>();
+        let mut i32_slab = slab.write_slab::<i32>();
         let all =
         let all =
             unsafe { i32_slab.get_many_mut_unchecked([parent, child, grandchild].into_iter()) }
             unsafe { i32_slab.get_many_mut_unchecked([parent, child, grandchild].into_iter()) }
                 .unwrap();
                 .unwrap();
@@ -974,7 +927,7 @@ fn get_many_mut_unchecked() {
     }
     }
 
 
     {
     {
-        let mut i32_slab = slab.get_slab_mut::<i32>();
+        let mut i32_slab = slab.write_slab::<i32>();
         assert!(
         assert!(
             unsafe { i32_slab.get_many_mut_unchecked([NodeId(3), NodeId(100)].into_iter()) }
             unsafe { i32_slab.get_many_mut_unchecked([NodeId(3), NodeId(100)].into_iter()) }
                 .is_none()
                 .is_none()
@@ -1001,8 +954,8 @@ fn get_many_many_mut_unchecked() {
 
 
     println!("slab: {:#?}", slab);
     println!("slab: {:#?}", slab);
 
 
-    let mut num_entries = slab.get_slab_mut::<i32>();
-    let mut str_entries = slab.get_slab_mut::<&str>();
+    let mut num_entries = slab.write_slab::<i32>();
+    let mut str_entries = slab.write_slab::<&str>();
 
 
     let all_num = unsafe {
     let all_num = unsafe {
         num_entries
         num_entries

+ 2 - 2
packages/native-core/src/utils/mod.rs

@@ -1,3 +1,3 @@
-mod persistant_iterator;
-pub use persistant_iterator::*;
+// mod persistant_iterator;
+// pub use persistant_iterator::*;
 pub mod cursor;
 pub mod cursor;

+ 0 - 2
packages/native-core/src/utils/persistant_iterator.rs

@@ -2,8 +2,6 @@ use crate::{
     node::{ElementNode, FromAnyValue, NodeType},
     node::{ElementNode, FromAnyValue, NodeType},
     passes::{AnyMapLike, TypeErasedPass},
     passes::{AnyMapLike, TypeErasedPass},
     real_dom::RealDom,
     real_dom::RealDom,
-    state::State,
-    tree::TreeView,
     NodeId,
     NodeId,
 };
 };
 use dioxus_core::{Mutation, Mutations};
 use dioxus_core::{Mutation, Mutations};