Browse Source

all native-core tests passing

Evan Almloff 2 years ago
parent
commit
865c5aa957

+ 23 - 5
packages/native-core-macro/src/lib.rs

@@ -50,11 +50,16 @@ pub fn partial_derive_state(_: TokenStream, input: TokenStream) -> TokenStream {
 
     let mut combined_dependencies = HashSet::new();
 
+    let self_path: TypePath = syn::parse_quote!(Self);
+
     let parent_dependencies = match extract_tuple(parent_dependencies) {
         Some(tuple) => {
             let mut parent_dependencies = Vec::new();
             for type_ in &tuple.elems {
-                let type_ = extract_type_path(type_).unwrap_or_else(|| panic!("ParentDependencies must be a tuple of type paths, found {}", quote!(#type_)));
+                let mut type_ = extract_type_path(type_).unwrap_or_else(|| panic!("ParentDependencies must be a tuple of type paths, found {}", quote!(#type_)));
+                if type_ == self_path {
+                    type_ = this_type.clone();
+                }
                 combined_dependencies.insert(type_.clone());
                 parent_dependencies.push(type_);
             }
@@ -66,7 +71,10 @@ pub fn partial_derive_state(_: TokenStream, input: TokenStream) -> TokenStream {
         Some(tuple) => {
             let mut child_dependencies = Vec::new();
             for type_ in &tuple.elems {
-                let type_ = extract_type_path(type_).unwrap_or_else(|| panic!("ChildDependencies must be a tuple of type paths, found {}", quote!(#type_)));
+                let mut type_ = extract_type_path(type_).unwrap_or_else(|| panic!("ChildDependencies must be a tuple of type paths, found {}", quote!(#type_)));
+                if type_ == self_path {
+                    type_ = this_type.clone();
+                }
                 combined_dependencies.insert(type_.clone());
                 child_dependencies.push(type_);
             }
@@ -78,7 +86,10 @@ pub fn partial_derive_state(_: TokenStream, input: TokenStream) -> TokenStream {
         Some(tuple) => {
             let mut node_dependencies = Vec::new();
             for type_ in &tuple.elems {
-                let type_ = extract_type_path(type_).unwrap_or_else(|| panic!("NodeDependencies must be a tuple of type paths, found {}", quote!(#type_)));
+                let mut type_ = extract_type_path(type_).unwrap_or_else(|| panic!("NodeDependencies must be a tuple of type paths, found {}", quote!(#type_)));
+                if type_ == self_path {
+                    type_ = this_type.clone();
+                }
                 combined_dependencies.insert(type_.clone());
                 node_dependencies.push(type_);
             }
@@ -152,8 +163,14 @@ pub fn partial_derive_state(_: TokenStream, input: TokenStream) -> TokenStream {
                 let raw_node = ();
             }
         } else {
+            let temps = (0..node_dependencies.len())
+                .map(|i| format_ident!("__temp{}", i))
+                .collect::<Vec<_>>();
             quote! {
-                let raw_node: (#(*const #node_dependencies,)*) = (#(&#node_view,)*).get(id).unwrap();
+                let raw_node: (#(*const #node_dependencies,)*) = {
+                    let (#(#temps,)*) = (#(&#node_view,)*).get(id).unwrap_or_else(|err| panic!("Failed to get node view {:?}", err));
+                    (#(#temps as *const _,)*)
+                };
             }
         }
     };
@@ -225,13 +242,14 @@ let get_child_view = {
                 use dioxus_native_core::tree::TreeRef;
 
                 (move |data: #combined_dependencies_quote, run_view: dioxus_native_core::RunPassView #trait_generics| {
+                    println!("Running system for {:?}", type_id);
                     let (#(#split_views,)*) = data;
                     let (tree, types, _, _, _) = &run_view;
                     let tree = tree.clone();
                     let node_mask = Self::NODE_MASK.build();
                     let node_types = types.clone();
                     dioxus_native_core::run_pass(type_id, dependants.clone(), pass_direction, run_view, |id, context| {
-                        let node_data: &NodeType<_> = node_types.get(id).unwrap();
+                        let node_data: &NodeType<_> = node_types.get(id).unwrap_or_else(|err| panic!("Failed to get node type {:?}", err));
                         // get all of the states from the tree view
                         // Safety: No node has itself as a parent or child.
                         let raw_myself: Option<*mut Self> = (&mut #this_view).get(id).ok().map(|c| c as *mut _);

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

@@ -37,6 +37,7 @@ rand = "0.8.5"
 dioxus = { path = "../dioxus", version = "^0.3.0" }
 tokio = { version = "*", features = ["full"] }
 dioxus-native-core = { path = ".", features = ["dioxus"] }
+dioxus-native-core-macro = { path = "../native-core-macro" }
 
 [features]
 default = []

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

@@ -54,7 +54,7 @@ impl DioxusState {
     pub fn load_child(&self, rdom: &RealDom, path: &[u8]) -> NodeId {
         let mut current = rdom.get(*self.stack.last().unwrap()).unwrap();
         for i in path {
-            let new_id = current.child_ids().unwrap()[*i as usize];
+            let new_id = current.child_ids()[*i as usize];
             current = rdom.get(new_id).unwrap();
         }
         current.id()

+ 57 - 52
packages/native-core/src/passes.rs

@@ -1,13 +1,14 @@
 use anymap::AnyMap;
 use parking_lot::RwLock;
 use rustc_hash::{FxHashMap, FxHashSet};
-use shipyard::{BorrowInfo, Component, IntoBorrow, Unique, UniqueView, View, WorkloadSystem};
+use shipyard::{Component, Unique, UniqueView, View, WorkloadSystem};
 use std::any::{Any, TypeId};
 use std::collections::BTreeMap;
 use std::marker::PhantomData;
+use std::ops::Deref;
 use std::sync::Arc;
 
-use crate::node::FromAnyValue;
+use crate::node::{FromAnyValue, NodeType};
 use crate::node_ref::{NodeMaskBuilder, NodeView};
 use crate::real_dom::{DirtyNodesResult, SendAnyMapWrapper};
 use crate::tree::{TreeRef, TreeRefView};
@@ -104,11 +105,11 @@ impl DirtyNodeStates {
 }
 
 pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
-    /// This is a tuple of (T: Pass, ..) of states read from the parent required to run this pass
+    /// This is a tuple of (T: State, ..) of states read from the parent required to run this pass
     type ParentDependencies: Dependancy;
-    /// This is a tuple of (T: Pass, ..) of states read from the children required to run this pass
+    /// This is a tuple of (T: State, ..) of states read from the children required to run this pass
     type ChildDependencies: Dependancy;
-    /// This is a tuple of (T: Pass, ..) of states read from the node required to run this pass
+    /// This is a tuple of (T: State, ..) of states read from the node required to run this pass
     type NodeDependencies: Dependancy;
     /// This is a mask of what aspects of the node are required to run this pass
     const NODE_MASK: NodeMaskBuilder<'static>;
@@ -119,7 +120,7 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
         node_view: NodeView<V>,
         node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
         parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-        children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+        children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
         context: &SendAnyMap,
     ) -> bool;
 
@@ -128,7 +129,7 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
         node_view: NodeView<V>,
         node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
         parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-        children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+        children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
         context: &SendAnyMap,
     ) -> Self;
 
@@ -140,52 +141,22 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
     ) -> WorkloadSystem;
 }
 
-pub struct RunPassView<'a> {
-    tree: TreeRefView<'a>,
-    nodes_updated: UniqueView<'a, DirtyNodesResult>,
-    dirty: UniqueView<'a, DirtyNodeStates>,
-    ctx: UniqueView<'a, SendAnyMapWrapper>,
-}
+pub type RunPassView<'a, V = ()> = (
+    TreeRefView<'a>,
+    View<'a, NodeType<V>>,
+    UniqueView<'a, DirtyNodesResult>,
+    UniqueView<'a, DirtyNodeStates>,
+    UniqueView<'a, SendAnyMapWrapper>,
+);
 
-impl<'v> shipyard::Borrow<'v> for RunPassView<'v> {
-    type View = RunPassView<'v>;
-
-    fn borrow(
-        world: &'v shipyard::World,
-        last_run: Option<u32>,
-        current: u32,
-    ) -> Result<Self::View, shipyard::error::GetStorage> {
-        Ok(RunPassView {
-            tree: <TreeRefView<'v> as shipyard::IntoBorrow>::Borrow::borrow(
-                world, last_run, current,
-            )?,
-            nodes_updated:
-                <UniqueView<'v, DirtyNodesResult> as shipyard::IntoBorrow>::Borrow::borrow(
-                    world, last_run, current,
-                )?,
-            dirty: <UniqueView<'v, DirtyNodeStates> as shipyard::IntoBorrow>::Borrow::borrow(
-                world, last_run, current,
-            )?,
-            ctx: <UniqueView<'v, SendAnyMapWrapper> as shipyard::IntoBorrow>::Borrow::borrow(
-                world, last_run, current,
-            )?,
-        })
-    }
-}
-
-pub fn run_pass(
+pub fn run_pass<V: FromAnyValue>(
     type_id: TypeId,
     dependants: FxHashSet<TypeId>,
     pass_direction: PassDirection,
-    view: RunPassView,
+    view: RunPassView<V>,
     mut update_node: impl FnMut(NodeId, &SendAnyMap) -> bool,
 ) {
-    let RunPassView {
-        tree,
-        nodes_updated,
-        dirty,
-        ctx,
-    } = view;
+    let (tree, _, nodes_updated, dirty, ctx, ..) = view;
     let ctx = ctx.as_ref();
     match pass_direction {
         PassDirection::ParentToChild => {
@@ -193,7 +164,7 @@ pub fn run_pass(
                 let id = tree.id_at(id).unwrap();
                 if (update_node)(id, ctx) {
                     nodes_updated.insert(id);
-                    for id in tree.children_ids(id).unwrap() {
+                    for id in tree.children_ids(id) {
                         for dependant in &dependants {
                             dirty.insert(*dependant, id, height + 1);
                         }
@@ -283,6 +254,8 @@ pub trait AnyState<V: FromAnyValue + Send + Sync = ()>: State<V> {
     }
 }
 
+impl<V: FromAnyValue + Send + Sync, S: State<V>> AnyState<V> for S {}
+
 pub struct TypeErasedPass<V: FromAnyValue + Send = ()> {
     pub(crate) this_type_id: TypeId,
     pub(crate) parent_dependant: bool,
@@ -295,7 +268,17 @@ pub struct TypeErasedPass<V: FromAnyValue + Send = ()> {
     phantom: PhantomData<V>,
 }
 
-#[derive(Debug)]
+impl<V: FromAnyValue + Send> TypeErasedPass<V> {
+    pub(crate) fn create_workload(&self) -> WorkloadSystem {
+        (self.workload)(
+            self.this_type_id,
+            self.dependants.clone(),
+            self.pass_direction,
+        )
+    }
+}
+
+#[derive(Debug, Clone, Copy)]
 pub enum PassDirection {
     ParentToChild,
     ChildToParent,
@@ -319,7 +302,7 @@ impl<'a> AnyMapLike<'a> for &'a SendAnyMap {
 }
 
 pub trait Dependancy {
-    type ElementBorrowed<'a>: IntoBorrow + BorrowInfo;
+    type ElementBorrowed<'a>;
 
     fn type_ids() -> Box<[TypeId]> {
         Box::new([])
@@ -328,8 +311,8 @@ pub trait Dependancy {
 
 macro_rules! impl_dependancy {
     ($($t:ident),*) => {
-        impl< $($t: Send + Sync + Component),* > Dependancy for ($($t,)*) {
-            type ElementBorrowed<'a> = ($(View<'a, $t>,)*);
+        impl< $($t: Send + Sync + Component + State),* > Dependancy for ($($t,)*) {
+            type ElementBorrowed<'a> = ($(DependancyView<'a, $t>,)*);
 
             fn type_ids() -> Box<[TypeId]> {
                 Box::new([$(TypeId::of::<$t>()),*])
@@ -338,6 +321,28 @@ macro_rules! impl_dependancy {
     };
 }
 
+// TODO: track what components are actually read to update subscriptions
+// making this a wrapper makes it possible to implement that optimization without a breaking change
+pub struct DependancyView<'a, T> {
+    inner: &'a T,
+}
+
+impl<'a, T> DependancyView<'a, T> {
+    // This should only be used in the macro. This is not a public API or stable
+    #[doc(hidden)]
+    pub fn new(inner: &'a T) -> Self {
+        Self { inner }
+    }
+}
+
+impl<'a, T> Deref for DependancyView<'a, T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        self.inner
+    }
+}
+
 impl_dependancy!();
 impl_dependancy!(A);
 impl_dependancy!(A, B);

+ 57 - 62
packages/native-core/src/real_dom.rs

@@ -101,6 +101,19 @@ pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
 
 impl<V: FromAnyValue + Send + Sync> RealDom<V> {
     pub fn new(mut passes: Box<[TypeErasedPass<V>]>) -> RealDom<V> {
+        // resolve dependants for each pass
+        for i in 1..passes.len() {
+            let (before, after) = passes.split_at_mut(i);
+            let (current, before) = before.split_last_mut().unwrap();
+            for pass in before.iter_mut().chain(after.iter_mut()) {
+                if current
+                    .combined_dependancy_type_ids
+                    .contains(&pass.this_type_id)
+                {
+                    pass.dependants.insert(current.this_type_id);
+                }
+            }
+        }
         let workload = construct_workload(&mut passes);
         let (workload, _) = workload.build().unwrap();
         let mut world = World::new();
@@ -111,18 +124,9 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
             listeners: FxHashSet::default(),
         });
         let root_id = world.add_entity(root_node);
-
-        // resolve dependants for each pass
-        for i in 1..passes.len() {
-            let (before, after) = passes.split_at_mut(i);
-            let (current, before) = before.split_last_mut().unwrap();
-            for pass in before.iter_mut().chain(after.iter_mut()) {
-                for dependancy in &current.combined_dependancy_type_ids {
-                    if pass.this_type_id == *dependancy {
-                        pass.dependants.insert(current.this_type_id);
-                    }
-                }
-            }
+        {
+            let mut tree: TreeMutView = world.borrow().unwrap();
+            tree.create_node(root_id);
         }
 
         let mut passes_updated = FxHashMap::default();
@@ -199,7 +203,7 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
     }
 
     pub fn get_mut(&mut self, id: NodeId) -> Option<NodeMut<'_, V>> {
-        let contains = { self.tree_ref().contains(id) };
+        let contains = self.tree_ref().contains(id);
         contains.then(|| NodeMut::new(id, self))
     }
 
@@ -252,9 +256,8 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         while let Some(id) = stack.pop() {
             if let Some(node) = self.get(id) {
                 f(node);
-                if let Some(children) = tree.children_ids(id) {
-                    stack.extend(children.iter().copied().rev());
-                }
+                let children = tree.children_ids(id);
+                stack.extend(children.iter().copied().rev());
             }
         }
     }
@@ -266,10 +269,9 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         while let Some(id) = queue.pop_front() {
             if let Some(node) = self.get(id) {
                 f(node);
-                if let Some(children) = tree.children_ids(id) {
-                    for id in children {
-                        queue.push_back(id);
-                    }
+                let children = tree.children_ids(id);
+                for id in children {
+                    queue.push_back(id);
                 }
             }
         }
@@ -279,14 +281,13 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         let mut stack = vec![self.root_id()];
         while let Some(id) = stack.pop() {
             let tree = self.tree_ref();
-            if let Some(mut children) = tree.children_ids(id) {
-                drop(tree);
-                children.reverse();
-                if let Some(node) = self.get_mut(id) {
-                    let node = node;
-                    f(node);
-                    stack.extend(children.iter());
-                }
+            let mut children = tree.children_ids(id);
+            drop(tree);
+            children.reverse();
+            if let Some(node) = self.get_mut(id) {
+                let node = node;
+                f(node);
+                stack.extend(children.iter());
             }
         }
     }
@@ -296,13 +297,12 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
         queue.push_back(self.root_id());
         while let Some(id) = queue.pop_front() {
             let tree = self.tree_ref();
-            if let Some(children) = tree.children_ids(id) {
-                drop(tree);
-                if let Some(node) = self.get_mut(id) {
-                    f(node);
-                    for id in children {
-                        queue.push_back(id);
-                    }
+            let children = tree.children_ids(id);
+            drop(tree);
+            if let Some(node) = self.get_mut(id) {
+                f(node);
+                for id in children {
+                    queue.push_back(id);
                 }
             }
         }
@@ -375,22 +375,19 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
     }
 
     #[inline]
-    fn child_ids(&self) -> Option<Vec<NodeId>> {
+    fn child_ids(&self) -> Vec<NodeId> {
         self.real_dom().tree_ref().children_ids(self.id())
     }
 
     #[inline]
     fn children(&self) -> Vec<NodeRef<V>> {
         self.child_ids()
-            .map(|ids| {
-                ids.iter()
-                    .map(|id| NodeRef {
-                        id: *id,
-                        dom: self.real_dom(),
-                    })
-                    .collect()
+            .iter()
+            .map(|id| NodeRef {
+                id: *id,
+                dom: self.real_dom(),
             })
-            .unwrap_or_default()
+            .collect()
     }
 
     #[inline]
@@ -409,7 +406,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
     #[inline]
     fn next(&self) -> Option<NodeRef<V>> {
         let parent = self.parent_id()?;
-        let children = self.real_dom().tree_ref().children_ids(parent)?;
+        let children = self.real_dom().tree_ref().children_ids(parent);
         let index = children.iter().position(|id| *id == self.id())?;
         if index + 1 < children.len() {
             Some(NodeRef {
@@ -424,7 +421,7 @@ pub trait NodeImmutable<V: FromAnyValue + Send + Sync>: Sized {
     #[inline]
     fn prev(&self) -> Option<NodeRef<V>> {
         let parent = self.parent_id()?;
-        let children = self.real_dom().tree_ref().children_ids(parent)?;
+        let children = self.real_dom().tree_ref().children_ids(parent);
         let index = children.iter().position(|id| *id == self.id())?;
         if index > 0 {
             Some(NodeRef {
@@ -534,7 +531,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
     #[inline]
     pub fn next_mut(self) -> Option<NodeMut<'a, V>> {
         let parent = self.parent_id()?;
-        let children = self.dom.tree_mut().children_ids(parent)?;
+        let children = self.dom.tree_mut().children_ids(parent);
         let index = children.iter().position(|id| *id == self.id)?;
         if index + 1 < children.len() {
             Some(NodeMut::new(children[index + 1], self.dom))
@@ -546,7 +543,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
     #[inline]
     pub fn prev_mut(self) -> Option<NodeMut<'a, V>> {
         let parent = self.parent_id()?;
-        let children = self.dom.tree_ref().children_ids(parent)?;
+        let children = self.dom.tree_ref().children_ids(parent);
         let index = children.iter().position(|id| *id == self.id)?;
         if index > 0 {
             Some(NodeMut::new(children[index - 1], self.dom))
@@ -613,11 +610,10 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
                 .dirty_nodes
                 .mark_child_changed(parent_id);
         }
-        if let Some(children_ids) = self.child_ids() {
-            let children_ids_vec = children_ids.to_vec();
-            for child in children_ids_vec {
-                self.dom.get_mut(child).unwrap().remove();
-            }
+        let children_ids = self.child_ids();
+        let children_ids_vec = children_ids.to_vec();
+        for child in children_ids_vec {
+            self.dom.get_mut(child).unwrap().remove();
         }
         self.dom.tree_mut().remove_single(id);
     }
@@ -739,13 +735,12 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
         let rdom = self.real_dom_mut();
         let new_id = rdom.create_node(new_node).id();
 
-        if let Some(children) = self.child_ids() {
-            let children = children.to_vec();
-            let rdom = self.real_dom_mut();
-            for child in children {
-                let child_id = rdom.get_mut(child).unwrap().clone_node();
-                rdom.get_mut(new_id).unwrap().add_child(child_id);
-            }
+        let children = self.child_ids();
+        let children = children.to_vec();
+        let rdom = self.real_dom_mut();
+        for child in children {
+            let child_id = rdom.get_mut(child).unwrap().clone_node();
+            rdom.get_mut(new_id).unwrap().add_child(child_id);
         }
         new_id
     }
@@ -894,7 +889,7 @@ fn construct_workload<V: FromAnyValue + Send + Sync>(passes: &mut [TypeErasedPas
         .iter_mut()
         .enumerate()
         .map(|(i, pass)| {
-            let workload = Some((pass.workload)(pass.dependants.clone()));
+            let workload = Some(pass.create_workload());
             (i, pass, workload)
         })
         .collect::<Vec<_>>();
@@ -913,7 +908,7 @@ fn construct_workload<V: FromAnyValue + Send + Sync>(passes: &mut [TypeErasedPas
             let (_, _, workload) = &mut unresloved_workloads[i];
             *workload = workload
                 .take()
-                .map(|workload| workload.tag(dependancy_id.to_string()));
+                .map(|workload| workload.after_all(dependancy_id.to_string()));
         }
     }
     for (_, _, mut workload_system) in unresloved_workloads {

+ 65 - 83
packages/native-core/src/tree.rs

@@ -14,7 +14,7 @@ pub type TreeMutView<'a> = (EntitiesViewMut<'a>, ViewMut<'a, Node>);
 
 pub trait TreeRef {
     fn parent_id(&self, id: NodeId) -> Option<NodeId>;
-    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>>;
+    fn children_ids(&self, id: NodeId) -> Vec<NodeId>;
     fn height(&self, id: NodeId) -> Option<u16>;
     fn contains(&self, id: NodeId) -> bool;
 }
@@ -35,8 +35,10 @@ impl<'a> TreeRef for TreeRefView<'a> {
         self.get(id).unwrap().parent
     }
 
-    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
-        Some(self.get(id).unwrap().children.clone())
+    fn children_ids(&self, id: NodeId) -> Vec<NodeId> {
+        self.get(id)
+            .map(|node| node.children.clone())
+            .unwrap_or_default()
     }
 
     fn height(&self, id: NodeId) -> Option<u16> {
@@ -50,12 +52,10 @@ impl<'a> TreeRef for TreeRefView<'a> {
 
 impl<'a> TreeMut for TreeMutView<'a> {
     fn remove(&mut self, id: NodeId) {
-        fn recurse<'a>(tree: &mut TreeMutView<'a>, id: NodeId) {
+        fn recurse(tree: &mut TreeMutView<'_>, id: NodeId) {
             let children = tree.children_ids(id);
-            if let Some(children) = children {
-                for child in children {
-                    recurse(tree, child);
-                }
+            for child in children {
+                recurse(tree, child);
             }
         }
         {
@@ -175,9 +175,12 @@ impl<'a> TreeRef for TreeMutView<'a> {
         node_data.get(id).unwrap().parent
     }
 
-    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>> {
+    fn children_ids(&self, id: NodeId) -> Vec<NodeId> {
         let node_data = &self.1;
-        node_data.get(id).map(|node| node.children.clone()).ok()
+        node_data
+            .get(id)
+            .map(|node| node.children.clone())
+            .unwrap_or_default()
     }
 
     fn height(&self, id: NodeId) -> Option<u16> {
@@ -192,47 +195,51 @@ impl<'a> TreeRef for TreeMutView<'a> {
 
 #[test]
 fn creation() {
-    let mut tree = Tree::new();
-    let parent_id = tree.root;
-    tree.insert(parent_id, 1i32);
-    let mut child = tree.create_node();
-    child.insert(0i32);
-    let child_id = child.id();
+    use shipyard::World;
+    #[derive(Component)]
+    struct Num(i32);
+
+    let mut world = World::new();
+    let parent_id = world.add_entity(Num(1i32));
+    let child_id = world.add_entity(Num(0i32));
+
+    let mut tree = world.borrow::<TreeMutView>().unwrap();
+
+    tree.create_node(parent_id);
+    tree.create_node(child_id);
 
     tree.add_child(parent_id, child_id);
 
-    println!("Tree: {tree:#?}");
-    assert_eq!(tree.size(), 2);
     assert_eq!(tree.height(parent_id), Some(0));
     assert_eq!(tree.height(child_id), Some(1));
     assert_eq!(tree.parent_id(parent_id), None);
     assert_eq!(tree.parent_id(child_id).unwrap(), parent_id);
-    assert_eq!(tree.children_ids(parent_id).unwrap(), &[child_id]);
-
-    assert_eq!(*tree.get::<i32>(parent_id).unwrap(), 1);
-    assert_eq!(*tree.get::<i32>(child_id).unwrap(), 0);
+    assert_eq!(tree.children_ids(parent_id), &[child_id]);
 }
 
 #[test]
 fn insertion() {
-    let mut tree = Tree::new();
-    let parent = tree.root();
-    tree.insert(parent, 0);
-    let mut child = tree.create_node();
-    child.insert(2);
-    let child = child.id();
+    use shipyard::World;
+    #[derive(Component)]
+    struct Num(i32);
+
+    let mut world = World::new();
+    let parent = world.add_entity(Num(0));
+    let child = world.add_entity(Num(2));
+    let before = world.add_entity(Num(1));
+    let after = world.add_entity(Num(3));
+
+    let mut tree = world.borrow::<TreeMutView>().unwrap();
+
+    tree.create_node(parent);
+    tree.create_node(child);
+    tree.create_node(before);
+    tree.create_node(after);
+
     tree.add_child(parent, child);
-    let mut before = tree.create_node();
-    before.insert(1);
-    let before = before.id();
     tree.insert_before(child, before);
-    let mut after = tree.create_node();
-    after.insert(3);
-    let after = after.id();
     tree.insert_after(child, after);
 
-    println!("Tree: {tree:#?}");
-    assert_eq!(tree.size(), 4);
     assert_eq!(tree.height(parent), Some(0));
     assert_eq!(tree.height(child), Some(1));
     assert_eq!(tree.height(before), Some(1));
@@ -240,34 +247,32 @@ fn insertion() {
     assert_eq!(tree.parent_id(before).unwrap(), parent);
     assert_eq!(tree.parent_id(child).unwrap(), parent);
     assert_eq!(tree.parent_id(after).unwrap(), parent);
-    assert_eq!(tree.children_ids(parent).unwrap(), &[before, child, after]);
-
-    assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
-    assert_eq!(*tree.get::<i32>(before).unwrap(), 1);
-    assert_eq!(*tree.get::<i32>(child).unwrap(), 2);
-    assert_eq!(*tree.get::<i32>(after).unwrap(), 3);
+    assert_eq!(tree.children_ids(parent), &[before, child, after]);
 }
 
 #[test]
 fn deletion() {
-    let mut tree = Tree::new();
-    let parent = tree.root();
-    tree.insert(parent, 0);
-    let mut child = tree.create_node();
-    child.insert(2);
-    let child = child.id();
+    use shipyard::World;
+    #[derive(Component)]
+    struct Num(i32);
+
+    let mut world = World::new();
+    let parent = world.add_entity(Num(0));
+    let child = world.add_entity(Num(2));
+    let before = world.add_entity(Num(1));
+    let after = world.add_entity(Num(3));
+
+    let mut tree = world.borrow::<TreeMutView>().unwrap();
+
+    tree.create_node(parent);
+    tree.create_node(child);
+    tree.create_node(before);
+    tree.create_node(after);
+
     tree.add_child(parent, child);
-    let mut before = tree.create_node();
-    before.insert(1);
-    let before = before.id();
     tree.insert_before(child, before);
-    let mut after = tree.create_node();
-    after.insert(3);
-    let after = after.id();
     tree.insert_after(child, after);
 
-    println!("Tree: {tree:#?}");
-    assert_eq!(tree.size(), 4);
     assert_eq!(tree.height(parent), Some(0));
     assert_eq!(tree.height(child), Some(1));
     assert_eq!(tree.height(before), Some(1));
@@ -275,49 +280,26 @@ fn deletion() {
     assert_eq!(tree.parent_id(before).unwrap(), parent);
     assert_eq!(tree.parent_id(child).unwrap(), parent);
     assert_eq!(tree.parent_id(after).unwrap(), parent);
-    assert_eq!(tree.children_ids(parent).unwrap(), &[before, child, after]);
-
-    assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
-    assert_eq!(*tree.get::<i32>(before).unwrap(), 1);
-    assert_eq!(*tree.get::<i32>(child).unwrap(), 2);
-    assert_eq!(*tree.get::<i32>(after).unwrap(), 3);
+    assert_eq!(tree.children_ids(parent), &[before, child, after]);
 
     tree.remove(child);
 
-    println!("Tree: {tree:#?}");
-    assert_eq!(tree.size(), 3);
     assert_eq!(tree.height(parent), Some(0));
     assert_eq!(tree.height(before), Some(1));
     assert_eq!(tree.height(after), Some(1));
     assert_eq!(tree.parent_id(before).unwrap(), parent);
     assert_eq!(tree.parent_id(after).unwrap(), parent);
-    assert_eq!(tree.children_ids(parent).unwrap(), &[before, after]);
-
-    assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
-    assert_eq!(*tree.get::<i32>(before).unwrap(), 1);
-    assert_eq!(tree.get::<i32>(child), None);
-    assert_eq!(*tree.get::<i32>(after).unwrap(), 3);
+    assert_eq!(tree.children_ids(parent), &[before, after]);
 
     tree.remove(before);
 
-    println!("Tree: {tree:#?}");
-    assert_eq!(tree.size(), 2);
     assert_eq!(tree.height(parent), Some(0));
     assert_eq!(tree.height(after), Some(1));
     assert_eq!(tree.parent_id(after).unwrap(), parent);
-    assert_eq!(tree.children_ids(parent).unwrap(), &[after]);
-
-    assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
-    assert_eq!(tree.get::<i32>(before), None);
-    assert_eq!(*tree.get::<i32>(after).unwrap(), 3);
+    assert_eq!(tree.children_ids(parent), &[after]);
 
     tree.remove(after);
 
-    println!("Tree: {tree:#?}");
-    assert_eq!(tree.size(), 1);
     assert_eq!(tree.height(parent), Some(0));
-    assert_eq!(tree.children_ids(parent).unwrap(), &[]);
-
-    assert_eq!(*tree.get::<i32>(parent).unwrap(), 0);
-    assert_eq!(tree.get::<i32>(after), None);
+    assert_eq!(tree.children_ids(parent), &[]);
 }

+ 20 - 20
packages/native-core/src/utils/persistant_iterator.rs

@@ -199,68 +199,68 @@ fn traverse() {
 
     let div_tag = "div".to_string();
     assert!(matches!(
-        &rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: div_tag, .. })
     ));
     assert!(matches!(
-        &rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: div_tag, .. })
     ));
     let text1 = "hello".to_string();
     assert!(matches!(
-        &rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
         NodeType::Text(text1)
     ));
     let p_tag = "p".to_string();
     assert!(matches!(
-        &rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: p_tag, .. })
     ));
     let text2 = "world".to_string();
     assert!(matches!(
-        &rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
         NodeType::Text(text2)
     ));
     let text3 = "hello world".to_string();
     assert!(matches!(
-        &rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
         NodeType::Text(text3)
     ));
     assert!(matches!(
-        &rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.next(&rdom).id()).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: div_tag, .. })
     ));
 
     assert!(matches!(
-        &rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
         NodeType::Text(text3)
     ));
     assert!(matches!(
-        &rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
         NodeType::Text(text2)
     ));
     assert!(matches!(
-        &rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: p_tag, .. })
     ));
     assert!(matches!(
-        &rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
         NodeType::Text(text1)
     ));
     assert!(matches!(
-        &rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: div_tag, .. })
     ));
     assert!(matches!(
-        &rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: div_tag, .. })
     ));
     assert!(matches!(
-        &rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: div_tag, .. })
     ));
     assert!(matches!(
-        &rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
+        &*rdom.get(iter.prev(&rdom).id()).unwrap().node_type(),
         NodeType::Text(text3)
     ));
 }
@@ -335,13 +335,13 @@ fn persist_removes() {
     let root_tag = "Root".to_string();
     let idx = iter1.next(&rdom).id();
     assert!(matches!(
-        &rdom.get(idx).unwrap().node_type(),
+        &*rdom.get(idx).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: root_tag, .. })
     ));
 
     let idx = iter2.next(&rdom).id();
     assert!(matches!(
-        &rdom.get(idx).unwrap().node_type(),
+        &*rdom.get(idx).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: root_tag, .. })
     ));
 }
@@ -399,7 +399,7 @@ fn persist_instertions_before() {
     let p_tag = "div".to_string();
     let idx = iter.next(&rdom).id();
     assert!(matches!(
-        &rdom.get(idx).unwrap().node_type(),
+        &*rdom.get(idx).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: p_tag, .. })
     ));
 }
@@ -456,13 +456,13 @@ fn persist_instertions_after() {
     let p_tag = "p".to_string();
     let idx = iter.next(&rdom).id();
     assert!(matches!(
-        &rdom.get(idx).unwrap().node_type(),
+        &*rdom.get(idx).unwrap().node_type(),
         NodeType::Element(ElementNode { tag: p_tag, .. })
     ));
     let text = "hello world".to_string();
     let idx = iter.next(&rdom).id();
     assert!(matches!(
-        &rdom.get(idx).unwrap().node_type(),
+        &*rdom.get(idx).unwrap().node_type(),
         NodeType::Text(text)
     ));
 }

+ 35 - 30
packages/native-core/tests/called_minimally_on_build.rs

@@ -6,22 +6,25 @@ use dioxus_native_core::{
     real_dom::RealDom,
     Dependancy, SendAnyMap, State,
 };
+use dioxus_native_core_macro::partial_derive_state;
+use shipyard::Component;
 
 macro_rules! dep {
     ( child( $name:ty, $dep:ty ) ) => {
-        impl Pass for $name {
+        #[partial_derive_state]
+        impl State for $name {
             type ParentDependencies = ();
             type ChildDependencies = $dep;
             type NodeDependencies = ();
 
             const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::ALL;
 
-            fn pass<'a>(
+            fn update<'a>(
                 &mut self,
                 _: NodeView,
                 _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
                 _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-                _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+                _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
                 _: &SendAnyMap,
             ) -> bool {
                 self.0 += 1;
@@ -32,30 +35,31 @@ macro_rules! dep {
                 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>>>,
+                children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
                 context: &SendAnyMap,
             ) -> Self {
                 let mut myself = Self::default();
-                myself.pass(node_view, node, parent, children, context);
+                myself.update(node_view, node, parent, children, context);
                 myself
             }
         }
     };
 
     ( parent( $name:ty, $dep:ty ) ) => {
-        impl Pass for $name {
+        #[partial_derive_state]
+        impl State for $name {
             type ParentDependencies = $dep;
             type ChildDependencies = ();
             type NodeDependencies = ();
 
             const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::ALL;
 
-            fn pass<'a>(
+            fn update<'a>(
                 &mut self,
                 _: NodeView,
                 _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
                 _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-                _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+                _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
                 _: &SendAnyMap,
             ) -> bool {
                 self.0 += 1;
@@ -66,30 +70,31 @@ macro_rules! dep {
                 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>>>,
+                children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
                 context: &SendAnyMap,
             ) -> Self {
                 let mut myself = Self::default();
-                myself.pass(node_view, node, parent, children, context);
+                myself.update(node_view, node, parent, children, context);
                 myself
             }
         }
     };
 
     ( node( $name:ty, $dep:ty ) ) => {
-        impl Pass for $name {
+        #[partial_derive_state]
+        impl State for $name {
             type ParentDependencies = $dep;
             type ChildDependencies = ();
             type NodeDependencies = ();
 
             const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::ALL;
 
-            fn pass<'a>(
+            fn update<'a>(
                 &mut self,
                 _: NodeView,
                 _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
                 _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-                _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+                _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
                 _: &SendAnyMap,
             ) -> bool {
                 self.0 += 1;
@@ -100,11 +105,11 @@ macro_rules! dep {
                 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>>>,
+                children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
                 context: &SendAnyMap,
             ) -> Self {
                 let mut myself = Self::default();
-                myself.pass(node_view, node, parent, children, context);
+                myself.update(node_view, node, parent, children, context);
                 myself
             }
         }
@@ -145,7 +150,7 @@ macro_rules! test_state{
             let mut dioxus_state = DioxusState::create(&mut dom);
 
             dioxus_state.apply_mutations(&mut dom, mutations);
-            dom.update_state(SendAnyMap::new(), false);
+            dom.update_state(SendAnyMap::new());
 
             dom.traverse_depth_first(|n| {
                 $(
@@ -158,15 +163,15 @@ macro_rules! test_state{
 
 mod node_depends_on_child_and_parent {
     use super::*;
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Node(i32);
     dep!(node(Node, (Child, Parent)));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Child(i32);
     dep!(child(Child, (Child,)));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Parent(i32);
     dep!(parent(Parent, (Parent,)));
 
@@ -175,15 +180,15 @@ mod node_depends_on_child_and_parent {
 
 mod child_depends_on_node_that_depends_on_parent {
     use super::*;
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Node(i32);
     dep!(node(Node, (Parent,)));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Child(i32);
     dep!(child(Child, (Node,)));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Parent(i32);
     dep!(parent(Parent, (Parent,)));
 
@@ -192,15 +197,15 @@ mod child_depends_on_node_that_depends_on_parent {
 
 mod parent_depends_on_node_that_depends_on_child {
     use super::*;
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Node(i32);
     dep!(node(Node, (Child,)));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Child(i32);
     dep!(child(Child, (Child,)));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Parent(i32);
     dep!(parent(Parent, (Node,)));
 
@@ -209,11 +214,11 @@ mod parent_depends_on_node_that_depends_on_child {
 
 mod node_depends_on_other_node_state {
     use super::*;
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Node1(i32);
     dep!(node(Node1, (Node2,)));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Node2(i32);
     dep!(node(Node2, ()));
 
@@ -222,15 +227,15 @@ mod node_depends_on_other_node_state {
 
 mod node_child_and_parent_state_depends_on_self {
     use super::*;
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Node(i32);
     dep!(node(Node, ()));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Child(i32);
     dep!(child(Child, (Child,)));
 
-    #[derive(Debug, Clone, Default, PartialEq)]
+    #[derive(Debug, Clone, Default, PartialEq, Component)]
     struct Parent(i32);
     dep!(parent(Parent, (Parent,)));
 

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

@@ -3,9 +3,12 @@ use dioxus_core::*;
 use dioxus_native_core::{
     dioxus::DioxusState,
     node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
+    prelude::*,
     real_dom::RealDom,
     Dependancy, SendAnyMap, State,
 };
+use dioxus_native_core_macro::partial_derive_state;
+use shipyard::Component;
 use std::cell::Cell;
 
 fn random_ns() -> Option<&'static str> {
@@ -231,7 +234,7 @@ fn create_random_dynamic_attr(cx: &ScopeState) -> Attribute {
 
 static mut TEMPLATE_COUNT: usize = 0;
 
-#[derive(PartialEq, Props)]
+#[derive(PartialEq, Props, Component)]
 struct DepthProps {
     depth: usize,
     root: bool,
@@ -293,11 +296,12 @@ fn create_random_element(cx: Scope<DepthProps>) -> Element {
     node
 }
 
-#[derive(Debug, Clone, PartialEq, Eq, Default)]
+#[derive(Debug, Clone, PartialEq, Eq, Default, Component)]
 pub struct BlablaState {
     count: usize,
 }
 
+#[partial_derive_state]
 impl State for BlablaState {
     type ParentDependencies = (Self,);
     type ChildDependencies = ();
@@ -312,7 +316,7 @@ impl State for BlablaState {
         _: NodeView,
         _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
         parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-        _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+        _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
         _: &SendAnyMap,
     ) -> bool {
         if let Some((parent,)) = parent {
@@ -327,7 +331,7 @@ impl State for BlablaState {
         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>>>,
+        children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
         context: &SendAnyMap,
     ) -> Self {
         let mut myself = Self::default();
@@ -353,7 +357,7 @@ fn create() {
         dioxus_state.apply_mutations(&mut rdom, mutations);
 
         let ctx = SendAnyMap::new();
-        rdom.update_state(ctx, false);
+        rdom.update_state(ctx);
     }
 }
 
@@ -375,13 +379,13 @@ fn diff() {
         dioxus_state.apply_mutations(&mut rdom, mutations);
 
         let ctx = SendAnyMap::new();
-        rdom.update_state(ctx, false);
+        rdom.update_state(ctx);
         for _ in 0..10 {
             let mutations = vdom.render_immediate();
             dioxus_state.apply_mutations(&mut rdom, mutations);
 
             let ctx = SendAnyMap::new();
-            rdom.update_state(ctx, false);
+            rdom.update_state(ctx);
         }
     }
 }

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

@@ -2,16 +2,20 @@ use dioxus::prelude::*;
 use dioxus_native_core::{
     dioxus::DioxusState,
     node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
+    prelude::*,
     real_dom::RealDom,
     Dependancy, SendAnyMap, State,
 };
+use dioxus_native_core_macro::partial_derive_state;
+use shipyard::Component;
 use tokio::time::sleep;
 
-#[derive(Debug, Clone, PartialEq, Eq, Default)]
+#[derive(Debug, Clone, PartialEq, Eq, Default, Component)]
 pub struct BlablaState {
     count: usize,
 }
 
+#[partial_derive_state]
 impl State for BlablaState {
     type ParentDependencies = (Self,);
     type ChildDependencies = ();
@@ -26,7 +30,7 @@ impl State for BlablaState {
         _: NodeView,
         _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
         parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-        _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+        _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
         _: &SendAnyMap,
     ) -> bool {
         if let Some((parent,)) = parent {
@@ -41,7 +45,7 @@ impl State for BlablaState {
         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>>>,
+        children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
         context: &SendAnyMap,
     ) -> Self {
         let mut myself = Self::default();
@@ -143,7 +147,7 @@ fn native_core_is_okay() {
         dioxus_state.apply_mutations(&mut *rdom.lock().unwrap(), mutations);
 
         let ctx = SendAnyMap::new();
-        rdom.lock().unwrap().update_state(ctx, false);
+        rdom.lock().unwrap().update_state(ctx);
 
         for _ in 0..10 {
             dom.wait_for_work().await;
@@ -152,7 +156,7 @@ fn native_core_is_okay() {
             dioxus_state.apply_mutations(&mut *rdom.lock().unwrap(), mutations);
 
             let ctx = SendAnyMap::new();
-            rdom.lock().unwrap().update_state(ctx, false);
+            rdom.lock().unwrap().update_state(ctx);
         }
     });
 }

+ 71 - 59
packages/native-core/tests/passes.rs

@@ -1,6 +1,8 @@
 use dioxus_native_core::node::NodeType;
 use dioxus_native_core::prelude::*;
+use dioxus_native_core_macro::partial_derive_state;
 use rustc_hash::{FxHashMap, FxHashSet};
+use shipyard::Component;
 
 fn create_blank_element() -> NodeType {
     NodeType::Element(ElementNode {
@@ -13,9 +15,10 @@ fn create_blank_element() -> NodeType {
 
 #[test]
 fn node_pass() {
-    #[derive(Debug, Default, Clone, PartialEq)]
+    #[derive(Debug, Default, Clone, PartialEq, Component)]
     struct Number(i32);
 
+    #[partial_derive_state]
     impl State for Number {
         type ChildDependencies = ();
         type NodeDependencies = ();
@@ -27,7 +30,7 @@ fn node_pass() {
             _: NodeView,
             _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
             _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-            _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             _: &SendAnyMap,
         ) -> bool {
             self.0 += 1;
@@ -38,7 +41,7 @@ fn node_pass() {
             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>>>,
+            children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             context: &SendAnyMap,
         ) -> Self {
             let mut myself = Self::default();
@@ -48,22 +51,29 @@ fn node_pass() {
     }
 
     let mut tree: RealDom = RealDom::new(Box::new([Number::to_type_erased()]));
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
 
-    assert_eq!(tree.get(tree.root_id()).unwrap().get(), Some(&Number(1)));
+    assert_eq!(
+        tree.get(tree.root_id()).unwrap().get().as_deref(),
+        Some(&Number(1))
+    );
 
     // mark the node as dirty
     tree.get_mut(tree.root_id()).unwrap().get_mut::<Number>();
 
-    tree.update_state(SendAnyMap::new(), false);
-    assert_eq!(tree.get(tree.root_id()).unwrap().get(), Some(&Number(2)));
+    tree.update_state(SendAnyMap::new());
+    assert_eq!(
+        tree.get(tree.root_id()).unwrap().get().as_deref(),
+        Some(&Number(2))
+    );
 }
 
 #[test]
 fn dependant_node_pass() {
-    #[derive(Debug, Default, Clone, PartialEq)]
+    #[derive(Debug, Default, Clone, PartialEq, Component)]
     struct AddNumber(i32);
 
+    #[partial_derive_state]
     impl State for AddNumber {
         type ChildDependencies = ();
         type NodeDependencies = (SubtractNumber,);
@@ -75,7 +85,7 @@ fn dependant_node_pass() {
             _: NodeView,
             _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
             _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-            _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             _: &SendAnyMap,
         ) -> bool {
             self.0 += 1;
@@ -86,7 +96,7 @@ fn dependant_node_pass() {
             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>>>,
+            children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             context: &SendAnyMap,
         ) -> Self {
             let mut myself = Self::default();
@@ -95,9 +105,10 @@ fn dependant_node_pass() {
         }
     }
 
-    #[derive(Debug, Default, Clone, PartialEq)]
+    #[derive(Debug, Default, Clone, PartialEq, Component)]
     struct SubtractNumber(i32);
 
+    #[partial_derive_state]
     impl State for SubtractNumber {
         type ChildDependencies = ();
         type NodeDependencies = ();
@@ -109,7 +120,7 @@ fn dependant_node_pass() {
             _: NodeView,
             _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
             _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-            _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             _: &SendAnyMap,
         ) -> bool {
             self.0 -= 1;
@@ -120,7 +131,7 @@ fn dependant_node_pass() {
             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>>>,
+            children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             context: &SendAnyMap,
         ) -> Self {
             let mut myself = Self::default();
@@ -133,36 +144,37 @@ fn dependant_node_pass() {
         AddNumber::to_type_erased(),
         SubtractNumber::to_type_erased(),
     ]));
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
 
     let root = tree.get(tree.root_id()).unwrap();
-    assert_eq!(root.get(), Some(&AddNumber(1)));
-    assert_eq!(root.get(), Some(&SubtractNumber(-1)));
+    assert_eq!(root.get().as_deref(), Some(&AddNumber(1)));
+    assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-1)));
 
     // mark the subtract state as dirty, it should update the add state
     tree.get_mut(tree.root_id())
         .unwrap()
         .get_mut::<SubtractNumber>();
 
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
     let root = tree.get(tree.root_id()).unwrap();
-    assert_eq!(root.get(), Some(&AddNumber(2)));
-    assert_eq!(root.get(), Some(&SubtractNumber(-2)));
+    assert_eq!(root.get().as_deref(), Some(&AddNumber(2)));
+    assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-2)));
 
     // mark the add state as dirty, it should ~not~ update the subtract state
     tree.get_mut(tree.root_id()).unwrap().get_mut::<AddNumber>();
 
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
     let root = tree.get(tree.root_id()).unwrap();
-    assert_eq!(root.get(), Some(&AddNumber(3)));
-    assert_eq!(root.get(), Some(&SubtractNumber(-2)));
+    assert_eq!(root.get().as_deref(), Some(&AddNumber(3)));
+    assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-2)));
 }
 
 #[test]
 fn independant_node_pass() {
-    #[derive(Debug, Default, Clone, PartialEq)]
+    #[derive(Debug, Default, Clone, PartialEq, Component)]
     struct AddNumber(i32);
 
+    #[partial_derive_state]
     impl State for AddNumber {
         type ChildDependencies = ();
         type NodeDependencies = ();
@@ -175,7 +187,7 @@ fn independant_node_pass() {
             _: NodeView,
             _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
             _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-            _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             _: &SendAnyMap,
         ) -> bool {
             self.0 += 1;
@@ -186,7 +198,7 @@ fn independant_node_pass() {
             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>>>,
+            children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             context: &SendAnyMap,
         ) -> Self {
             let mut myself = Self::default();
@@ -195,9 +207,10 @@ fn independant_node_pass() {
         }
     }
 
-    #[derive(Debug, Default, Clone, PartialEq)]
+    #[derive(Debug, Default, Clone, PartialEq, Component)]
     struct SubtractNumber(i32);
 
+    #[partial_derive_state]
     impl State for SubtractNumber {
         type ChildDependencies = ();
         type NodeDependencies = ();
@@ -210,7 +223,7 @@ fn independant_node_pass() {
             _: NodeView,
             _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
             _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-            _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             _: &SendAnyMap,
         ) -> bool {
             self.0 -= 1;
@@ -221,7 +234,7 @@ fn independant_node_pass() {
             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>>>,
+            children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             context: &SendAnyMap,
         ) -> Self {
             let mut myself = Self::default();
@@ -234,36 +247,36 @@ fn independant_node_pass() {
         AddNumber::to_type_erased(),
         SubtractNumber::to_type_erased(),
     ]));
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
 
     let root = tree.get(tree.root_id()).unwrap();
-    assert_eq!(root.get(), Some(&AddNumber(1)));
-    assert_eq!(root.get(), Some(&SubtractNumber(-1)));
+    assert_eq!(root.get().as_deref(), Some(&AddNumber(1)));
+    assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-1)));
 
     // mark the subtract state as dirty, it should ~not~ update the add state
     tree.get_mut(tree.root_id())
         .unwrap()
         .get_mut::<SubtractNumber>();
 
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
 
     let root = tree.get(tree.root_id()).unwrap();
-    assert_eq!(root.get(), Some(&AddNumber(1)));
-    assert_eq!(root.get(), Some(&SubtractNumber(-2)));
+    assert_eq!(root.get().as_deref(), Some(&AddNumber(1)));
+    assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-2)));
 
     // mark the add state as dirty, it should ~not~ update the subtract state
     tree.get_mut(tree.root_id()).unwrap().get_mut::<AddNumber>();
 
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
 
     let root = tree.get(tree.root_id()).unwrap();
-    assert_eq!(root.get(), Some(&AddNumber(2)));
-    assert_eq!(root.get(), Some(&SubtractNumber(-2)));
+    assert_eq!(root.get().as_deref(), Some(&AddNumber(2)));
+    assert_eq!(root.get().as_deref(), Some(&SubtractNumber(-2)));
 }
 
 #[test]
 fn down_pass() {
-    #[derive(Debug, Clone, PartialEq)]
+    #[derive(Debug, Clone, PartialEq, Component)]
     struct AddNumber(i32);
 
     impl Default for AddNumber {
@@ -272,6 +285,7 @@ fn down_pass() {
         }
     }
 
+    #[partial_derive_state]
     impl State for AddNumber {
         type ChildDependencies = ();
         type NodeDependencies = ();
@@ -284,7 +298,7 @@ fn down_pass() {
             _: NodeView,
             _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
             parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-            _: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            _: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             _: &SendAnyMap,
         ) -> bool {
             if let Some((parent,)) = parent {
@@ -297,7 +311,7 @@ fn down_pass() {
             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>>>,
+            children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             context: &SendAnyMap,
         ) -> Self {
             let mut myself = Self::default();
@@ -321,25 +335,24 @@ fn down_pass() {
     parent.add_child(child1);
     parent.add_child(child2);
 
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
 
     let root = tree.get(tree.root_id()).unwrap();
     dbg!(root.id());
-    assert_eq!(root.get(), Some(&AddNumber(1)));
+    assert_eq!(root.get().as_deref(), 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)));
+    assert_eq!(child1.get().as_deref(), Some(&AddNumber(2)));
 
     let grandchild1 = tree.get(grandchild1).unwrap();
-    assert_eq!(grandchild1.get(), Some(&AddNumber(3)));
+    assert_eq!(grandchild1.get().as_deref(), Some(&AddNumber(3)));
 
     let child2 = tree.get(child2).unwrap();
-    assert_eq!(child2.get(), Some(&AddNumber(2)));
+    assert_eq!(child2.get().as_deref(), Some(&AddNumber(2)));
 
     let grandchild2 = tree.get(grandchild2).unwrap();
-    assert_eq!(grandchild2.get(), Some(&AddNumber(3)));
+    assert_eq!(grandchild2.get().as_deref(), Some(&AddNumber(3)));
 }
 
 #[test]
@@ -357,9 +370,10 @@ fn up_pass() {
     //   2=\
     //     1
 
-    #[derive(Debug, Clone, PartialEq)]
+    #[derive(Debug, Clone, PartialEq, Component)]
     struct AddNumber(i32);
 
+    #[partial_derive_state]
     impl State for AddNumber {
         type ChildDependencies = (AddNumber,);
         type NodeDependencies = ();
@@ -372,12 +386,10 @@ fn up_pass() {
             _: NodeView,
             _: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
             _: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
-            children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
+            children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             _: &SendAnyMap,
         ) -> bool {
-            if let Some(children) = children {
-                self.0 += children.iter().map(|(i,)| i.0).sum::<i32>();
-            }
+            self.0 += children.iter().map(|(i,)| i.0).sum::<i32>();
             true
         }
 
@@ -385,7 +397,7 @@ fn up_pass() {
             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>>>,
+            children: Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
             context: &SendAnyMap,
         ) -> Self {
             let mut myself = Self(1);
@@ -409,20 +421,20 @@ fn up_pass() {
     parent.add_child(child1);
     parent.add_child(child2);
 
-    tree.update_state(SendAnyMap::new(), false);
+    tree.update_state(SendAnyMap::new());
 
     let root = tree.get(tree.root_id()).unwrap();
-    assert_eq!(root.get(), Some(&AddNumber(5)));
+    assert_eq!(root.get().as_deref(), Some(&AddNumber(5)));
 
     let child1 = tree.get(child1).unwrap();
-    assert_eq!(child1.get(), Some(&AddNumber(2)));
+    assert_eq!(child1.get().as_deref(), Some(&AddNumber(2)));
 
     let grandchild1 = tree.get(grandchild1).unwrap();
-    assert_eq!(grandchild1.get(), Some(&AddNumber(1)));
+    assert_eq!(grandchild1.get().as_deref(), Some(&AddNumber(1)));
 
     let child2 = tree.get(child2).unwrap();
-    assert_eq!(child2.get(), Some(&AddNumber(2)));
+    assert_eq!(child2.get().as_deref(), Some(&AddNumber(2)));
 
     let grandchild2 = tree.get(grandchild2).unwrap();
-    assert_eq!(grandchild2.get(), Some(&AddNumber(1)));
+    assert_eq!(grandchild2.get().as_deref(), Some(&AddNumber(1)));
 }