1use std::any::{type_name, Any, TypeId};
11use std::cell::{Cell, RefCell};
12use std::fmt;
13use std::hash::{Hash, Hasher};
14use std::ops::{BitOr, BitOrAssign};
15use std::rc::Rc;
16
17use cranpose_core::hash::default;
18use rustc_hash::FxHashMap;
19
20pub use cranpose_ui_graphics::DrawScope;
21pub use cranpose_ui_graphics::Size;
22pub use cranpose_ui_layout::{Constraints, Measurable};
23
24use crate::nodes::input::types::PointerEvent;
25#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
30pub enum InvalidationKind {
31 Layout,
32 Draw,
33 PointerInput,
34 Semantics,
35 Focus,
36}
37
38pub trait ModifierNodeContext {
40 fn invalidate(&mut self, _kind: InvalidationKind) {}
42
43 fn request_update(&mut self) {}
46
47 fn node_id(&self) -> Option<cranpose_core::NodeId> {
50 None
51 }
52
53 fn push_active_capabilities(&mut self, _capabilities: NodeCapabilities) {}
55
56 fn pop_active_capabilities(&mut self) {}
58}
59
60#[derive(Default, Debug, Clone)]
69pub struct BasicModifierNodeContext {
70 invalidations: Vec<ModifierInvalidation>,
71 update_requested: bool,
72 active_capabilities: Vec<NodeCapabilities>,
73 node_id: Option<cranpose_core::NodeId>,
74}
75
76impl BasicModifierNodeContext {
77 pub fn new() -> Self {
79 Self::default()
80 }
81
82 pub fn invalidations(&self) -> &[ModifierInvalidation] {
86 &self.invalidations
87 }
88
89 pub fn clear_invalidations(&mut self) {
91 self.invalidations.clear();
92 }
93
94 pub fn take_invalidations(&mut self) -> Vec<ModifierInvalidation> {
96 std::mem::take(&mut self.invalidations)
97 }
98
99 pub fn update_requested(&self) -> bool {
102 self.update_requested
103 }
104
105 pub fn take_update_requested(&mut self) -> bool {
107 std::mem::take(&mut self.update_requested)
108 }
109
110 pub fn set_node_id(&mut self, id: Option<cranpose_core::NodeId>) {
112 self.node_id = id;
113 }
114
115 fn push_invalidation(&mut self, kind: InvalidationKind) {
116 let mut capabilities = self.current_capabilities();
117 capabilities.insert(NodeCapabilities::for_invalidation(kind));
118 if let Some(existing) = self
119 .invalidations
120 .iter_mut()
121 .find(|entry| entry.kind() == kind)
122 {
123 let updated = existing.capabilities() | capabilities;
124 *existing = ModifierInvalidation::new(kind, updated);
125 } else {
126 self.invalidations
127 .push(ModifierInvalidation::new(kind, capabilities));
128 }
129 }
130
131 fn current_capabilities(&self) -> NodeCapabilities {
132 self.active_capabilities
133 .last()
134 .copied()
135 .unwrap_or_else(NodeCapabilities::empty)
136 }
137}
138
139impl ModifierNodeContext for BasicModifierNodeContext {
140 fn invalidate(&mut self, kind: InvalidationKind) {
141 self.push_invalidation(kind);
142 }
143
144 fn request_update(&mut self) {
145 self.update_requested = true;
146 }
147
148 fn push_active_capabilities(&mut self, capabilities: NodeCapabilities) {
149 self.active_capabilities.push(capabilities);
150 }
151
152 fn pop_active_capabilities(&mut self) {
153 self.active_capabilities.pop();
154 }
155
156 fn node_id(&self) -> Option<cranpose_core::NodeId> {
157 self.node_id
158 }
159}
160
161const MAX_DELEGATE_DEPTH: usize = 3;
165
166#[derive(Copy, Clone, Debug, PartialEq, Eq)]
167pub(crate) struct NodePath {
168 entry: usize,
169 delegate_buf: [u8; MAX_DELEGATE_DEPTH],
170 delegate_len: u8,
171}
172
173impl NodePath {
174 #[inline]
175 fn root(entry: usize) -> Self {
176 Self {
177 entry,
178 delegate_buf: [0; MAX_DELEGATE_DEPTH],
179 delegate_len: 0,
180 }
181 }
182
183 #[inline]
184 fn from_slice(entry: usize, path: &[usize]) -> Self {
185 debug_assert!(
186 path.len() <= MAX_DELEGATE_DEPTH,
187 "delegate depth {} exceeds MAX_DELEGATE_DEPTH {}",
188 path.len(),
189 MAX_DELEGATE_DEPTH
190 );
191 debug_assert!(
192 path.iter().all(|&i| i <= u8::MAX as usize),
193 "delegate index exceeds u8 range"
194 );
195 let mut delegate_buf = [0u8; MAX_DELEGATE_DEPTH];
196 for (i, &v) in path.iter().enumerate().take(MAX_DELEGATE_DEPTH) {
197 delegate_buf[i] = v as u8;
198 }
199 Self {
200 entry,
201 delegate_buf,
202 delegate_len: path.len().min(MAX_DELEGATE_DEPTH) as u8,
203 }
204 }
205
206 #[inline]
207 fn entry(&self) -> usize {
208 self.entry
209 }
210
211 #[inline]
212 fn delegates(&self) -> &[u8] {
213 &self.delegate_buf[..self.delegate_len as usize]
214 }
215}
216
217#[derive(Copy, Clone, Debug, PartialEq, Eq)]
218pub(crate) enum NodeLink {
219 Head,
220 Tail,
221 Entry(NodePath),
222}
223
224#[derive(Debug)]
230pub struct NodeState {
231 aggregate_child_capabilities: Cell<NodeCapabilities>,
232 capabilities: Cell<NodeCapabilities>,
233 parent: RefCell<Option<NodeLink>>,
234 child: RefCell<Option<NodeLink>>,
235 attached: Cell<bool>,
236 is_sentinel: bool,
237}
238
239impl Default for NodeState {
240 fn default() -> Self {
241 Self::new()
242 }
243}
244
245impl NodeState {
246 pub const fn new() -> Self {
247 Self {
248 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
249 capabilities: Cell::new(NodeCapabilities::empty()),
250 parent: RefCell::new(None),
251 child: RefCell::new(None),
252 attached: Cell::new(false),
253 is_sentinel: false,
254 }
255 }
256
257 pub const fn sentinel() -> Self {
258 Self {
259 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
260 capabilities: Cell::new(NodeCapabilities::empty()),
261 parent: RefCell::new(None),
262 child: RefCell::new(None),
263 attached: Cell::new(true),
264 is_sentinel: true,
265 }
266 }
267
268 pub fn set_capabilities(&self, capabilities: NodeCapabilities) {
269 self.capabilities.set(capabilities);
270 }
271
272 #[inline]
273 pub fn capabilities(&self) -> NodeCapabilities {
274 self.capabilities.get()
275 }
276
277 pub fn set_aggregate_child_capabilities(&self, capabilities: NodeCapabilities) {
278 self.aggregate_child_capabilities.set(capabilities);
279 }
280
281 #[inline]
282 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
283 self.aggregate_child_capabilities.get()
284 }
285
286 pub(crate) fn set_parent_link(&self, parent: Option<NodeLink>) {
287 *self.parent.borrow_mut() = parent;
288 }
289
290 #[inline]
291 pub(crate) fn parent_link(&self) -> Option<NodeLink> {
292 *self.parent.borrow()
293 }
294
295 pub(crate) fn set_child_link(&self, child: Option<NodeLink>) {
296 *self.child.borrow_mut() = child;
297 }
298
299 #[inline]
300 pub(crate) fn child_link(&self) -> Option<NodeLink> {
301 *self.child.borrow()
302 }
303
304 pub fn set_attached(&self, attached: bool) {
305 self.attached.set(attached);
306 }
307
308 pub fn is_attached(&self) -> bool {
309 self.attached.get()
310 }
311
312 pub fn is_sentinel(&self) -> bool {
313 self.is_sentinel
314 }
315}
316
317pub trait DelegatableNode {
319 fn node_state(&self) -> &NodeState;
320 fn aggregate_child_capabilities(&self) -> NodeCapabilities {
321 self.node_state().aggregate_child_capabilities()
322 }
323}
324
325pub trait ModifierNode: Any + DelegatableNode {
383 fn on_attach(&mut self, _context: &mut dyn ModifierNodeContext) {}
384
385 fn on_detach(&mut self) {}
386
387 fn on_reset(&mut self) {}
388
389 fn as_draw_node(&self) -> Option<&dyn DrawModifierNode> {
391 None
392 }
393
394 fn as_draw_node_mut(&mut self) -> Option<&mut dyn DrawModifierNode> {
396 None
397 }
398
399 fn as_pointer_input_node(&self) -> Option<&dyn PointerInputNode> {
401 None
402 }
403
404 fn as_pointer_input_node_mut(&mut self) -> Option<&mut dyn PointerInputNode> {
406 None
407 }
408
409 fn as_semantics_node(&self) -> Option<&dyn SemanticsNode> {
411 None
412 }
413
414 fn as_semantics_node_mut(&mut self) -> Option<&mut dyn SemanticsNode> {
416 None
417 }
418
419 fn as_focus_node(&self) -> Option<&dyn FocusNode> {
421 None
422 }
423
424 fn as_focus_node_mut(&mut self) -> Option<&mut dyn FocusNode> {
426 None
427 }
428
429 fn as_layout_node(&self) -> Option<&dyn LayoutModifierNode> {
431 None
432 }
433
434 fn as_layout_node_mut(&mut self) -> Option<&mut dyn LayoutModifierNode> {
436 None
437 }
438
439 fn for_each_delegate<'b>(&'b self, _visitor: &mut dyn FnMut(&'b dyn ModifierNode)) {}
441
442 fn for_each_delegate_mut<'b>(&'b mut self, _visitor: &mut dyn FnMut(&'b mut dyn ModifierNode)) {
444 }
445}
446
447pub trait LayoutModifierNode: ModifierNode {
453 fn measure(
475 &self,
476 _context: &mut dyn ModifierNodeContext,
477 measurable: &dyn Measurable,
478 constraints: Constraints,
479 ) -> cranpose_ui_layout::LayoutModifierMeasureResult {
480 let placeable = measurable.measure(constraints);
482 cranpose_ui_layout::LayoutModifierMeasureResult::with_size(Size {
483 width: placeable.width(),
484 height: placeable.height(),
485 })
486 }
487
488 fn min_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
490 0.0
491 }
492
493 fn max_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
495 0.0
496 }
497
498 fn min_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
500 0.0
501 }
502
503 fn max_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
505 0.0
506 }
507
508 fn create_measurement_proxy(
532 &self,
533 ) -> Option<Box<dyn crate::measurement_proxy::MeasurementProxy>> {
534 None
535 }
536}
537
538pub trait DrawModifierNode: ModifierNode {
546 fn draw(&self, _draw_scope: &mut dyn DrawScope) {
555 }
557
558 fn create_draw_closure(
569 &self,
570 ) -> Option<Rc<dyn Fn(Size) -> Vec<cranpose_ui_graphics::DrawPrimitive>>> {
571 None
572 }
573}
574
575pub trait PointerInputNode: ModifierNode {
581 fn on_pointer_event(
584 &mut self,
585 _context: &mut dyn ModifierNodeContext,
586 _event: &PointerEvent,
587 ) -> bool {
588 false
589 }
590
591 fn hit_test(&self, _x: f32, _y: f32) -> bool {
594 true
595 }
596
597 fn pointer_input_handler(&self) -> Option<Rc<dyn Fn(PointerEvent)>> {
599 None
600 }
601}
602
603pub trait SemanticsNode: ModifierNode {
609 fn merge_semantics(&self, _config: &mut SemanticsConfiguration) {
611 }
613}
614
615#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
620pub enum FocusState {
621 Active,
623 ActiveParent,
625 Captured,
629 #[default]
632 Inactive,
633}
634
635impl FocusState {
636 pub fn is_focused(self) -> bool {
638 matches!(self, FocusState::Active | FocusState::Captured)
639 }
640
641 pub fn has_focus(self) -> bool {
643 matches!(
644 self,
645 FocusState::Active | FocusState::ActiveParent | FocusState::Captured
646 )
647 }
648
649 pub fn is_captured(self) -> bool {
651 matches!(self, FocusState::Captured)
652 }
653}
654
655pub trait FocusNode: ModifierNode {
660 fn focus_state(&self) -> FocusState;
662
663 fn on_focus_changed(&mut self, _context: &mut dyn ModifierNodeContext, _state: FocusState) {
665 }
667}
668
669#[derive(Clone, Debug, Default, PartialEq)]
671pub struct SemanticsConfiguration {
672 pub content_description: Option<String>,
673 pub is_button: bool,
674 pub is_clickable: bool,
675}
676
677impl SemanticsConfiguration {
678 pub fn merge(&mut self, other: &SemanticsConfiguration) {
679 if let Some(description) = &other.content_description {
680 self.content_description = Some(description.clone());
681 }
682 self.is_button |= other.is_button;
683 self.is_clickable |= other.is_clickable;
684 }
685}
686
687impl fmt::Debug for dyn ModifierNode {
688 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
689 f.debug_struct("ModifierNode").finish_non_exhaustive()
690 }
691}
692
693impl dyn ModifierNode {
694 pub fn as_any(&self) -> &dyn Any {
695 self
696 }
697
698 pub fn as_any_mut(&mut self) -> &mut dyn Any {
699 self
700 }
701}
702
703pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
706 type Node: ModifierNode;
707
708 fn create(&self) -> Self::Node;
710
711 fn update(&self, node: &mut Self::Node);
713
714 fn key(&self) -> Option<u64> {
716 None
717 }
718
719 fn inspector_name(&self) -> &'static str {
721 type_name::<Self>()
722 }
723
724 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
726
727 fn capabilities(&self) -> NodeCapabilities {
730 NodeCapabilities::default()
731 }
732
733 fn always_update(&self) -> bool {
739 false
740 }
741}
742
743pub trait ModifierElement: ModifierNodeElement {}
746
747impl<T> ModifierElement for T where T: ModifierNodeElement {}
748
749#[derive(Clone, Copy, PartialEq, Eq, Hash)]
751pub struct NodeCapabilities(u32);
752
753impl NodeCapabilities {
754 pub const NONE: Self = Self(0);
756 pub const LAYOUT: Self = Self(1 << 0);
758 pub const DRAW: Self = Self(1 << 1);
760 pub const POINTER_INPUT: Self = Self(1 << 2);
762 pub const SEMANTICS: Self = Self(1 << 3);
764 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
766 pub const FOCUS: Self = Self(1 << 5);
768
769 pub const fn empty() -> Self {
771 Self::NONE
772 }
773
774 pub const fn contains(self, other: Self) -> bool {
776 (self.0 & other.0) == other.0
777 }
778
779 pub const fn intersects(self, other: Self) -> bool {
781 (self.0 & other.0) != 0
782 }
783
784 pub fn insert(&mut self, other: Self) {
786 self.0 |= other.0;
787 }
788
789 pub const fn bits(self) -> u32 {
791 self.0
792 }
793
794 pub const fn is_empty(self) -> bool {
796 self.0 == 0
797 }
798
799 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
801 match kind {
802 InvalidationKind::Layout => Self::LAYOUT,
803 InvalidationKind::Draw => Self::DRAW,
804 InvalidationKind::PointerInput => Self::POINTER_INPUT,
805 InvalidationKind::Semantics => Self::SEMANTICS,
806 InvalidationKind::Focus => Self::FOCUS,
807 }
808 }
809}
810
811impl Default for NodeCapabilities {
812 fn default() -> Self {
813 Self::NONE
814 }
815}
816
817impl fmt::Debug for NodeCapabilities {
818 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
819 f.debug_struct("NodeCapabilities")
820 .field("layout", &self.contains(Self::LAYOUT))
821 .field("draw", &self.contains(Self::DRAW))
822 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
823 .field("semantics", &self.contains(Self::SEMANTICS))
824 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
825 .field("focus", &self.contains(Self::FOCUS))
826 .finish()
827 }
828}
829
830impl BitOr for NodeCapabilities {
831 type Output = Self;
832
833 fn bitor(self, rhs: Self) -> Self::Output {
834 Self(self.0 | rhs.0)
835 }
836}
837
838impl BitOrAssign for NodeCapabilities {
839 fn bitor_assign(&mut self, rhs: Self) {
840 self.0 |= rhs.0;
841 }
842}
843
844#[derive(Clone, Copy, Debug, PartialEq, Eq)]
846pub struct ModifierInvalidation {
847 kind: InvalidationKind,
848 capabilities: NodeCapabilities,
849}
850
851impl ModifierInvalidation {
852 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
854 Self { kind, capabilities }
855 }
856
857 pub const fn kind(self) -> InvalidationKind {
859 self.kind
860 }
861
862 pub const fn capabilities(self) -> NodeCapabilities {
864 self.capabilities
865 }
866}
867
868pub trait AnyModifierElement: fmt::Debug {
870 fn node_type(&self) -> TypeId;
871
872 fn element_type(&self) -> TypeId;
873
874 fn create_node(&self) -> Box<dyn ModifierNode>;
875
876 fn update_node(&self, node: &mut dyn ModifierNode);
877
878 fn key(&self) -> Option<u64>;
879
880 fn capabilities(&self) -> NodeCapabilities {
881 NodeCapabilities::default()
882 }
883
884 fn hash_code(&self) -> u64;
885
886 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
887
888 fn inspector_name(&self) -> &'static str;
889
890 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
891
892 fn requires_update(&self) -> bool;
893
894 fn as_any(&self) -> &dyn Any;
895}
896
897struct TypedModifierElement<E: ModifierNodeElement> {
898 element: E,
899 cached_hash: u64,
900}
901
902impl<E: ModifierNodeElement> TypedModifierElement<E> {
903 fn new(element: E) -> Self {
904 let mut hasher = default::new();
905 element.hash(&mut hasher);
906 Self {
907 element,
908 cached_hash: hasher.finish(),
909 }
910 }
911}
912
913impl<E> fmt::Debug for TypedModifierElement<E>
914where
915 E: ModifierNodeElement,
916{
917 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
918 f.debug_struct("TypedModifierElement")
919 .field("type", &type_name::<E>())
920 .finish()
921 }
922}
923
924impl<E> AnyModifierElement for TypedModifierElement<E>
925where
926 E: ModifierNodeElement,
927{
928 fn node_type(&self) -> TypeId {
929 TypeId::of::<E::Node>()
930 }
931
932 fn element_type(&self) -> TypeId {
933 TypeId::of::<E>()
934 }
935
936 fn create_node(&self) -> Box<dyn ModifierNode> {
937 Box::new(self.element.create())
938 }
939
940 fn update_node(&self, node: &mut dyn ModifierNode) {
941 let typed = node
942 .as_any_mut()
943 .downcast_mut::<E::Node>()
944 .expect("modifier node type mismatch");
945 self.element.update(typed);
946 }
947
948 fn key(&self) -> Option<u64> {
949 self.element.key()
950 }
951
952 fn capabilities(&self) -> NodeCapabilities {
953 self.element.capabilities()
954 }
955
956 fn hash_code(&self) -> u64 {
957 self.cached_hash
958 }
959
960 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
961 other
962 .as_any()
963 .downcast_ref::<Self>()
964 .map(|typed| typed.element == self.element)
965 .unwrap_or(false)
966 }
967
968 fn inspector_name(&self) -> &'static str {
969 self.element.inspector_name()
970 }
971
972 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
973 self.element.inspector_properties(visitor);
974 }
975
976 fn requires_update(&self) -> bool {
977 self.element.always_update()
978 }
979
980 fn as_any(&self) -> &dyn Any {
981 self
982 }
983}
984
985pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
988 Rc::new(TypedModifierElement::new(element))
989}
990
991pub type DynModifierElement = Rc<dyn AnyModifierElement>;
993
994#[derive(Clone, Copy, Debug, PartialEq, Eq)]
995enum TraversalDirection {
996 Forward,
997 Backward,
998}
999
1000pub struct ModifierChainIter<'a> {
1005 chain: &'a ModifierNodeChain,
1006 cursor: usize,
1009 remaining: usize,
1011 direction: TraversalDirection,
1012}
1013
1014impl<'a> ModifierChainIter<'a> {
1015 fn forward(chain: &'a ModifierNodeChain) -> Self {
1016 Self {
1017 chain,
1018 cursor: 0,
1019 remaining: chain.ordered_nodes.len(),
1020 direction: TraversalDirection::Forward,
1021 }
1022 }
1023
1024 fn backward(chain: &'a ModifierNodeChain) -> Self {
1025 let len = chain.ordered_nodes.len();
1026 Self {
1027 chain,
1028 cursor: len.wrapping_sub(1),
1029 remaining: len,
1030 direction: TraversalDirection::Backward,
1031 }
1032 }
1033}
1034
1035impl<'a> Iterator for ModifierChainIter<'a> {
1036 type Item = ModifierChainNodeRef<'a>;
1037
1038 #[inline]
1039 fn next(&mut self) -> Option<Self::Item> {
1040 if self.remaining == 0 {
1041 return None;
1042 }
1043 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
1044 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
1045 self.remaining -= 1;
1046 match self.direction {
1047 TraversalDirection::Forward => self.cursor += 1,
1048 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
1049 }
1050 Some(node_ref)
1051 }
1052
1053 #[inline]
1054 fn size_hint(&self) -> (usize, Option<usize>) {
1055 (self.remaining, Some(self.remaining))
1056 }
1057}
1058
1059impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
1060impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
1061
1062#[derive(Debug)]
1063struct ModifierNodeEntry {
1064 element_type: TypeId,
1065 key: Option<u64>,
1066 hash_code: u64,
1067 element: DynModifierElement,
1068 node: Rc<RefCell<Box<dyn ModifierNode>>>,
1069 capabilities: NodeCapabilities,
1070}
1071
1072impl ModifierNodeEntry {
1073 fn new(
1074 element_type: TypeId,
1075 key: Option<u64>,
1076 element: DynModifierElement,
1077 node: Box<dyn ModifierNode>,
1078 hash_code: u64,
1079 capabilities: NodeCapabilities,
1080 ) -> Self {
1081 let node_rc = Rc::new(RefCell::new(node));
1083 let entry = Self {
1084 element_type,
1085 key,
1086 hash_code,
1087 element,
1088 node: Rc::clone(&node_rc),
1089 capabilities,
1090 };
1091 entry
1092 .node
1093 .borrow()
1094 .node_state()
1095 .set_capabilities(entry.capabilities);
1096 entry
1097 }
1098}
1099
1100fn visit_node_tree_mut(
1101 node: &mut dyn ModifierNode,
1102 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
1103) {
1104 visitor(node);
1105 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
1106}
1107
1108fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
1109 let mut current = 0usize;
1110 let mut result: Option<&dyn ModifierNode> = None;
1111 node.for_each_delegate(&mut |child| {
1112 if result.is_none() && current == target {
1113 result = Some(child);
1114 }
1115 current += 1;
1116 });
1117 result
1118}
1119
1120fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
1121 let mut current = 0usize;
1122 let mut result: Option<&mut dyn ModifierNode> = None;
1123 node.for_each_delegate_mut(&mut |child| {
1124 if result.is_none() && current == target {
1125 result = Some(child);
1126 }
1127 current += 1;
1128 });
1129 result
1130}
1131
1132fn with_node_context<F, R>(
1133 node: &mut dyn ModifierNode,
1134 context: &mut dyn ModifierNodeContext,
1135 f: F,
1136) -> R
1137where
1138 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
1139{
1140 context.push_active_capabilities(node.node_state().capabilities());
1141 let result = f(node, context);
1142 context.pop_active_capabilities();
1143 result
1144}
1145
1146fn request_auto_invalidations(
1147 context: &mut dyn ModifierNodeContext,
1148 capabilities: NodeCapabilities,
1149) {
1150 if capabilities.is_empty() {
1151 return;
1152 }
1153
1154 context.push_active_capabilities(capabilities);
1155
1156 if capabilities.contains(NodeCapabilities::LAYOUT) {
1157 context.invalidate(InvalidationKind::Layout);
1158 }
1159 if capabilities.contains(NodeCapabilities::DRAW) {
1160 context.invalidate(InvalidationKind::Draw);
1161 }
1162 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
1163 context.invalidate(InvalidationKind::PointerInput);
1164 }
1165 if capabilities.contains(NodeCapabilities::SEMANTICS) {
1166 context.invalidate(InvalidationKind::Semantics);
1167 }
1168 if capabilities.contains(NodeCapabilities::FOCUS) {
1169 context.invalidate(InvalidationKind::Focus);
1170 }
1171
1172 context.pop_active_capabilities();
1173}
1174
1175fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
1183 visit_node_tree_mut(node, &mut |n| {
1184 if !n.node_state().is_attached() {
1185 n.node_state().set_attached(true);
1186 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
1187 }
1188 });
1189}
1190
1191fn reset_node_tree(node: &mut dyn ModifierNode) {
1192 visit_node_tree_mut(node, &mut |n| n.on_reset());
1193}
1194
1195fn detach_node_tree(node: &mut dyn ModifierNode) {
1196 visit_node_tree_mut(node, &mut |n| {
1197 if n.node_state().is_attached() {
1198 n.on_detach();
1199 n.node_state().set_attached(false);
1200 }
1201 n.node_state().set_parent_link(None);
1202 n.node_state().set_child_link(None);
1203 n.node_state()
1204 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1205 });
1206}
1207
1208pub struct ModifierNodeChain {
1215 entries: Vec<ModifierNodeEntry>,
1216 aggregated_capabilities: NodeCapabilities,
1217 head_aggregate_child_capabilities: NodeCapabilities,
1218 head_sentinel: Box<SentinelNode>,
1219 tail_sentinel: Box<SentinelNode>,
1220 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
1222 scratch_old_used: Vec<bool>,
1224 scratch_match_order: Vec<Option<usize>>,
1225 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
1226 scratch_elements: Vec<DynModifierElement>,
1227}
1228
1229struct SentinelNode {
1230 state: NodeState,
1231}
1232
1233impl SentinelNode {
1234 fn new() -> Self {
1235 Self {
1236 state: NodeState::sentinel(),
1237 }
1238 }
1239}
1240
1241impl DelegatableNode for SentinelNode {
1242 fn node_state(&self) -> &NodeState {
1243 &self.state
1244 }
1245}
1246
1247impl ModifierNode for SentinelNode {}
1248
1249#[derive(Clone)]
1250pub struct ModifierChainNodeRef<'a> {
1251 chain: &'a ModifierNodeChain,
1252 link: NodeLink,
1253 cached_capabilities: Option<NodeCapabilities>,
1255 cached_aggregate_child: Option<NodeCapabilities>,
1257}
1258
1259impl Default for ModifierNodeChain {
1260 fn default() -> Self {
1261 Self::new()
1262 }
1263}
1264
1265struct EntryIndex {
1271 keyed: FxHashMap<(TypeId, u64), Vec<usize>>,
1273 hashed: FxHashMap<(TypeId, u64), Vec<usize>>,
1275 typed: FxHashMap<TypeId, Vec<usize>>,
1277}
1278
1279impl EntryIndex {
1280 fn build(entries: &[ModifierNodeEntry]) -> Self {
1281 let mut keyed = FxHashMap::default();
1282 let mut hashed = FxHashMap::default();
1283 let mut typed = FxHashMap::default();
1284
1285 for (i, entry) in entries.iter().enumerate() {
1286 if let Some(key_value) = entry.key {
1287 keyed
1289 .entry((entry.element_type, key_value))
1290 .or_insert_with(Vec::new)
1291 .push(i);
1292 } else {
1293 hashed
1295 .entry((entry.element_type, entry.hash_code))
1296 .or_insert_with(Vec::new)
1297 .push(i);
1298 typed
1299 .entry(entry.element_type)
1300 .or_insert_with(Vec::new)
1301 .push(i);
1302 }
1303 }
1304
1305 Self {
1306 keyed,
1307 hashed,
1308 typed,
1309 }
1310 }
1311
1312 fn find_match(
1319 &self,
1320 entries: &[ModifierNodeEntry],
1321 used: &[bool],
1322 element_type: TypeId,
1323 key: Option<u64>,
1324 hash_code: u64,
1325 element: &DynModifierElement,
1326 ) -> Option<usize> {
1327 if let Some(key_value) = key {
1328 if let Some(candidates) = self.keyed.get(&(element_type, key_value)) {
1330 for &i in candidates {
1331 if !used[i] {
1332 return Some(i);
1333 }
1334 }
1335 }
1336 } else {
1337 if let Some(candidates) = self.hashed.get(&(element_type, hash_code)) {
1339 for &i in candidates {
1340 if !used[i] && entries[i].element.as_ref().equals_element(element.as_ref()) {
1341 return Some(i);
1342 }
1343 }
1344 }
1345
1346 if let Some(candidates) = self.typed.get(&element_type) {
1348 for &i in candidates {
1349 if !used[i] {
1350 return Some(i);
1351 }
1352 }
1353 }
1354 }
1355
1356 None
1357 }
1358}
1359
1360impl ModifierNodeChain {
1361 pub fn new() -> Self {
1362 let mut chain = Self {
1363 entries: Vec::new(),
1364 aggregated_capabilities: NodeCapabilities::empty(),
1365 head_aggregate_child_capabilities: NodeCapabilities::empty(),
1366 head_sentinel: Box::new(SentinelNode::new()),
1367 tail_sentinel: Box::new(SentinelNode::new()),
1368 ordered_nodes: Vec::new(),
1369 scratch_old_used: Vec::new(),
1370 scratch_match_order: Vec::new(),
1371 scratch_final_slots: Vec::new(),
1372 scratch_elements: Vec::new(),
1373 };
1374 chain.sync_chain_links();
1375 chain
1376 }
1377
1378 pub fn detach_nodes(&mut self) {
1380 for entry in &self.entries {
1381 detach_node_tree(&mut **entry.node.borrow_mut());
1382 }
1383 }
1384
1385 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
1387 for entry in &self.entries {
1388 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1389 }
1390 }
1391
1392 pub fn repair_chain(&mut self) {
1395 self.sync_chain_links();
1396 }
1397
1398 pub fn update_from_slice(
1404 &mut self,
1405 elements: &[DynModifierElement],
1406 context: &mut dyn ModifierNodeContext,
1407 ) {
1408 self.update_from_ref_iter(elements.iter(), context);
1409 }
1410
1411 pub fn update_from_ref_iter<'a, I>(
1416 &mut self,
1417 elements: I,
1418 context: &mut dyn ModifierNodeContext,
1419 ) where
1420 I: Iterator<Item = &'a DynModifierElement>,
1421 {
1422 let old_len = self.entries.len();
1426 let mut fast_path_failed_at: Option<usize> = None;
1427 let mut elements_count = 0;
1428
1429 self.scratch_elements.clear();
1431
1432 for (idx, element) in elements.enumerate() {
1433 elements_count = idx + 1;
1434
1435 if fast_path_failed_at.is_none() && idx < old_len {
1436 let entry = &mut self.entries[idx];
1437 let same_type = entry.element_type == element.element_type();
1438 let same_key = entry.key == element.key();
1439 let same_hash = entry.hash_code == element.hash_code();
1440
1441 if same_type && same_key && same_hash {
1444 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1446 let capabilities = element.capabilities();
1447
1448 {
1450 let node_borrow = entry.node.borrow();
1451 if !node_borrow.node_state().is_attached() {
1452 drop(node_borrow);
1453 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1454 }
1455 }
1456
1457 let needs_update = !same_element || element.requires_update();
1459 if needs_update {
1460 element.update_node(&mut **entry.node.borrow_mut());
1461 entry.element = element.clone();
1462 entry.hash_code = element.hash_code();
1463 request_auto_invalidations(context, capabilities);
1464 }
1465
1466 entry.capabilities = capabilities;
1468 entry
1469 .node
1470 .borrow()
1471 .node_state()
1472 .set_capabilities(capabilities);
1473 continue;
1474 }
1475 fast_path_failed_at = Some(idx);
1477 }
1478
1479 self.scratch_elements.push(element.clone());
1481 }
1482
1483 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
1488 if elements_count < self.entries.len() {
1490 for entry in self.entries.drain(elements_count..) {
1491 detach_node_tree(&mut **entry.node.borrow_mut());
1492 }
1493 }
1494 self.sync_chain_links();
1495 return;
1496 }
1497
1498 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
1501
1502 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
1504 let processed_entries_len = self.entries.len();
1505 let old_len = old_entries.len();
1506
1507 self.scratch_old_used.clear();
1509 self.scratch_old_used.resize(old_len, false);
1510
1511 self.scratch_match_order.clear();
1512 self.scratch_match_order.resize(old_len, None);
1513
1514 let index = EntryIndex::build(&old_entries);
1516
1517 let new_elements_count = self.scratch_elements.len();
1518 self.scratch_final_slots.clear();
1519 self.scratch_final_slots.reserve(new_elements_count);
1520
1521 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
1523 self.scratch_final_slots.push(None);
1524 let element_type = element.element_type();
1525 let key = element.key();
1526 let hash_code = element.hash_code();
1527 let capabilities = element.capabilities();
1528
1529 let matched_idx = index.find_match(
1531 &old_entries,
1532 &self.scratch_old_used,
1533 element_type,
1534 key,
1535 hash_code,
1536 &element,
1537 );
1538
1539 if let Some(idx) = matched_idx {
1540 self.scratch_old_used[idx] = true;
1542 self.scratch_match_order[idx] = Some(new_pos);
1543 let entry = &mut old_entries[idx];
1544
1545 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1547
1548 {
1550 let node_borrow = entry.node.borrow();
1551 if !node_borrow.node_state().is_attached() {
1552 drop(node_borrow);
1553 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1554 }
1555 }
1556
1557 let needs_update = !same_element || element.requires_update();
1559 if needs_update {
1560 element.update_node(&mut **entry.node.borrow_mut());
1561 entry.element = element;
1562 entry.hash_code = hash_code;
1563 request_auto_invalidations(context, capabilities);
1564 }
1565
1566 entry.key = key;
1568 entry.element_type = element_type;
1569 entry.capabilities = capabilities;
1570 entry
1571 .node
1572 .borrow()
1573 .node_state()
1574 .set_capabilities(capabilities);
1575 } else {
1576 let entry = ModifierNodeEntry::new(
1578 element_type,
1579 key,
1580 element.clone(),
1581 element.create_node(),
1582 hash_code,
1583 capabilities,
1584 );
1585 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1586 element.update_node(&mut **entry.node.borrow_mut());
1587 request_auto_invalidations(context, capabilities);
1588 self.scratch_final_slots[new_pos] = Some(entry);
1589 }
1590 }
1591
1592 for (i, entry) in old_entries.into_iter().enumerate() {
1594 if self.scratch_old_used[i] {
1595 let pos = self.scratch_match_order[i]
1596 .expect("Missing match order for used modifier entry");
1597 self.scratch_final_slots[pos] = Some(entry);
1598 } else {
1599 detach_node_tree(&mut **entry.node.borrow_mut());
1600 }
1601 }
1602
1603 self.entries.reserve(self.scratch_final_slots.len());
1605 for slot in self.scratch_final_slots.drain(..) {
1606 let entry = slot.expect("Missing modifier entry for reconciled position");
1607 self.entries.push(entry);
1608 }
1609
1610 debug_assert_eq!(
1611 self.entries.len(),
1612 processed_entries_len + new_elements_count
1613 );
1614 self.sync_chain_links();
1615 }
1616
1617 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
1621 where
1622 I: IntoIterator<Item = DynModifierElement>,
1623 {
1624 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
1625 self.update_from_slice(&collected, context);
1626 }
1627
1628 pub fn reset(&mut self) {
1631 for entry in &mut self.entries {
1632 reset_node_tree(&mut **entry.node.borrow_mut());
1633 }
1634 }
1635
1636 pub fn detach_all(&mut self) {
1638 for entry in std::mem::take(&mut self.entries) {
1639 detach_node_tree(&mut **entry.node.borrow_mut());
1640 {
1641 let node_borrow = entry.node.borrow();
1642 let state = node_borrow.node_state();
1643 state.set_capabilities(NodeCapabilities::empty());
1644 }
1645 }
1646 self.aggregated_capabilities = NodeCapabilities::empty();
1647 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
1648 self.ordered_nodes.clear();
1649 self.sync_chain_links();
1650 }
1651
1652 pub fn len(&self) -> usize {
1653 self.entries.len()
1654 }
1655
1656 pub fn is_empty(&self) -> bool {
1657 self.entries.is_empty()
1658 }
1659
1660 pub fn capabilities(&self) -> NodeCapabilities {
1662 self.aggregated_capabilities
1663 }
1664
1665 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
1667 self.aggregated_capabilities.contains(capability)
1668 }
1669
1670 pub fn head(&self) -> ModifierChainNodeRef<'_> {
1672 self.make_node_ref(NodeLink::Head)
1673 }
1674
1675 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
1677 self.make_node_ref(NodeLink::Tail)
1678 }
1679
1680 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
1682 ModifierChainIter::forward(self)
1683 }
1684
1685 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
1687 ModifierChainIter::backward(self)
1688 }
1689
1690 pub fn for_each_forward<F>(&self, mut f: F)
1692 where
1693 F: FnMut(ModifierChainNodeRef<'_>),
1694 {
1695 for node in self.head_to_tail() {
1696 f(node);
1697 }
1698 }
1699
1700 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
1702 where
1703 F: FnMut(ModifierChainNodeRef<'_>),
1704 {
1705 if mask.is_empty() {
1706 self.for_each_forward(f);
1707 return;
1708 }
1709
1710 if !self.head().aggregate_child_capabilities().intersects(mask) {
1711 return;
1712 }
1713
1714 for node in self.head_to_tail() {
1715 if node.kind_set().intersects(mask) {
1716 f(node);
1717 }
1718 }
1719 }
1720
1721 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
1723 where
1724 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
1725 {
1726 self.for_each_forward_matching(mask, |node_ref| {
1727 node_ref.with_node(|node| f(node_ref.clone(), node));
1728 });
1729 }
1730
1731 pub fn for_each_backward<F>(&self, mut f: F)
1733 where
1734 F: FnMut(ModifierChainNodeRef<'_>),
1735 {
1736 for node in self.tail_to_head() {
1737 f(node);
1738 }
1739 }
1740
1741 pub fn for_each_backward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
1743 where
1744 F: FnMut(ModifierChainNodeRef<'_>),
1745 {
1746 if mask.is_empty() {
1747 self.for_each_backward(f);
1748 return;
1749 }
1750
1751 if !self.head().aggregate_child_capabilities().intersects(mask) {
1752 return;
1753 }
1754
1755 for node in self.tail_to_head() {
1756 if node.kind_set().intersects(mask) {
1757 f(node);
1758 }
1759 }
1760 }
1761
1762 pub fn node_ref_at(&self, index: usize) -> Option<ModifierChainNodeRef<'_>> {
1764 if index >= self.entries.len() {
1765 None
1766 } else {
1767 Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))))
1768 }
1769 }
1770
1771 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
1773 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
1774 node as *const dyn ModifierNode as *const ()
1775 }
1776
1777 let target = node_data_ptr(node);
1778 for (index, entry) in self.entries.iter().enumerate() {
1779 if node_data_ptr(&**entry.node.borrow()) == target {
1780 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
1781 }
1782 }
1783
1784 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
1785 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
1786 return None;
1787 }
1788 let matches_target = match link {
1789 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
1790 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
1791 NodeLink::Entry(path) => {
1792 let node_borrow = self.entries[path.entry()].node.borrow();
1793 node_data_ptr(&**node_borrow) == target
1794 }
1795 };
1796 if matches_target {
1797 Some(self.make_node_ref(*link))
1798 } else {
1799 None
1800 }
1801 })
1802 }
1803
1804 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
1807 self.entries.get(index).and_then(|entry| {
1808 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
1809 boxed_node.as_any().downcast_ref::<N>()
1810 })
1811 .ok()
1812 })
1813 }
1814
1815 pub fn node_mut<N: ModifierNode + 'static>(
1818 &self,
1819 index: usize,
1820 ) -> Option<std::cell::RefMut<'_, N>> {
1821 self.entries.get(index).and_then(|entry| {
1822 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
1823 boxed_node.as_any_mut().downcast_mut::<N>()
1824 })
1825 .ok()
1826 })
1827 }
1828
1829 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
1832 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
1833 }
1834
1835 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
1837 self.aggregated_capabilities
1838 .contains(NodeCapabilities::for_invalidation(kind))
1839 }
1840
1841 pub fn visit_nodes<F>(&self, mut f: F)
1843 where
1844 F: FnMut(&dyn ModifierNode, NodeCapabilities),
1845 {
1846 for (link, cached_caps, _agg) in &self.ordered_nodes {
1847 match link {
1848 NodeLink::Head => {
1849 f(self.head_sentinel.as_ref(), *cached_caps);
1850 }
1851 NodeLink::Tail => {
1852 f(self.tail_sentinel.as_ref(), *cached_caps);
1853 }
1854 NodeLink::Entry(path) => {
1855 let node_borrow = self.entries[path.entry()].node.borrow();
1856 if path.delegates().is_empty() {
1857 f(&**node_borrow, *cached_caps);
1858 } else {
1859 let mut current: &dyn ModifierNode = &**node_borrow;
1860 for &delegate_index in path.delegates() {
1861 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
1862 current = delegate;
1863 } else {
1864 return; }
1866 }
1867 f(current, *cached_caps);
1868 }
1869 }
1870 }
1871 }
1872 }
1873
1874 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
1876 where
1877 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
1878 {
1879 for index in 0..self.ordered_nodes.len() {
1880 let (link, cached_caps, _agg) = self.ordered_nodes[index];
1881 match link {
1882 NodeLink::Head => {
1883 f(self.head_sentinel.as_mut(), cached_caps);
1884 }
1885 NodeLink::Tail => {
1886 f(self.tail_sentinel.as_mut(), cached_caps);
1887 }
1888 NodeLink::Entry(path) => {
1889 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
1890 if path.delegates().is_empty() {
1891 f(&mut **node_borrow, cached_caps);
1892 } else {
1893 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
1894 for &delegate_index in path.delegates() {
1895 if let Some(delegate) =
1896 nth_delegate_mut(current, delegate_index as usize)
1897 {
1898 current = delegate;
1899 } else {
1900 return; }
1902 }
1903 f(current, cached_caps);
1904 }
1905 }
1906 }
1907 }
1908 }
1909
1910 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
1911 ModifierChainNodeRef {
1912 chain: self,
1913 link,
1914 cached_capabilities: None,
1915 cached_aggregate_child: None,
1916 }
1917 }
1918
1919 fn make_node_ref_with_caps(
1920 &self,
1921 link: NodeLink,
1922 caps: NodeCapabilities,
1923 aggregate_child: NodeCapabilities,
1924 ) -> ModifierChainNodeRef<'_> {
1925 ModifierChainNodeRef {
1926 chain: self,
1927 link,
1928 cached_capabilities: Some(caps),
1929 cached_aggregate_child: Some(aggregate_child),
1930 }
1931 }
1932
1933 fn sync_chain_links(&mut self) {
1934 self.rebuild_ordered_nodes();
1935
1936 self.head_sentinel.node_state().set_parent_link(None);
1937 self.tail_sentinel.node_state().set_child_link(None);
1938
1939 if self.ordered_nodes.is_empty() {
1940 self.head_sentinel
1941 .node_state()
1942 .set_child_link(Some(NodeLink::Tail));
1943 self.tail_sentinel
1944 .node_state()
1945 .set_parent_link(Some(NodeLink::Head));
1946 self.aggregated_capabilities = NodeCapabilities::empty();
1947 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
1948 self.head_sentinel
1949 .node_state()
1950 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1951 self.tail_sentinel
1952 .node_state()
1953 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1954 return;
1955 }
1956
1957 let mut previous = NodeLink::Head;
1958 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
1959 match &previous {
1961 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
1962 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
1963 NodeLink::Entry(path) => {
1964 let node_borrow = self.entries[path.entry()].node.borrow();
1965 if path.delegates().is_empty() {
1967 node_borrow.node_state().set_child_link(Some(link));
1968 } else {
1969 let mut current: &dyn ModifierNode = &**node_borrow;
1970 for &delegate_index in path.delegates() {
1971 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
1972 current = delegate;
1973 }
1974 }
1975 current.node_state().set_child_link(Some(link));
1976 }
1977 }
1978 }
1979 match &link {
1981 NodeLink::Head => self
1982 .head_sentinel
1983 .node_state()
1984 .set_parent_link(Some(previous)),
1985 NodeLink::Tail => self
1986 .tail_sentinel
1987 .node_state()
1988 .set_parent_link(Some(previous)),
1989 NodeLink::Entry(path) => {
1990 let node_borrow = self.entries[path.entry()].node.borrow();
1991 if path.delegates().is_empty() {
1993 node_borrow.node_state().set_parent_link(Some(previous));
1994 } else {
1995 let mut current: &dyn ModifierNode = &**node_borrow;
1996 for &delegate_index in path.delegates() {
1997 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
1998 current = delegate;
1999 }
2000 }
2001 current.node_state().set_parent_link(Some(previous));
2002 }
2003 }
2004 }
2005 previous = link;
2006 }
2007
2008 match &previous {
2010 NodeLink::Head => self
2011 .head_sentinel
2012 .node_state()
2013 .set_child_link(Some(NodeLink::Tail)),
2014 NodeLink::Tail => self
2015 .tail_sentinel
2016 .node_state()
2017 .set_child_link(Some(NodeLink::Tail)),
2018 NodeLink::Entry(path) => {
2019 let node_borrow = self.entries[path.entry()].node.borrow();
2020 if path.delegates().is_empty() {
2022 node_borrow
2023 .node_state()
2024 .set_child_link(Some(NodeLink::Tail));
2025 } else {
2026 let mut current: &dyn ModifierNode = &**node_borrow;
2027 for &delegate_index in path.delegates() {
2028 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2029 current = delegate;
2030 }
2031 }
2032 current.node_state().set_child_link(Some(NodeLink::Tail));
2033 }
2034 }
2035 }
2036 self.tail_sentinel
2037 .node_state()
2038 .set_parent_link(Some(previous));
2039 self.tail_sentinel.node_state().set_child_link(None);
2040
2041 let mut aggregate = NodeCapabilities::empty();
2042 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
2043 aggregate |= *cached_caps;
2044 *cached_aggregate = aggregate;
2045 match link {
2047 NodeLink::Head => {
2048 self.head_sentinel
2049 .node_state()
2050 .set_aggregate_child_capabilities(aggregate);
2051 }
2052 NodeLink::Tail => {
2053 self.tail_sentinel
2054 .node_state()
2055 .set_aggregate_child_capabilities(aggregate);
2056 }
2057 NodeLink::Entry(path) => {
2058 let node_borrow = self.entries[path.entry()].node.borrow();
2059 let state = if path.delegates().is_empty() {
2060 node_borrow.node_state()
2061 } else {
2062 let mut current: &dyn ModifierNode = &**node_borrow;
2063 for &delegate_index in path.delegates() {
2064 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2065 current = delegate;
2066 }
2067 }
2068 current.node_state()
2069 };
2070 state.set_aggregate_child_capabilities(aggregate);
2071 }
2072 }
2073 }
2074
2075 self.aggregated_capabilities = aggregate;
2076 self.head_aggregate_child_capabilities = aggregate;
2077 self.head_sentinel
2078 .node_state()
2079 .set_aggregate_child_capabilities(aggregate);
2080 self.tail_sentinel
2081 .node_state()
2082 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2083 }
2084
2085 fn rebuild_ordered_nodes(&mut self) {
2086 self.ordered_nodes.clear();
2087 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
2088 for (index, entry) in self.entries.iter().enumerate() {
2089 let node_borrow = entry.node.borrow();
2090 Self::enumerate_link_order(
2091 &**node_borrow,
2092 index,
2093 &mut path_buf,
2094 0,
2095 &mut self.ordered_nodes,
2096 );
2097 }
2098 }
2099
2100 fn enumerate_link_order(
2101 node: &dyn ModifierNode,
2102 entry: usize,
2103 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
2104 path_len: usize,
2105 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2106 ) {
2107 let caps = node.node_state().capabilities();
2108 out.push((
2109 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
2110 caps,
2111 NodeCapabilities::empty(),
2112 ));
2113 let mut delegate_index = 0usize;
2114 node.for_each_delegate(&mut |child| {
2115 if path_len < MAX_DELEGATE_DEPTH {
2116 path_buf[path_len] = delegate_index;
2117 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
2118 }
2119 delegate_index += 1;
2120 });
2121 }
2122}
2123
2124impl<'a> ModifierChainNodeRef<'a> {
2125 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
2128 match &self.link {
2129 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
2130 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
2131 NodeLink::Entry(path) => {
2132 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2133 if path.delegates().is_empty() {
2135 f(node_borrow.node_state())
2136 } else {
2137 let mut current: &dyn ModifierNode = &**node_borrow;
2139 for &delegate_index in path.delegates() {
2140 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2141 current = delegate;
2142 } else {
2143 return f(node_borrow.node_state());
2145 }
2146 }
2147 f(current.node_state())
2148 }
2149 }
2150 }
2151 }
2152
2153 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
2156 match &self.link {
2157 NodeLink::Head => None, NodeLink::Tail => None, NodeLink::Entry(path) => {
2160 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2161 if path.delegates().is_empty() {
2163 Some(f(&**node_borrow))
2164 } else {
2165 let mut current: &dyn ModifierNode = &**node_borrow;
2167 for &delegate_index in path.delegates() {
2168 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2169 current = delegate;
2170 } else {
2171 return None;
2173 }
2174 }
2175 Some(f(current))
2176 }
2177 }
2178 }
2179 }
2180
2181 #[inline]
2183 pub fn parent(&self) -> Option<Self> {
2184 self.with_state(|state| state.parent_link())
2185 .map(|link| self.chain.make_node_ref(link))
2186 }
2187
2188 #[inline]
2190 pub fn child(&self) -> Option<Self> {
2191 self.with_state(|state| state.child_link())
2192 .map(|link| self.chain.make_node_ref(link))
2193 }
2194
2195 #[inline]
2197 pub fn kind_set(&self) -> NodeCapabilities {
2198 if let Some(caps) = self.cached_capabilities {
2199 return caps;
2200 }
2201 match &self.link {
2202 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
2203 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
2204 }
2205 }
2206
2207 pub fn entry_index(&self) -> Option<usize> {
2209 match &self.link {
2210 NodeLink::Entry(path) => Some(path.entry()),
2211 _ => None,
2212 }
2213 }
2214
2215 pub fn delegate_depth(&self) -> usize {
2217 match &self.link {
2218 NodeLink::Entry(path) => path.delegates().len(),
2219 _ => 0,
2220 }
2221 }
2222
2223 #[inline]
2225 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
2226 if let Some(agg) = self.cached_aggregate_child {
2227 return agg;
2228 }
2229 if self.is_tail() {
2230 NodeCapabilities::empty()
2231 } else {
2232 self.with_state(|state| state.aggregate_child_capabilities())
2233 }
2234 }
2235
2236 pub fn is_head(&self) -> bool {
2238 matches!(self.link, NodeLink::Head)
2239 }
2240
2241 pub fn is_tail(&self) -> bool {
2243 matches!(self.link, NodeLink::Tail)
2244 }
2245
2246 pub fn is_sentinel(&self) -> bool {
2248 matches!(self.link, NodeLink::Head | NodeLink::Tail)
2249 }
2250
2251 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
2253 !mask.is_empty() && self.kind_set().intersects(mask)
2254 }
2255
2256 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
2258 where
2259 F: FnMut(ModifierChainNodeRef<'a>),
2260 {
2261 let mut current = if include_self {
2262 Some(self)
2263 } else {
2264 self.child()
2265 };
2266 while let Some(node) = current {
2267 if node.is_tail() {
2268 break;
2269 }
2270 if !node.is_sentinel() {
2271 f(node.clone());
2272 }
2273 current = node.child();
2274 }
2275 }
2276
2277 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2279 where
2280 F: FnMut(ModifierChainNodeRef<'a>),
2281 {
2282 if mask.is_empty() {
2283 self.visit_descendants(include_self, f);
2284 return;
2285 }
2286
2287 if !self.aggregate_child_capabilities().intersects(mask) {
2288 return;
2289 }
2290
2291 self.visit_descendants(include_self, |node| {
2292 if node.kind_set().intersects(mask) {
2293 f(node);
2294 }
2295 });
2296 }
2297
2298 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
2300 where
2301 F: FnMut(ModifierChainNodeRef<'a>),
2302 {
2303 let mut current = if include_self {
2304 Some(self)
2305 } else {
2306 self.parent()
2307 };
2308 while let Some(node) = current {
2309 if node.is_head() {
2310 break;
2311 }
2312 f(node.clone());
2313 current = node.parent();
2314 }
2315 }
2316
2317 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2319 where
2320 F: FnMut(ModifierChainNodeRef<'a>),
2321 {
2322 if mask.is_empty() {
2323 self.visit_ancestors(include_self, f);
2324 return;
2325 }
2326
2327 self.visit_ancestors(include_self, |node| {
2328 if node.kind_set().intersects(mask) {
2329 f(node);
2330 }
2331 });
2332 }
2333
2334 pub fn find_parent_focus_target(&self) -> Option<ModifierChainNodeRef<'a>> {
2339 let mut result = None;
2340 self.clone()
2341 .visit_ancestors_matching(false, NodeCapabilities::FOCUS, |node| {
2342 if result.is_none() {
2343 result = Some(node);
2344 }
2345 });
2346 result
2347 }
2348
2349 pub fn find_first_focus_target(&self) -> Option<ModifierChainNodeRef<'a>> {
2354 let mut result = None;
2355 self.clone()
2356 .visit_descendants_matching(false, NodeCapabilities::FOCUS, |node| {
2357 if result.is_none() {
2358 result = Some(node);
2359 }
2360 });
2361 result
2362 }
2363
2364 pub fn has_focus_capability_in_ancestors(&self) -> bool {
2366 let mut found = false;
2367 self.clone()
2368 .visit_ancestors_matching(true, NodeCapabilities::FOCUS, |_| {
2369 found = true;
2370 });
2371 found
2372 }
2373}
2374
2375#[cfg(test)]
2376#[path = "tests/modifier_tests.rs"]
2377mod tests;