clean up the API

This commit is contained in:
Evan Almloff committed 2023-01-20 13:23:26 -06:00
1 parent 1587b41829
commit ebb6300fc7
4 files changed
+255 -292

No files matched your search

+12 -9
View File
@@ -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
View File
@@ -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
View File
@@ -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>;
pub(crate) struct DynamicallyBorrowedTree<'a> {
nodes: DynamiclyBorrowedAnySlabView<'a>,
root: NodeId,
}
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());
}
}
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(&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);
}
}
}
}
}
}
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());
}
}
}
}
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> {
+114 -114
View File
@@ -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;
// 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 {}
// #[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,);
// /// 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",])));
// 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
}
}
// 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,
}
// #[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;
// 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;
// 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);
)*
}
// $(
// pub const $fil: (&'static str, Option<&'static str>, bool) = (stringify!($fil), None, false);
// )*
// }
impl GlobalAttributes for $name {}
)*
}
}
// impl GlobalAttributes for $name {}
// )*
// }
// }
pub trait GlobalAttributes {}
// pub trait GlobalAttributes {}
pub trait SvgAttributes {}
// pub trait SvgAttributes {}
builder_constructors! {
blabla {
// builder_constructors! {
// blabla {
};
}
}
// };
// }
// }
#[test]
fn native_core_is_okay() {
use std::time::Duration;
// #[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);
// 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, 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;
}
});
});
// 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];
// let _big = colors[0];
// let _mid = colors[1];
// let _small = colors[2];
cx.render(rsx! {
blabla {}
})
}
// cx.render(rsx! {
// blabla {}
// })
// }
let rt = tokio::runtime::Builder::new_current_thread()
.enable_time()
.build()
.unwrap();
// 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);
// 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 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);
// let ctx = SendAnyMap::new();
// rdom.lock().unwrap().update_state(to_update, ctx);
for _ in 0..10 {
dom.wait_for_work().await;
// 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 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);
}
});
}
// let ctx = SendAnyMap::new();
// rdom.lock().unwrap().update_state(to_update, ctx);
// }
// });
// }