1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069 |
- use anymap::AnyMap;
- use parking_lot::RwLock;
- use rustc_hash::FxHashSet;
- use std::any::{self, Any, TypeId};
- use std::collections::BTreeMap;
- use std::marker::PhantomData;
- use std::sync::Arc;
- use crate::node::{FromAnyValue, NodeData};
- use crate::node_ref::NodeView;
- use crate::real_dom::RealDom;
- use crate::tree::{self, Node, TreeStateView};
- use crate::{FxDashMap, FxDashSet, SendAnyMap};
- use crate::{NodeId, NodeMask};
- #[derive(Default)]
- struct DirtyNodes {
- passes_dirty: Vec<u64>,
- }
- impl DirtyNodes {
- pub fn add_node(&mut self, node_id: NodeId) {
- let node_id = node_id.0;
- let index = node_id / 64;
- let bit = node_id % 64;
- let encoded = 1 << bit;
- if let Some(passes) = self.passes_dirty.get_mut(index) {
- *passes |= encoded;
- } else {
- self.passes_dirty.resize(index + 1, 0);
- self.passes_dirty[index] |= encoded;
- }
- }
- pub fn is_empty(&self) -> bool {
- self.passes_dirty.iter().all(|dirty| *dirty == 0)
- }
- pub fn pop(&mut self) -> Option<NodeId> {
- let index = self.passes_dirty.iter().position(|dirty| *dirty != 0)?;
- let passes = self.passes_dirty[index];
- let node_id = passes.trailing_zeros();
- let encoded = 1 << node_id;
- self.passes_dirty[index] &= !encoded;
- Some(NodeId((index * 64) + node_id as usize))
- }
- }
- #[derive(Default, Clone)]
- pub struct DirtyNodeStates {
- dirty: Arc<RwLock<BTreeMap<u16, FxDashMap<TypeId, DirtyNodes>>>>,
- }
- impl DirtyNodeStates {
- pub fn insert(&self, pass_id: TypeId, node_id: NodeId, height: u16) {
- let mut dirty = self.dirty.write();
- if let Some(dirty) = dirty.get_mut(&height) {
- if let Some(mut entry) = dirty.get_mut(&pass_id) {
- entry.add_node(node_id);
- } else {
- let mut entry = DirtyNodes::default();
- entry.add_node(node_id);
- dirty.insert(pass_id, entry);
- }
- } else {
- let mut entry = DirtyNodes::default();
- entry.add_node(node_id);
- let hm = FxDashMap::default();
- hm.insert(pass_id, entry);
- dirty.insert(height, hm);
- }
- }
- fn pop_front(&self, pass_id: TypeId) -> Option<(u16, NodeId)> {
- let dirty_read = self.dirty.read();
- let (&height, values) = dirty_read
- .iter()
- .find(|(_, values)| values.contains_key(&pass_id))?;
- let mut dirty = values.get_mut(&pass_id)?;
- let node_id = dirty.pop()?;
- if dirty.is_empty() {
- values.remove(&pass_id);
- }
- if values.is_empty() {
- let mut dirty_write = self.dirty.write();
- dirty_write.remove(&height);
- }
- Some((height, node_id))
- }
- fn pop_back(&self, pass_id: TypeId) -> Option<(u16, NodeId)> {
- let dirty_read = self.dirty.read();
- let (&height, values) = dirty_read
- .iter()
- .rev()
- .find(|(_, values)| values.contains_key(&pass_id))?;
- let mut dirty = values.get_mut(&pass_id)?;
- let node_id = dirty.pop()?;
- if dirty.is_empty() {
- values.remove(&pass_id);
- }
- if values.is_empty() {
- let mut dirty_write = self.dirty.write();
- dirty_write.remove(&height);
- }
- Some((height, node_id))
- }
- }
- pub trait Pass<V: FromAnyValue + Send = ()>: Any {
- /// This is a tuple of (T: Any, ..)
- type ParentDependencies: Dependancy;
- /// This is a tuple of (T: Any, ..)
- type ChildDependencies: Dependancy;
- /// This is a tuple of (T: Any, ..)
- type NodeDependencies: Dependancy;
- const NODE_MASK: NodeMask;
- fn pass<'a>(
- &mut self,
- node_view: NodeView<V>,
- 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,
- ) -> bool;
- fn validate() {
- // no type can be a child and parent dependency
- for type_id in Self::parent_type_ids().into_iter().copied() {
- for type_id2 in Self::child_type_ids().into_iter().copied() {
- if type_id == type_id2 {
- panic!("type cannot be both a parent and child dependency");
- }
- }
- }
- // this type should not be a node dependency
- for type_id in Self::node_type_ids().into_iter().copied() {
- if type_id == TypeId::of::<Self>() {
- panic!("The current type cannot be a node dependency");
- }
- }
- // no states have the same type id
- if Self::all_dependanices()
- .into_iter()
- .collect::<FxDashSet<_>>()
- .len()
- != Self::all_dependanices().len()
- {
- panic!("all states must have unique type ids");
- }
- }
- fn to_type_erased() -> TypeErasedPass<V>
- where
- Self: Sized,
- {
- Self::validate();
- TypeErasedPass {
- this_type_id: TypeId::of::<Self>(),
- combined_dependancy_type_ids: Self::all_dependanices().into_iter().copied().collect(),
- parent_dependant: !Self::parent_type_ids().is_empty(),
- child_dependant: !Self::child_type_ids().is_empty(),
- dependants: FxHashSet::default(),
- mask: Self::NODE_MASK,
- pass_direction: Self::pass_direction(),
- pass: Box::new(
- |node_id: NodeId, tree: &mut TreeStateView, context: &SendAnyMap| {
- debug_assert!(!Self::NodeDependencies::type_ids()
- .into_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 node_raw = tree.get_mut::<Self>(node_id).unwrap() as *mut Self;
- let node_data = tree.get_single::<NodeData<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 myself = unsafe { &mut *node_raw };
- myself.pass(
- NodeView::new(&node_data, Self::NODE_MASK),
- node,
- parent,
- children,
- context,
- )
- },
- ) as PassCallback,
- phantom: PhantomData,
- }
- }
- fn parent_type_ids() -> Box<[TypeId]> {
- Self::ParentDependencies::type_ids()
- }
- fn child_type_ids() -> Box<[TypeId]> {
- Self::ChildDependencies::type_ids()
- }
- fn node_type_ids() -> Box<[TypeId]> {
- Self::NodeDependencies::type_ids()
- }
- fn all_dependanices() -> Box<[TypeId]> {
- let mut dependencies = Self::parent_type_ids().to_vec();
- dependencies.extend(Self::child_type_ids().into_iter());
- dependencies.extend(Self::node_type_ids().into_iter());
- dependencies.into_boxed_slice()
- }
- fn pass_direction() -> PassDirection {
- if Self::child_type_ids()
- .into_iter()
- .any(|type_id| *type_id == TypeId::of::<Self>())
- {
- PassDirection::ChildToParent
- } else if Self::parent_type_ids()
- .into_iter()
- .any(|type_id| *type_id == TypeId::of::<Self>())
- {
- PassDirection::ParentToChild
- } else {
- PassDirection::AnyOrder
- }
- }
- }
- pub struct TypeErasedPass<V: FromAnyValue + Send = ()> {
- pub(crate) this_type_id: TypeId,
- pub(crate) parent_dependant: bool,
- pub(crate) child_dependant: bool,
- pub(crate) combined_dependancy_type_ids: FxHashSet<TypeId>,
- pub(crate) dependants: FxHashSet<TypeId>,
- pub(crate) mask: NodeMask,
- pass: PassCallback,
- pub(crate) pass_direction: PassDirection,
- 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);
- }
- }
- }
- }
- }
- }
- }
- #[derive(Debug)]
- pub enum PassDirection {
- ParentToChild,
- ChildToParent,
- AnyOrder,
- }
- type PassCallback = Box<dyn Fn(NodeId, &mut TreeStateView, &SendAnyMap) -> bool + Send + Sync>;
- pub trait AnyMapLike<'a> {
- fn get<T: Any>(self) -> Option<&'a T>;
- }
- impl<'a> AnyMapLike<'a> for &'a AnyMap {
- fn get<T: Any>(self) -> Option<&'a T> {
- self.get()
- }
- }
- impl<'a> AnyMapLike<'a> for &'a SendAnyMap {
- fn get<T: Any>(self) -> Option<&'a T> {
- todo!()
- }
- }
- pub trait Dependancy {
- type ElementBorrowed<'a>
- where
- Self: 'a;
- fn borrow_elements_from<'a, T: AnyMapLike<'a> + Copy>(
- map: T,
- ) -> Option<Self::ElementBorrowed<'a>>;
- fn type_ids() -> Box<[TypeId]>;
- }
- macro_rules! impl_dependancy {
- ($($t:ident),*) => {
- impl< $($t: Any),* > 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>()?,)*))
- }
- fn type_ids() -> Box<[TypeId]> {
- Box::new([$(TypeId::of::<$t>()),*])
- }
- }
- };
- }
- impl_dependancy!();
- impl_dependancy!(A);
- impl_dependancy!(A, B);
- impl_dependancy!(A, B, C);
- impl_dependancy!(A, B, C, D);
- impl_dependancy!(A, B, C, D, E);
- impl_dependancy!(A, B, C, D, E, F);
- 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, 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, 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>(
- tree: &mut RealDom<V>,
- dirty_nodes: DirtyNodeStates,
- ctx: SendAnyMap,
- ) -> FxDashSet<NodeId> {
- let passes = &tree.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();
- std::thread::scope(|_| {
- 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];
- 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);
- 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);
- // });
- },
- );
- } 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::real_dom::RealDom;
- // use crate::tree::{Tree, TreeLike};
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct Number(i32);
- // impl State for Number {
- // fn create_passes() -> Box<[TypeErasedPass<Self>]> {
- // Box::new([Number::to_type_erased()])
- // }
- // }
- // impl AnyMapLike for Number {
- // fn get<T: Any>(&self) -> Option<&T> {
- // if TypeId::of::<Self>() == TypeId::of::<T>() {
- // Some(unsafe { &*(self as *const Self as *const T) })
- // } else {
- // None
- // }
- // }
- // fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
- // if TypeId::of::<Self>() == TypeId::of::<T>() {
- // Some(unsafe { &mut *(self as *mut Self as *mut T) })
- // } else {
- // None
- // }
- // }
- // }
- // impl Pass for Number {
- // type ChildDependencies = ();
- // type NodeDependencies = ();
- // type ParentDependencies = ();
- // type Ctx = ();
- // const MASK: NodeMask = NodeMask::new();
- // fn pass<'a>(
- // &mut self,
- // node_view: NodeView,
- // node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- // parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- // children: Option<
- // impl Iterator<Item = <Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- // >,
- // context: <Self::Ctx as Dependancy>::ElementBorrowed<'a>,
- // ) -> bool {
- // self.0 += 1;
- // true
- // }
- // }
- // let mut tree: RealDom<Number> = RealDom::new();
- // tree.dirty_nodes.insert(TypeId::of::<Number>(), NodeId(0));
- // tree.update_state(SendAnyMap::new());
- // assert_eq!(tree.get(tree.root()).unwrap().state.0, 1);
- // }
- // #[test]
- // fn dependant_node_pass() {
- // use crate::real_dom::RealDom;
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct AddNumber(i32);
- // impl Pass for AddNumber {
- // type ChildDependencies = ();
- // type NodeDependencies = (SubtractNumber,);
- // type ParentDependencies = ();
- // type Ctx = ();
- // const MASK: NodeMask = NodeMask::new();
- // fn pass<'a>(
- // &mut self,
- // node_view: NodeView,
- // node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- // parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- // children: Option<
- // impl Iterator<Item = <Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- // >,
- // context: <Self::Ctx as Dependancy>::ElementBorrowed<'a>,
- // ) -> bool {
- // self.0 += 1;
- // true
- // }
- // }
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct SubtractNumber(i32);
- // impl Pass for SubtractNumber {
- // type ChildDependencies = ();
- // type NodeDependencies = ();
- // type ParentDependencies = ();
- // type Ctx = ();
- // const MASK: NodeMask = NodeMask::new();
- // fn pass<'a>(
- // &mut self,
- // node_view: NodeView,
- // node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- // parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- // children: Option<
- // impl Iterator<Item = <Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- // >,
- // context: <Self::Ctx as Dependancy>::ElementBorrowed<'a>,
- // ) -> bool {
- // self.0 -= 1;
- // true
- // }
- // }
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct NumberState {
- // add_number: AddNumber,
- // subtract_number: SubtractNumber,
- // }
- // impl AnyMapLike for NumberState {
- // fn get<T: Any>(&self) -> Option<&T> {
- // if TypeId::of::<AddNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &*(&self.add_number as *const AddNumber as *const T) })
- // } else if TypeId::of::<SubtractNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &*(&self.subtract_number as *const SubtractNumber as *const T) })
- // } else {
- // None
- // }
- // }
- // fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
- // if TypeId::of::<AddNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &mut *(&mut self.add_number as *mut AddNumber as *mut T) })
- // } else if TypeId::of::<SubtractNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &mut *(&mut self.subtract_number as *mut SubtractNumber as *mut T) })
- // } else {
- // None
- // }
- // }
- // }
- // impl State for NumberState {
- // fn create_passes() -> Box<[TypeErasedPass<Self>]> {
- // Box::new([
- // AddNumber::to_type_erased(),
- // SubtractNumber::to_type_erased(),
- // ])
- // }
- // }
- // let mut tree: RealDom<NumberState> = RealDom::new();
- // tree.dirty_nodes
- // .insert(TypeId::of::<SubtractNumber>(), NodeId(0));
- // tree.update_state(dirty_nodes, SendAnyMap::new());
- // assert_eq!(
- // tree.get(tree.root()).unwrap().state,
- // NumberState {
- // add_number: AddNumber(1),
- // subtract_number: SubtractNumber(-1)
- // }
- // );
- // }
- // #[test]
- // fn independant_node_pass() {
- // use crate::real_dom::RealDom;
- // use crate::tree::{Tree, TreeLike};
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct AddNumber(i32);
- // impl Pass for AddNumber {
- // type ChildDependencies = ();
- // type NodeDependencies = ();
- // type ParentDependencies = ();
- // type Ctx = ();
- // const MASK: NodeMask = NodeMask::new();
- // fn pass<'a>(
- // &mut self,
- // node_view: NodeView,
- // node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- // parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- // children: Option<
- // impl Iterator<Item = <Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- // >,
- // context: <Self::Ctx as Dependancy>::ElementBorrowed<'a>,
- // ) -> bool {
- // self.0 += 1;
- // true
- // }
- // }
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct SubtractNumber(i32);
- // impl Pass for SubtractNumber {
- // type ChildDependencies = ();
- // type NodeDependencies = ();
- // type ParentDependencies = ();
- // type Ctx = ();
- // const MASK: NodeMask = NodeMask::new();
- // fn pass<'a>(
- // &mut self,
- // node_view: NodeView,
- // node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- // parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- // children: Option<
- // impl Iterator<Item = <Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- // >,
- // context: <Self::Ctx as Dependancy>::ElementBorrowed<'a>,
- // ) -> bool {
- // self.0 -= 1;
- // true
- // }
- // }
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct NumberState {
- // add_number: AddNumber,
- // subtract_number: SubtractNumber,
- // }
- // impl AnyMapLike for NumberState {
- // fn get<T: Any>(&self) -> Option<&T> {
- // if TypeId::of::<AddNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &*(&self.add_number as *const AddNumber as *const T) })
- // } else if TypeId::of::<SubtractNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &*(&self.subtract_number as *const SubtractNumber as *const T) })
- // } else {
- // None
- // }
- // }
- // fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
- // if TypeId::of::<AddNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &mut *(&mut self.add_number as *mut AddNumber as *mut T) })
- // } else if TypeId::of::<SubtractNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &mut *(&mut self.subtract_number as *mut SubtractNumber as *mut T) })
- // } else {
- // None
- // }
- // }
- // }
- // impl State for NumberState {
- // fn create_passes() -> Box<[TypeErasedPass<Self>]> {
- // Box::new([
- // AddNumber::to_type_erased(),
- // SubtractNumber::to_type_erased(),
- // ])
- // }
- // }
- // let mut tree: RealDom<NumberState> = RealDom::new();
- // tree.dirty_nodes
- // .insert(TypeId::of::<SubtractNumber>(), NodeId(0));
- // tree.update_state(SendAnyMap::new());
- // assert_eq!(
- // tree.get(tree.root()).unwrap().state,
- // NumberState {
- // add_number: AddNumber(0),
- // subtract_number: SubtractNumber(-1)
- // }
- // );
- // }
- // #[test]
- // fn down_pass() {
- // use crate::real_dom::RealDom;
- // use crate::tree::{Tree, TreeLike};
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct AddNumber(i32);
- // impl Pass for AddNumber {
- // type ChildDependencies = ();
- // type NodeDependencies = ();
- // type ParentDependencies = (AddNumber,);
- // type Ctx = ();
- // const MASK: NodeMask = NodeMask::new();
- // fn pass<'a>(
- // &mut self,
- // node_view: NodeView,
- // node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
- // parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
- // children: Option<
- // impl Iterator<Item = <Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>,
- // >,
- // context: <Self::Ctx as Dependancy>::ElementBorrowed<'a>,
- // ) -> bool {
- // if let Some((parent,)) = parent {
- // *self.0 += *parent.0;
- // }
- // true
- // }
- // }
- // #[derive(Debug, Default, Clone, PartialEq)]
- // struct NumberState {
- // add_number: AddNumber,
- // }
- // impl AnyMapLike for NumberState {
- // fn get<T: Any>(&self) -> Option<&T> {
- // if TypeId::of::<AddNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &*(&self.add_number as *const AddNumber as *const T) })
- // } else {
- // None
- // }
- // }
- // fn get_mut<T: Any>(&mut self) -> Option<&mut T> {
- // if TypeId::of::<AddNumber>() == TypeId::of::<T>() {
- // Some(unsafe { &mut *(&mut self.add_number as *mut AddNumber as *mut T) })
- // } else {
- // None
- // }
- // }
- // }
- // impl State for NumberState {
- // fn create_passes() -> Box<[TypeErasedPass<Self>]> {
- // Box::new([AddNumber::to_type_erased()])
- // }
- // }
- // let mut tree: RealDom<NumberState> = RealDom::new();
- // let parent = tree.root();
- // let child1 = tree.create_node(1);
- // tree.add_child(parent, child1);
- // let grandchild1 = tree.create_node(1);
- // tree.add_child(child1, grandchild1);
- // let child2 = tree.create_node(1);
- // tree.add_child(parent, child2);
- // let grandchild2 = tree.create_node(1);
- // tree.add_child(child2, grandchild2);
- // tree.dirty_nodes
- // .insert(TypeId::of::<AddNumber>(), NodeId(0));
- // tree.update_state(SendAnyMap::new());
- // assert_eq!(tree.get(tree.root()).unwrap().state.add_number.0, 1);
- // assert_eq!(tree.get(child1).unwrap().state.add_number.0, 2);
- // assert_eq!(tree.get(grandchild1).unwrap().state.add_number.0, 3);
- // assert_eq!(tree.get(child2).unwrap().state.add_number.0, 2);
- // assert_eq!(tree.get(grandchild2).unwrap().state.add_number.0, 3);
- // }
- // #[test]
- // fn dependant_down_pass() {
- // use crate::tree::{Tree, TreeLike};
- // // 0
- // let mut tree = Tree::new(1);
- // let parent = tree.root();
- // // 1
- // let child1 = tree.create_node(1);
- // tree.add_child(parent, child1);
- // // 2
- // let grandchild1 = tree.create_node(1);
- // tree.add_child(child1, grandchild1);
- // // 3
- // let child2 = tree.create_node(1);
- // 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 DownwardPass<i32> for AddPass {
- // 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,
- // }
- // }
- // }
- // 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 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 subtract_pass = AnyPass::Downward(&SubtractPass);
- // let passes = vec![&add_pass, &subtract_pass];
- // let dirty_nodes: DirtyNodeStates = DirtyNodeStates::default();
- // dirty_nodes.insert(PassId(1), tree.root());
- // resolve_passes(&mut tree, dirty_nodes, passes, SendAnyMap::new());
- // // Tree before:
- // // 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()).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]
- // fn up_pass() {
- // use crate::tree::{Tree, TreeLike};
- // // Tree before:
- // // 0=\
- // // 0=\
- // // 1
- // // 0=\
- // // 1
- // // Tree after:
- // // 2=\
- // // 1=\
- // // 1
- // // 1=\
- // // 1
- // let mut tree = Tree::new(0);
- // let parent = tree.root();
- // 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;
- // impl Pass for AddPass {
- // 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()).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() {
- // use crate::tree::{Tree, TreeLike};
- // // 0
- // let mut tree = Tree::new(0);
- // let parent = tree.root();
- // // 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()).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);
- // }
|