浏览代码

clean up the API

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

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

@@ -9,7 +9,7 @@ use std::sync::Arc;
 use crate::node::{FromAnyValue, NodeData};
 use crate::node_ref::NodeView;
 use crate::real_dom::RealDom;
-use crate::tree::{Node, TreeStateView};
+use crate::tree::{self, Node, TreeStateView};
 use crate::{FxDashMap, FxDashSet, SendAnyMap};
 use crate::{NodeId, NodeMask};
 
@@ -374,6 +374,7 @@ pub fn resolve_passes<V: FromAnyValue + Send + Sync>(
         let mut currently_in_use = FxHashSet::<TypeId>::default();
         std::thread::scope(|s| {
             let mut i = 0;
+            let dynamically_borrowed_tree = tree.tree.dynamically_borrowed();
             while i < pass_indexes_remaining.len() {
                 let passes_idx = pass_indexes_remaining[i];
                 let pass = &passes[passes_idx];
@@ -385,16 +386,18 @@ pub fn resolve_passes<V: FromAnyValue + Send + Sync>(
                     pass_indexes_remaining.remove(i);
                     resolving.push(pass_id);
                     currently_in_use.insert(pass.this_type_id);
-                    let tree_view = tree.tree.state_views(
-                        [pass.this_type_id],
+                    dynamically_borrowed_tree.with_view(
                         pass.combined_dependancy_type_ids.iter().copied(),
+                        [pass.this_type_id],
+                        |tree_view| {
+                            let dirty_nodes = dirty_nodes.clone();
+                            let nodes_updated = nodes_updated.clone();
+                            let ctx = ctx.clone();
+                            // s.spawn(move || {
+                            pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
+                            // });
+                        },
                     );
-                    let dirty_nodes = dirty_nodes.clone();
-                    let nodes_updated = nodes_updated.clone();
-                    let ctx = ctx.clone();
-                    s.spawn(move || {
-                        pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
-                    });
                 } else {
                     i += 1;
                 }

+ 2 - 2
packages/native-core/src/real_dom.rs

@@ -35,9 +35,9 @@ pub struct RealDom<V: FromAnyValue + Send = ()> {
 
 impl<V: FromAnyValue + Send + Sync> RealDom<V> {
     pub fn new(mut passes: Box<[TypeErasedPass<V>]>) -> RealDom<V> {
-        let tree = Tree::new();
+        let mut tree = Tree::new();
         let root_id = tree.root();
-        let root = tree.get_node(root_id);
+        let mut root = tree.get_node(root_id);
         let mut root_node: NodeData<V> = NodeData::new(NodeType::Element(ElementNode {
             tag: "Root".to_string(),
             namespace: Some("Root".to_string()),

+ 127 - 167
packages/native-core/src/tree.rs

@@ -1,12 +1,13 @@
 use parking_lot::{
     MappedRwLockReadGuard, MappedRwLockWriteGuard, RwLock, RwLockReadGuard, RwLockWriteGuard,
 };
-use rustc_hash::FxHasher;
+use rustc_hash::{FxHashMap, FxHasher};
 use std::any::{Any, TypeId};
 use std::collections::VecDeque;
 use std::fmt::Debug;
 use std::hash::BuildHasherDefault;
 
+use crate::node::NodeData;
 use crate::{AnyMapLike, Dependancy};
 
 #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug, Hash)]
@@ -20,12 +21,12 @@ pub(crate) struct Node {
 }
 
 pub(crate) struct NodeView<'a> {
-    tree: &'a Tree,
+    tree: &'a mut Tree,
     id: NodeId,
 }
 
 impl NodeView<'_> {
-    pub fn insert<T>(&self, data: T)
+    pub fn insert<T>(&mut self, data: T)
     where
         T: Any,
     {
@@ -39,7 +40,7 @@ impl NodeView<'_> {
         self.tree.nodes.read_slab::<T>().get(self.id).unwrap()
     }
 
-    pub fn get_mut<T>(&self) -> &mut T
+    pub fn get_mut<T>(&mut self) -> &mut T
     where
         T: Any,
     {
@@ -90,11 +91,11 @@ impl Tree {
         self.node_slab().get(id).unwrap()
     }
 
-    fn node_slab_mut(&self) -> &mut SlabStorage<Node> {
+    fn node_slab_mut(&mut self) -> &mut SlabStorage<Node> {
         self.nodes.write_slab()
     }
 
-    pub fn get_node_data_mut(&self, id: NodeId) -> &mut Node {
+    pub fn get_node_data_mut(&mut self, id: NodeId) -> &mut Node {
         self.node_slab_mut().get_mut(id).unwrap()
     }
 
@@ -118,7 +119,7 @@ impl Tree {
         recurse(self, id);
     }
 
-    fn set_height(&self, node: NodeId, height: u16) {
+    fn set_height(&mut self, node: NodeId, height: u16) {
         let children = {
             let mut node = self.get_node_data_mut(node);
             node.height = height;
@@ -145,7 +146,6 @@ impl Tree {
         let parent = node_state.get_mut(parent).unwrap();
         parent.children.push(new);
         let height = parent.height + 1;
-        drop(node_state);
         self.set_height(new, height);
     }
 
@@ -162,7 +162,6 @@ impl Tree {
                     }
                 }
                 let height = parent.height + 1;
-                drop(node_state);
                 self.set_height(new_id, height);
             }
         }
@@ -183,7 +182,6 @@ impl Tree {
             .unwrap();
         parent.children.insert(index, new_id);
         let height = parent.height + 1;
-        drop(node_state);
         self.set_height(new_id, height);
     }
 
@@ -200,7 +198,6 @@ impl Tree {
             .unwrap();
         parent.children.insert(index + 1, new_id);
         let height = parent.height + 1;
-        drop(node_state);
         self.set_height(new_id, height);
     }
 
@@ -212,22 +209,9 @@ impl Tree {
         self.nodes.len()
     }
 
-    pub fn state_views(
-        &self,
-        immutable: impl IntoIterator<Item = TypeId>,
-        mutable: impl IntoIterator<Item = TypeId>,
-    ) -> TreeStateView<'_> {
-        TreeStateView {
-            nodes_data: self.node_slab(),
-            nodes: immutable
-                .into_iter()
-                .map(|id| (id, MaybeRead::Read(self.nodes.data.get(&id).unwrap())))
-                .chain(
-                    mutable
-                        .into_iter()
-                        .map(|id| (id, MaybeRead::Write(self.nodes.data.get_mut(&id).unwrap()))),
-                )
-                .collect(),
+    pub fn dynamically_borrowed(&mut self) -> DynamicallyBorrowedTree<'_> {
+        DynamicallyBorrowedTree {
+            nodes: self.nodes.dynamically_borrowed(),
             root: self.root,
         }
     }
@@ -240,7 +224,7 @@ impl Tree {
         self.nodes.write_slab().get_mut(id)
     }
 
-    pub fn get_node(&self, id: NodeId) -> NodeView<'_> {
+    pub fn get_node(&mut self, id: NodeId) -> NodeView<'_> {
         NodeView { tree: self, id }
     }
 
@@ -265,111 +249,34 @@ impl Tree {
     }
 }
 
-pub(crate) trait NodeDataView {
-    fn root(&self) -> NodeId;
-
-    fn parent_id(&self, id: NodeId) -> Option<NodeId>;
-
-    fn children_ids(&self, id: NodeId) -> Option<Vec<NodeId>>;
-
-    fn height(&self, id: NodeId) -> Option<u16>;
-}
-
-trait TreeView<T>: Sized + NodeDataView {
-    fn get(&self, id: NodeId) -> Option<&T>;
-
-    fn get_unchecked(&self, id: NodeId) -> &T {
-        unsafe { self.get(id).unwrap_unchecked() }
-    }
-
-    fn children(&self, id: NodeId) -> Option<Vec<&T>>;
-
-    fn parent(&self, id: NodeId) -> Option<&T>;
-
-    fn traverse_depth_first(&self, mut f: impl FnMut(&T)) {
-        let mut stack = vec![self.root()];
-        while let Some(id) = stack.pop() {
-            if let Some(node) = self.get(id) {
-                f(node);
-                if let Some(children) = self.children_ids(id) {
-                    stack.extend(children.iter().copied().rev());
-                }
-            }
-        }
-    }
-
-    fn traverse_breadth_first(&self, mut f: impl FnMut(&T)) {
-        let mut queue = VecDeque::new();
-        queue.push_back(self.root());
-        while let Some(id) = queue.pop_front() {
-            if let Some(node) = self.get(id) {
-                f(node);
-                if let Some(children) = self.children_ids(id) {
-                    for id in children {
-                        queue.push_back(id);
-                    }
-                }
-            }
-        }
-    }
+pub(crate) struct DynamicallyBorrowedTree<'a> {
+    nodes: DynamiclyBorrowedAnySlabView<'a>,
+    root: NodeId,
 }
 
-trait TreeViewMut<T>: Sized + TreeView<T> {
-    fn get_mut(&mut self, id: NodeId) -> Option<&mut T>;
-
-    unsafe fn get_mut_unchecked(&mut self, id: NodeId) -> &mut T {
-        unsafe { self.get_mut(id).unwrap_unchecked() }
-    }
-
-    fn children_mut(&mut self, id: NodeId) -> Option<Vec<&mut T>>;
-
-    fn parent_child_mut(&mut self, id: NodeId) -> Option<(&mut T, Vec<&mut T>)> {
-        let mut_ptr: *mut Self = self;
-        unsafe {
-            // Safety: No node has itself as a child.
-            (*mut_ptr).get_mut(id).and_then(|parent| {
-                (*mut_ptr)
-                    .children_mut(id)
-                    .map(|children| (parent, children))
-            })
-        }
-    }
-
-    fn parent_mut(&mut self, id: NodeId) -> Option<&mut T>;
-
-    fn node_parent_mut(&mut self, id: NodeId) -> Option<(&mut T, Option<&mut T>)>;
-
-    #[allow(clippy::type_complexity)]
-    fn node_parent_children_mut(
-        &mut self,
-        id: NodeId,
-    ) -> Option<(&mut T, Option<&mut T>, Option<Vec<&mut T>>)>;
-
-    fn traverse_depth_first_mut(&mut self, mut f: impl FnMut(&mut T)) {
-        let mut stack = vec![self.root()];
-        while let Some(id) = stack.pop() {
-            if let Some(node) = self.get_mut(id) {
-                f(node);
-                if let Some(children) = self.children_ids(id) {
-                    stack.extend(children.iter().copied().rev());
-                }
-            }
+impl<'a> DynamicallyBorrowedTree<'a> {
+    pub fn with_view(
+        &self,
+        immutable: impl IntoIterator<Item = TypeId>,
+        mutable: impl IntoIterator<Item = TypeId>,
+        mut f: impl FnMut(TreeStateView),
+    ) {
+        let node_data = self.node_slab();
+        let nodes = FxHashMap::default();
+        {
+            let mut view = TreeStateView {
+                root: self.root,
+                nodes_data: &*node_data,
+                nodes,
+            };
+            f(view)
         }
     }
 
-    fn traverse_breadth_first_mut(&mut self, mut f: impl FnMut(&mut T)) {
-        let mut queue = VecDeque::new();
-        queue.push_back(self.root());
-        while let Some(id) = queue.pop_front() {
-            if let Some(node) = self.get_mut(id) {
-                f(node);
-                if let Some(children) = self.children_ids(id) {
-                    for id in children {
-                        queue.push_back(id);
-                    }
-                }
-            }
-        }
+    fn node_slab(&self) -> MappedRwLockReadGuard<'_, SlabStorage<Node>> {
+        RwLockReadGuard::map(self.nodes.get_slab(TypeId::of::<Node>()).unwrap(), |slab| {
+            slab.as_any().downcast_ref().unwrap()
+        })
     }
 }
 
@@ -379,7 +286,7 @@ enum MaybeRead<'a> {
 }
 
 #[derive(Clone, Copy)]
-struct TreeStateViewEntry<'a> {
+pub struct TreeStateViewEntry<'a> {
     view: &'a TreeStateView<'a>,
     id: NodeId,
 }
@@ -392,7 +299,7 @@ impl<'a> AnyMapLike<'a> for TreeStateViewEntry<'a> {
 
 pub struct TreeStateView<'a> {
     nodes_data: &'a SlabStorage<Node>,
-    nodes: hashbrown::HashMap<TypeId, MaybeRead<'a>, BuildHasherDefault<FxHasher>>,
+    nodes: FxHashMap<TypeId, MaybeRead<'a>>,
     root: NodeId,
 }
 
@@ -443,7 +350,7 @@ impl<'a> TreeStateView<'a> {
         self.get_slab_mut().and_then(|slab| slab.get_mut(id))
     }
 
-    fn entry(&self, id: NodeId) -> TreeStateViewEntry<'_> {
+    pub fn entry(&self, id: NodeId) -> TreeStateViewEntry<'_> {
         TreeStateViewEntry { view: self, id }
     }
 
@@ -459,6 +366,33 @@ impl<'a> TreeStateView<'a> {
     pub fn parent<T: Dependancy>(&self, id: NodeId) -> Option<T::ElementBorrowed<'_>> {
         T::borrow_elements_from(self.entry(id))
     }
+
+    fn traverse_depth_first<T: Dependancy>(&self, mut f: impl FnMut(T::ElementBorrowed<'_>)) {
+        let mut stack = vec![self.root()];
+        while let Some(id) = stack.pop() {
+            if let Some(node) = self.get::<T>(id) {
+                f(node);
+                if let Some(children) = self.children_ids(id) {
+                    stack.extend(children.iter().copied().rev());
+                }
+            }
+        }
+    }
+
+    fn traverse_breadth_first<T: Dependancy>(&self, mut f: impl FnMut(T::ElementBorrowed<'_>)) {
+        let mut queue = VecDeque::new();
+        queue.push_back(self.root());
+        while let Some(id) = queue.pop_front() {
+            if let Some(node) = self.get::<T>(id) {
+                f(node);
+                if let Some(children) = self.children_ids(id) {
+                    for id in children {
+                        queue.push_back(id);
+                    }
+                }
+            }
+        }
+    }
 }
 
 #[test]
@@ -479,9 +413,9 @@ fn creation() {
     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]);
-    let view = tree.state_view::<i32>();
-    assert_eq!(*view.get(parent_id).unwrap(), 1);
-    assert_eq!(*view.get(child_id).unwrap(), 0);
+
+    assert_eq!(*tree.read::<i32>(parent_id).unwrap(), 1);
+    assert_eq!(*tree.read::<i32>(child_id).unwrap(), 0);
 }
 
 #[test]
@@ -512,11 +446,11 @@ fn insertion() {
     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]);
-    let view = tree.state_view::<i32>();
-    assert_eq!(*view.get(parent).unwrap(), 0);
-    assert_eq!(*view.get(before).unwrap(), 1);
-    assert_eq!(*view.get(child).unwrap(), 2);
-    assert_eq!(*view.get(after).unwrap(), 3);
+
+    assert_eq!(*tree.read::<i32>(parent).unwrap(), 0);
+    assert_eq!(*tree.read::<i32>(before).unwrap(), 1);
+    assert_eq!(*tree.read::<i32>(child).unwrap(), 2);
+    assert_eq!(*tree.read::<i32>(after).unwrap(), 3);
 }
 
 #[test]
@@ -547,13 +481,11 @@ fn deletion() {
     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]);
-    {
-        let view = tree.state_view::<i32>();
-        assert_eq!(*view.get(parent).unwrap(), 0);
-        assert_eq!(*view.get(before).unwrap(), 1);
-        assert_eq!(*view.get(child).unwrap(), 2);
-        assert_eq!(*view.get(after).unwrap(), 3);
-    }
+
+    assert_eq!(*tree.read::<i32>(parent).unwrap(), 0);
+    assert_eq!(*tree.read::<i32>(before).unwrap(), 1);
+    assert_eq!(*tree.read::<i32>(child).unwrap(), 2);
+    assert_eq!(*tree.read::<i32>(after).unwrap(), 3);
 
     tree.remove(child);
 
@@ -565,13 +497,11 @@ fn deletion() {
     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]);
-    {
-        let view = tree.state_view::<i32>();
-        assert_eq!(*view.get(parent).unwrap(), 0);
-        assert_eq!(*view.get(before).unwrap(), 1);
-        assert_eq!(view.get(child), None);
-        assert_eq!(*view.get(after).unwrap(), 3);
-    }
+
+    assert_eq!(*tree.read::<i32>(parent).unwrap(), 0);
+    assert_eq!(*tree.read::<i32>(before).unwrap(), 1);
+    assert_eq!(tree.read::<i32>(child), None);
+    assert_eq!(*tree.read::<i32>(after).unwrap(), 3);
 
     tree.remove(before);
 
@@ -581,12 +511,10 @@ fn deletion() {
     assert_eq!(tree.height(after), Some(1));
     assert_eq!(tree.parent_id(after).unwrap(), parent);
     assert_eq!(tree.children_ids(parent).unwrap(), &[after]);
-    {
-        let view = tree.state_view::<i32>();
-        assert_eq!(*view.get(parent).unwrap(), 0);
-        assert_eq!(view.get(before), None);
-        assert_eq!(*view.get(after).unwrap(), 3);
-    }
+
+    assert_eq!(*tree.read::<i32>(parent).unwrap(), 0);
+    assert_eq!(tree.read::<i32>(before), None);
+    assert_eq!(*tree.read::<i32>(after).unwrap(), 3);
 
     tree.remove(after);
 
@@ -594,11 +522,9 @@ fn deletion() {
     assert_eq!(tree.size(), 1);
     assert_eq!(tree.height(parent), Some(0));
     assert_eq!(tree.children_ids(parent).unwrap(), &[]);
-    {
-        let view = tree.state_view::<i32>();
-        assert_eq!(*view.get(parent).unwrap(), 0);
-        assert_eq!(view.get(after), None);
-    }
+
+    assert_eq!(*tree.read::<i32>(parent).unwrap(), 0);
+    assert_eq!(tree.read::<i32>(after), None);
 }
 
 #[test]
@@ -752,6 +678,30 @@ impl<T: 'static + Send + Sync> AnySlabStorageImpl for SlabStorage<T> {
     }
 }
 
+pub(crate) struct DynamiclyBorrowedAnySlabView<'a> {
+    data: hashbrown::HashMap<
+        TypeId,
+        RwLock<&'a mut dyn AnySlabStorageImpl>,
+        BuildHasherDefault<FxHasher>,
+    >,
+}
+
+impl<'a> DynamiclyBorrowedAnySlabView<'a> {
+    fn get_slab(
+        &self,
+        type_id: TypeId,
+    ) -> Option<RwLockReadGuard<'_, &'a mut dyn AnySlabStorageImpl>> {
+        self.data.get(&type_id).map(|x| x.read())
+    }
+
+    fn get_slab_mut(
+        &self,
+        type_id: TypeId,
+    ) -> Option<RwLockWriteGuard<'_, &'a mut dyn AnySlabStorageImpl>> {
+        self.data.get(&type_id).map(|x| x.write())
+    }
+}
+
 pub(crate) struct AnySlab {
     data: hashbrown::HashMap<TypeId, Box<dyn AnySlabStorageImpl>, BuildHasherDefault<FxHasher>>,
     filled: Vec<bool>,
@@ -795,13 +745,13 @@ impl AnySlab {
         self.try_read_slab().unwrap()
     }
 
-    fn try_write_slab<T: Any>(&self) -> Option<&mut SlabStorage<T>> {
+    fn try_write_slab<T: Any>(&mut self) -> Option<&mut SlabStorage<T>> {
         self.data
-            .get(&TypeId::of::<T>())
+            .get_mut(&TypeId::of::<T>())
             .map(|x| x.as_any_mut().downcast_mut().unwrap())
     }
 
-    fn write_slab<T: Any>(&self) -> &mut SlabStorage<T> {
+    fn write_slab<T: Any>(&mut self) -> &mut SlabStorage<T> {
         self.try_write_slab().unwrap()
     }
 
@@ -855,6 +805,16 @@ impl AnySlab {
     fn contains(&self, id: NodeId) -> bool {
         self.filled.get(id.0).copied().unwrap_or_default()
     }
+
+    fn dynamically_borrowed(&mut self) -> DynamiclyBorrowedAnySlabView<'_> {
+        DynamiclyBorrowedAnySlabView {
+            data: self
+                .data
+                .iter_mut()
+                .map(|(k, v)| (*k, RwLock::new(&mut **v)))
+                .collect(),
+        }
+    }
 }
 
 pub struct EntryBuilder<'a> {

+ 140 - 140
packages/native-core/tests/miri_native.rs

@@ -1,140 +1,140 @@
-use dioxus::prelude::*;
-use dioxus_native_core::{
-    node_ref::{AttributeMask, NodeView},
-    real_dom::RealDom,
-    state::{ParentDepState, State},
-    NodeMask, SendAnyMap,
-};
-use dioxus_native_core_macro::{sorted_str_slice, State};
-use std::sync::{Arc, Mutex};
-use tokio::time::sleep;
-
-#[derive(Debug, Clone, PartialEq, Eq, Default)]
-pub struct BlablaState {}
-
-/// Font style are inherited by default if not specified otherwise by some of the supported attributes.
-impl ParentDepState for BlablaState {
-    type Ctx = ();
-    type DepState = (Self,);
-
-    const NODE_MASK: NodeMask =
-        NodeMask::new_with_attrs(AttributeMask::Static(&sorted_str_slice!(["blabla",])));
-
-    fn reduce<'a>(
-        &mut self,
-        _node: NodeView,
-        _parent: Option<(&'a Self,)>,
-        _ctx: &Self::Ctx,
-    ) -> bool {
-        false
-    }
-}
-
-#[derive(Clone, State, Default, Debug)]
-pub struct NodeState {
-    #[parent_dep_state(blabla)]
-    blabla: BlablaState,
-}
-
-mod dioxus_elements {
-    macro_rules! builder_constructors {
-        (
-            $(
-                $(#[$attr:meta])*
-                $name:ident {
-                    $(
-                        $(#[$attr_method:meta])*
-                        $fil:ident: $vil:ident,
-                    )*
-                };
-            )*
-        ) => {
-            $(
-                #[allow(non_camel_case_types)]
-                $(#[$attr])*
-                pub struct $name;
-
-                impl $name {
-                    pub const TAG_NAME: &'static str = stringify!($name);
-                    pub const NAME_SPACE: Option<&'static str> = None;
-
-                    $(
-                        pub const $fil: (&'static str, Option<&'static str>, bool) = (stringify!($fil), None, false);
-                    )*
-                }
-
-                impl GlobalAttributes for $name {}
-            )*
-        }
-    }
-
-    pub trait GlobalAttributes {}
-
-    pub trait SvgAttributes {}
-
-    builder_constructors! {
-        blabla {
-
-        };
-    }
-}
-
-#[test]
-fn native_core_is_okay() {
-    use std::time::Duration;
-
-    fn app(cx: Scope) -> Element {
-        let colors = use_state(cx, || vec!["green", "blue", "red"]);
-        let padding = use_state(cx, || 10);
-
-        use_effect(cx, colors, |colors| async move {
-            sleep(Duration::from_millis(1000)).await;
-            colors.with_mut(|colors| colors.reverse());
-        });
-
-        use_effect(cx, padding, |padding| async move {
-            sleep(Duration::from_millis(10)).await;
-            padding.with_mut(|padding| {
-                if *padding < 65 {
-                    *padding += 1;
-                } else {
-                    *padding = 5;
-                }
-            });
-        });
-
-        let _big = colors[0];
-        let _mid = colors[1];
-        let _small = colors[2];
-
-        cx.render(rsx! {
-            blabla {}
-        })
-    }
-
-    let rt = tokio::runtime::Builder::new_current_thread()
-        .enable_time()
-        .build()
-        .unwrap();
-
-    rt.block_on(async {
-        let rdom = Arc::new(Mutex::new(RealDom::<NodeState>::new()));
-        let mut dom = VirtualDom::new(app);
-
-        let muts = dom.rebuild();
-        let (to_update, _diff) = rdom.lock().unwrap().apply_mutations(muts);
-
-        let ctx = SendAnyMap::new();
-        rdom.lock().unwrap().update_state(to_update, ctx);
-
-        for _ in 0..10 {
-            dom.wait_for_work().await;
-
-            let mutations = dom.render_immediate();
-            let (to_update, _diff) = rdom.lock().unwrap().apply_mutations(mutations);
-
-            let ctx = SendAnyMap::new();
-            rdom.lock().unwrap().update_state(to_update, ctx);
-        }
-    });
-}
+// use dioxus::prelude::*;
+// use dioxus_native_core::{
+//     node_ref::{AttributeMask, NodeView},
+//     real_dom::RealDom,
+//     state::{ParentDepState, State},
+//     NodeMask, SendAnyMap,
+// };
+// use dioxus_native_core_macro::{sorted_str_slice, State};
+// use std::sync::{Arc, Mutex};
+// use tokio::time::sleep;
+
+// #[derive(Debug, Clone, PartialEq, Eq, Default)]
+// pub struct BlablaState {}
+
+// /// Font style are inherited by default if not specified otherwise by some of the supported attributes.
+// impl ParentDepState for BlablaState {
+//     type Ctx = ();
+//     type DepState = (Self,);
+
+//     const NODE_MASK: NodeMask =
+//         NodeMask::new_with_attrs(AttributeMask::Static(&sorted_str_slice!(["blabla",])));
+
+//     fn reduce<'a>(
+//         &mut self,
+//         _node: NodeView,
+//         _parent: Option<(&'a Self,)>,
+//         _ctx: &Self::Ctx,
+//     ) -> bool {
+//         false
+//     }
+// }
+
+// #[derive(Clone, State, Default, Debug)]
+// pub struct NodeState {
+//     #[parent_dep_state(blabla)]
+//     blabla: BlablaState,
+// }
+
+// mod dioxus_elements {
+//     macro_rules! builder_constructors {
+//         (
+//             $(
+//                 $(#[$attr:meta])*
+//                 $name:ident {
+//                     $(
+//                         $(#[$attr_method:meta])*
+//                         $fil:ident: $vil:ident,
+//                     )*
+//                 };
+//             )*
+//         ) => {
+//             $(
+//                 #[allow(non_camel_case_types)]
+//                 $(#[$attr])*
+//                 pub struct $name;
+
+//                 impl $name {
+//                     pub const TAG_NAME: &'static str = stringify!($name);
+//                     pub const NAME_SPACE: Option<&'static str> = None;
+
+//                     $(
+//                         pub const $fil: (&'static str, Option<&'static str>, bool) = (stringify!($fil), None, false);
+//                     )*
+//                 }
+
+//                 impl GlobalAttributes for $name {}
+//             )*
+//         }
+//     }
+
+//     pub trait GlobalAttributes {}
+
+//     pub trait SvgAttributes {}
+
+//     builder_constructors! {
+//         blabla {
+
+//         };
+//     }
+// }
+
+// #[test]
+// fn native_core_is_okay() {
+//     use std::time::Duration;
+
+//     fn app(cx: Scope) -> Element {
+//         let colors = use_state(cx, || vec!["green", "blue", "red"]);
+//         let padding = use_state(cx, || 10);
+
+//         use_effect(cx, colors, |colors| async move {
+//             sleep(Duration::from_millis(1000)).await;
+//             colors.with_mut(|colors| colors.reverse());
+//         });
+
+//         use_effect(cx, padding, |padding| async move {
+//             sleep(Duration::from_millis(10)).await;
+//             padding.with_mut(|padding| {
+//                 if *padding < 65 {
+//                     *padding += 1;
+//                 } else {
+//                     *padding = 5;
+//                 }
+//             });
+//         });
+
+//         let _big = colors[0];
+//         let _mid = colors[1];
+//         let _small = colors[2];
+
+//         cx.render(rsx! {
+//             blabla {}
+//         })
+//     }
+
+//     let rt = tokio::runtime::Builder::new_current_thread()
+//         .enable_time()
+//         .build()
+//         .unwrap();
+
+//     rt.block_on(async {
+//         let rdom = Arc::new(Mutex::new(RealDom::<NodeState>::new()));
+//         let mut dom = VirtualDom::new(app);
+
+//         let muts = dom.rebuild();
+//         let (to_update, _diff) = rdom.lock().unwrap().apply_mutations(muts);
+
+//         let ctx = SendAnyMap::new();
+//         rdom.lock().unwrap().update_state(to_update, ctx);
+
+//         for _ in 0..10 {
+//             dom.wait_for_work().await;
+
+//             let mutations = dom.render_immediate();
+//             let (to_update, _diff) = rdom.lock().unwrap().apply_mutations(mutations);
+
+//             let ctx = SendAnyMap::new();
+//             rdom.lock().unwrap().update_state(to_update, ctx);
+//         }
+//     });
+// }