state.rs 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. use std::{
  2. cmp::Ordering,
  3. fmt::Debug,
  4. ops::{Add, AddAssign, Sub, SubAssign},
  5. };
  6. use anymap::AnyMap;
  7. use dioxus_core::VNode;
  8. use crate::node_ref::{NodeMask, NodeView};
  9. pub(crate) fn union_ordered_iter<T: Ord + Debug>(
  10. s_iter: impl Iterator<Item = T>,
  11. o_iter: impl Iterator<Item = T>,
  12. new_len_guess: usize,
  13. ) -> Vec<T> {
  14. let mut s_peekable = s_iter.peekable();
  15. let mut o_peekable = o_iter.peekable();
  16. let mut v = Vec::with_capacity(new_len_guess);
  17. while let Some(s_i) = s_peekable.peek() {
  18. while let Some(o_i) = o_peekable.peek() {
  19. match o_i.cmp(s_i) {
  20. Ordering::Greater => {
  21. break;
  22. }
  23. Ordering::Less => {
  24. v.push(o_peekable.next().unwrap());
  25. }
  26. Ordering::Equal => {
  27. o_peekable.next();
  28. break;
  29. }
  30. }
  31. }
  32. v.push(s_peekable.next().unwrap());
  33. }
  34. for o_i in o_peekable {
  35. v.push(o_i);
  36. }
  37. for w in v.windows(2) {
  38. debug_assert!(w[1] > w[0]);
  39. }
  40. v
  41. }
  42. /// This state is derived from children. For example a node's size could be derived from the size of children.
  43. /// Called when the current node's node properties are modified, a child's [ChildDepState] is modified or a child is removed.
  44. /// Called at most once per update.
  45. pub trait ChildDepState {
  46. /// The context is passed to the [ChildDepState::reduce] when it is pushed down.
  47. /// This is sometimes nessisary for lifetime purposes.
  48. type Ctx;
  49. /// This must be either a [ChildDepState] or [NodeDepState]
  50. type DepState;
  51. const NODE_MASK: NodeMask = NodeMask::NONE;
  52. fn reduce<'a>(
  53. &mut self,
  54. node: NodeView,
  55. children: impl Iterator<Item = &'a Self::DepState>,
  56. ctx: &Self::Ctx,
  57. ) -> bool
  58. where
  59. Self::DepState: 'a;
  60. }
  61. /// This state that is passed down to children. For example text properties (`<b>` `<i>` `<u>`) would be passed to children.
  62. /// Called when the current node's node properties are modified or a parrent's [ParentDepState] is modified.
  63. /// Called at most once per update.
  64. pub trait ParentDepState {
  65. /// The context is passed to the [ParentDepState::reduce] when it is pushed down.
  66. /// This is sometimes nessisary for lifetime purposes.
  67. type Ctx;
  68. /// This must be either a [ParentDepState] or [NodeDepState]
  69. type DepState;
  70. const NODE_MASK: NodeMask = NodeMask::NONE;
  71. fn reduce(&mut self, node: NodeView, parent: Option<&Self::DepState>, ctx: &Self::Ctx) -> bool;
  72. }
  73. /// This state that is upadated lazily. For example any propertys that do not effect other parts of the dom like bg-color.
  74. /// Called when the current node's node properties are modified or a sibling's [NodeDepState] is modified.
  75. /// Called at most once per update.
  76. pub trait NodeDepState {
  77. type Ctx;
  78. type DepState: NodeDepState;
  79. const NODE_MASK: NodeMask = NodeMask::NONE;
  80. fn reduce(&mut self, node: NodeView, sibling: &Self::DepState, ctx: &Self::Ctx) -> bool;
  81. }
  82. #[derive(Debug)]
  83. pub struct ChildStatesChanged {
  84. pub node_dep: Vec<MemberId>,
  85. pub child_dep: Vec<MemberId>,
  86. }
  87. #[derive(Debug)]
  88. pub struct ParentStatesChanged {
  89. pub node_dep: Vec<MemberId>,
  90. pub parent_dep: Vec<MemberId>,
  91. }
  92. #[derive(Debug)]
  93. pub struct NodeStatesChanged {
  94. pub node_dep: Vec<MemberId>,
  95. }
  96. pub trait State: Default + Clone {
  97. const SIZE: usize;
  98. fn update_node_dep_state<'a>(
  99. &'a mut self,
  100. ty: MemberId,
  101. node: &'a VNode<'a>,
  102. vdom: &'a dioxus_core::VirtualDom,
  103. ctx: &AnyMap,
  104. ) -> Option<NodeStatesChanged>;
  105. /// This must be a valid resolution order. (no nodes updated before a state they rely on)
  106. fn child_dep_types(&self, mask: &NodeMask) -> Vec<MemberId>;
  107. fn update_parent_dep_state<'a>(
  108. &'a mut self,
  109. ty: MemberId,
  110. node: &'a VNode<'a>,
  111. vdom: &'a dioxus_core::VirtualDom,
  112. parent: Option<&Self>,
  113. ctx: &AnyMap,
  114. ) -> Option<ParentStatesChanged>;
  115. /// This must be a valid resolution order. (no nodes updated before a state they rely on)
  116. fn parent_dep_types(&self, mask: &NodeMask) -> Vec<MemberId>;
  117. fn update_child_dep_state<'a>(
  118. &'a mut self,
  119. ty: MemberId,
  120. node: &'a VNode<'a>,
  121. vdom: &'a dioxus_core::VirtualDom,
  122. children: &Vec<&Self>,
  123. ctx: &AnyMap,
  124. ) -> Option<ChildStatesChanged>;
  125. /// This must be a valid resolution order. (no nodes updated before a state they rely on)
  126. fn node_dep_types(&self, mask: &NodeMask) -> Vec<MemberId>;
  127. }
  128. // Todo: once GATs land we can model multable dependencies
  129. impl ChildDepState for () {
  130. type Ctx = ();
  131. type DepState = ();
  132. fn reduce<'a>(
  133. &mut self,
  134. _: NodeView,
  135. _: impl Iterator<Item = &'a Self::DepState>,
  136. _: &Self::Ctx,
  137. ) -> bool
  138. where
  139. Self::DepState: 'a,
  140. {
  141. false
  142. }
  143. }
  144. impl ParentDepState for () {
  145. type Ctx = ();
  146. type DepState = ();
  147. fn reduce(&mut self, _: NodeView, _: Option<&Self::DepState>, _: &Self::Ctx) -> bool {
  148. false
  149. }
  150. }
  151. impl NodeDepState for () {
  152. type Ctx = ();
  153. type DepState = ();
  154. fn reduce(&mut self, _: NodeView, _sibling: &Self::DepState, _: &Self::Ctx) -> bool {
  155. false
  156. }
  157. }
  158. #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
  159. pub struct MemberId(pub usize);
  160. impl Sub<usize> for MemberId {
  161. type Output = MemberId;
  162. fn sub(self, rhs: usize) -> Self::Output {
  163. MemberId(self.0 - rhs)
  164. }
  165. }
  166. impl Add<usize> for MemberId {
  167. type Output = MemberId;
  168. fn add(self, rhs: usize) -> Self::Output {
  169. MemberId(self.0 + rhs)
  170. }
  171. }
  172. impl SubAssign<usize> for MemberId {
  173. fn sub_assign(&mut self, rhs: usize) {
  174. *self = *self - rhs;
  175. }
  176. }
  177. impl AddAssign<usize> for MemberId {
  178. fn add_assign(&mut self, rhs: usize) {
  179. *self = *self + rhs;
  180. }
  181. }