浏览代码

make dioxus an optional dependancy

Evan Almloff 2 年之前
父节点
当前提交
e4c7218fe8

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

@@ -36,5 +36,5 @@ tokio = { version = "*", features = ["full"] }
 dioxus-native-core = { path = ".", features = ["dioxus"] }
 dioxus-native-core = { path = ".", features = ["dioxus"] }
 
 
 [features]
 [features]
-default = ["dioxus"]
+default = []
 dioxus = ["dioxus-core"]
 dioxus = ["dioxus-core"]

+ 1 - 1
packages/native-core/src/dioxus.rs

@@ -15,7 +15,7 @@ pub struct DioxusState {
 }
 }
 
 
 impl DioxusState {
 impl DioxusState {
-    pub fn new(rdom: &mut RealDom) -> Self {
+    pub fn create(rdom: &mut RealDom) -> Self {
         rdom.insert_slab::<ElementId>();
         rdom.insert_slab::<ElementId>();
         let root_id = rdom.root_id();
         let root_id = rdom.root_id();
         let mut root = rdom.get_mut(root_id).unwrap();
         let mut root = rdom.get_mut(root_id).unwrap();

+ 7 - 7
packages/native-core/src/node_ref.rs

@@ -203,12 +203,12 @@ impl NodeMask {
 }
 }
 
 
 #[derive(PartialEq, Eq, Clone, Debug)]
 #[derive(PartialEq, Eq, Clone, Debug)]
-pub enum AttributeMaskBuilder {
+pub enum AttributeMaskBuilder<'a> {
     All,
     All,
-    Some(&'static [&'static str]),
+    Some(&'a [&'a str]),
 }
 }
 
 
-impl Default for AttributeMaskBuilder {
+impl Default for AttributeMaskBuilder<'_> {
     fn default() -> Self {
     fn default() -> Self {
         AttributeMaskBuilder::Some(&[])
         AttributeMaskBuilder::Some(&[])
     }
     }
@@ -216,15 +216,15 @@ impl Default for AttributeMaskBuilder {
 
 
 /// A mask that limits what parts of a node a dependency can see.
 /// A mask that limits what parts of a node a dependency can see.
 #[derive(Default, PartialEq, Eq, Clone, Debug)]
 #[derive(Default, PartialEq, Eq, Clone, Debug)]
-pub struct NodeMaskBuilder {
-    attritutes: AttributeMaskBuilder,
+pub struct NodeMaskBuilder<'a> {
+    attritutes: AttributeMaskBuilder<'a>,
     tag: bool,
     tag: bool,
     namespace: bool,
     namespace: bool,
     text: bool,
     text: bool,
     listeners: bool,
     listeners: bool,
 }
 }
 
 
-impl NodeMaskBuilder {
+impl<'a> NodeMaskBuilder<'a> {
     /// A node mask with no parts visible.
     /// A node mask with no parts visible.
     pub const NONE: Self = Self::new();
     pub const NONE: Self = Self::new();
     /// A node mask with every part visible.
     /// A node mask with every part visible.
@@ -246,7 +246,7 @@ impl NodeMaskBuilder {
     }
     }
 
 
     /// Allow the mask to view the given attributes
     /// Allow the mask to view the given attributes
-    pub const fn with_attrs(mut self, attritutes: AttributeMaskBuilder) -> Self {
+    pub const fn with_attrs(mut self, attritutes: AttributeMaskBuilder<'a>) -> Self {
         self.attritutes = attritutes;
         self.attritutes = attritutes;
         self
         self
     }
     }

+ 13 - 12
packages/native-core/src/passes.rs

@@ -64,14 +64,15 @@ impl DirtyNodeStates {
     }
     }
 
 
     pub fn insert(&self, pass_id: TypeId, node_id: NodeId, height: u16) {
     pub fn insert(&self, pass_id: TypeId, node_id: NodeId, height: u16) {
-        let btree = self.dirty.get(&pass_id).unwrap();
-        let mut write = btree.write();
-        if let Some(entry) = write.get_mut(&height) {
-            entry.add_node(node_id);
-        } else {
-            let mut entry = DirtyNodes::default();
-            entry.add_node(node_id);
-            write.insert(height, entry);
+        if let Some(btree) = self.dirty.get(&pass_id) {
+            let mut write = btree.write();
+            if let Some(entry) = write.get_mut(&height) {
+                entry.add_node(node_id);
+            } else {
+                let mut entry = DirtyNodes::default();
+                entry.add_node(node_id);
+                write.insert(height, entry);
+            }
         }
         }
     }
     }
 
 
@@ -109,7 +110,7 @@ pub trait Pass<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
     type ChildDependencies: Dependancy;
     type ChildDependencies: Dependancy;
     /// This is a tuple of (T: Any, ..)
     /// This is a tuple of (T: Any, ..)
     type NodeDependencies: Dependancy;
     type NodeDependencies: Dependancy;
-    const NODE_MASK: NodeMaskBuilder;
+    const NODE_MASK: NodeMaskBuilder<'static>;
 
 
     fn pass<'a>(
     fn pass<'a>(
         &mut self,
         &mut self,
@@ -137,12 +138,12 @@ pub trait Pass<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
         }
         }
         // this type cannot be both a parent and child dependency
         // this type cannot be both a parent and child dependency
         assert!(
         assert!(
-            Self::parent_type_ids()
+            !(Self::parent_type_ids()
                 .iter()
                 .iter()
-                .any(|type_id| *type_id != TypeId::of::<Self>())
+                .any(|type_id| *type_id == TypeId::of::<Self>())
                 && Self::child_type_ids()
                 && Self::child_type_ids()
                     .iter()
                     .iter()
-                    .any(|type_id| *type_id != TypeId::of::<Self>()),
+                    .any(|type_id| *type_id == TypeId::of::<Self>())),
             "The current type cannot be a parent and child dependency"
             "The current type cannot be a parent and child dependency"
         );
         );
         // no states have the same type id
         // no states have the same type id

+ 127 - 87
packages/native-core/src/real_dom.rs

@@ -1,15 +1,57 @@
 use rustc_hash::{FxHashMap, FxHashSet};
 use rustc_hash::{FxHashMap, FxHashSet};
 use std::any::{Any, TypeId};
 use std::any::{Any, TypeId};
 use std::collections::VecDeque;
 use std::collections::VecDeque;
+use std::rc::Rc;
 
 
 use crate::node::{
 use crate::node::{
     ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue,
     ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue,
 };
 };
