|
@@ -1,17 +1,15 @@
|
|
use anymap::AnyMap;
|
|
use anymap::AnyMap;
|
|
-use core::panic;
|
|
|
|
use parking_lot::RwLock;
|
|
use parking_lot::RwLock;
|
|
use rustc_hash::{FxHashMap, FxHashSet};
|
|
use rustc_hash::{FxHashMap, FxHashSet};
|
|
|
|
+use shipyard::{Component, IntoBorrow, Unique, View, WorkloadSystem};
|
|
use std::any::{Any, TypeId};
|
|
use std::any::{Any, TypeId};
|
|
use std::collections::BTreeMap;
|
|
use std::collections::BTreeMap;
|
|
use std::marker::PhantomData;
|
|
use std::marker::PhantomData;
|
|
use std::sync::Arc;
|
|
use std::sync::Arc;
|
|
|
|
|
|
-use crate::node::{FromAnyValue, NodeType};
|
|
|
|
|
|
+use crate::node::FromAnyValue;
|
|
use crate::node_ref::{NodeMaskBuilder, NodeView};
|
|
use crate::node_ref::{NodeMaskBuilder, NodeView};
|
|
-use crate::real_dom::RealDom;
|
|
|
|
-use crate::tree::{SlabEntry, Tree, TreeStateView};
|
|
|
|
-use crate::{FxDashSet, SendAnyMap};
|
|
|
|
|
|
+use crate::SendAnyMap;
|
|
use crate::{NodeId, NodeMask};
|
|
use crate::{NodeId, NodeMask};
|
|
|
|
|
|
#[derive(Default)]
|
|
#[derive(Default)]
|
|
@@ -21,7 +19,7 @@ struct DirtyNodes {
|
|
|
|
|
|
impl DirtyNodes {
|
|
impl DirtyNodes {
|
|
pub fn add_node(&mut self, node_id: NodeId) {
|
|
pub fn add_node(&mut self, node_id: NodeId) {
|
|
- let node_id = node_id.0;
|
|
|
|
|
|
+ let node_id = node_id.uindex();
|
|
let index = node_id / 64;
|
|
let index = node_id / 64;
|
|
let bit = node_id % 64;
|
|
let bit = node_id % 64;
|
|
let encoded = 1 << bit;
|
|
let encoded = 1 << bit;
|
|
@@ -37,17 +35,17 @@ impl DirtyNodes {
|
|
self.passes_dirty.iter().all(|dirty| *dirty == 0)
|
|
self.passes_dirty.iter().all(|dirty| *dirty == 0)
|
|
}
|
|
}
|
|
|
|
|
|
- pub fn pop(&mut self) -> Option<NodeId> {
|
|
|
|
|
|
+ pub fn pop(&mut self) -> Option<usize> {
|
|
let index = self.passes_dirty.iter().position(|dirty| *dirty != 0)?;
|
|
let index = self.passes_dirty.iter().position(|dirty| *dirty != 0)?;
|
|
let passes = self.passes_dirty[index];
|
|
let passes = self.passes_dirty[index];
|
|
let node_id = passes.trailing_zeros();
|
|
let node_id = passes.trailing_zeros();
|
|
let encoded = 1 << node_id;
|
|
let encoded = 1 << node_id;
|
|
self.passes_dirty[index] &= !encoded;
|
|
self.passes_dirty[index] &= !encoded;
|
|
- Some(NodeId((index * 64) + node_id as usize))
|
|
|
|
|
|
+ Some((index * 64) + node_id as usize)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
-#[derive(Clone)]
|
|
|
|
|
|
+#[derive(Clone, Unique)]
|
|
pub struct DirtyNodeStates {
|
|
pub struct DirtyNodeStates {
|
|
dirty: Arc<FxHashMap<TypeId, RwLock<BTreeMap<u16, DirtyNodes>>>>,
|
|
dirty: Arc<FxHashMap<TypeId, RwLock<BTreeMap<u16, DirtyNodes>>>>,
|
|
}
|
|
}
|
|
@@ -76,7 +74,7 @@ impl DirtyNodeStates {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
- fn pop_front(&self, pass_id: TypeId) -> Option<(u16, NodeId)> {
|
|
|
|
|
|
+ fn pop_front(&self, pass_id: TypeId) -> Option<(u16, usize)> {
|
|
let mut values = self.dirty.get(&pass_id)?.write();
|
|
let mut values = self.dirty.get(&pass_id)?.write();
|
|
let mut value = values.first_entry()?;
|
|
let mut value = values.first_entry()?;
|
|
let height = *value.key();
|
|
let height = *value.key();
|
|
@@ -89,7 +87,7 @@ impl DirtyNodeStates {
|
|
Some((height, id))
|
|
Some((height, id))
|
|
}
|
|
}
|
|
|
|
|
|
- fn pop_back(&self, pass_id: TypeId) -> Option<(u16, NodeId)> {
|
|
|
|
|
|
+ fn pop_back(&self, pass_id: TypeId) -> Option<(u16, usize)> {
|
|
let mut values = self.dirty.get(&pass_id)?.write();
|
|
let mut values = self.dirty.get(&pass_id)?.write();
|
|
let mut value = values.last_entry()?;
|
|
let mut value = values.last_entry()?;
|
|
let height = *value.key();
|
|
let height = *value.key();
|
|
@@ -110,6 +108,7 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
|
|
type ChildDependencies: Dependancy;
|
|
type ChildDependencies: Dependancy;
|
|
/// This is a tuple of (T: Pass, ..) of states read from the node required to run this pass
|
|
/// This is a tuple of (T: Pass, ..) of states read from the node required to run this pass
|
|
type NodeDependencies: Dependancy;
|
|
type NodeDependencies: Dependancy;
|
|
|
|
+ type CombinedDependencies: Dependancy;
|
|
/// This is a mask of what aspects of the node are required to run this pass
|
|
/// This is a mask of what aspects of the node are required to run this pass
|
|
const NODE_MASK: NodeMaskBuilder<'static>;
|
|
const NODE_MASK: NodeMaskBuilder<'static>;
|
|
|
|
|
|
@@ -131,47 +130,43 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
|
|
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
|
|
children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
|
|
context: &SendAnyMap,
|
|
context: &SendAnyMap,
|
|
) -> Self;
|
|
) -> Self;
|
|
|
|
+}
|
|
|
|
|
|
- fn validate() {
|
|
|
|
- // this type should not be a node dependency
|
|
|
|
- for type_id in Self::node_type_ids().iter().copied() {
|
|
|
|
- if type_id == TypeId::of::<Self>() {
|
|
|
|
- panic!("The current type cannot be a node dependency");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // this type cannot be both a parent and child dependency
|
|
|
|
- assert!(
|
|
|
|
- !(Self::parent_type_ids()
|
|
|
|
- .iter()
|
|
|
|
- .any(|type_id| *type_id == TypeId::of::<Self>())
|
|
|
|
- && Self::child_type_ids()
|
|
|
|
- .iter()
|
|
|
|
- .any(|type_id| *type_id == TypeId::of::<Self>())),
|
|
|
|
- "The current type cannot be a parent and child dependency"
|
|
|
|
- );
|
|
|
|
- // no states have the same type id
|
|
|
|
- if Self::child_type_ids()
|
|
|
|
- .iter()
|
|
|
|
- .collect::<FxHashSet<_>>()
|
|
|
|
- .len()
|
|
|
|
- != Self::child_type_ids().len()
|
|
|
|
- || Self::parent_type_ids()
|
|
|
|
- .iter()
|
|
|
|
- .collect::<FxHashSet<_>>()
|
|
|
|
- .len()
|
|
|
|
- != Self::parent_type_ids().len()
|
|
|
|
- || Self::node_type_ids().iter().collect::<FxHashSet<_>>().len()
|
|
|
|
- != Self::node_type_ids().len()
|
|
|
|
- {
|
|
|
|
- panic!("all states must have unique type ids");
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+pub trait AnyState<V: FromAnyValue + Send + Sync = ()>: State<V> {
|
|
|
|
+ fn workload_system() -> WorkloadSystem;
|
|
|
|
+ // Box::new(
|
|
|
|
+ // move |node_id: NodeId, tree: &mut TreeStateView, context: &SendAnyMap| {
|
|
|
|
+ // debug_assert!(!Self::NodeDependencies::type_ids()
|
|
|
|
+ // .iter()
|
|
|
|
+ // .any(|id| *id == TypeId::of::<Self>()));
|
|
|
|
+ // // get all of the states from the tree view
|
|
|
|
+ // // Safety: No node has itself as a parent or child.
|
|
|
|
+ // let myself: SlabEntry<'static, Self> = unsafe {
|
|
|
|
+ // std::mem::transmute(tree.get_slab_mut::<Self>().unwrap().entry(node_id))
|
|
|
|
+ // };
|
|
|
|
+ // let node_data = tree.get_single::<NodeType<V>>(node_id).unwrap();
|
|
|
|
+ // let node = tree.get::<Self::NodeDependencies>(node_id).unwrap();
|
|
|
|
+ // let children = tree.children::<Self::ChildDependencies>(node_id);
|
|
|
|
+ // let parent = tree.parent::<Self::ParentDependencies>(node_id);
|
|
|
|
+
|
|
|
|
+ // let view = NodeView::new(node_id, node_data, &node_mask);
|
|
|
|
+ // if myself.value.is_none() {
|
|
|
|
+ // *myself.value = Some(Self::create(view, node, parent, children, context));
|
|
|
|
+ // true
|
|
|
|
+ // } else {
|
|
|
|
+ // myself
|
|
|
|
+ // .value
|
|
|
|
+ // .as_mut()
|
|
|
|
+ // .unwrap()
|
|
|
|
+ // .update(view, node, parent, children, context)
|
|
|
|
+ // }
|
|
|
|
+ // },
|
|
|
|
+ // ) as PassCallback
|
|
|
|
|
|
fn to_type_erased() -> TypeErasedPass<V>
|
|
fn to_type_erased() -> TypeErasedPass<V>
|
|
where
|
|
where
|
|
Self: Sized,
|
|
Self: Sized,
|
|
{
|
|
{
|
|
- Self::validate();
|
|
|
|
let node_mask = Self::NODE_MASK.build();
|
|
let node_mask = Self::NODE_MASK.build();
|
|
TypeErasedPass {
|
|
TypeErasedPass {
|
|
this_type_id: TypeId::of::<Self>(),
|
|
this_type_id: TypeId::of::<Self>(),
|
|
@@ -181,35 +176,7 @@ pub trait State<V: FromAnyValue + Send + Sync = ()>: Any + Send + Sync {
|
|
dependants: FxHashSet::default(),
|
|
dependants: FxHashSet::default(),
|
|
mask: node_mask.clone(),
|
|
mask: node_mask.clone(),
|
|
pass_direction: Self::pass_direction(),
|
|
pass_direction: Self::pass_direction(),
|
|
- pass: Box::new(
|
|
|
|
- move |node_id: NodeId, tree: &mut TreeStateView, context: &SendAnyMap| {
|
|
|
|
- debug_assert!(!Self::NodeDependencies::type_ids()
|
|
|
|
- .iter()
|
|
|
|
- .any(|id| *id == TypeId::of::<Self>()));
|
|
|
|
- // get all of the states from the tree view
|
|
|
|
- // Safety: No node has itself as a parent or child.
|
|
|
|
- let myself: SlabEntry<'static, Self> = unsafe {
|
|
|
|
- std::mem::transmute(tree.get_slab_mut::<Self>().unwrap().entry(node_id))
|
|
|
|
- };
|
|
|
|
- let node_data = tree.get_single::<NodeType<V>>(node_id).unwrap();
|
|
|
|
- let node = tree.get::<Self::NodeDependencies>(node_id).unwrap();
|
|
|
|
- let children = tree.children::<Self::ChildDependencies>(node_id);
|
|
|
|
- let parent = tree.parent::<Self::ParentDependencies>(node_id);
|
|
|
|
-
|
|
|
|
- let view = NodeView::new(node_id, node_data, &node_mask);
|
|
|
|
- if myself.value.is_none() {
|
|
|
|
- *myself.value = Some(Self::create(view, node, parent, children, context));
|
|
|
|
- true
|
|
|
|
- } else {
|
|
|
|
- myself
|
|
|
|
- .value
|
|
|
|
- .as_mut()
|
|
|
|
- .unwrap()
|
|
|
|
- .update(view, node, parent, children, context)
|
|
|
|
- }
|
|
|
|
- },
|
|
|
|
- ) as PassCallback,
|
|
|
|
- create: Box::new(|tree: &mut Tree| tree.insert_slab::<Self>()) as CreatePassCallback,
|
|
|
|
|
|
+ workload: Some(Self::workload_system()),
|
|
phantom: PhantomData,
|
|
phantom: PhantomData,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -257,58 +224,57 @@ pub struct TypeErasedPass<V: FromAnyValue + Send = ()> {
|
|
pub(crate) combined_dependancy_type_ids: FxHashSet<TypeId>,
|
|
pub(crate) combined_dependancy_type_ids: FxHashSet<TypeId>,
|
|
pub(crate) dependants: FxHashSet<TypeId>,
|
|
pub(crate) dependants: FxHashSet<TypeId>,
|
|
pub(crate) mask: NodeMask,
|
|
pub(crate) mask: NodeMask,
|
|
- pass: PassCallback,
|
|
|
|
- pub(crate) create: CreatePassCallback,
|
|
|
|
|
|
+ pub(crate) workload: Option<WorkloadSystem>,
|
|
pub(crate) pass_direction: PassDirection,
|
|
pub(crate) pass_direction: PassDirection,
|
|
phantom: PhantomData<V>,
|
|
phantom: PhantomData<V>,
|
|
}
|
|
}
|
|
|
|
|
|
-impl<V: FromAnyValue + Send> TypeErasedPass<V> {
|
|
|
|
- fn resolve(
|
|
|
|
- &self,
|
|
|
|
- mut tree: TreeStateView,
|
|
|
|
- dirty: &DirtyNodeStates,
|
|
|
|
- nodes_updated: &FxDashSet<NodeId>,
|
|
|
|
- ctx: &SendAnyMap,
|
|
|
|
- ) {
|
|
|
|
- match self.pass_direction {
|
|
|
|
- PassDirection::ParentToChild => {
|
|
|
|
- while let Some((height, id)) = dirty.pop_front(self.this_type_id) {
|
|
|
|
- if (self.pass)(id, &mut tree, ctx) {
|
|
|
|
- nodes_updated.insert(id);
|
|
|
|
- for id in tree.children_ids(id).unwrap() {
|
|
|
|
- for dependant in &self.dependants {
|
|
|
|
- dirty.insert(*dependant, *id, height + 1);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PassDirection::ChildToParent => {
|
|
|
|
- while let Some((height, id)) = dirty.pop_back(self.this_type_id) {
|
|
|
|
- if (self.pass)(id, &mut tree, ctx) {
|
|
|
|
- nodes_updated.insert(id);
|
|
|
|
- if let Some(id) = tree.parent_id(id) {
|
|
|
|
- for dependant in &self.dependants {
|
|
|
|
- dirty.insert(*dependant, id, height - 1);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- PassDirection::AnyOrder => {
|
|
|
|
- while let Some((height, id)) = dirty.pop_back(self.this_type_id) {
|
|
|
|
- if (self.pass)(id, &mut tree, ctx) {
|
|
|
|
- nodes_updated.insert(id);
|
|
|
|
- for dependant in &self.dependants {
|
|
|
|
- dirty.insert(*dependant, id, height);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
|
|
+// impl<V: FromAnyValue + Send> TypeErasedPass<V> {
|
|
|
|
+// fn resolve(
|
|
|
|
+// &self,
|
|
|
|
+// mut tree: TreeStateView,
|
|
|
|
+// dirty: &DirtyNodeStates,
|
|
|
|
+// nodes_updated: &FxDashSet<NodeId>,
|
|
|
|
+// ctx: &SendAnyMap,
|
|
|
|
+// ) {
|
|
|
|
+// match self.pass_direction {
|
|
|
|
+// PassDirection::ParentToChild => {
|
|
|
|
+// while let Some((height, id)) = dirty.pop_front(self.this_type_id) {
|
|
|
|
+// if (self.pass)(id, &mut tree, ctx) {
|
|
|
|
+// nodes_updated.insert(id);
|
|
|
|
+// for id in tree.children_ids(id).unwrap() {
|
|
|
|
+// for dependant in &self.dependants {
|
|
|
|
+// dirty.insert(*dependant, *id, height + 1);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// PassDirection::ChildToParent => {
|
|
|
|
+// while let Some((height, id)) = dirty.pop_back(self.this_type_id) {
|
|
|
|
+// if (self.pass)(id, &mut tree, ctx) {
|
|
|
|
+// nodes_updated.insert(id);
|
|
|
|
+// if let Some(id) = tree.parent_id(id) {
|
|
|
|
+// for dependant in &self.dependants {
|
|
|
|
+// dirty.insert(*dependant, id, height - 1);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// PassDirection::AnyOrder => {
|
|
|
|
+// while let Some((height, id)) = dirty.pop_back(self.this_type_id) {
|
|
|
|
+// if (self.pass)(id, &mut tree, ctx) {
|
|
|
|
+// nodes_updated.insert(id);
|
|
|
|
+// for dependant in &self.dependants {
|
|
|
|
+// dirty.insert(*dependant, id, height);
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
|
|
#[derive(Debug)]
|
|
#[derive(Debug)]
|
|
pub enum PassDirection {
|
|
pub enum PassDirection {
|
|
@@ -317,9 +283,6 @@ pub enum PassDirection {
|
|
AnyOrder,
|
|
AnyOrder,
|
|
}
|
|
}
|
|
|
|
|
|
-type PassCallback = Box<dyn Fn(NodeId, &mut TreeStateView, &SendAnyMap) -> bool + Send + Sync>;
|
|
|
|
-type CreatePassCallback = Box<dyn Fn(&mut Tree) + Send + Sync>;
|
|
|
|
-
|
|
|
|
pub trait AnyMapLike<'a> {
|
|
pub trait AnyMapLike<'a> {
|
|
fn get<T: Any + Sync + Send>(self) -> Option<&'a T>;
|
|
fn get<T: Any + Sync + Send>(self) -> Option<&'a T>;
|
|
}
|
|
}
|
|
@@ -337,25 +300,17 @@ impl<'a> AnyMapLike<'a> for &'a SendAnyMap {
|
|
}
|
|
}
|
|
|
|
|
|
pub trait Dependancy {
|
|
pub trait Dependancy {
|
|
- type ElementBorrowed<'a>
|
|
|
|
- where
|
|
|
|
- Self: 'a;
|
|
|
|
|
|
+ type ElementBorrowed<'a>: IntoBorrow;
|
|
|
|
|
|
- fn borrow_elements_from<'a, T: AnyMapLike<'a> + Copy>(
|
|
|
|
- map: T,
|
|
|
|
- ) -> Option<Self::ElementBorrowed<'a>>;
|
|
|
|
- fn type_ids() -> Box<[TypeId]>;
|
|
|
|
|
|
+ fn type_ids() -> Box<[TypeId]> {
|
|
|
|
+ Box::new([])
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
macro_rules! impl_dependancy {
|
|
macro_rules! impl_dependancy {
|
|
($($t:ident),*) => {
|
|
($($t:ident),*) => {
|
|
- impl< $($t: Any + Send + Sync),* > Dependancy for ($($t,)*) {
|
|
|
|
- type ElementBorrowed<'a> = ($(&'a $t,)*) where Self: 'a;
|
|
|
|
-
|
|
|
|
- #[allow(unused_variables, clippy::unused_unit, non_snake_case)]
|
|
|
|
- fn borrow_elements_from<'a, T: AnyMapLike<'a> + Copy>(map: T) -> Option<Self::ElementBorrowed<'a>> {
|
|
|
|
- Some(($(map.get::<$t>()?,)*))
|
|
|
|
- }
|
|
|
|
|
|
+ impl< $($t: Send + Sync + Component),* > Dependancy for ($($t,)*) {
|
|
|
|
+ type ElementBorrowed<'a> = ($(View<'a, $t>,)*);
|
|
|
|
|
|
fn type_ids() -> Box<[TypeId]> {
|
|
fn type_ids() -> Box<[TypeId]> {
|
|
Box::new([$(TypeId::of::<$t>()),*])
|
|
Box::new([$(TypeId::of::<$t>()),*])
|
|
@@ -375,66 +330,60 @@ impl_dependancy!(A, B, C, D, E, F, G);
|
|
impl_dependancy!(A, B, C, D, E, F, G, H);
|
|
impl_dependancy!(A, B, C, D, E, F, G, H);
|
|
impl_dependancy!(A, B, C, D, E, F, G, H, I);
|
|
impl_dependancy!(A, B, C, D, E, F, G, H, I);
|
|
impl_dependancy!(A, B, C, D, E, F, G, H, I, J);
|
|
impl_dependancy!(A, B, C, D, E, F, G, H, I, J);
|
|
-impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K);
|
|
|
|
-impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L);
|
|
|
|
-impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M);
|
|
|
|
-impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M, N);
|
|
|
|
-impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O);
|
|
|
|
-impl_dependancy!(A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P);
|
|
|
|
-
|
|
|
|
-pub fn resolve_passes<V: FromAnyValue + Send + Sync>(
|
|
|
|
- dom: &mut RealDom<V>,
|
|
|
|
- dirty_nodes: DirtyNodeStates,
|
|
|
|
- ctx: SendAnyMap,
|
|
|
|
- parallel: bool,
|
|
|
|
-) -> FxDashSet<NodeId> {
|
|
|
|
- let passes = &dom.dirty_nodes.passes;
|
|
|
|
- let mut resolved_passes: FxHashSet<TypeId> = FxHashSet::default();
|
|
|
|
- let mut resolving = Vec::new();
|
|
|
|
- let nodes_updated = Arc::new(FxDashSet::default());
|
|
|
|
- let ctx = Arc::new(ctx);
|
|
|
|
- let mut pass_indexes_remaining: Vec<_> = (0..passes.len()).collect::<Vec<_>>();
|
|
|
|
- while !pass_indexes_remaining.is_empty() {
|
|
|
|
- let mut currently_in_use = FxHashSet::<TypeId>::default();
|
|
|
|
- let dynamically_borrowed_tree = dom.tree.dynamically_borrowed();
|
|
|
|
- rayon::in_place_scope(|s| {
|
|
|
|
- let mut i = 0;
|
|
|
|
- while i < pass_indexes_remaining.len() {
|
|
|
|
- let passes_idx = pass_indexes_remaining[i];
|
|
|
|
- let pass = &passes[passes_idx];
|
|
|
|
- let pass_id = pass.this_type_id;
|
|
|
|
- // check if the pass is ready to be run
|
|
|
|
- if pass.combined_dependancy_type_ids.iter().all(|d| {
|
|
|
|
- (resolved_passes.contains(d) || *d == pass_id) && !currently_in_use.contains(d)
|
|
|
|
- }) {
|
|
|
|
- pass_indexes_remaining.remove(i);
|
|
|
|
- resolving.push(pass_id);
|
|
|
|
- currently_in_use.insert(pass.this_type_id);
|
|
|
|
- let tree_view = dynamically_borrowed_tree.view(
|
|
|
|
- pass.combined_dependancy_type_ids
|
|
|
|
- .iter()
|
|
|
|
- .filter(|id| **id != pass.this_type_id)
|
|
|
|
- .copied()
|
|
|
|
- .chain(std::iter::once(TypeId::of::<NodeType<V>>())),
|
|
|
|
- [pass.this_type_id],
|
|
|
|
- );
|
|
|
|
- let dirty_nodes = dirty_nodes.clone();
|
|
|
|
- let nodes_updated = nodes_updated.clone();
|
|
|
|
- let ctx = ctx.clone();
|
|
|
|
- if parallel {
|
|
|
|
- s.spawn(move |_| {
|
|
|
|
- pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
|
|
|
|
- });
|
|
|
|
- } else {
|
|
|
|
- pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
|
|
|
|
- }
|
|
|
|
- } else {
|
|
|
|
- i += 1;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- });
|
|
|
|
- resolved_passes.extend(resolving.iter().copied());
|
|
|
|
- resolving.clear()
|
|
|
|
- }
|
|
|
|
- std::sync::Arc::try_unwrap(nodes_updated).unwrap()
|
|
|
|
-}
|
|
|
|
|
|
+
|
|
|
|
+// pub fn resolve_passes<V: FromAnyValue + Send + Sync>(
|
|
|
|
+// dom: &mut RealDom<V>,
|
|
|
|
+// dirty_nodes: DirtyNodeStates,
|
|
|
|
+// ctx: SendAnyMap,
|
|
|
|
+// parallel: bool,
|
|
|
|
+// ) -> FxDashSet<NodeId> {
|
|
|
|
+// let passes = &dom.dirty_nodes.passes;
|
|
|
|
+// let mut resolved_passes: FxHashSet<TypeId> = FxHashSet::default();
|
|
|
|
+// let mut resolving = Vec::new();
|
|
|
|
+// let nodes_updated = Arc::new(FxDashSet::default());
|
|
|
|
+// let ctx = Arc::new(ctx);
|
|
|
|
+// let mut pass_indexes_remaining: Vec<_> = (0..passes.len()).collect::<Vec<_>>();
|
|
|
|
+// while !pass_indexes_remaining.is_empty() {
|
|
|
|
+// let mut currently_in_use = FxHashSet::<TypeId>::default();
|
|
|
|
+// let dynamically_borrowed_tree = dom.tree.dynamically_borrowed();
|
|
|
|
+// rayon::in_place_scope(|s| {
|
|
|
|
+// let mut i = 0;
|
|
|
|
+// while i < pass_indexes_remaining.len() {
|
|
|
|
+// let passes_idx = pass_indexes_remaining[i];
|
|
|
|
+// let pass = &passes[passes_idx];
|
|
|
|
+// let pass_id = pass.this_type_id;
|
|
|
|
+// // check if the pass is ready to be run
|
|
|
|
+// if pass.combined_dependancy_type_ids.iter().all(|d| {
|
|
|
|
+// (resolved_passes.contains(d) || *d == pass_id) && !currently_in_use.contains(d)
|
|
|
|
+// }) {
|
|
|
|
+// pass_indexes_remaining.remove(i);
|
|
|
|
+// resolving.push(pass_id);
|
|
|
|
+// currently_in_use.insert(pass.this_type_id);
|
|
|
|
+// let tree_view = dynamically_borrowed_tree.view(
|
|
|
|
+// pass.combined_dependancy_type_ids
|
|
|
|
+// .iter()
|
|
|
|
+// .filter(|id| **id != pass.this_type_id)
|
|
|
|
+// .copied()
|
|
|
|
+// .chain(std::iter::once(TypeId::of::<NodeType<V>>())),
|
|
|
|
+// [pass.this_type_id],
|
|
|
|
+// );
|
|
|
|
+// let dirty_nodes = dirty_nodes.clone();
|
|
|
|
+// let nodes_updated = nodes_updated.clone();
|
|
|
|
+// let ctx = ctx.clone();
|
|
|
|
+// if parallel {
|
|
|
|
+// s.spawn(move |_| {
|
|
|
|
+// pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
|
|
|
|
+// });
|
|
|
|
+// } else {
|
|
|
|
+// pass.resolve(tree_view, &dirty_nodes, &nodes_updated, &ctx);
|
|
|
|
+// }
|
|
|
|
+// } else {
|
|
|
|
+// i += 1;
|
|
|
|
+// }
|
|
|
|
+// }
|
|
|
|
+// });
|
|
|
|
+// resolved_passes.extend(resolving.iter().copied());
|
|
|
|
+// resolving.clear()
|
|
|
|
+// }
|
|
|
|
+// std::sync::Arc::try_unwrap(nodes_updated).unwrap()
|
|
|
|
+// }
|