passes.rs 15 KB

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