-use crate::node_ref::{AttributeMask, NodeMask, NodeMaskBuilder};
+use crate::node_ref::{NodeMask, NodeMaskBuilder};
 use crate::passes::{resolve_passes, DirtyNodeStates, TypeErasedPass};
 use crate::passes::{resolve_passes, DirtyNodeStates, TypeErasedPass};
+use crate::prelude::AttributeMaskBuilder;
 use crate::tree::{NodeId, Tree};
 use crate::tree::{NodeId, Tree};
 use crate::{FxDashSet, SendAnyMap};
 use crate::{FxDashSet, SendAnyMap};
 
 
+struct NodesDirty<V: FromAnyValue + Send + Sync> {
+    passes_updated: FxHashMap<NodeId, FxHashSet<TypeId>>,
+    nodes_updated: FxHashMap<NodeId, NodeMask>,
+    passes: Rc<Box<[TypeErasedPass<V>]>>,
+}
+
+impl<V: FromAnyValue + Send + Sync> NodesDirty<V> {
+    fn mark_dirty(&mut self, node_id: NodeId, mask: NodeMask) {
+        self.passes_updated.entry(node_id).or_default().extend(
+            self.passes
+                .iter()
+                .filter_map(|x| x.mask.overlaps(&mask).then_some(x.this_type_id)),
+        );
+        let nodes_updated = &mut self.nodes_updated;
+        if let Some(node) = nodes_updated.get_mut(&node_id) {
+            *node = node.union(&mask);
+        } else {
+            nodes_updated.insert(node_id, mask);
+        }
+    }
+
+    fn mark_parent_added_or_removed(&mut self, node_id: NodeId) {
+        let hm = self.passes_updated.entry(node_id).or_default();
+        for pass in &**self.passes {
+            if pass.parent_dependant {
+                hm.insert(pass.this_type_id);
+            }
+        }
+    }
+
+    fn mark_child_changed(&mut self, node_id: NodeId) {
+        let hm = self.passes_updated.entry(node_id).or_default();
+        for pass in &**self.passes {
+            if pass.child_dependant {
+                hm.insert(pass.this_type_id);
+            }
+        }
+    }
+}
+
 /// 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.
 /// The render state passes from parent to children and or accumulates state from children to parents.
 /// The render state passes from parent to children and or accumulates state from children to parents.
 /// To get started implement [crate::state::ParentDepState], [crate::state::NodeDepState], or [crate::state::ChildDepState] and call [RealDom::apply_mutations] to update the dom and [RealDom::update_state] to update the state of the nodes.
 /// To get started implement [crate::state::ParentDepState], [crate::state::NodeDepState], or [crate::state::ChildDepState] and call [RealDom::apply_mutations] to update the dom and [RealDom::update_state] to update the state of the nodes.
@@ -19,9 +61,8 @@ use crate::{FxDashSet, SendAnyMap};
 pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
 pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
     pub(crate) tree: Tree,
     pub(crate) tree: Tree,
     nodes_listening: FxHashMap<String, FxHashSet<NodeId>>,
     nodes_listening: FxHashMap<String, FxHashSet<NodeId>>,
-    pub(crate) passes: Box<[TypeErasedPass<V>]>,
-    passes_updated: FxHashMap<NodeId, FxHashSet<TypeId>>,
-    nodes_updated: FxHashMap<NodeId, NodeMask>,
+    pub(crate) passes: Rc<Box<[TypeErasedPass<V>]>>,
+    dirty_nodes: NodesDirty<V>,
     phantom: std::marker::PhantomData<V>,
     phantom: std::marker::PhantomData<V>,
 }
 }
 
 
@@ -53,6 +94,7 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
                 }
                 }
             }
             }
         }
         }
+        let passes = Rc::new(passes);
 
 
         let mut passes_updated = FxHashMap::default();
         let mut passes_updated = FxHashMap::default();
         let mut nodes_updated = FxHashMap::default();
         let mut nodes_updated = FxHashMap::default();
@@ -64,50 +106,22 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         RealDom {
         RealDom {
             tree,
             tree,
             nodes_listening: FxHashMap::default(),
             nodes_listening: FxHashMap::default(),
-            passes,
-            passes_updated,
-            nodes_updated,
+            passes: passes.clone(),
+            dirty_nodes: NodesDirty {
+                passes_updated,
+                nodes_updated,
+                passes,
+            },
             phantom: std::marker::PhantomData,
             phantom: std::marker::PhantomData,
         }
         }
     }
     }
 
 
-    fn mark_dirty(&mut self, node_id: NodeId, mask: NodeMask) {
-        self.passes_updated.entry(node_id).or_default().extend(
-            self.passes
-                .iter()
-                .filter_map(|x| x.mask.overlaps(&mask).then_some(x.this_type_id)),
-        );
-        let nodes_updated = &mut self.nodes_updated;
-        if let Some(node) = nodes_updated.get_mut(&node_id) {
-            *node = node.union(&mask);
-        } else {
-            nodes_updated.insert(node_id, mask);
-        }
-    }
-
-    fn mark_parent_added_or_removed(&mut self, node_id: NodeId) {
-        let hm = self.passes_updated.entry(node_id).or_default();
-        for pass in &*self.passes {
-            if pass.parent_dependant {
-                hm.insert(pass.this_type_id);
-            }
-        }
-    }
-
-    fn mark_child_changed(&mut self, node_id: NodeId) {
-        let hm = self.passes_updated.entry(node_id).or_default();
-        for pass in &*self.passes {
-            if pass.child_dependant {
-                hm.insert(pass.this_type_id);
-            }
-        }
-    }
-
     pub fn create_node(&mut self, node: NodeType<V>, mark_dirty: bool) -> NodeMut<'_, V> {
     pub fn create_node(&mut self, node: NodeType<V>, mark_dirty: bool) -> NodeMut<'_, V> {
         let mut node_entry = self.tree.create_node();
         let mut node_entry = self.tree.create_node();
         let id = node_entry.id();
         let id = node_entry.id();
         if mark_dirty {
         if mark_dirty {
-            self.passes_updated
+            self.dirty_nodes
+                .passes_updated
                 .entry(id)
                 .entry(id)
                 .or_default()
                 .or_default()
                 .extend(self.passes.iter().map(|x| x.this_type_id));
                 .extend(self.passes.iter().map(|x| x.this_type_id));
@@ -186,8 +200,8 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         ctx: SendAnyMap,
         ctx: SendAnyMap,
         parallel: bool,
         parallel: bool,
     ) -> (FxDashSet<NodeId>, FxHashMap<NodeId, NodeMask>) {
     ) -> (FxDashSet<NodeId>, FxHashMap<NodeId, NodeMask>) {
-        let passes = std::mem::take(&mut self.passes_updated);
-        let nodes_updated = std::mem::take(&mut self.nodes_updated);
+        let passes = std::mem::take(&mut self.dirty_nodes.passes_updated);
+        let nodes_updated = std::mem::take(&mut self.dirty_nodes.nodes_updated);
         let dirty_nodes = DirtyNodeStates::with_passes(self.passes.iter().map(|p| p.this_type_id));
         let dirty_nodes = DirtyNodeStates::with_passes(self.passes.iter().map(|p| p.this_type_id));
         for (node_id, passes) in passes {
         for (node_id, passes) in passes {
             // 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
@@ -206,15 +220,15 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
 
 
     pub fn remove(&mut self, id: NodeId) {
     pub 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.dirty_nodes.mark_child_changed(parent_id);
         }
         }
         self.tree.remove(id)
         self.tree.remove(id)
     }
     }
 
 
     pub fn replace(&mut self, old: NodeId, new: NodeId) {
     pub 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_parent_added_or_removed(new);
+            self.dirty_nodes.mark_child_changed(parent_id);
+            self.dirty_nodes.mark_parent_added_or_removed(new);
         }
         }
         self.tree.replace(old, new);
         self.tree.replace(old, new);
     }
     }
