make dioxus an optional dependancy
This commit is contained in:
1 parent
dd1d492e61
commit
e4c7218fe8
9 files changed
+300
-432
No files matched your search
@@ -36,5 +36,5 @@ tokio = { version = "*", features = ["full"] }
|
|||||||
dioxus-native-core = { path = ".", features = ["dioxus"] }
|
dioxus-native-core = { path = ".", features = ["dioxus"] }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["dioxus"]
|
default = []
|
||||||
dioxus = ["dioxus-core"]
|
dioxus = ["dioxus-core"]
|
||||||
@@ -15,7 +15,7 @@ pub struct DioxusState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl DioxusState {
|
impl DioxusState {
|
||||||
pub fn new(rdom: &mut RealDom) -> Self {
|
pub fn create(rdom: &mut RealDom) -> Self {
|
||||||
rdom.insert_slab::<ElementId>();
|
rdom.insert_slab::<ElementId>();
|
||||||
let root_id = rdom.root_id();
|
let root_id = rdom.root_id();
|
||||||
let mut root = rdom.get_mut(root_id).unwrap();
|
let mut root = rdom.get_mut(root_id).unwrap();
|
||||||
|
|||||||
@@ -203,12 +203,12 @@ impl NodeMask {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(PartialEq, Eq, Clone, Debug)]
|
#[derive(PartialEq, Eq, Clone, Debug)]
|
||||||
pub enum AttributeMaskBuilder {
|
pub enum AttributeMaskBuilder<'a> {
|
||||||
All,
|
All,
|
||||||
Some(&'static [&'static str]),
|
Some(&'a [&'a str]),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AttributeMaskBuilder {
|
impl Default for AttributeMaskBuilder<'_> {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
AttributeMaskBuilder::Some(&[])
|
AttributeMaskBuilder::Some(&[])
|
||||||
}
|
}
|
||||||
@@ -216,15 +216,15 @@ impl Default for AttributeMaskBuilder {
|
|||||||
|
|
||||||
/// A mask that limits what parts of a node a dependency can see.
|
/// A mask that limits what parts of a node a dependency can see.
|
||||||
#[derive(Default, PartialEq, Eq, Clone, Debug)]
|
#[derive(Default, PartialEq, Eq, Clone, Debug)]
|
||||||
pub struct NodeMaskBuilder {
|
pub struct NodeMaskBuilder<'a> {
|
||||||
attritutes: AttributeMaskBuilder,
|
attritutes: AttributeMaskBuilder<'a>,
|
||||||
tag: bool,
|
tag: bool,
|
||||||
namespace: bool,
|
namespace: bool,
|
||||||
text: bool,
|
text: bool,
|
||||||
listeners: bool,
|
listeners: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NodeMaskBuilder {
|
impl<'a> NodeMaskBuilder<'a> {
|
||||||
/// A node mask with no parts visible.
|
/// A node mask with no parts visible.
|
||||||
pub const NONE: Self = Self::new();
|
pub const NONE: Self = Self::new();
|
||||||
/// A node mask with every part visible.
|
/// A node mask with every part visible.
|
||||||
@@ -246,7 +246,7 @@ impl NodeMaskBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Allow the mask to view the given attributes
|
/// Allow the mask to view the given attributes
|
||||||
pub const fn with_attrs(mut self, attritutes: AttributeMaskBuilder) -> Self {
|
pub const fn with_attrs(mut self, attritutes: AttributeMaskBuilder<'a>) -> Self {
|
||||||
self.attritutes = attritutes;
|
self.attritutes = attritutes;
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,14 +64,15 @@ impl DirtyNodeStates {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn insert(&self, pass_id: TypeId, node_id: NodeId, height: u16) {
|
pub fn insert(&self, pass_id: TypeId, node_id: NodeId, height: u16) {
|
||||||
let btree = self.dirty.get(&pass_id).unwrap();
|
if let Some(btree) = self.dirty.get(&pass_id) {
|
||||||
let mut write = btree.write();
|
let mut write = btree.write();
|
||||||
if let Some(entry) = write.get_mut(&height) {
|
if let Some(entry) = write.get_mut(&height) {
|
||||||
entry.add_node(node_id);
|
entry.add_node(node_id);
|
||||||
} else {
|
} else {
|
||||||
let mut entry = DirtyNodes::default();
|
let mut entry = DirtyNodes::default();
|
||||||
entry.add_node(node_id);
|
entry.add_node(node_id);
|
||||||
write.insert(height, entry);
|
write.insert(height, entry);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +110,7 @@ pub trait Pass<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
|
|||||||
type ChildDependencies: Dependancy;
|
type ChildDependencies: Dependancy;
|
||||||
/// This is a tuple of (T: Any, ..)
|
/// This is a tuple of (T: Any, ..)
|
||||||
type NodeDependencies: Dependancy;
|
type NodeDependencies: Dependancy;
|
||||||
const NODE_MASK: NodeMaskBuilder;
|
const NODE_MASK: NodeMaskBuilder<'static>;
|
||||||
|
|
||||||
fn pass<'a>(
|
fn pass<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -137,12 +138,12 @@ pub trait Pass<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
|
|||||||
}
|
}
|
||||||
// this type cannot be both a parent and child dependency
|
// this type cannot be both a parent and child dependency
|
||||||
assert!(
|
assert!(
|
||||||
Self::parent_type_ids()
|
!(Self::parent_type_ids()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|type_id| *type_id != TypeId::of::<Self>())
|
.any(|type_id| *type_id == TypeId::of::<Self>())
|
||||||
&& Self::child_type_ids()
|
&& Self::child_type_ids()
|
||||||
.iter()
|
.iter()
|
||||||
.any(|type_id| *type_id != TypeId::of::<Self>()),
|
.any(|type_id| *type_id == TypeId::of::<Self>())),
|
||||||
"The current type cannot be a parent and child dependency"
|
"The current type cannot be a parent and child dependency"
|
||||||
);
|
);
|
||||||
// no states have the same type id
|
// no states have the same type id
|
||||||
|
|||||||
@@ -1,15 +1,57 @@
|
|||||||
use rustc_hash::{FxHashMap, FxHashSet};
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use std::any::{Any, TypeId};
|
use std::any::{Any, TypeId};
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
use std::rc::Rc;
|
||||||
|
|
||||||
use crate::node::{
|
use crate::node::{
|
||||||
ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue,
|
ElementNode, FromAnyValue, NodeType, OwnedAttributeDiscription, OwnedAttributeValue,
|
||||||
};
|
};
|
||||||
use crate::node_ref::{AttributeMask, NodeMask, NodeMaskBuilder};
|
use crate::node_ref::{NodeMask, NodeMaskBuilder};
|
||||||
use crate::passes::{resolve_passes, DirtyNodeStates, TypeErasedPass};
|
use crate::passes::{resolve_passes, DirtyNodeStates, TypeErasedPass};
|
||||||
|
use crate::prelude::AttributeMaskBuilder;
|
||||||
use crate::tree::{NodeId, Tree};
|
use crate::tree::{NodeId, Tree};
|
||||||
use crate::{FxDashSet, SendAnyMap};
|
use crate::{FxDashSet, SendAnyMap};
|
||||||
|
|
||||||
|
struct NodesDirty<V: FromAnyValue + Send + Sync> {
|
||||||
|
passes_updated: FxHashMap<NodeId, FxHashSet<TypeId>>,
|
||||||
|
nodes_updated: FxHashMap<NodeId, NodeMask>,
|
||||||
|
passes: Rc<Box<[TypeErasedPass<V>]>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<V: FromAnyValue + Send + Sync> NodesDirty<V> {
|
||||||
|
fn mark_dirty(&mut self, node_id: NodeId, mask: NodeMask) {
|
||||||
|
self.passes_updated.entry(node_id).or_default().extend(
|
||||||
|
self.passes
|
||||||
|
.iter()
|
||||||
|
.filter_map(|x| x.mask.overlaps(&mask).then_some(x.this_type_id)),
|
||||||
|
);
|
||||||
|
let nodes_updated = &mut self.nodes_updated;
|
||||||
|
if let Some(node) = nodes_updated.get_mut(&node_id) {
|
||||||
|
*node = node.union(&mask);
|
||||||
|
} else {
|
||||||
|
nodes_updated.insert(node_id, mask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mark_parent_added_or_removed(&mut self, node_id: NodeId) {
|
||||||
|
let hm = self.passes_updated.entry(node_id).or_default();
|
||||||
|
for pass in &**self.passes {
|
||||||
|
if pass.parent_dependant {
|
||||||
|
hm.insert(pass.this_type_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn mark_child_changed(&mut self, node_id: NodeId) {
|
||||||
|
let hm = self.passes_updated.entry(node_id).or_default();
|
||||||
|
for pass in &**self.passes {
|
||||||
|
if pass.child_dependant {
|
||||||
|
hm.insert(pass.this_type_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A Dom that can sync with the VirtualDom mutations intended for use in lazy renderers.
|
/// A Dom that can sync with the VirtualDom mutations intended for use in lazy renderers.
|
||||||
/// The render state passes from parent to children and or accumulates state from children to parents.
|
/// The render state passes from parent to children and or accumulates state from children to parents.
|
||||||
/// To get started implement [crate::state::ParentDepState], [crate::state::NodeDepState], or [crate::state::ChildDepState] and call [RealDom::apply_mutations] to update the dom and [RealDom::update_state] to update the state of the nodes.
|
/// To get started implement [crate::state::ParentDepState], [crate::state::NodeDepState], or [crate::state::ChildDepState] and call [RealDom::apply_mutations] to update the dom and [RealDom::update_state] to update the state of the nodes.
|
||||||
@@ -19,9 +61,8 @@ use crate::{FxDashSet, SendAnyMap};
|
|||||||
pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
|
pub struct RealDom<V: FromAnyValue + Send + Sync = ()> {
|
||||||
pub(crate) tree: Tree,
|
pub(crate) tree: Tree,
|
||||||
nodes_listening: FxHashMap<String, FxHashSet<NodeId>>,
|
nodes_listening: FxHashMap<String, FxHashSet<NodeId>>,
|
||||||
pub(crate) passes: Box<[TypeErasedPass<V>]>,
|
pub(crate) passes: Rc<Box<[TypeErasedPass<V>]>>,
|
||||||
passes_updated: FxHashMap<NodeId, FxHashSet<TypeId>>,
|
dirty_nodes: NodesDirty<V>,
|
||||||
nodes_updated: FxHashMap<NodeId, NodeMask>,
|
|
||||||
phantom: std::marker::PhantomData<V>,
|
phantom: std::marker::PhantomData<V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -53,6 +94,7 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
let passes = Rc::new(passes);
|
||||||
|
|
||||||
let mut passes_updated = FxHashMap::default();
|
let mut passes_updated = FxHashMap::default();
|
||||||
let mut nodes_updated = FxHashMap::default();
|
let mut nodes_updated = FxHashMap::default();
|
||||||
@@ -64,50 +106,22 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
|||||||
RealDom {
|
RealDom {
|
||||||
tree,
|
tree,
|
||||||
nodes_listening: FxHashMap::default(),
|
nodes_listening: FxHashMap::default(),
|
||||||
passes,
|
passes: passes.clone(),
|
||||||
passes_updated,
|
dirty_nodes: NodesDirty {
|
||||||
nodes_updated,
|
passes_updated,
|
||||||
|
nodes_updated,
|
||||||
|
passes,
|
||||||
|
},
|
||||||
phantom: std::marker::PhantomData,
|
phantom: std::marker::PhantomData,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mark_dirty(&mut self, node_id: NodeId, mask: NodeMask) {
|
|
||||||
self.passes_updated.entry(node_id).or_default().extend(
|
|
||||||
self.passes
|
|
||||||
.iter()
|
|
||||||
.filter_map(|x| x.mask.overlaps(&mask).then_some(x.this_type_id)),
|
|
||||||
);
|
|
||||||
let nodes_updated = &mut self.nodes_updated;
|
|
||||||
if let Some(node) = nodes_updated.get_mut(&node_id) {
|
|
||||||
*node = node.union(&mask);
|
|
||||||
} else {
|
|
||||||
nodes_updated.insert(node_id, mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mark_parent_added_or_removed(&mut self, node_id: NodeId) {
|
|
||||||
let hm = self.passes_updated.entry(node_id).or_default();
|
|
||||||
for pass in &*self.passes {
|
|
||||||
if pass.parent_dependant {
|
|
||||||
hm.insert(pass.this_type_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn mark_child_changed(&mut self, node_id: NodeId) {
|
|
||||||
let hm = self.passes_updated.entry(node_id).or_default();
|
|
||||||
for pass in &*self.passes {
|
|
||||||
if pass.child_dependant {
|
|
||||||
hm.insert(pass.this_type_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn create_node(&mut self, node: NodeType<V>, mark_dirty: bool) -> NodeMut<'_, V> {
|
pub fn create_node(&mut self, node: NodeType<V>, mark_dirty: bool) -> NodeMut<'_, V> {
|
||||||
let mut node_entry = self.tree.create_node();
|
let mut node_entry = self.tree.create_node();
|
||||||
let id = node_entry.id();
|
let id = node_entry.id();
|
||||||
if mark_dirty {
|
if mark_dirty {
|
||||||
self.passes_updated
|
self.dirty_nodes
|
||||||
|
.passes_updated
|
||||||
.entry(id)
|
.entry(id)
|
||||||
.or_default()
|
.or_default()
|
||||||
.extend(self.passes.iter().map(|x| x.this_type_id));
|
.extend(self.passes.iter().map(|x| x.this_type_id));
|
||||||
@@ -186,8 +200,8 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
|||||||
ctx: SendAnyMap,
|
ctx: SendAnyMap,
|
||||||
parallel: bool,
|
parallel: bool,
|
||||||
) -> (FxDashSet<NodeId>, FxHashMap<NodeId, NodeMask>) {
|
) -> (FxDashSet<NodeId>, FxHashMap<NodeId, NodeMask>) {
|
||||||
let passes = std::mem::take(&mut self.passes_updated);
|
let passes = std::mem::take(&mut self.dirty_nodes.passes_updated);
|
||||||
let nodes_updated = std::mem::take(&mut self.nodes_updated);
|
let nodes_updated = std::mem::take(&mut self.dirty_nodes.nodes_updated);
|
||||||
let dirty_nodes = DirtyNodeStates::with_passes(self.passes.iter().map(|p| p.this_type_id));
|
let dirty_nodes = DirtyNodeStates::with_passes(self.passes.iter().map(|p| p.this_type_id));
|
||||||
for (node_id, passes) in passes {
|
for (node_id, passes) in passes {
|
||||||
// remove any nodes that were created and then removed in the same mutations from the dirty nodes list
|
// remove any nodes that were created and then removed in the same mutations from the dirty nodes list
|
||||||
@@ -206,15 +220,15 @@ impl<V: FromAnyValue + Send + Sync> RealDom<V> {
|
|||||||
|
|
||||||
pub fn remove(&mut self, id: NodeId) {
|
pub fn remove(&mut self, id: NodeId) {
|
||||||
if let Some(parent_id) = self.tree.parent_id(id) {
|
if let Some(parent_id) = self.tree.parent_id(id) {
|
||||||
self.mark_child_changed(parent_id);
|
self.dirty_nodes.mark_child_changed(parent_id);
|
||||||
}
|
}
|
||||||
self.tree.remove(id)
|
self.tree.remove(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn replace(&mut self, old: NodeId, new: NodeId) {
|
pub fn replace(&mut self, old: NodeId, new: NodeId) {
|
||||||
if let Some(parent_id) = self.tree.parent_id(old) {
|
if let Some(parent_id) = self.tree.parent_id(old) {
|
||||||
self.mark_child_changed(parent_id);
|
self.dirty_nodes.mark_child_changed(parent_id);
|
||||||
self.mark_parent_added_or_removed(new);
|
self.dirty_nodes.mark_parent_added_or_removed(new);
|
||||||
}
|
}
|
||||||
self.tree.replace(old, new);
|
self.tree.replace(old, new);
|
||||||
}
|
}
|
||||||
@@ -376,16 +390,11 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeImmutable<V> for NodeRef<'a, V> {
|
|||||||
pub struct NodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
|
pub struct NodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
|
||||||
id: NodeId,
|
id: NodeId,
|
||||||
dom: &'a mut RealDom<V>,
|
dom: &'a mut RealDom<V>,
|
||||||
dirty: NodeMask,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
||||||
pub fn new(id: NodeId, dom: &'a mut RealDom<V>) -> Self {
|
pub fn new(id: NodeId, dom: &'a mut RealDom<V>) -> Self {
|
||||||
Self {
|
Self { id, dom }
|
||||||
id,
|
|
||||||
dom,
|
|
||||||
dirty: NodeMask::default(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -407,6 +416,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
|
|||||||
fn get_mut<T: Any + Sync + Send>(&mut self) -> Option<&mut T> {
|
fn get_mut<T: Any + Sync + Send>(&mut self) -> Option<&mut T> {
|
||||||
// mark the node state as dirty
|
// mark the node state as dirty
|
||||||
self.dom
|
self.dom
|
||||||
|
.dirty_nodes
|
||||||
.passes_updated
|
.passes_updated
|
||||||
.entry(self.id)
|
.entry(self.id)
|
||||||
.or_default()
|
.or_default()
|
||||||
@@ -417,6 +427,7 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
|
|||||||
fn insert<T: Any + Sync + Send>(&mut self, value: T) {
|
fn insert<T: Any + Sync + Send>(&mut self, value: T) {
|
||||||
// mark the node state as dirty
|
// mark the node state as dirty
|
||||||
self.dom
|
self.dom
|
||||||
|
.dirty_nodes
|
||||||
.passes_updated
|
.passes_updated
|
||||||
.entry(self.id)
|
.entry(self.id)
|
||||||
.or_default()
|
.or_default()
|
||||||
@@ -427,8 +438,8 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
|
|||||||
fn insert_after(&mut self, old: NodeId) {
|
fn insert_after(&mut self, old: NodeId) {
|
||||||
let id = self.id();
|
let id = self.id();
|
||||||
if let Some(parent_id) = self.dom.tree.parent_id(old) {
|
if let Some(parent_id) = self.dom.tree.parent_id(old) {
|
||||||
self.dom.mark_child_changed(parent_id);
|
self.dom.dirty_nodes.mark_child_changed(parent_id);
|
||||||
self.dom.mark_parent_added_or_removed(id);
|
self.dom.dirty_nodes.mark_parent_added_or_removed(id);
|
||||||
}
|
}
|
||||||
self.dom.tree.insert_after(old, id);
|
self.dom.tree.insert_after(old, id);
|
||||||
}
|
}
|
||||||
@@ -436,16 +447,20 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
|
|||||||
fn insert_before(&mut self, old: NodeId) {
|
fn insert_before(&mut self, old: NodeId) {
|
||||||
let id = self.id();
|
let id = self.id();
|
||||||
if let Some(parent_id) = self.dom.tree.parent_id(old) {
|
if let Some(parent_id) = self.dom.tree.parent_id(old) {
|
||||||
self.dom.mark_child_changed(parent_id);
|
self.dom.dirty_nodes.mark_child_changed(parent_id);
|
||||||
self.dom.mark_parent_added_or_removed(id);
|
self.dom.dirty_nodes.mark_parent_added_or_removed(id);
|
||||||
}
|
}
|
||||||
self.dom.tree.insert_before(old, id);
|
self.dom.tree.insert_before(old, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn add_event_listener(&mut self, event: &str) {
|
fn add_event_listener(&mut self, event: &str) {
|
||||||
let id = self.id();
|
let id = self.id();
|
||||||
if let NodeTypeMut::Element(mut element) = self.node_type_mut() {
|
let node_type: &mut NodeType<V> = self.dom.tree.get_mut(self.id).unwrap();
|
||||||
element.listeners_mut().insert(event.to_string());
|
if let NodeType::Element(ElementNode { listeners, .. }) = node_type {
|
||||||
|
self.dom
|
||||||
|
.dirty_nodes
|
||||||
|
.mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
|
||||||
|
listeners.insert(event.to_string());
|
||||||
match self.dom.nodes_listening.get_mut(event) {
|
match self.dom.nodes_listening.get_mut(event) {
|
||||||
Some(hs) => {
|
Some(hs) => {
|
||||||
hs.insert(id);
|
hs.insert(id);
|
||||||
@@ -461,21 +476,33 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMutable<V> for NodeMut<'a, V> {
|
|||||||
|
|
||||||
fn remove_event_listener(&mut self, event: &str) {
|
fn remove_event_listener(&mut self, event: &str) {
|
||||||
let id = self.id();
|
let id = self.id();
|
||||||
if let NodeTypeMut::Element(mut element) = self.node_type_mut() {
|
let node_type: &mut NodeType<V> = self.dom.tree.get_mut(self.id).unwrap();
|
||||||
element.listeners_mut().remove(event);
|
if let NodeType::Element(ElementNode { listeners, .. }) = node_type {
|
||||||
|
self.dom
|
||||||
|
.dirty_nodes
|
||||||
|
.mark_dirty(self.id, NodeMaskBuilder::new().with_listeners().build());
|
||||||
|
listeners.remove(event);
|
||||||
|
|
||||||
|
self.dom.nodes_listening.get_mut(event).unwrap().remove(&id);
|
||||||
}
|
}
|
||||||
self.dom.nodes_listening.get_mut(event).unwrap().remove(&id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
||||||
pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
|
pub fn node_type_mut(&mut self) -> NodeTypeMut<'_, V> {
|
||||||
let Self { id, dom, dirty } = self;
|
let Self { id, dom } = self;
|
||||||
let node_type = dom.tree.get_mut::<NodeType<V>>(*id).unwrap();
|
let RealDom {
|
||||||
|
dirty_nodes, tree, ..
|
||||||
|
} = dom;
|
||||||
|
let node_type = tree.get_mut(*id).unwrap();
|
||||||
match node_type {
|
match node_type {
|
||||||
NodeType::Element(element) => NodeTypeMut::Element(ElementNodeMut { element, dirty }),
|
NodeType::Element(element) => NodeTypeMut::Element(ElementNodeMut {
|
||||||
|
id: *id,
|
||||||
|
element,
|
||||||
|
dirty_nodes,
|
||||||
|
}),
|
||||||
NodeType::Text(text) => {
|
NodeType::Text(text) => {
|
||||||
dirty.set_text();
|
dirty_nodes.mark_dirty(self.id, NodeMaskBuilder::new().with_text().build());
|
||||||
NodeTypeMut::Text(text)
|
NodeTypeMut::Text(text)
|
||||||
}
|
}
|
||||||
NodeType::Placeholder => NodeTypeMut::Placeholder,
|
NodeType::Placeholder => NodeTypeMut::Placeholder,
|
||||||
@@ -484,35 +511,32 @@ impl<'a, V: FromAnyValue + Send + Sync> NodeMut<'a, V> {
|
|||||||
|
|
||||||
pub fn set_type(&mut self, new: NodeType<V>) {
|
pub fn set_type(&mut self, new: NodeType<V>) {
|
||||||
*self.dom.tree.get_mut::<NodeType<V>>(self.id).unwrap() = new;
|
*self.dom.tree.get_mut::<NodeType<V>>(self.id).unwrap() = new;
|
||||||
self.dirty = NodeMaskBuilder::ALL.build();
|
self.dom
|
||||||
|
.dirty_nodes
|
||||||
|
.mark_dirty(self.id, NodeMaskBuilder::ALL.build())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: FromAnyValue + Send + Sync> Drop for NodeMut<'_, V> {
|
pub enum NodeTypeMut<'a, V: FromAnyValue + Send + Sync = ()> {
|
||||||
fn drop(&mut self) {
|
|
||||||
let mask = std::mem::take(&mut self.dirty);
|
|
||||||
self.dom.mark_dirty(self.id, mask);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub enum NodeTypeMut<'a, V: FromAnyValue = ()> {
|
|
||||||
Element(ElementNodeMut<'a, V>),
|
Element(ElementNodeMut<'a, V>),
|
||||||
Text(&'a mut String),
|
Text(&'a mut String),
|
||||||
Placeholder,
|
Placeholder,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ElementNodeMut<'a, V: FromAnyValue = ()> {
|
pub struct ElementNodeMut<'a, V: FromAnyValue + Send + Sync = ()> {
|
||||||
|
id: NodeId,
|
||||||
element: &'a mut ElementNode<V>,
|
element: &'a mut ElementNode<V>,
|
||||||
dirty: &'a mut NodeMask,
|
dirty_nodes: &'a mut NodesDirty<V>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: FromAnyValue> ElementNodeMut<'_, V> {
|
impl<V: FromAnyValue + Send + Sync> ElementNodeMut<'_, V> {
|
||||||
pub fn tag(&self) -> &str {
|
pub fn tag(&self) -> &str {
|
||||||
&self.element.tag
|
&self.element.tag
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn tag_mut(&mut self) -> &mut String {
|
pub fn tag_mut(&mut self) -> &mut String {
|
||||||
self.dirty.set_tag();
|
self.dirty_nodes
|
||||||
|
.mark_dirty(self.id, NodeMaskBuilder::new().with_tag().build());
|
||||||
&mut self.element.tag
|
&mut self.element.tag
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,7 +545,8 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn namespace_mut(&mut self) -> &mut Option<String> {
|
pub fn namespace_mut(&mut self) -> &mut Option<String> {
|
||||||
self.dirty.set_namespace();
|
self.dirty_nodes
|
||||||
|
.mark_dirty(self.id, NodeMaskBuilder::new().with_namespace().build());
|
||||||
&mut self.element.namespace
|
&mut self.element.namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -532,7 +557,12 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
|
|||||||
pub fn attributes_mut(
|
pub fn attributes_mut(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> &mut FxHashMap<OwnedAttributeDiscription, OwnedAttributeValue<V>> {
|
) -> &mut FxHashMap<OwnedAttributeDiscription, OwnedAttributeValue<V>> {
|
||||||
self.dirty.add_attributes(AttributeMask::All);
|
self.dirty_nodes.mark_dirty(
|
||||||
|
self.id,
|
||||||
|
NodeMaskBuilder::new()
|
||||||
|
.with_attrs(AttributeMaskBuilder::All)
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
&mut self.element.attributes
|
&mut self.element.attributes
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -541,7 +571,12 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
|
|||||||
name: OwnedAttributeDiscription,
|
name: OwnedAttributeDiscription,
|
||||||
value: OwnedAttributeValue<V>,
|
value: OwnedAttributeValue<V>,
|
||||||
) -> Option<OwnedAttributeValue<V>> {
|
) -> Option<OwnedAttributeValue<V>> {
|
||||||
self.dirty.add_attributes(AttributeMask::single(&name.name));
|
self.dirty_nodes.mark_dirty(
|
||||||
|
self.id,
|
||||||
|
NodeMaskBuilder::new()
|
||||||
|
.with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
self.element.attributes.insert(name, value)
|
self.element.attributes.insert(name, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -549,7 +584,12 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
name: &OwnedAttributeDiscription,
|
name: &OwnedAttributeDiscription,
|
||||||
) -> Option<OwnedAttributeValue<V>> {
|
) -> Option<OwnedAttributeValue<V>> {
|
||||||
self.dirty.add_attributes(AttributeMask::single(&name.name));
|
self.dirty_nodes.mark_dirty(
|
||||||
|
self.id,
|
||||||
|
NodeMaskBuilder::new()
|
||||||
|
.with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
self.element.attributes.remove(name)
|
self.element.attributes.remove(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,18 +597,18 @@ impl<V: FromAnyValue> ElementNodeMut<'_, V> {
|
|||||||
&mut self,
|
&mut self,
|
||||||
name: &OwnedAttributeDiscription,
|
name: &OwnedAttributeDiscription,
|
||||||
) -> Option<&mut OwnedAttributeValue<V>> {
|
) -> Option<&mut OwnedAttributeValue<V>> {
|
||||||
self.dirty.add_attributes(AttributeMask::single(&name.name));
|
self.dirty_nodes.mark_dirty(
|
||||||
|
self.id,
|
||||||
|
NodeMaskBuilder::new()
|
||||||
|
.with_attrs(AttributeMaskBuilder::Some(&[&name.name]))
|
||||||
|
.build(),
|
||||||
|
);
|
||||||
self.element.attributes.get_mut(name)
|
self.element.attributes.get_mut(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listeners(&self) -> &FxHashSet<String> {
|
pub fn listeners(&self) -> &FxHashSet<String> {
|
||||||
&self.element.listeners
|
&self.element.listeners
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn listeners_mut(&mut self) -> &mut FxHashSet<String> {
|
|
||||||
self.dirty.set_listeners();
|
|
||||||
&mut self.element.listeners
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NodeMutRaw<'a, V: FromAnyValue + Send + Sync = ()> {
|
pub struct NodeMutRaw<'a, V: FromAnyValue + Send + Sync = ()> {
|
||||||
|
|||||||
@@ -249,7 +249,13 @@ pub struct TreeStateViewEntry<'a, 'b> {
|
|||||||
|
|
||||||
impl<'a, 'b> AnyMapLike<'a> for TreeStateViewEntry<'a, 'b> {
|
impl<'a, 'b> AnyMapLike<'a> for TreeStateViewEntry<'a, 'b> {
|
||||||
fn get<T: Any + Sync + Send>(self) -> Option<&'a T> {
|
fn get<T: Any + Sync + Send>(self) -> Option<&'a T> {
|
||||||
self.view.get_slab().and_then(|slab| slab.get(self.id))
|
let slab = self.view.get_slab();
|
||||||
|
dbg!(slab.is_some());
|
||||||
|
slab.and_then(|slab| {
|
||||||
|
let r = slab.get(self.id);
|
||||||
|
dbg!(r.is_some());
|
||||||
|
r
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -315,7 +321,7 @@ impl<'a, 'b> TreeStateView<'a, 'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn parent<T: Dependancy>(&self, id: NodeId) -> Option<T::ElementBorrowed<'_>> {
|
pub fn parent<T: Dependancy>(&self, id: NodeId) -> Option<T::ElementBorrowed<'_>> {
|
||||||
T::borrow_elements_from(self.entry(id))
|
T::borrow_elements_from(self.entry(self.parent_id(id)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use dioxus::prelude::Props;
|
use dioxus::prelude::Props;
|
||||||
use dioxus_core::*;
|
use dioxus_core::*;
|
||||||
use dioxus_native_core::{
|
use dioxus_native_core::{
|
||||||
|
dioxus::DioxusState,
|
||||||
node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
|
node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
|
||||||
real_dom::RealDom,
|
real_dom::RealDom,
|
||||||
Dependancy, Pass, SendAnyMap,
|
Dependancy, Pass, SendAnyMap,
|
||||||
@@ -302,7 +303,7 @@ impl Pass for BlablaState {
|
|||||||
type ChildDependencies = ();
|
type ChildDependencies = ();
|
||||||
type NodeDependencies = ();
|
type NodeDependencies = ();
|
||||||
|
|
||||||
const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new()
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new()
|
||||||
.with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
|
.with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
|
||||||
.with_element();
|
.with_element();
|
||||||
|
|
||||||
@@ -348,7 +349,8 @@ fn create() {
|
|||||||
);
|
);
|
||||||
let mutations = vdom.rebuild();
|
let mutations = vdom.rebuild();
|
||||||
let mut rdom: RealDom = RealDom::new(Box::new([BlablaState::to_type_erased()]));
|
let mut rdom: RealDom = RealDom::new(Box::new([BlablaState::to_type_erased()]));
|
||||||
rdom.apply_mutations(mutations);
|
let mut dioxus_state = DioxusState::create(&mut rdom);
|
||||||
|
dioxus_state.apply_mutations(&mut rdom, mutations);
|
||||||
|
|
||||||
let ctx = SendAnyMap::new();
|
let ctx = SendAnyMap::new();
|
||||||
rdom.update_state(ctx, false);
|
rdom.update_state(ctx, false);
|
||||||
@@ -369,13 +371,14 @@ fn diff() {
|
|||||||
);
|
);
|
||||||
let mutations = vdom.rebuild();
|
let mutations = vdom.rebuild();
|
||||||
let mut rdom: RealDom = RealDom::new(Box::new([BlablaState::to_type_erased()]));
|
let mut rdom: RealDom = RealDom::new(Box::new([BlablaState::to_type_erased()]));
|
||||||
rdom.apply_mutations(mutations);
|
let mut dioxus_state = DioxusState::create(&mut rdom);
|
||||||
|
dioxus_state.apply_mutations(&mut rdom, mutations);
|
||||||
|
|
||||||
let ctx = SendAnyMap::new();
|
let ctx = SendAnyMap::new();
|
||||||
rdom.update_state(ctx, false);
|
rdom.update_state(ctx, false);
|
||||||
for _ in 0..10 {
|
for _ in 0..10 {
|
||||||
let mutations = vdom.render_immediate();
|
let mutations = vdom.render_immediate();
|
||||||
rdom.apply_mutations(mutations);
|
dioxus_state.apply_mutations(&mut rdom, mutations);
|
||||||
|
|
||||||
let ctx = SendAnyMap::new();
|
let ctx = SendAnyMap::new();
|
||||||
rdom.update_state(ctx, false);
|
rdom.update_state(ctx, false);
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_native_core::{
|
use dioxus_native_core::{
|
||||||
|
dioxus::DioxusState,
|
||||||
node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
|
node_ref::{AttributeMaskBuilder, NodeMaskBuilder, NodeView},
|
||||||
real_dom::RealDom,
|
real_dom::RealDom,
|
||||||
Dependancy, Pass, SendAnyMap,
|
Dependancy, Pass, SendAnyMap,
|
||||||
};
|
};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::{
|
||||||
|
borrow::BorrowMut,
|
||||||
|
sync::{Arc, Mutex},
|
||||||
|
};
|
||||||
use tokio::time::sleep;
|
use tokio::time::sleep;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
@@ -17,7 +21,7 @@ impl Pass for BlablaState {
|
|||||||
type ChildDependencies = ();
|
type ChildDependencies = ();
|
||||||
type NodeDependencies = ();
|
type NodeDependencies = ();
|
||||||
|
|
||||||
const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new()
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new()
|
||||||
.with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
|
.with_attrs(AttributeMaskBuilder::Some(&["blabla"]))
|
||||||
.with_element();
|
.with_element();
|
||||||
|
|
||||||
@@ -135,10 +139,11 @@ fn native_core_is_okay() {
|
|||||||
let rdom = Arc::new(Mutex::new(RealDom::new(Box::new([
|
let rdom = Arc::new(Mutex::new(RealDom::new(Box::new([
|
||||||
BlablaState::to_type_erased(),
|
BlablaState::to_type_erased(),
|
||||||
]))));
|
]))));
|
||||||
|
let mut dioxus_state = DioxusState::create(&mut *rdom.lock().unwrap());
|
||||||
let mut dom = VirtualDom::new(app);
|
let mut dom = VirtualDom::new(app);
|
||||||
|
|
||||||
let muts = dom.rebuild();
|
let mutations = dom.rebuild();
|
||||||
rdom.lock().unwrap().apply_mutations(muts);
|
dioxus_state.apply_mutations(&mut *rdom.lock().unwrap(), mutations);
|
||||||
|
|
||||||
let ctx = SendAnyMap::new();
|
let ctx = SendAnyMap::new();
|
||||||
rdom.lock().unwrap().update_state(ctx, false);
|
rdom.lock().unwrap().update_state(ctx, false);
|
||||||
@@ -147,7 +152,7 @@ fn native_core_is_okay() {
|
|||||||
dom.wait_for_work().await;
|
dom.wait_for_work().await;
|
||||||
|
|
||||||
let mutations = dom.render_immediate();
|
let mutations = dom.render_immediate();
|
||||||
rdom.lock().unwrap().apply_mutations(mutations);
|
dioxus_state.apply_mutations(&mut *rdom.lock().unwrap(), mutations);
|
||||||
|
|
||||||
let ctx = SendAnyMap::new();
|
let ctx = SendAnyMap::new();
|
||||||
rdom.lock().unwrap().update_state(ctx, false);
|
rdom.lock().unwrap().update_state(ctx, false);
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
use dioxus::prelude::*;
|
use dioxus::prelude::*;
|
||||||
use dioxus_native_core::node::NodeType;
|
use dioxus_native_core::node::NodeType;
|
||||||
use dioxus_native_core::prelude::*;
|
use dioxus_native_core::prelude::*;
|
||||||
|
use rustc_hash::{FxHashMap, FxHashSet};
|
||||||
use std::any::TypeId;
|
use std::any::TypeId;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
@@ -8,8 +9,8 @@ fn create_blank_element() -> NodeType {
|
|||||||
NodeType::Element(ElementNode {
|
NodeType::Element(ElementNode {
|
||||||
tag: "div".to_owned(),
|
tag: "div".to_owned(),
|
||||||
namespace: None,
|
namespace: None,
|
||||||
attributes: HashMap::new(),
|
attributes: FxHashMap::default(),
|
||||||
listeners: HashMap::new(),
|
listeners: FxHashSet::default(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -22,7 +23,7 @@ fn node_pass() {
|
|||||||
type ChildDependencies = ();
|
type ChildDependencies = ();
|
||||||
type NodeDependencies = ();
|
type NodeDependencies = ();
|
||||||
type ParentDependencies = ();
|
type ParentDependencies = ();
|
||||||
const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
|
||||||
|
|
||||||
fn pass<'a>(
|
fn pass<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -70,7 +71,7 @@ fn dependant_node_pass() {
|
|||||||
type ChildDependencies = ();
|
type ChildDependencies = ();
|
||||||
type NodeDependencies = (SubtractNumber,);
|
type NodeDependencies = (SubtractNumber,);
|
||||||
type ParentDependencies = ();
|
type ParentDependencies = ();
|
||||||
const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
|
||||||
|
|
||||||
fn pass<'a>(
|
fn pass<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -104,7 +105,7 @@ fn dependant_node_pass() {
|
|||||||
type ChildDependencies = ();
|
type ChildDependencies = ();
|
||||||
type NodeDependencies = ();
|
type NodeDependencies = ();
|
||||||
type ParentDependencies = ();
|
type ParentDependencies = ();
|
||||||
const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
|
||||||
|
|
||||||
fn pass<'a>(
|
fn pass<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -170,7 +171,7 @@ fn independant_node_pass() {
|
|||||||
type NodeDependencies = ();
|
type NodeDependencies = ();
|
||||||
type ParentDependencies = ();
|
type ParentDependencies = ();
|
||||||
|
|
||||||
const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
|
||||||
|
|
||||||
fn pass<'a>(
|
fn pass<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -205,7 +206,7 @@ fn independant_node_pass() {
|
|||||||
type NodeDependencies = ();
|
type NodeDependencies = ();
|
||||||
type ParentDependencies = ();
|
type ParentDependencies = ();
|
||||||
|
|
||||||
const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
|
||||||
|
|
||||||
fn pass<'a>(
|
fn pass<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -279,7 +280,7 @@ fn down_pass() {
|
|||||||
type NodeDependencies = ();
|
type NodeDependencies = ();
|
||||||
type ParentDependencies = (AddNumber,);
|
type ParentDependencies = (AddNumber,);
|
||||||
|
|
||||||
const NODE_MASK: NodeMaskBuilder = NodeMaskBuilder::new();
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
|
||||||
|
|
||||||
fn pass<'a>(
|
fn pass<'a>(
|
||||||
&mut self,
|
&mut self,
|
||||||
@@ -289,332 +290,144 @@ fn down_pass() {
|
|||||||
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
|
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
|
||||||
context: &SendAnyMap,
|
context: &SendAnyMap,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
|
dbg!(parent);
|
||||||
|
dbg!(node_view);
|
||||||
if let Some((parent,)) = parent {
|
if let Some((parent,)) = parent {
|
||||||
*self.0 += *parent.0;
|
self.0 += parent.0;
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn create<'a>(
|
||||||
|
node_view: NodeView<()>,
|
||||||
|
node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
|
||||||
|
parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
|
||||||
|
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
|
||||||
|
context: &SendAnyMap,
|
||||||
|
) -> Self {
|
||||||
|
let mut myself = Self::default();
|
||||||
|
myself.pass(node_view, node, parent, children, context);
|
||||||
|
myself
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut tree: RealDom = RealDom::new(Box::new([AddNumber::to_type_erased()]));
|
let mut tree: RealDom = RealDom::new(Box::new([AddNumber::to_type_erased()]));
|
||||||
let parent = tree.root_id();
|
let mut grandchild1 = tree.create_node(create_blank_element(), true);
|
||||||
let child1 = tree.create_node(create_blank_element(), true);
|
let grandchild1 = grandchild1.id();
|
||||||
tree.add_child(parent, child1);
|
let mut child1 = tree.create_node(create_blank_element(), true);
|
||||||
let grandchild1 = tree.create_node(create_blank_element(), true);
|
child1.add_child(grandchild1);
|
||||||
tree.add_child(child1, grandchild1);
|
let child1 = child1.id();
|
||||||
let child2 = tree.create_node(create_blank_element(), true);
|
let mut grandchild2 = tree.create_node(create_blank_element(), true);
|
||||||
tree.add_child(parent, child2);
|
let grandchild2 = grandchild2.id();
|
||||||
let grandchild2 = tree.create_node(create_blank_element(), true);
|
let mut child2 = tree.create_node(create_blank_element(), true);
|
||||||
tree.add_child(child2, grandchild2);
|
child2.add_child(grandchild2);
|
||||||
|
let child2 = child2.id();
|
||||||
|
let mut parent = tree.get_mut(tree.root_id()).unwrap();
|
||||||
|
parent.add_child(child1);
|
||||||
|
parent.add_child(child2);
|
||||||
|
|
||||||
tree.dirty_nodes
|
|
||||||
.insert(TypeId::of::<AddNumber>(), NodeId(0));
|
|
||||||
tree.update_state(SendAnyMap::new(), false);
|
tree.update_state(SendAnyMap::new(), false);
|
||||||
|
|
||||||
assert_eq!(tree.get(tree.root_id()).unwrap().state.add_number.0, 1);
|
let root = tree.get(tree.root_id()).unwrap();
|
||||||
assert_eq!(tree.get(child1).unwrap().state.add_number.0, 2);
|
dbg!(root.id());
|
||||||
assert_eq!(tree.get(grandchild1).unwrap().state.add_number.0, 3);
|
assert_eq!(root.get(), Some(&AddNumber(1)));
|
||||||
assert_eq!(tree.get(child2).unwrap().state.add_number.0, 2);
|
|
||||||
assert_eq!(tree.get(grandchild2).unwrap().state.add_number.0, 3);
|
let child1 = tree.get(child1).unwrap();
|
||||||
|
dbg!(child1.id());
|
||||||
|
dbg!(child1.parent().unwrap().get::<AddNumber>());
|
||||||
|
assert_eq!(child1.get(), Some(&AddNumber(2)));
|
||||||
|
|
||||||
|
let grandchild1 = tree.get(grandchild1).unwrap();
|
||||||
|
assert_eq!(grandchild1.get(), Some(&AddNumber(3)));
|
||||||
|
|
||||||
|
let child2 = tree.get(child2).unwrap();
|
||||||
|
assert_eq!(child2.get(), Some(&AddNumber(2)));
|
||||||
|
|
||||||
|
let grandchild2 = tree.get(grandchild2).unwrap();
|
||||||
|
assert_eq!(grandchild2.get(), Some(&AddNumber(3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn dependant_down_pass() {
|
fn up_pass() {
|
||||||
// // 0
|
// Tree before:
|
||||||
// let mut tree = Tree::new(1);
|
// 1=\
|
||||||
// let parent = tree.root_id();
|
// 1=\
|
||||||
// // 1
|
// 1
|
||||||
// let child1 = tree.create_node(1);
|
// 1=\
|
||||||
// tree.add_child(parent, child1);
|
// 1
|
||||||
// // 2
|
// Tree after:
|
||||||
// let grandchild1 = tree.create_node(1);
|
// 4=\
|
||||||
// tree.add_child(child1, grandchild1);
|
// 2=\
|
||||||
// // 3
|
// 1
|
||||||
// let child2 = tree.create_node(1);
|
// 2=\
|
||||||
// tree.add_child(parent, child2);
|
// 1
|
||||||
// // 4
|
|
||||||
// let grandchild2 = tree.create_node(1);
|
|
||||||
// tree.add_child(child2, grandchild2);
|
|
||||||
|
|
||||||
// struct AddPass;
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
// impl Pass for AddPass {
|
struct AddNumber(i32);
|
||||||
// fn pass_id(&self) -> PassId {
|
|
||||||
// PassId(0)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn dependancies(&self) -> &'static [PassId] {
|
impl Pass for AddNumber {
|
||||||
// &[PassId(1)]
|
type ChildDependencies = (AddNumber,);
|
||||||
// }
|
type NodeDependencies = ();
|
||||||
|
type ParentDependencies = ();
|
||||||
|
|
||||||
// fn dependants(&self) -> &'static [PassId] {
|
const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
|
||||||
// &[]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn mask(&self) -> MemberMask {
|
fn pass<'a>(
|
||||||
// MemberMask(0)
|
&mut self,
|
||||||
// }
|
node_view: NodeView,
|
||||||
// }
|
node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
|
||||||
// impl DownwardPass<i32> for AddPass {
|
parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
|
||||||
// fn pass(&self, node: &mut i32, parent: Option<&mut i32>, _: &SendAnyMap) -> PassReturn {
|
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
|
||||||
// if let Some(parent) = parent {
|
context: &SendAnyMap,
|
||||||
// *node += *parent;
|
) -> bool {
|
||||||
// } else {
|
if let Some(children) = children {
|
||||||
// }
|
self.0 += children.iter().map(|(i,)| i.0).sum::<i32>();
|
||||||
// PassReturn {
|
}
|
||||||
// progress: true,
|
true
|
||||||
// mark_dirty: true,
|
}
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// struct SubtractPass;
|
fn create<'a>(
|
||||||
// impl Pass for SubtractPass {
|
node_view: NodeView<()>,
|
||||||
// fn pass_id(&self) -> PassId {
|
node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
|
||||||
// PassId(1)
|
parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
|
||||||
// }
|
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
|
||||||
|
context: &SendAnyMap,
|
||||||
|
) -> Self {
|
||||||
|
let mut myself = Self(1);
|
||||||
|
myself.pass(node_view, node, parent, children, context);
|
||||||
|
myself
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// fn dependancies(&self) -> &'static [PassId] {
|
let mut tree: RealDom = RealDom::new(Box::new([AddNumber::to_type_erased()]));
|
||||||
// &[]
|
let mut grandchild1 = tree.create_node(create_blank_element(), true);
|
||||||
// }
|
let grandchild1 = grandchild1.id();
|
||||||
|
let mut child1 = tree.create_node(create_blank_element(), true);
|
||||||
|
child1.add_child(grandchild1);
|
||||||
|
let child1 = child1.id();
|
||||||
|
let mut grandchild2 = tree.create_node(create_blank_element(), true);
|
||||||
|
let grandchild2 = grandchild2.id();
|
||||||
|
let mut child2 = tree.create_node(create_blank_element(), true);
|
||||||
|
child2.add_child(grandchild2);
|
||||||
|
let child2 = child2.id();
|
||||||
|
let mut parent = tree.get_mut(tree.root_id()).unwrap();
|
||||||
|
parent.add_child(child1);
|
||||||
|
parent.add_child(child2);
|
||||||
|
|
||||||
// fn dependants(&self) -> &'static [PassId] {
|
tree.update_state(SendAnyMap::new(), false);
|
||||||
// &[PassId(0)]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn mask(&self) -> MemberMask {
|
let root = tree.get(tree.root_id()).unwrap();
|
||||||
// MemberMask(0)
|
assert_eq!(root.get(), Some(&AddNumber(5)));
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// impl DownwardPass<i32> for SubtractPass {
|
|
||||||
// fn pass(&self, node: &mut i32, parent: Option<&mut i32>, _: &SendAnyMap) -> PassReturn {
|
|
||||||
// if let Some(parent) = parent {
|
|
||||||
// *node -= *parent;
|
|
||||||
// } else {
|
|
||||||
// }
|
|
||||||
// PassReturn {
|
|
||||||
// progress: true,
|
|
||||||
// mark_dirty: true,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let add_pass = AnyPass::Downward(&AddPass);
|
let child1 = tree.get(child1).unwrap();
|
||||||
// let subtract_pass = AnyPass::Downward(&SubtractPass);
|
assert_eq!(child1.get(), Some(&AddNumber(2)));
|
||||||
// let passes = vec![&add_pass, &subtract_pass];
|
|
||||||
// let dirty_nodes: DirtyNodeStates = DirtyNodeStates::default();
|
|
||||||
// dirty_nodes.insert(PassId(1), tree.root_id());
|
|
||||||
// resolve_passes(&mut tree, dirty_nodes, passes, SendAnyMap::new());
|
|
||||||
|
|
||||||
// // Tree before:
|
let grandchild1 = tree.get(grandchild1).unwrap();
|
||||||
// // 1=\
|
assert_eq!(grandchild1.get(), Some(&AddNumber(1)));
|
||||||
// // 1=\
|
|
||||||
// // 1
|
|
||||||
// // 1=\
|
|
||||||
// // 1
|
|
||||||
// // Tree after subtract:
|
|
||||||
// // 1=\
|
|
||||||
// // 0=\
|
|
||||||
// // 1
|
|
||||||
// // 0=\
|
|
||||||
// // 1
|
|
||||||
// // Tree after add:
|
|
||||||
// // 1=\
|
|
||||||
// // 1=\
|
|
||||||
// // 2
|
|
||||||
// // 1=\
|
|
||||||
// // 2
|
|
||||||
// assert_eq!(tree.get(tree.root_id()).unwrap(), &1);
|
|
||||||
// assert_eq!(tree.get(child1).unwrap(), &1);
|
|
||||||
// assert_eq!(tree.get(grandchild1).unwrap(), &2);
|
|
||||||
// assert_eq!(tree.get(child2).unwrap(), &1);
|
|
||||||
// assert_eq!(tree.get(grandchild2).unwrap(), &2);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
let child2 = tree.get(child2).unwrap();
|
||||||
// fn up_pass() {
|
assert_eq!(child2.get(), Some(&AddNumber(2)));
|
||||||
// // Tree before:
|
|
||||||
// // 0=\
|
|
||||||
// // 0=\
|
|
||||||
// // 1
|
|
||||||
// // 0=\
|
|
||||||
// // 1
|
|
||||||
// // Tree after:
|
|
||||||
// // 2=\
|
|
||||||
// // 1=\
|
|
||||||
// // 1
|
|
||||||
// // 1=\
|
|
||||||
// // 1
|
|
||||||
// let mut tree = Tree::new(0);
|
|
||||||
// let parent = tree.root_id();
|
|
||||||
// let child1 = tree.create_node(0);
|
|
||||||
// tree.add_child(parent, child1);
|
|
||||||
// let grandchild1 = tree.create_node(1);
|
|
||||||
// tree.add_child(child1, grandchild1);
|
|
||||||
// let child2 = tree.create_node(0);
|
|
||||||
// tree.add_child(parent, child2);
|
|
||||||
// let grandchild2 = tree.create_node(1);
|
|
||||||
// tree.add_child(child2, grandchild2);
|
|
||||||
|
|
||||||
// struct AddPass;
|
let grandchild2 = tree.get(grandchild2).unwrap();
|
||||||
// impl Pass for AddPass {
|
assert_eq!(grandchild2.get(), Some(&AddNumber(1)));
|
||||||
// fn pass_id(&self) -> PassId {
|
}
|
||||||
// PassId(0)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn dependancies(&self) -> &'static [PassId] {
|
|
||||||
// &[]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn dependants(&self) -> &'static [PassId] {
|
|
||||||
// &[]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn mask(&self) -> MemberMask {
|
|
||||||
// MemberMask(0)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// impl UpwardPass<i32> for AddPass {
|
|
||||||
// fn pass<'a>(
|
|
||||||
// &self,
|
|
||||||
// node: &mut i32,
|
|
||||||
// children: &mut dyn Iterator<Item = &'a mut i32>,
|
|
||||||
// _: &SendAnyMap,
|
|
||||||
// ) -> PassReturn {
|
|
||||||
// *node += children.map(|i| *i).sum::<i32>();
|
|
||||||
// PassReturn {
|
|
||||||
// progress: true,
|
|
||||||
// mark_dirty: true,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let add_pass = AnyPass::Upward(&AddPass);
|
|
||||||
// let passes = vec![&add_pass];
|
|
||||||
// let dirty_nodes: DirtyNodeStates = DirtyNodeStates::default();
|
|
||||||
// dirty_nodes.insert(PassId(0), grandchild1);
|
|
||||||
// dirty_nodes.insert(PassId(0), grandchild2);
|
|
||||||
// resolve_passes(&mut tree, dirty_nodes, passes, SendAnyMap::new());
|
|
||||||
|
|
||||||
// assert_eq!(tree.get(tree.root_id()).unwrap(), &2);
|
|
||||||
// assert_eq!(tree.get(child1).unwrap(), &1);
|
|
||||||
// assert_eq!(tree.get(grandchild1).unwrap(), &1);
|
|
||||||
// assert_eq!(tree.get(child2).unwrap(), &1);
|
|
||||||
// assert_eq!(tree.get(grandchild2).unwrap(), &1);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
|
||||||
// fn dependant_up_pass() {
|
|
||||||
// // 0
|
|
||||||
// let mut tree = Tree::new(0);
|
|
||||||
// let parent = tree.root_id();
|
|
||||||
// // 1
|
|
||||||
// let child1 = tree.create_node(0);
|
|
||||||
// tree.add_child(parent, child1);
|
|
||||||
// // 2
|
|
||||||
// let grandchild1 = tree.create_node(1);
|
|
||||||
// tree.add_child(child1, grandchild1);
|
|
||||||
// // 3
|
|
||||||
// let child2 = tree.create_node(0);
|
|
||||||
// tree.add_child(parent, child2);
|
|
||||||
// // 4
|
|
||||||
// let grandchild2 = tree.create_node(1);
|
|
||||||
// tree.add_child(child2, grandchild2);
|
|
||||||
|
|
||||||
// struct AddPass;
|
|
||||||
// impl Pass for AddPass {
|
|
||||||
// fn pass_id(&self) -> PassId {
|
|
||||||
// PassId(0)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn dependancies(&self) -> &'static [PassId] {
|
|
||||||
// &[PassId(1)]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn dependants(&self) -> &'static [PassId] {
|
|
||||||
// &[]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn mask(&self) -> MemberMask {
|
|
||||||
// MemberMask(0)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// impl UpwardPass<i32> for AddPass {
|
|
||||||
// fn pass<'a>(
|
|
||||||
// &self,
|
|
||||||
// node: &mut i32,
|
|
||||||
// children: &mut dyn Iterator<Item = &'a mut i32>,
|
|
||||||
// _: &SendAnyMap,
|
|
||||||
// ) -> PassReturn {
|
|
||||||
// *node += children.map(|i| *i).sum::<i32>();
|
|
||||||
// PassReturn {
|
|
||||||
// progress: true,
|
|
||||||
// mark_dirty: true,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// struct SubtractPass;
|
|
||||||
// impl Pass for SubtractPass {
|
|
||||||
// fn pass_id(&self) -> PassId {
|
|
||||||
// PassId(1)
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn dependancies(&self) -> &'static [PassId] {
|
|
||||||
// &[]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn dependants(&self) -> &'static [PassId] {
|
|
||||||
// &[PassId(0)]
|
|
||||||
// }
|
|
||||||
|
|
||||||
// fn mask(&self) -> MemberMask {
|
|
||||||
// MemberMask(0)
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// impl UpwardPass<i32> for SubtractPass {
|
|
||||||
// fn pass<'a>(
|
|
||||||
// &self,
|
|
||||||
// node: &mut i32,
|
|
||||||
// children: &mut dyn Iterator<Item = &'a mut i32>,
|
|
||||||
// _: &SendAnyMap,
|
|
||||||
// ) -> PassReturn {
|
|
||||||
// *node -= children.map(|i| *i).sum::<i32>();
|
|
||||||
// PassReturn {
|
|
||||||
// progress: true,
|
|
||||||
// mark_dirty: true,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// let add_pass = AnyPass::Upward(&AddPass);
|
|
||||||
// let subtract_pass = AnyPass::Upward(&SubtractPass);
|
|
||||||
// let passes = vec![&add_pass, &subtract_pass];
|
|
||||||
// let dirty_nodes: DirtyNodeStates = DirtyNodeStates::default();
|
|
||||||
// dirty_nodes.insert(PassId(1), grandchild1);
|
|
||||||
// dirty_nodes.insert(PassId(1), grandchild2);
|
|
||||||
// resolve_passes(&mut tree, dirty_nodes, passes, SendAnyMap::new());
|
|
||||||
|
|
||||||
// // Tree before:
|
|
||||||
// // 0=\
|
|
||||||
// // 0=\
|
|
||||||
// // 1
|
|
||||||
// // 0=\
|
|
||||||
// // 1
|
|
||||||
// // Tree after subtract:
|
|
||||||
// // 2=\
|
|
||||||
// // -1=\
|
|
||||||
// // 1
|
|
||||||
// // -1=\
|
|
||||||
// // 1
|
|
||||||
// // Tree after add:
|
|
||||||
// // 2=\
|
|
||||||
// // 0=\
|
|
||||||
// // 1
|
|
||||||
// // 0=\
|
|
||||||
// // 1
|
|
||||||
// assert_eq!(tree.get(tree.root_id()).unwrap(), &2);
|
|
||||||
// assert_eq!(tree.get(child1).unwrap(), &0);
|
|
||||||
// assert_eq!(tree.get(grandchild1).unwrap(), &1);
|
|
||||||
// assert_eq!(tree.get(child2).unwrap(), &0);
|
|
||||||
// assert_eq!(tree.get(grandchild2).unwrap(), &1);
|
|
||||||
// }
|
|
||||||
Reference in new issue
Block a user