add sync behind a feature flag

This commit is contained in:
= committed 2022-12-11 17:31:15 -06:00
1 parent 0ac02cc893
commit 74e9d5977a
9 files changed
+137 -33

No files matched your search

+2 -2
View File
@@ -1,5 +1,5 @@
use crate::{state::State, tree::NodeId};
use dioxus_core::{AnyValueRc, AttributeValue, ElementId};
use dioxus_core::{AnyValueContainer, AttributeValue, ElementId};
use rustc_hash::{FxHashMap, FxHashSet};
use std::fmt::Debug;
@@ -79,7 +79,7 @@ pub enum OwnedAttributeValue {
Float(f64),
Int(i64),
Bool(bool),
Any(AnyValueRc),
Any(AnyValueContainer),
None,
}
+45 -1
View File
@@ -314,7 +314,7 @@ struct RawPointer<T>(*mut T);
unsafe impl<T> Send for RawPointer<T> {}
unsafe impl<T> Sync for RawPointer<T> {}
pub fn resolve_passes<T, Tr: TreeView<T>>(
pub fn resolve_passes<T, Tr: TreeView<T> + Sync>(
tree: &mut Tr,
dirty_nodes: DirtyNodeStates,
mut passes: Vec<&AnyPass<T>>,
@@ -368,6 +368,50 @@ pub fn resolve_passes<T, Tr: TreeView<T>>(
std::sync::Arc::try_unwrap(nodes_updated).unwrap()
}
pub fn resolve_passes_single_threaded<T, Tr: TreeView<T>>(
tree: &mut Tr,
dirty_nodes: DirtyNodeStates,
mut passes: Vec<&AnyPass<T>>,
ctx: SendAnyMap,
) -> FxDashSet<NodeId> {
let dirty_states = Arc::new(dirty_nodes);
let mut resolved_passes: FxHashSet<PassId> = FxHashSet::default();
let mut resolving = Vec::new();
let nodes_updated = Arc::new(FxDashSet::default());
let ctx = Arc::new(ctx);
while !passes.is_empty() {
let mut currently_borrowed = MemberMask::default();
let mut i = 0;
while i < passes.len() {
let pass = &passes[i];
let pass_id = pass.pass_id();
let pass_mask = pass.mask();
if pass
.dependancies()
.iter()
.all(|d| resolved_passes.contains(d) || *d == pass_id)
&& !pass_mask.overlaps(currently_borrowed)
{
let pass = passes.remove(i);
resolving.push(pass_id);
currently_borrowed |= pass_mask;
let dirty_states = dirty_states.clone();
let nodes_updated = nodes_updated.clone();
let ctx = ctx.clone();
// this is safe because the member_mask acts as a per-member mutex and we have verified that the pass does not overlap with any other pass
let mut dirty = DirtyNodes::default();
dirty_states.all_dirty(pass_id, &mut dirty, tree);
pass.resolve(tree, dirty, &dirty_states, &nodes_updated, &ctx);
} else {
i += 1;
}
}
resolved_passes.extend(resolving.iter().copied());
resolving.clear()
}
std::sync::Arc::try_unwrap(nodes_updated).unwrap()
}
#[test]
fn node_pass() {
use crate::tree::{Tree, TreeLike};
+17 -2
View File
@@ -339,12 +339,12 @@ impl<S: State> RealDom<S> {
}
/// Update the state of the dom, after appling some mutations. This will keep the nodes in the dom up to date with their VNode counterparts.
pub fn update_state(
pub fn update_state_single_threaded(
&mut self,
nodes_updated: DirtyNodeStates,
ctx: SendAnyMap,
) -> FxDashSet<RealNodeId> {
S::update(nodes_updated, &mut self.tree, ctx)
S::update_single_threaded(nodes_updated, &mut self.tree, ctx)
}
/// Find all nodes that are listening for an event, sorted by there height in the dom progressing starting at the bottom and progressing up.
@@ -396,6 +396,21 @@ impl<S: State> RealDom<S> {
}
}
impl<S: State + Sync> RealDom<S>
where
Tree<Node<S>>: Sync,
{
/// Update the state of the dom, after appling some mutations. This will keep the nodes in the dom up to date with their VNode counterparts.
/// This will resolve the state in parallel
pub fn update_state(
&mut self,
nodes_updated: DirtyNodeStates,
ctx: SendAnyMap,
) -> FxDashSet<RealNodeId> {
S::update(nodes_updated, &mut self.tree, ctx)
}
}
impl<S: State> Deref for RealDom<S> {
type Target = Tree<Node<S>>;
+12 -2
View File
@@ -2,7 +2,7 @@ use std::cmp::Ordering;
use crate::node::Node;
use crate::node_ref::{NodeMask, NodeView};
use crate::passes::{resolve_passes, AnyPass, DirtyNodeStates};
use crate::passes::{resolve_passes, resolve_passes_single_threaded, AnyPass, DirtyNodeStates};
use crate::tree::TreeView;
use crate::{FxDashSet, RealNodeId, SendAnyMap};
@@ -217,7 +217,7 @@ pub trait State: Default + Clone + 'static {
const MASKS: &'static [NodeMask];
#[doc(hidden)]
fn update<T: TreeView<Node<Self>>>(
fn update<T: TreeView<Node<Self>> + Sync>(
dirty: DirtyNodeStates,
tree: &mut T,
ctx: SendAnyMap,
@@ -225,6 +225,16 @@ pub trait State: Default + Clone + 'static {
let passes = Self::PASSES.iter().collect();
resolve_passes(tree, dirty, passes, ctx)
}
#[doc(hidden)]
fn update_single_threaded<T: TreeView<Node<Self>>>(
dirty: DirtyNodeStates,
tree: &mut T,
ctx: SendAnyMap,
) -> FxDashSet<RealNodeId> {
let passes = Self::PASSES.iter().collect();
resolve_passes_single_threaded(tree, dirty, passes, ctx)
}
}
impl ChildDepState for () {
+2 -2
View File
@@ -564,8 +564,8 @@ impl<'a, T, Tr: TreeView<T>> SharedView<'a, T, Tr> {
}
}
unsafe impl<'a, T, Tr: TreeView<T>> Send for SharedView<'a, T, Tr> {}
unsafe impl<'a, T, Tr: TreeView<T>> Sync for SharedView<'a, T, Tr> {}
unsafe impl<'a, T, Tr: TreeView<T> + Send> Send for SharedView<'a, T, Tr> {}
unsafe impl<'a, T, Tr: TreeView<T> + Sync> Sync for SharedView<'a, T, Tr> {}
impl<'a, T, Tr: TreeView<T>> Clone for SharedView<'a, T, Tr> {
fn clone(&self) -> Self {
Self {