@@ -376,16 +390,11 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeImmutable<V> for NodeRef<'a, V> {
 pub struct NodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
 pub struct NodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
     id: NodeId,
     id: NodeId,
     dom: &'a mut RealDom<V>,
     dom: &'a mut RealDom<V>,
-    dirty: NodeMask,
 }
 }
 
 
 impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
 impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
     pub fn new(id: NodeId, dom: &'a mut RealDom<V>) -> Self {
     pub fn new(id: NodeId, dom: &'a mut RealDom<V>) -> Self {
-        Self {
-            id,
-            dom,
-            dirty: NodeMask::default(),
-        }
+        Self { id, dom }
     }
     }
 }
 }
 
 
@@ -407,6 +416,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
     fn get_mut<T: Any + Sync + Send>(&mut self) -> Option<&mut T> {
     fn get_mut<T: Any + Sync + Send>(&mut self) -> Option<&mut T> {
         // mark the node state as dirty
         // mark the node state as dirty
         self.dom
         self.dom
+            .dirty_nodes
             .passes_updated
             .passes_updated
             .entry(self.id)
             .entry(self.id)
             .or_default()
             .or_default()
@@ -417,6 +427,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
     fn insert<T: Any + Sync + Send>(&mut self, value: T) {
     fn insert<T: Any + Sync + Send>(&mut self, value: T) {
         // mark the node state as dirty
         // mark the node state as dirty
         self.dom
         self.dom
+            .dirty_nodes
             .passes_updated
             .passes_updated
             .entry(self.id)
             .entry(self.id)
             .or_default()
             .or_default()
@@ -427,8 +438,8 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
     fn insert_after(&mut self, old: NodeId) {
     fn insert_after(&mut self, old: NodeId) {
         let id = self.id();
         let id = self.id();
         if let Some(parent_id) = self.dom.tree.parent_id(old) {
         if let Some(parent_id) = self.dom.tree.parent_id(old) {
-            self.dom.mark_child_changed(parent_id);
-            self.dom.mark_parent_added_or_removed(id);
+            self.dom.dirty_nodes.mark_child_changed(parent_id);
+            self.dom.dirty_nodes.mark_parent_added_or_removed(id);
         }
         }
         self.dom.tree.insert_after(old, id);
         self.dom.tree.insert_after(old, id);
     }
     }
@@ -436,16 +447,20 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
     fn insert_before(&mut self, old: NodeId) {
     fn insert_before(&mut self, old: NodeId) {
         let id = self.id();
         let id = self.id();
         if let Some(parent_id) = self.dom.tree.parent_id(old) {
         if let Some(parent_id) = self.dom.tree.parent_id(old) {
-            self.dom.mark_child_changed(parent_id);
-            self.dom.mark_parent_added_or_removed(id);
+            self.dom.dirty_nodes.mark_child_changed(parent_id);
+            self.dom.dirty_nodes.mark_parent_added_or_removed(id);
         }
         }
         self.dom.tree.insert_before(old, id);
         self.dom.tree.insert_before(old, id);
     }
     }
 
 
     fn add_event_listener(&mut self, event: &str) {
     fn add_event_listener(&mut self, event: &str) {
         let id = self.id();
         let id = self.id();
-        if let NodeTypeMut::Element(mut element) = self.node_type_mut() {
-            element.listeners_mut().insert(event.to_string());
+        let node_type: &mut NodeType<V> = self.dom.tree.get_mut(self.id).unwrap();
+        if let NodeType::Element(ElementNode { listeners, .. }) = node_type {
+            self.dom
+                .dirty_nodes
+                .mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
+            listeners.insert(event.to_string());
             match self.dom.nodes_listening.get_mut(event) {
             match self.dom.nodes_listening.get_mut(event) {
                 Some(hs) => {
                 Some(hs) => {
                     hs.insert(id);
                     hs.insert(id);
@@ -461,21 +476,33 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
 
 
     fn remove_event_listener(&mut self, event: &str) {
     fn remove_event_listener(&mut self, event: &str) {
         let id = self.id();
         let id = self.id();
-        if let NodeTypeMut::Element(mut element) = self.node_type_mut() {
-            element.listeners_mut().remove(event);
+        let node_type: &mut NodeType<V> = self.dom.tree.get_mut(self.id).unwrap();
+        if let NodeType::Element(ElementNode { listeners, .. }) = node_type {
+            self.dom
+                .dirty_nodes
+                .mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
+            listeners.remove(event);
+
+            self.dom.nodes_listening.get_mut(event).unwrap().remove(&id);
         }
         }
-        self.dom.nodes_listening.get_mut(event).unwrap().remove(&id);
     }
     }
 }
 }
 
 
 impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
 impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
     pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
     pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
-        let Self { id, dom, dirty } = self;
-        let node_type = dom.tree.get_mut::<NodeType<V>>(*id).unwrap();
+        let Self { id, dom } = self;
+        let RealDom {
+            dirty_nodes, tree, ..
+        } = dom;
+        let node_type = tree.get_mut(*id).unwrap();
         match node_type {
         match node_type {
-            NodeType::Element(element) => NodeTypeMut::Element(ElementNodeMut { element, dirty }),
+            NodeType::Element(element) => NodeTypeMut::Element(ElementNodeMut {
+                id: *id,
+                element,
+                dirty_nodes,
+            }),
             NodeType::Text(text) => {
             NodeType::Text(text) => {
-                dirty.set_text();
+                dirty_nodes.mark_dirty(self.id, NodeMaskBuilder::new().with_text().build());
                 NodeTypeMut::Text(text)
                 NodeTypeMut::Text(text)
             }
             }
             NodeType::Placeholder => NodeTypeMut::Placeholder,
             NodeType::Placeholder => NodeTypeMut::Placeholder,
@@ -484,35 +511,32 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
 
 
     pub fn set_type(&mut self, new: NodeType<V>) {
     pub fn set_type(&mut self, new: NodeType<V>) {
         *self.dom.tree.get_mut::<NodeType<V>>(self.id).unwrap() = new;
         *self.dom.tree.get_mut::<NodeType<V>>(self.id).unwrap() = new;
-        self.dirty = NodeMaskBuilder::ALL.build();
-    }
-}
-
-impl<V: FromAnyValue + Send + Sync> Drop for NodeMut<'_, V> {
-    fn drop(&mut self) {
-        let mask = std::mem::take(&mut self.dirty);
-        self.dom.mark_dirty(self.id, mask);
+        self.dom
+            .dirty_nodes
+            .mark_dirty(self.id, NodeMaskBuilder::ALL.build())
     }
     }
 }
 }
 
 
-pub enum NodeTypeMut<'a, V: FromAnyValue = ()> {
+pub enum NodeTypeMut<'a, V: FromAnyValue + Send + Sync = ()> {
     Element(ElementNodeMut<'a, V>),
     Element(ElementNodeMut<'a, V>),
     Text(&'a mut String),
     Text(&'a mut String),
     Placeholder,
     Placeholder,
 }
 }
 
 
-pub struct ElementNodeMut<'a, V: FromAnyValue = ()> {
+pub struct ElementNodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
+    id: NodeId,
     element: &'a mut ElementNode<V>,
     element: &'a mut ElementNode<V>,
-    dirty: &'a mut NodeMask,
+    dirty_nodes: &'a mut NodesDirty<V>,
 }
 }
 
 
-impl<V: FromAnyValue> ElementNodeMut<'_, V> {
+impl<V: FromAnyValue + Send + Sync> ElementNodeMut<'_, V> {
     pub fn tag(&self) -> &str {
     pub fn tag(&self) -> &str {
         &self.element.tag
         &self.element.tag
     }
     }
 
 
     pub fn tag_mut(&mut self) -> &mut String {
     pub fn tag_mut(&mut self) -> &mut String {
-        self.dirty.set_tag();
+        self.dirty_nodes
+            .mark_dirty(self.id, NodeMaskBuilder::new().with_tag().build());
         &mut self.element.tag
         &mut self.element.tag
     }
     }
 
 
@@ -521,7 +545,8 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
     }
     }
 
 
     pub fn namespace_mut(&mut self) -> &mut Option<String> {
     pub fn namespace_mut(&mut self) -> &mut Option<String> {
-        self.dirty.set_namespace();
+        self.dirty_nodes
+            .mark_dirty(self.id, NodeMaskBuilder::new().with_namespace().build());
         &mut self.element.namespace
         &mut self.element.namespace
     }
     }
 
 
@@ -532,7 +557,12 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
     pub fn attributes_mut(
     pub fn attributes_mut(
         &mut self,
         &mut self,
     ) -> &mut FxHashMap<OwnedAttributeDiscription, OwnedAttributeValue<V>> {
     ) -> &mut FxHashMap<OwnedAttributeDiscription, OwnedAttributeValue<V>> {
-        self.dirty.add_attributes(AttributeMask::All);
+        self.dirty_nodes.mark_dirty(
+            self.id,
+            NodeMaskBuilder::new()
+                .with_attrs(AttributeMaskBuilder::All)
+                .build(),
+        );
         &mut self.element.attributes
         &mut self.element.attributes
     }
     }
 
 
@@ -541,7 +571,12 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
         name: OwnedAttributeDiscription,
         name: OwnedAttributeDiscription,
         value: OwnedAttributeValue<V>,
         value: OwnedAttributeValue<V>,
     ) -> Option<OwnedAttributeValue<V>> {
     ) -> Option<OwnedAttributeValue<V>> {
-        self.dirty.add_attributes(AttributeMask::single(&name.name));
+        self.dirty_nodes.mark_dirty(
+            self.id,
+            NodeMaskBuilder::new()
+                .with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
+                .build(),
+        );
         self.element.attributes.insert(name, value)
         self.element.attributes.insert(name, value)
     }
     }
 
 
@@ -549,7 +584,12 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
         &mut self,
         &mut self,
         name: &OwnedAttributeDiscription,
         name: &OwnedAttributeDiscription,
     ) -> Option<OwnedAttributeValue<V>> {
     ) -> Option<OwnedAttributeValue<V>> {
-        self.dirty.add_attributes(AttributeMask::single(&name.name));
+        self.dirty_nodes.mark_dirty(
+            self.id,
+            NodeMaskBuilder::new()
+                .with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
+                .build(),
+        );
         self.element.attributes.remove(name)
         self.element.attributes.remove(name)
     }
     }
 
 
@@ -557,18 +597,18 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
         &mut self,
         &mut self,
         name: &OwnedAttributeDiscription,
         name: &OwnedAttributeDiscription,
     ) -> Option<&mut OwnedAttributeValue<V>> {
     ) -> Option<&mut OwnedAttributeValue<V>> {
-        self.dirty.add_attributes(AttributeMask::single(&name.name));
+        self.dirty_nodes.mark_dirty(
+            self.id,
+            NodeMaskBuilder::new()
+                .with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
+                .build(),
+        );
         self.element.attributes.get_mut(name)
         self.element.attributes.get_mut(name)
     }
     }
 
 
     pub fn listeners(&self) -> &FxHashSet<String> {
     pub fn listeners(&self) -> &FxHashSet<String> {
         &self.element.listeners
         &self.element.listeners
     }
     }
-
-    pub fn listeners_mut(&mut self) -> &mut FxHashSet<String> {
-        self.dirty.set_listeners();
-        &mut self.element.listeners
-    }
 }
 }
 
 
 pub struct NodeMutRaw<'a, V: FromAnyValue + Send + Sync = ()> {
 pub struct NodeMutRaw<'a, V: FromAnyValue + Send + Sync = ()> {

