From 865c5aa9579a800744c0acc1a9b4755461cd6112 Mon Sep 17 00:00:00 2001 From: Evan Almloff Date: Sun, 12 Mar 2023 15:35:48 -0500 Subject: [PATCH] all native-core tests passing --- packages/native-core-macro/src/lib.rs | 28 +++- packages/native-core/Cargo.toml | 1 + packages/native-core/src/dioxus.rs | 2 +- packages/native-core/src/passes.rs | 109 +++++++------ packages/native-core/src/real_dom.rs | 119 +++++++------- packages/native-core/src/tree.rs | 148 ++++++++---------- .../src/utils/persistant_iterator.rs | 40 ++--- .../tests/called_minimally_on_build.rs | 65 ++++---- packages/native-core/tests/fuzzing.rs | 18 ++- packages/native-core/tests/miri_native.rs | 14 +- packages/native-core/tests/passes.rs | 130 ++++++++------- 11 files changed, 350 insertions(+), 324 deletions(-) diff --git a/packages/native-core-macro/src/lib.rs b/packages/native-core-macro/src/lib.rs index 4343743d1..e1e104bf3 100644 --- a/packages/native-core-macro/src/lib.rs +++ b/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::>(); 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 _); diff --git a/packages/native-core/Cargo.toml b/packages/native-core/Cargo.toml index 5b5868de9..2b08d2c04 100644 --- a/packages/native-core/Cargo.toml +++ b/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 = [] diff --git a/packages/native-core/src/dioxus.rs b/packages/native-core/src/dioxus.rs index 4deada6ab..938ed16c4 100644 --- a/packages/native-core/src/dioxus.rs +++ b/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() diff --git a/packages/native-core/src/passes.rs b/packages/native-core/src/passes.rs index 99553b124..ff55f65f2 100644 --- a/packages/native-core/src/passes.rs +++ b/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: 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: Any + Send + Sync { node_view: NodeView, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::ElementBorrowed<'a>>, context: &SendAnyMap, ) -> bool; @@ -128,7 +129,7 @@ pub trait State: Any + Send + Sync { node_view: NodeView, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::ElementBorrowed<'a>>, context: &SendAnyMap, ) -> Self; @@ -140,52 +141,22 @@ pub trait State: 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>, + 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, - current: u32, - ) -> Result { - Ok(RunPassView { - tree: as shipyard::IntoBorrow>::Borrow::borrow( - world, last_run, current, - )?, - nodes_updated: - as shipyard::IntoBorrow>::Borrow::borrow( - world, last_run, current, - )?, - dirty: as shipyard::IntoBorrow>::Borrow::borrow( - world, last_run, current, - )?, - ctx: as shipyard::IntoBorrow>::Borrow::borrow( - world, last_run, current, - )?, - }) - } -} - -pub fn run_pass( +pub fn run_pass( type_id: TypeId, dependants: FxHashSet, pass_direction: PassDirection, - view: RunPassView, + view: RunPassView, 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: State { } } +impl> AnyState for S {} + pub struct TypeErasedPass { pub(crate) this_type_id: TypeId, pub(crate) parent_dependant: bool, @@ -295,7 +268,17 @@ pub struct TypeErasedPass { phantom: PhantomData, } -#[derive(Debug)] +impl TypeErasedPass { + 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); diff --git a/packages/native-core/src/real_dom.rs b/packages/native-core/src/real_dom.rs index c87564dab..fc077d143 100644 --- a/packages/native-core/src/real_dom.rs +++ b/packages/native-core/src/real_dom.rs @@ -101,6 +101,19 @@ pub struct RealDom { impl RealDom { pub fn new(mut passes: Box<[TypeErasedPass]>) -> RealDom { + // 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 RealDom { 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 ¤t.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 RealDom { } pub fn get_mut(&mut self, id: NodeId) -> Option> { - 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 RealDom { 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 RealDom { 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 RealDom { 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 RealDom { 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: Sized { } #[inline] - fn child_ids(&self) -> Option> { + fn child_ids(&self) -> Vec { self.real_dom().tree_ref().children_ids(self.id()) } #[inline] fn children(&self) -> Vec> { 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: Sized { #[inline] fn next(&self) -> Option> { 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: Sized { #[inline] fn prev(&self) -> Option> { 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> { 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> { 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(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::>(); @@ -913,7 +908,7 @@ fn construct_workload(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 { diff --git a/packages/native-core/src/tree.rs b/packages/native-core/src/tree.rs index f1c542a3c..ec5e02895 100644 --- a/packages/native-core/src/tree.rs +++ b/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; - fn children_ids(&self, id: NodeId) -> Option>; + fn children_ids(&self, id: NodeId) -> Vec; fn height(&self, id: NodeId) -> Option; 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> { - Some(self.get(id).unwrap().children.clone()) + fn children_ids(&self, id: NodeId) -> Vec { + self.get(id) + .map(|node| node.children.clone()) + .unwrap_or_default() } fn height(&self, id: NodeId) -> Option { @@ -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> { + fn children_ids(&self, id: NodeId) -> Vec { 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 { @@ -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::().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::(parent_id).unwrap(), 1); - assert_eq!(*tree.get::(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::().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::(parent).unwrap(), 0); - assert_eq!(*tree.get::(before).unwrap(), 1); - assert_eq!(*tree.get::(child).unwrap(), 2); - assert_eq!(*tree.get::(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::().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::(parent).unwrap(), 0); - assert_eq!(*tree.get::(before).unwrap(), 1); - assert_eq!(*tree.get::(child).unwrap(), 2); - assert_eq!(*tree.get::(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::(parent).unwrap(), 0); - assert_eq!(*tree.get::(before).unwrap(), 1); - assert_eq!(tree.get::(child), None); - assert_eq!(*tree.get::(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::(parent).unwrap(), 0); - assert_eq!(tree.get::(before), None); - assert_eq!(*tree.get::(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::(parent).unwrap(), 0); - assert_eq!(tree.get::(after), None); + assert_eq!(tree.children_ids(parent), &[]); } diff --git a/packages/native-core/src/utils/persistant_iterator.rs b/packages/native-core/src/utils/persistant_iterator.rs index 2469e3ce4..155909373 100644 --- a/packages/native-core/src/utils/persistant_iterator.rs +++ b/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) )); } diff --git a/packages/native-core/tests/called_minimally_on_build.rs b/packages/native-core/tests/called_minimally_on_build.rs index db0bda59c..feebc1ea6 100644 --- a/packages/native-core/tests/called_minimally_on_build.rs +++ b/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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { self.0 += 1; @@ -32,30 +35,31 @@ macro_rules! dep { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { self.0 += 1; @@ -66,30 +70,31 @@ macro_rules! dep { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { self.0 += 1; @@ -100,11 +105,11 @@ macro_rules! dep { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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,))); diff --git a/packages/native-core/tests/fuzzing.rs b/packages/native-core/tests/fuzzing.rs index 8a449c52a..38b23587a 100644 --- a/packages/native-core/tests/fuzzing.rs +++ b/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) -> 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, _: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { if let Some((parent,)) = parent { @@ -327,7 +331,7 @@ impl State for BlablaState { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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); } } } diff --git a/packages/native-core/tests/miri_native.rs b/packages/native-core/tests/miri_native.rs index 342445ae7..8e05fe934 100644 --- a/packages/native-core/tests/miri_native.rs +++ b/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, _: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { if let Some((parent,)) = parent { @@ -41,7 +45,7 @@ impl State for BlablaState { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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); } }); } diff --git a/packages/native-core/tests/passes.rs b/packages/native-core/tests/passes.rs index 6afe24bf6..7f69b8968 100644 --- a/packages/native-core/tests/passes.rs +++ b/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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { self.0 += 1; @@ -38,7 +41,7 @@ fn node_pass() { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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::(); - 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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { self.0 += 1; @@ -86,7 +96,7 @@ fn dependant_node_pass() { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { self.0 -= 1; @@ -120,7 +131,7 @@ fn dependant_node_pass() { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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::(); - 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::(); - 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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { self.0 += 1; @@ -186,7 +198,7 @@ fn independant_node_pass() { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { self.0 -= 1; @@ -221,7 +234,7 @@ fn independant_node_pass() { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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::(); - 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::(); - 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, _: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - _: Option::ElementBorrowed<'a>>>, + _: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { if let Some((parent,)) = parent { @@ -297,7 +311,7 @@ fn down_pass() { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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::()); - 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, _: ::ElementBorrowed<'a>, _: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::ElementBorrowed<'a>>, _: &SendAnyMap, ) -> bool { - if let Some(children) = children { - self.0 += children.iter().map(|(i,)| i.0).sum::(); - } + self.0 += children.iter().map(|(i,)| i.0).sum::(); true } @@ -385,7 +397,7 @@ fn up_pass() { node_view: NodeView<()>, node: ::ElementBorrowed<'a>, parent: Option<::ElementBorrowed<'a>>, - children: Option::ElementBorrowed<'a>>>, + children: Vec<::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))); }