passes.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433
  1. use dioxus::prelude::*;
  2. use dioxus_native_core::node::NodeType;
  3. use dioxus_native_core::prelude::*;
  4. use rustc_hash::{FxHashMap, FxHashSet};
  5. use std::any::TypeId;
  6. use std::sync::{Arc, Mutex};
  7. fn create_blank_element() -> NodeType {
  8. NodeType::Element(ElementNode {
  9. tag: "div".to_owned(),
  10. namespace: None,
  11. attributes: FxHashMap::default(),
  12. listeners: FxHashSet::default(),
  13. })
  14. }
  15. #[test]
  16. fn node_pass() {
  17. #[derive(Debug, Default, Clone, PartialEq)]
  18. struct Number(i32);
  19. impl Pass for Number {
  20. type ChildDependencies = ();
  21. type NodeDependencies = ();
  22. type ParentDependencies = ();
  23. const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
  24. fn pass<'a>(
  25. &mut self,
  26. node_view: NodeView,
  27. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  28. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  29. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  30. context: &SendAnyMap,
  31. ) -> bool {
  32. self.0 += 1;
  33. true
  34. }
  35. fn create<'a>(
  36. node_view: NodeView<()>,
  37. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  38. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  39. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  40. context: &SendAnyMap,
  41. ) -> Self {
  42. let mut myself = Self::default();
  43. myself.pass(node_view, node, parent, children, context);
  44. myself
  45. }
  46. }
  47. let mut tree: RealDom = RealDom::new(Box::new([Number::to_type_erased()]));
  48. tree.update_state(SendAnyMap::new(), false);
  49. assert_eq!(tree.get(tree.root_id()).unwrap().get(), Some(&Number(1)));
  50. // mark the node as dirty
  51. tree.get_mut(tree.root_id()).unwrap().get_mut::<Number>();
  52. tree.update_state(SendAnyMap::new(), false);
  53. assert_eq!(tree.get(tree.root_id()).unwrap().get(), Some(&Number(2)));
  54. }
  55. #[test]
  56. fn dependant_node_pass() {
  57. #[derive(Debug, Default, Clone, PartialEq)]
  58. struct AddNumber(i32);
  59. impl Pass for AddNumber {
  60. type ChildDependencies = ();
  61. type NodeDependencies = (SubtractNumber,);
  62. type ParentDependencies = ();
  63. const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
  64. fn pass<'a>(
  65. &mut self,
  66. node_view: NodeView,
  67. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  68. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  69. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  70. context: &SendAnyMap,
  71. ) -> bool {
  72. self.0 += 1;
  73. true
  74. }
  75. fn create<'a>(
  76. node_view: NodeView<()>,
  77. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  78. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  79. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  80. context: &SendAnyMap,
  81. ) -> Self {
  82. let mut myself = Self::default();
  83. myself.pass(node_view, node, parent, children, context);
  84. myself
  85. }
  86. }
  87. #[derive(Debug, Default, Clone, PartialEq)]
  88. struct SubtractNumber(i32);
  89. impl Pass for SubtractNumber {
  90. type ChildDependencies = ();
  91. type NodeDependencies = ();
  92. type ParentDependencies = ();
  93. const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
  94. fn pass<'a>(
  95. &mut self,
  96. node_view: NodeView,
  97. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  98. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  99. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  100. context: &SendAnyMap,
  101. ) -> bool {
  102. self.0 -= 1;
  103. true
  104. }
  105. fn create<'a>(
  106. node_view: NodeView<()>,
  107. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  108. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  109. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  110. context: &SendAnyMap,
  111. ) -> Self {
  112. let mut myself = Self::default();
  113. myself.pass(node_view, node, parent, children, context);
  114. myself
  115. }
  116. }
  117. let mut tree: RealDom = RealDom::new(Box::new([
  118. AddNumber::to_type_erased(),
  119. SubtractNumber::to_type_erased(),
  120. ]));
  121. tree.update_state(SendAnyMap::new(), false);
  122. let root = tree.get(tree.root_id()).unwrap();
  123. assert_eq!(root.get(), Some(&AddNumber(1)));
  124. assert_eq!(root.get(), Some(&SubtractNumber(-1)));
  125. // mark the subtract state as dirty, it should update the add state
  126. tree.get_mut(tree.root_id())
  127. .unwrap()
  128. .get_mut::<SubtractNumber>();
  129. tree.update_state(SendAnyMap::new(), false);
  130. let root = tree.get(tree.root_id()).unwrap();
  131. assert_eq!(root.get(), Some(&AddNumber(2)));
  132. assert_eq!(root.get(), Some(&SubtractNumber(-2)));
  133. // mark the add state as dirty, it should ~not~ update the subtract state
  134. tree.get_mut(tree.root_id()).unwrap().get_mut::<AddNumber>();
  135. tree.update_state(SendAnyMap::new(), false);
  136. let root = tree.get(tree.root_id()).unwrap();
  137. assert_eq!(root.get(), Some(&AddNumber(3)));
  138. assert_eq!(root.get(), Some(&SubtractNumber(-2)));
  139. }
  140. #[test]
  141. fn independant_node_pass() {
  142. #[derive(Debug, Default, Clone, PartialEq)]
  143. struct AddNumber(i32);
  144. impl Pass for AddNumber {
  145. type ChildDependencies = ();
  146. type NodeDependencies = ();
  147. type ParentDependencies = ();
  148. const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
  149. fn pass<'a>(
  150. &mut self,
  151. node_view: NodeView,
  152. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  153. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  154. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  155. context: &SendAnyMap,
  156. ) -> bool {
  157. self.0 += 1;
  158. true
  159. }
  160. fn create<'a>(
  161. node_view: NodeView<()>,
  162. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  163. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  164. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  165. context: &SendAnyMap,
  166. ) -> Self {
  167. let mut myself = Self::default();
  168. myself.pass(node_view, node, parent, children, context);
  169. myself
  170. }
  171. }
  172. #[derive(Debug, Default, Clone, PartialEq)]
  173. struct SubtractNumber(i32);
  174. impl Pass for SubtractNumber {
  175. type ChildDependencies = ();
  176. type NodeDependencies = ();
  177. type ParentDependencies = ();
  178. const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
  179. fn pass<'a>(
  180. &mut self,
  181. node_view: NodeView,
  182. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  183. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  184. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  185. context: &SendAnyMap,
  186. ) -> bool {
  187. self.0 -= 1;
  188. true
  189. }
  190. fn create<'a>(
  191. node_view: NodeView<()>,
  192. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  193. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  194. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  195. context: &SendAnyMap,
  196. ) -> Self {
  197. let mut myself = Self::default();
  198. myself.pass(node_view, node, parent, children, context);
  199. myself
  200. }
  201. }
  202. let mut tree: RealDom = RealDom::new(Box::new([
  203. AddNumber::to_type_erased(),
  204. SubtractNumber::to_type_erased(),
  205. ]));
  206. tree.update_state(SendAnyMap::new(), false);
  207. let root = tree.get(tree.root_id()).unwrap();
  208. assert_eq!(root.get(), Some(&AddNumber(1)));
  209. assert_eq!(root.get(), Some(&SubtractNumber(-1)));
  210. // mark the subtract state as dirty, it should ~not~ update the add state
  211. tree.get_mut(tree.root_id())
  212. .unwrap()
  213. .get_mut::<SubtractNumber>();
  214. tree.update_state(SendAnyMap::new(), false);
  215. let root = tree.get(tree.root_id()).unwrap();
  216. assert_eq!(root.get(), Some(&AddNumber(1)));
  217. assert_eq!(root.get(), Some(&SubtractNumber(-2)));
  218. // mark the add state as dirty, it should ~not~ update the subtract state
  219. tree.get_mut(tree.root_id()).unwrap().get_mut::<AddNumber>();
  220. tree.update_state(SendAnyMap::new(), false);
  221. let root = tree.get(tree.root_id()).unwrap();
  222. assert_eq!(root.get(), Some(&AddNumber(2)));
  223. assert_eq!(root.get(), Some(&SubtractNumber(-2)));
  224. }
  225. #[test]
  226. fn down_pass() {
  227. #[derive(Debug, Clone, PartialEq)]
  228. struct AddNumber(i32);
  229. impl Default for AddNumber {
  230. fn default() -> Self {
  231. Self(1)
  232. }
  233. }
  234. impl Pass for AddNumber {
  235. type ChildDependencies = ();
  236. type NodeDependencies = ();
  237. type ParentDependencies = (AddNumber,);
  238. const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
  239. fn pass<'a>(
  240. &mut self,
  241. node_view: NodeView,
  242. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  243. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  244. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  245. context: &SendAnyMap,
  246. ) -> bool {
  247. dbg!(parent);
  248. dbg!(node_view);
  249. if let Some((parent,)) = parent {
  250. self.0 += parent.0;
  251. }
  252. true
  253. }
  254. fn create<'a>(
  255. node_view: NodeView<()>,
  256. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  257. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  258. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  259. context: &SendAnyMap,
  260. ) -> Self {
  261. let mut myself = Self::default();
  262. myself.pass(node_view, node, parent, children, context);
  263. myself
  264. }
  265. }
  266. let mut tree: RealDom = RealDom::new(Box::new([AddNumber::to_type_erased()]));
  267. let mut grandchild1 = tree.create_node(create_blank_element(), true);
  268. let grandchild1 = grandchild1.id();
  269. let mut child1 = tree.create_node(create_blank_element(), true);
  270. child1.add_child(grandchild1);
  271. let child1 = child1.id();
  272. let mut grandchild2 = tree.create_node(create_blank_element(), true);
  273. let grandchild2 = grandchild2.id();
  274. let mut child2 = tree.create_node(create_blank_element(), true);
  275. child2.add_child(grandchild2);
  276. let child2 = child2.id();
  277. let mut parent = tree.get_mut(tree.root_id()).unwrap();
  278. parent.add_child(child1);
  279. parent.add_child(child2);
  280. tree.update_state(SendAnyMap::new(), false);
  281. let root = tree.get(tree.root_id()).unwrap();
  282. dbg!(root.id());
  283. assert_eq!(root.get(), Some(&AddNumber(1)));
  284. let child1 = tree.get(child1).unwrap();
  285. dbg!(child1.id());
  286. dbg!(child1.parent().unwrap().get::<AddNumber>());
  287. assert_eq!(child1.get(), Some(&AddNumber(2)));
  288. let grandchild1 = tree.get(grandchild1).unwrap();
  289. assert_eq!(grandchild1.get(), Some(&AddNumber(3)));
  290. let child2 = tree.get(child2).unwrap();
  291. assert_eq!(child2.get(), Some(&AddNumber(2)));
  292. let grandchild2 = tree.get(grandchild2).unwrap();
  293. assert_eq!(grandchild2.get(), Some(&AddNumber(3)));
  294. }
  295. #[test]
  296. fn up_pass() {
  297. // Tree before:
  298. // 1=\
  299. // 1=\
  300. // 1
  301. // 1=\
  302. // 1
  303. // Tree after:
  304. // 4=\
  305. // 2=\
  306. // 1
  307. // 2=\
  308. // 1
  309. #[derive(Debug, Clone, PartialEq)]
  310. struct AddNumber(i32);
  311. impl Pass for AddNumber {
  312. type ChildDependencies = (AddNumber,);
  313. type NodeDependencies = ();
  314. type ParentDependencies = ();
  315. const NODE_MASK: NodeMaskBuilder<'static> = NodeMaskBuilder::new();
  316. fn pass<'a>(
  317. &mut self,
  318. node_view: NodeView,
  319. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  320. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  321. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  322. context: &SendAnyMap,
  323. ) -> bool {
  324. if let Some(children) = children {
  325. self.0 += children.iter().map(|(i,)| i.0).sum::<i32>();
  326. }
  327. true
  328. }
  329. fn create<'a>(
  330. node_view: NodeView<()>,
  331. node: <Self::NodeDependencies as Dependancy>::ElementBorrowed<'a>,
  332. parent: Option<<Self::ParentDependencies as Dependancy>::ElementBorrowed<'a>>,
  333. children: Option<Vec<<Self::ChildDependencies as Dependancy>::ElementBorrowed<'a>>>,
  334. context: &SendAnyMap,
  335. ) -> Self {
  336. let mut myself = Self(1);
  337. myself.pass(node_view, node, parent, children, context);
  338. myself
  339. }
  340. }
  341. let mut tree: RealDom = RealDom::new(Box::new([AddNumber::to_type_erased()]));
  342. let mut grandchild1 = tree.create_node(create_blank_element(), true);
  343. let grandchild1 = grandchild1.id();
  344. let mut child1 = tree.create_node(create_blank_element(), true);
  345. child1.add_child(grandchild1);
  346. let child1 = child1.id();
  347. let mut grandchild2 = tree.create_node(create_blank_element(), true);
  348. let grandchild2 = grandchild2.id();
  349. let mut child2 = tree.create_node(create_blank_element(), true);
  350. child2.add_child(grandchild2);
  351. let child2 = child2.id();
  352. let mut parent = tree.get_mut(tree.root_id()).unwrap();
  353. parent.add_child(child1);
  354. parent.add_child(child2);
  355. tree.update_state(SendAnyMap::new(), false);
  356. let root = tree.get(tree.root_id()).unwrap();
  357. assert_eq!(root.get(), Some(&AddNumber(5)));
  358. let child1 = tree.get(child1).unwrap();
  359. assert_eq!(child1.get(), Some(&AddNumber(2)));
  360. let grandchild1 = tree.get(grandchild1).unwrap();
  361. assert_eq!(grandchild1.get(), Some(&AddNumber(1)));
  362. let child2 = tree.get(child2).unwrap();
  363. assert_eq!(child2.get(), Some(&AddNumber(2)));
  364. let grandchild2 = tree.get(grandchild2).unwrap();
  365. assert_eq!(grandchild2.get(), Some(&AddNumber(1)));
  366. }