+ 8 - 2
packages/native-core/src/tree.rs

@@ -249,7 +249,13 @@ pub struct TreeStateViewEntry<'a, 'b> {
 
 
 impl<'a, 'b> AnyMapLike<'a> for TreeStateViewEntry<'a, 'b> {
 impl<'a, 'b> AnyMapLike<'a> for TreeStateViewEntry<'a, 'b> {
     fn get<T: Any + Sync + Send>(self) -> Option<&'a T> {
     fn get<T: Any + Sync + Send>(self) -> Option<&'a T> {
-        self.view.get_slab().and_then(|slab| slab.get(self.id))
+        let slab = self.view.get_slab();
+        dbg!(slab.is_some());
+        slab.and_then(|slab| {
+            let r = slab.get(self.id);
+            dbg!(r.is_some());
+            r
+        })
     }
     }
 }
 }
 
 
@@ -315,7 +321,7 @@ impl<'a, 'b> TreeStateView<'a, 'b> {
     }
     }
 
 
     pub fn parent<T: Dependancy>(&self, id: NodeId) -> Option<T::ElementBorrowed<'_>> {
     pub fn parent<T: Dependancy>(&self, id: NodeId) -> Option<T::ElementBorrowed<'_>> {
-        T::borrow_elements_from(self.entry(id))
+        T::borrow_elements_from(self.entry(self.parent_id(id)?))
     }
     }
 }
 }
 
 

+ 7 - 4
packages/native-core/tests/fuzzing.rs

@@ -1,6 +1,7 @@
 use dioxus::prelude::Props;
 use dioxus::prelude::Props;
 use dioxus_core::*;
 use dioxus_core::*;
 use dioxus_native_core::{
 use dioxus_native_core::{
+    dioxus::DioxusState,
     node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
     node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
     real_dom::RealDom,
     real_dom::RealDom,
     Dependancy, Pass, SendAnyMap,
     Dependancy, Pass, SendAnyMap,
@@ -302,7 +303,7 @@ impl Pass for BlablaState {
     type ChildDependencies = ();
     type ChildDependencies = ();
     type NodeDependencies = ();
     type NodeDependencies = ();
 
 
-    const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new()
+    const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new()
         .with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
         .with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
         .with_element();
         .with_element();
 
 
@@ -348,7 +349,8 @@ fn create() {
         );
         );
         let mutations = vdom.rebuild();
         let mutations = vdom.rebuild();
         let mut rdom: RealDom = RealDom::new(Box::new([BlablaState::to_type_erased()]));
         let mut rdom: RealDom = RealDom::new(Box::new([BlablaState::to_type_erased()]));
-        rdom.apply_mutations(mutations);
+        let mut dioxus_state = DioxusState::create(&mut rdom);
+        dioxus_state.apply_mutations(&mut rdom, mutations);
 
 
         let ctx = SendAnyMap::new();
         let ctx = SendAnyMap::new();
         rdom.update_state(ctx, false);
         rdom.update_state(ctx, false);
@@ -369,13 +371,14 @@ fn diff() {
         );
         );
         let mutations = vdom.rebuild();
         let mutations = vdom.rebuild();
         let mut rdom: RealDom = RealDom::new(Box::new([BlablaState::to_type_erased()]));
         let mut rdom: RealDom = RealDom::new(Box::new([BlablaState::to_type_erased()]));
-        rdom.apply_mutations(mutations);
+        let mut dioxus_state = DioxusState::create(&mut rdom);
+        dioxus_state.apply_mutations(&mut rdom, mutations);
 
 
         let ctx = SendAnyMap::new();
         let ctx = SendAnyMap::new();
         rdom.update_state(ctx, false);
         rdom.update_state(ctx, false);
         for _ in 0..10 {
         for _ in 0..10 {
             let mutations = vdom.render_immediate();
             let mutations = vdom.render_immediate();
-            rdom.apply_mutations(mutations);
+            dioxus_state.apply_mutations(&mut rdom, mutations);
 
 
             let ctx = SendAnyMap::new();
             let ctx = SendAnyMap::new();
             rdom.update_state(ctx, false);
             rdom.update_state(ctx, false);

+ 10 - 5
packages/native-core/tests/miri_native.rs

@@ -1,10 +1,14 @@
 use dioxus::prelude::*;
 use dioxus::prelude::*;
 use dioxus_native_core::{
 use dioxus_native_core::{
+    dioxus::DioxusState,
     node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
     node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
     real_dom::RealDom,
     real_dom::RealDom,
     Dependancy, Pass, SendAnyMap,
     Dependancy, Pass, SendAnyMap,
 };
 };
-use std::sync::{Arc, Mutex};
+use std::{
+    borrow::BorrowMut,
+    sync::{Arc, Mutex},
+};
 use tokio::time::sleep;
 use tokio::time::sleep;
 
 
 #[derive(Debug, Clone, PartialEq, Eq, Default)]
 #[derive(Debug, Clone, PartialEq, Eq, Default)]
@@ -17,7 +21,7 @@ impl Pass for BlablaState {
     type ChildDependencies = ();
     type ChildDependencies = ();
     type NodeDependencies = ();
     type NodeDependencies = ();
 
 
-    const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new()
+    const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new()
         .with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
         .with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
         .with_element();
         .with_element();
 
 
@@ -135,10 +139,11 @@ fn native_core_is_okay() {
         let rdom = Arc::new(Mutex::new(RealDom::new(Box::new([
         let rdom = Arc::new(Mutex::new(RealDom::new(Box::new([
             BlablaState::to_type_erased(),
             BlablaState::to_type_erased(),
         ]))));
         ]))));
+        let mut dioxus_state = DioxusState::create(&mut *rdom.lock().unwrap());
         let mut dom = VirtualDom::new(app);
         let mut dom = VirtualDom::new(app);
 
 
-        let muts = dom.rebuild();
-        rdom.lock().unwrap().apply_mutations(muts);
+        let mutations = dom.rebuild();
+        dioxus_state.apply_mutations(&mut *rdom.lock().unwrap(), mutations);
 
 
         let ctx = SendAnyMap::new();
         let ctx = SendAnyMap::new();
         rdom.lock().unwrap().update_state(ctx, false);
         rdom.lock().unwrap().update_state(ctx, false);
@@ -147,7 +152,7 @@ fn native_core_is_okay() {
             dom.wait_for_work().await;
             dom.wait_for_work().await;
 
 
             let mutations = dom.render_immediate();
             let mutations = dom.render_immediate();
-            rdom.lock().unwrap().apply_mutations(mutations);
+            dioxus_state.apply_mutations(&mut *rdom.lock().unwrap(), mutations);
 
 
             let ctx = SendAnyMap::new();
             let ctx = SendAnyMap::new();
             rdom.lock().unwrap().update_state(ctx, false);
             rdom.lock().unwrap().update_state(ctx, false);

+ 139 - 326
packages/native-core/tests/passes.rs

@@ -1,6 +1,7 @@
 use dioxus::prelude::*;
 use dioxus::prelude::*;
 use dioxus_native_core::node::NodeType;
 use dioxus_native_core::node::NodeType;
 use dioxus_native_core::prelude::*;
 use dioxus_native_core::prelude::*;
+use rustc_hash::{FxHashMap, FxHashSet};
 use std::any::TypeId;
 use std::any::TypeId;
 use std::sync::{Arc, Mutex};
 use std::sync::{Arc, Mutex};
 
 
@@ -8,8 +9,8 @@ fn create_blank_element() -> NodeType {
     NodeType::Element(ElementNode {
     NodeType::Element(ElementNode {
         tag: "div".to_owned(),
         tag: "div".to_owned(),
         namespace: None,
         namespace: None,
-        attributes: HashMap::new(),
-        listeners: HashMap::new(),
+        attributes: FxHashMap::default(),
+        listeners: FxHashSet::default(),
     })
     })
 }
 }
 
 
@@ -22,7 +23,7 @@ fn node_pass() {
         type ChildDependencies = ();
         type ChildDependencies = ();
         type NodeDependencies = ();
         type NodeDependencies = ();
         type ParentDependencies = ();
         type ParentDependencies = ();
-        const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
+        const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
 
 
         fn pass<'a>(
         fn pass<'a>(
             &mut self,
             &mut self,
@@ -70,7 +71,7 @@ fn dependant_node_pass() {
         type ChildDependencies = ();
         type ChildDependencies = ();
         type NodeDependencies = (SubtractNumber,);
         type NodeDependencies = (SubtractNumber,);
         type ParentDependencies = ();
         type ParentDependencies = ();
-        const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
+        const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
 
 
         fn pass<'a>(
         fn pass<'a>(
             &mut self,
             &mut self,
@@ -104,7 +105,7 @@ fn dependant_node_pass() {
         type ChildDependencies = ();
         type ChildDependencies = ();
         type NodeDependencies = ();
         type NodeDependencies = ();
         type ParentDependencies = ();
         type ParentDependencies = ();
-        const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
+        const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
 
 
         fn pass<'a>(
         fn pass<'a>(
             &mut self,
             &mut self,
@@ -170,7 +171,7 @@ fn independant_node_pass() {
         type NodeDependencies = ();
         type NodeDependencies = ();
         type ParentDependencies = ();
         type ParentDependencies = ();
 
 
-        const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
+        const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
 
 
         fn pass<'a>(
         fn pass<'a>(
             &mut self,
             &mut self,
@@ -205,7 +206,7 @@ fn independant_node_pass() {
         type NodeDependencies = ();
         type NodeDependencies = ();
         type ParentDependencies = ();
         type ParentDependencies = ();
 
 
-        const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
+        const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
 
 
         fn pass<'a>(
         fn pass<'a>(
             &mut self,
             &mut self,
@@ -279,7 +280,7 @@ fn down_pass() {
         type NodeDependencies = ();
         type NodeDependencies = ();
         type ParentDependencies = (AddNumber,);
         type ParentDependencies = (AddNumber,);
 
 
-        const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
+        const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
 
 
         fn pass<'a>(
         fn pass<'a>(
             &mut self,
             &mut self,
@@ -289,332 +290,144 @@ fn down_pass() {
             children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
             children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
             context: &SendAnyMap,
             context: &SendAnyMap,
         ) -> bool {
         ) -> bool {
+            dbg!(parent);
+            dbg!(node_view);
             if let Some((parent,)) = parent {
             if let Some((parent,)) = parent {
-                *self.0 += *parent.0;
+                self.0 += parent.0;
             }
             }
             true
             true
         }
         }
+
+        fn create<'a>(
+            node_view: NodeView<()>,
+            node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
+            parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
+            children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            context: &SendAnyMap,
+        ) -> Self {
+            let mut myself = Self::default();
+            myself.pass(node_view, node, parent, children, context);
+            myself
+        }
     }
     }
 
 
     let mut tree: RealDom = RealDom::new(Box::new([AddNumber::to_type_erased()]));
     let mut tree: RealDom = RealDom::new(Box::new([AddNumber::to_type_erased()]));
-    let parent = tree.root_id();
-    let child1 = tree.create_node(create_blank_element(), true);
-    tree.add_child(parent, child1);
-    let grandchild1 = tree.create_node(create_blank_element(), true);
-    tree.add_child(child1, grandchild1);
-    let child2 = tree.create_node(create_blank_element(), true);
-    tree.add_child(parent, child2);
-    let grandchild2 = tree.create_node(create_blank_element(), true);
-    tree.add_child(child2, grandchild2);
-
-    tree.dirty_nodes
-        .insert(TypeId::of::<AddNumber>(), NodeId(0));
+    let mut grandchild1 = tree.create_node(create_blank_element(), true);
+    let grandchild1 = grandchild1.id();
+    let mut child1 = tree.create_node(create_blank_element(), true);
+    child1.add_child(grandchild1);
+    let child1 = child1.id();
+    let mut grandchild2 = tree.create_node(create_blank_element(), true);
+    let grandchild2 = grandchild2.id();
+    let mut child2 = tree.create_node(create_blank_element(), true);
+    child2.add_child(grandchild2);
+    let child2 = child2.id();
+    let mut parent = tree.get_mut(tree.root_id()).unwrap();
+    parent.add_child(child1);
+    parent.add_child(child2);
+
     tree.update_state(SendAnyMap::new(), false);
     tree.update_state(SendAnyMap::new(), false);
 
 
-    assert_eq!(tree.get(tree.root_id()).unwrap().state.add_number.0, 1);
-    assert_eq!(tree.get(child1).unwrap().state.add_number.0, 2);
-    assert_eq!(tree.get(grandchild1).unwrap().state.add_number.0, 3);
-    assert_eq!(tree.get(child2).unwrap().state.add_number.0, 2);
-    assert_eq!(tree.get(grandchild2).unwrap().state.add_number.0, 3);
+    let root = tree.get(tree.root_id()).unwrap();
+    dbg!(root.id());
+    assert_eq!(root.get(), Some(&AddNumber(1)));
+
+    let child1 = tree.get(child1).unwrap();
+    dbg!(child1.id());
+    dbg!(child1.parent().unwrap().get::<AddNumber>());
+    assert_eq!(child1.get(), Some(&AddNumber(2)));
+
+    let grandchild1 = tree.get(grandchild1).unwrap();
+    assert_eq!(grandchild1.get(), Some(&AddNumber(3)));
+
+    let child2 = tree.get(child2).unwrap();
+    assert_eq!(child2.get(), Some(&AddNumber(2)));
+
+    let grandchild2 = tree.get(grandchild2).unwrap();
+    assert_eq!(grandchild2.get(), Some(&AddNumber(3)));
 }
 }
 
 
-// #[test]
-// fn dependant_down_pass() {
-//     // 0
-//     let mut tree = Tree::new(1);
-//     let parent = tree.root_id();
-//     // 1
-//     let child1 = tree.create_node(1);
-//     tree.add_child(parent, child1);
-//     // 2
-//     let grandchild1 = tree.create_node(1);
-//     tree.add_child(child1, grandchild1);
-//     // 3
-//     let child2 = tree.create_node(1);
-//     tree.add_child(parent, child2);
-//     // 4
-//     let grandchild2 = tree.create_node(1);
-//     tree.add_child(child2, grandchild2);
-
-//     struct AddPass;
-//     impl Pass for AddPass {
-//         fn pass_id(&self) -> PassId {
-//             PassId(0)
-//         }
-
-//         fn dependancies(&self) -> &'static [PassId] {
-//             &[PassId(1)]
-//         }
-
-//         fn dependants(&self) -> &'static [PassId] {
-//             &[]
-//         }
-
-//         fn mask(&self) -> MemberMask {
-//             MemberMask(0)
-//         }
-//     }
-//     impl DownwardPass<i32> for AddPass {
-//         fn pass(&self, node: &mut i32, parent: Option<&mut i32>, _: &SendAnyMap) -> PassReturn {
-//             if let Some(parent) = parent {
-//                 *node += *parent;
-//             } else {
-//             }
-//             PassReturn {
-//                 progress: true,
-//                 mark_dirty: true,
-//             }
-//         }
-//     }
-
-//     struct SubtractPass;
-//     impl Pass for SubtractPass {
-//         fn pass_id(&self) -> PassId {
-//             PassId(1)
-//         }
-
-//         fn dependancies(&self) -> &'static [PassId] {
-//             &[]
-//         }
-
-//         fn dependants(&self) -> &'static [PassId] {
-//             &[PassId(0)]
-//         }
-
-//         fn mask(&self) -> MemberMask {
-//             MemberMask(0)
-//         }
-//     }
-//     impl DownwardPass<i32> for SubtractPass {
-//         fn pass(&self, node: &mut i32, parent: Option<&mut i32>, _: &SendAnyMap) -> PassReturn {
-//             if let Some(parent) = parent {
-//                 *node -= *parent;
-//             } else {
-//             }
-//             PassReturn {
-//                 progress: true,
-//                 mark_dirty: true,
-//             }
-//         }
-//     }
-
-//     let add_pass = AnyPass::Downward(&AddPass);
-//     let subtract_pass = AnyPass::Downward(&SubtractPass);
-//     let passes = vec![&add_pass, &subtract_pass];
-//     let dirty_nodes: DirtyNodeStates = DirtyNodeStates::default();
-//     dirty_nodes.insert(PassId(1), tree.root_id());
-//     resolve_passes(&mut tree, dirty_nodes, passes, SendAnyMap::new());
-
-//     // Tree before:
-//     // 1=\
-//     //   1=\
-//     //     1
-//     //   1=\
-//     //     1
-//     // Tree after subtract:
-//     // 1=\
-//     //   0=\
-//     //     1
-//     //   0=\
-//     //     1
-//     // Tree after add:
-//     // 1=\
-//     //   1=\
-//     //     2
-//     //   1=\
-//     //     2
-//     assert_eq!(tree.get(tree.root_id()).unwrap(), &1);
-//     assert_eq!(tree.get(child1).unwrap(), &1);
-//     assert_eq!(tree.get(grandchild1).unwrap(), &2);
-//     assert_eq!(tree.get(child2).unwrap(), &1);
-//     assert_eq!(tree.get(grandchild2).unwrap(), &2);
-// }
-
-// #[test]
-// fn up_pass() {
-//     // Tree before:
-//     // 0=\
-//     //   0=\
-//     //     1
-//     //   0=\
-//     //     1
-//     // Tree after:
-//     // 2=\
-//     //   1=\
-//     //     1
-//     //   1=\
-//     //     1
-//     let mut tree = Tree::new(0);
-//     let parent = tree.root_id();
-//     let child1 = tree.create_node(0);
-//     tree.add_child(parent, child1);
-//     let grandchild1 = tree.create_node(1);
-//     tree.add_child(child1, grandchild1);
-//     let child2 = tree.create_node(0);
-//     tree.add_child(parent, child2);
-//     let grandchild2 = tree.create_node(1);
-//     tree.add_child(child2, grandchild2);
-
-//     struct AddPass;
-//     impl Pass for AddPass {
-//         fn pass_id(&self) -> PassId {
-//             PassId(0)
-//         }
-
-//         fn dependancies(&self) -> &'static [PassId] {
-//             &[]
-//         }
-
-//         fn dependants(&self) -> &'static [PassId] {
-//             &[]
-//         }
-
-//         fn mask(&self) -> MemberMask {
-//             MemberMask(0)
-//         }
-//     }
-//     impl UpwardPass<i32> for AddPass {
-//         fn pass<'a>(
-//             &self,
-//             node: &mut i32,
-//             children: &mut dyn Iterator<Item = &'a mut i32>,
-//             _: &SendAnyMap,
-//         ) -> PassReturn {
-//             *node += children.map(|i| *i).sum::<i32>();
-//             PassReturn {
-//                 progress: true,
-//                 mark_dirty: true,
-//             }
-//         }
-//     }
-
-//     let add_pass = AnyPass::Upward(&AddPass);
-//     let passes = vec![&add_pass];
-//     let dirty_nodes: DirtyNodeStates = DirtyNodeStates::default();
-//     dirty_nodes.insert(PassId(0), grandchild1);
-//     dirty_nodes.insert(PassId(0), grandchild2);
-//     resolve_passes(&mut tree, dirty_nodes, passes, SendAnyMap::new());
-
-//     assert_eq!(tree.get(tree.root_id()).unwrap(), &2);
-//     assert_eq!(tree.get(child1).unwrap(), &1);
-//     assert_eq!(tree.get(grandchild1).unwrap(), &1);
-//     assert_eq!(tree.get(child2).unwrap(), &1);
-//     assert_eq!(tree.get(grandchild2).unwrap(), &1);
-// }
-
-// #[test]
-// fn dependant_up_pass() {
-//     // 0
-//     let mut tree = Tree::new(0);
-//     let parent = tree.root_id();
-//     // 1
-//     let child1 = tree.create_node(0);
-//     tree.add_child(parent, child1);
-//     // 2
-//     let grandchild1 = tree.create_node(1);
-//     tree.add_child(child1, grandchild1);
-//     // 3
-//     let child2 = tree.create_node(0);
-//     tree.add_child(parent, child2);
-//     // 4
-//     let grandchild2 = tree.create_node(1);
-//     tree.add_child(child2, grandchild2);
-
-//     struct AddPass;
-//     impl Pass for AddPass {
-//         fn pass_id(&self) -> PassId {
-//             PassId(0)
-//         }
-
-//         fn dependancies(&self) -> &'static [PassId] {
-//             &[PassId(1)]
-//         }
-
-//         fn dependants(&self) -> &'static [PassId] {
-//             &[]
-//         }
-
-//         fn mask(&self) -> MemberMask {
-//             MemberMask(0)
-//         }
-//     }
-//     impl UpwardPass<i32> for AddPass {
-//         fn pass<'a>(
-//             &self,
-//             node: &mut i32,
-//             children: &mut dyn Iterator<Item = &'a mut i32>,
-//             _: &SendAnyMap,
-//         ) -> PassReturn {
-//             *node += children.map(|i| *i).sum::<i32>();
-//             PassReturn {
-//                 progress: true,
-//                 mark_dirty: true,
-//             }
-//         }
-//     }
-
-//     struct SubtractPass;
-//     impl Pass for SubtractPass {
-//         fn pass_id(&self) -> PassId {
-//             PassId(1)
-//         }
-
-//         fn dependancies(&self) -> &'static [PassId] {
-//             &[]
-//         }
-
-//         fn dependants(&self) -> &'static [PassId] {
-//             &[PassId(0)]
-//         }
-
-//         fn mask(&self) -> MemberMask {
-//             MemberMask(0)
-//         }
-//     }
-//     impl UpwardPass<i32> for SubtractPass {
-//         fn pass<'a>(
-//             &self,
-//             node: &mut i32,
-//             children: &mut dyn Iterator<Item = &'a mut i32>,
-//             _: &SendAnyMap,
-//         ) -> PassReturn {
-//             *node -= children.map(|i| *i).sum::<i32>();
-//             PassReturn {
-//                 progress: true,
-//                 mark_dirty: true,
-//             }
-//         }
-//     }
-
-//     let add_pass = AnyPass::Upward(&AddPass);
-//     let subtract_pass = AnyPass::Upward(&SubtractPass);
-//     let passes = vec![&add_pass, &subtract_pass];
-//     let dirty_nodes: DirtyNodeStates = DirtyNodeStates::default();
-//     dirty_nodes.insert(PassId(1), grandchild1);
-//     dirty_nodes.insert(PassId(1), grandchild2);
-//     resolve_passes(&mut tree, dirty_nodes, passes, SendAnyMap::new());
-
-//     // Tree before:
-//     // 0=\
-//     //   0=\
-//     //     1
-//     //   0=\
-//     //     1
-//     // Tree after subtract:
-//     // 2=\
-//     //   -1=\
-//     //      1
-//     //   -1=\
-//     //      1
-//     // Tree after add:
-//     // 2=\
-//     //   0=\
-//     //     1
-//     //   0=\
-//     //     1
-//     assert_eq!(tree.get(tree.root_id()).unwrap(), &2);
-//     assert_eq!(tree.get(child1).unwrap(), &0);
-//     assert_eq!(tree.get(grandchild1).unwrap(), &1);
-//     assert_eq!(tree.get(child2).unwrap(), &0);
-//     assert_eq!(tree.get(grandchild2).unwrap(), &1);
-// }
+#[test]
+fn up_pass() {
+    // Tree before:
+    // 1=\
+    //   1=\
+    //     1
+    //   1=\
+    //     1
+    // Tree after:
+    // 4=\
+    //   2=\
+    //     1
+    //   2=\
+    //     1
+
+    #[derive(Debug, Clone, PartialEq)]
+    struct AddNumber(i32);
+
+    impl Pass for AddNumber {
+        type ChildDependencies = (AddNumber,);
+        type NodeDependencies = ();
+        type ParentDependencies = ();
+
+        const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
+
+        fn pass<'a>(
+            &mut self,
+            node_view: NodeView,
+            node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
+            parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
+            children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            context: &SendAnyMap,
+        ) -> bool {
+            if let Some(children) = children {
+                self.0 += children.iter().map(|(i,)| i.0).sum::<i32>();
+            }
+            true
+        }
+
+        fn create<'a>(
+            node_view: NodeView<()>,
+            node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
+            parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
+            children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            context: &SendAnyMap,
+        ) -> Self {
+            let mut myself = Self(1);
+            myself.pass(node_view, node, parent, children, context);
+            myself
+        }
+    }
+
+    let mut tree: RealDom = RealDom::new(Box::new([AddNumber::to_type_erased()]));
+    let mut grandchild1 = tree.create_node(create_blank_element(), true);
+    let grandchild1 = grandchild1.id();
+    let mut child1 = tree.create_node(create_blank_element(), true);
+    child1.add_child(grandchild1);
+    let child1 = child1.id();
+    let mut grandchild2 = tree.create_node(create_blank_element(), true);
+    let grandchild2 = grandchild2.id();
+    let mut child2 = tree.create_node(create_blank_element(), true);
+    child2.add_child(grandchild2);
+    let child2 = child2.id();
+    let mut parent = tree.get_mut(tree.root_id()).unwrap();
+    parent.add_child(child1);
+    parent.add_child(child2);
+
+    tree.update_state(SendAnyMap::new(), false);
+
+    let root = tree.get(tree.root_id()).unwrap();
+    assert_eq!(root.get(), Some(&AddNumber(5)));
+
+    let child1 = tree.get(child1).unwrap();
+    assert_eq!(child1.get(), Some(&AddNumber(2)));
+
+    let grandchild1 = tree.get(grandchild1).unwrap();
+    assert_eq!(grandchild1.get(), Some(&AddNumber(1)));
+
+    let child2 = tree.get(child2).unwrap();
+    assert_eq!(child2.get(), Some(&AddNumber(2)));
+
+    let grandchild2 = tree.get(grandchild2).unwrap();
+    assert_eq!(grandchild2.get(), Some(&AddNumber(1)));
+}