1use std::any::{type_name, Any, TypeId};
9use std::cell::{Cell, RefCell};
10use std::fmt;
11use std::hash::{Hash, Hasher};
12use std::ops::{BitOr, BitOrAssign};
13use std::rc::Rc;
14
15use cranpose_core::collections::map::HashMap;
16use cranpose_core::hash::default;
17
18pub use cranpose_ui_graphics::DrawScope;
19pub use cranpose_ui_graphics::Size;
20pub use cranpose_ui_layout::{Constraints, Measurable};
21
22use crate::nodes::input::types::PointerEvent;
23#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
28pub enum InvalidationKind {
29 Layout,
30 Draw,
31 PointerInput,
32 Semantics,
33 Focus,
34}
35
36pub trait ModifierNodeContext {
38 fn invalidate(&mut self, _kind: InvalidationKind) {}
40
41 fn request_update(&mut self) {}
44
45 fn node_id(&self) -> Option<cranpose_core::NodeId> {
48 None
49 }
50
51 fn push_active_capabilities(&mut self, _capabilities: NodeCapabilities) {}
53
54 fn pop_active_capabilities(&mut self) {}
56}
57
58#[derive(Default, Debug, Clone)]
67pub struct BasicModifierNodeContext {
68 invalidations: Vec<ModifierInvalidation>,
69 update_requested: bool,
70 active_capabilities: Vec<NodeCapabilities>,
71 node_id: Option<cranpose_core::NodeId>,
72}
73
74impl BasicModifierNodeContext {
75 pub fn new() -> Self {
77 Self::default()
78 }
79
80 pub fn invalidations(&self) -> &[ModifierInvalidation] {
84 &self.invalidations
85 }
86
87 pub fn clear_invalidations(&mut self) {
89 self.invalidations.clear();
90 }
91
92 pub fn take_invalidations(&mut self) -> Vec<ModifierInvalidation> {
94 std::mem::take(&mut self.invalidations)
95 }
96
97 pub fn update_requested(&self) -> bool {
100 self.update_requested
101 }
102
103 pub fn take_update_requested(&mut self) -> bool {
105 std::mem::take(&mut self.update_requested)
106 }
107
108 pub fn set_node_id(&mut self, id: Option<cranpose_core::NodeId>) {
110 self.node_id = id;
111 }
112
113 fn push_invalidation(&mut self, kind: InvalidationKind) {
114 let mut capabilities = self.current_capabilities();
115 capabilities.insert(NodeCapabilities::for_invalidation(kind));
116 if let Some(existing) = self
117 .invalidations
118 .iter_mut()
119 .find(|entry| entry.kind() == kind)
120 {
121 let updated = existing.capabilities() | capabilities;
122 *existing = ModifierInvalidation::new(kind, updated);
123 } else {
124 self.invalidations
125 .push(ModifierInvalidation::new(kind, capabilities));
126 }
127 }
128
129 fn current_capabilities(&self) -> NodeCapabilities {
130 self.active_capabilities
131 .last()
132 .copied()
133 .unwrap_or_else(NodeCapabilities::empty)
134 }
135}
136
137impl ModifierNodeContext for BasicModifierNodeContext {
138 fn invalidate(&mut self, kind: InvalidationKind) {
139 self.push_invalidation(kind);
140 }
141
142 fn request_update(&mut self) {
143 self.update_requested = true;
144 }
145
146 fn push_active_capabilities(&mut self, capabilities: NodeCapabilities) {
147 self.active_capabilities.push(capabilities);
148 }
149
150 fn pop_active_capabilities(&mut self) {
151 self.active_capabilities.pop();
152 }
153
154 fn node_id(&self) -> Option<cranpose_core::NodeId> {
155 self.node_id
156 }
157}
158
159const MAX_DELEGATE_DEPTH: usize = 3;
163
164#[derive(Copy, Clone, Debug, PartialEq, Eq)]
165pub(crate) struct NodePath {
166 entry: usize,
167 delegate_buf: [u8; MAX_DELEGATE_DEPTH],
168 delegate_len: u8,
169}
170
171impl NodePath {
172 #[inline]
173 fn root(entry: usize) -> Self {
174 Self {
175 entry,
176 delegate_buf: [0; MAX_DELEGATE_DEPTH],
177 delegate_len: 0,
178 }
179 }
180
181 #[inline]
182 fn from_slice(entry: usize, path: &[usize]) -> Self {
183 debug_assert!(
184 path.len() <= MAX_DELEGATE_DEPTH,
185 "delegate depth {} exceeds MAX_DELEGATE_DEPTH {}",
186 path.len(),
187 MAX_DELEGATE_DEPTH
188 );
189 debug_assert!(
190 path.iter().all(|&i| i <= u8::MAX as usize),
191 "delegate index exceeds u8 range"
192 );
193 let mut delegate_buf = [0u8; MAX_DELEGATE_DEPTH];
194 for (i, &v) in path.iter().enumerate().take(MAX_DELEGATE_DEPTH) {
195 delegate_buf[i] = v as u8;
196 }
197 Self {
198 entry,
199 delegate_buf,
200 delegate_len: path.len().min(MAX_DELEGATE_DEPTH) as u8,
201 }
202 }
203
204 #[inline]
205 fn entry(&self) -> usize {
206 self.entry
207 }
208
209 #[inline]
210 fn delegates(&self) -> &[u8] {
211 &self.delegate_buf[..self.delegate_len as usize]
212 }
213}
214
215#[derive(Copy, Clone, Debug, PartialEq, Eq)]
216pub(crate) enum NodeLink {
217 Head,
218 Tail,
219 Entry(NodePath),
220}
221
222#[derive(Debug)]
228pub struct NodeState {
229 aggregate_child_capabilities: Cell<NodeCapabilities>,
230 capabilities: Cell<NodeCapabilities>,
231 parent: RefCell<Option<NodeLink>>,
232 child: RefCell<Option<NodeLink>>,
233 attached: Cell<bool>,
234 is_sentinel: bool,
235}
236
237impl Default for NodeState {
238 fn default() -> Self {
239 Self::new()
240 }
241}
242
243impl NodeState {
244 pub const fn new() -> Self {
245 Self {
246 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
247 capabilities: Cell::new(NodeCapabilities::empty()),
248 parent: RefCell::new(None),
249 child: RefCell::new(None),
250 attached: Cell::new(false),
251 is_sentinel: false,
252 }
253 }
254
255 pub const fn sentinel() -> Self {
256 Self {
257 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
258 capabilities: Cell::new(NodeCapabilities::empty()),
259 parent: RefCell::new(None),
260 child: RefCell::new(None),
261 attached: Cell::new(true),
262 is_sentinel: true,
263 }
264 }
265
266 pub fn set_capabilities(&self, capabilities: NodeCapabilities) {
267 self.capabilities.set(capabilities);
268 }
269
270 #[inline]
271 pub fn capabilities(&self) -> NodeCapabilities {
272 self.capabilities.get()
273 }
274
275 pub fn set_aggregate_child_capabilities(&self, capabilities: NodeCapabilities) {
276 self.aggregate_child_capabilities.set(capabilities);
277 }
278
279 #[inline]
280 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
281 self.aggregate_child_capabilities.get()
282 }
283
284 pub(crate) fn set_parent_link(&self, parent: Option<NodeLink>) {
285 *self.parent.borrow_mut() = parent;
286 }
287
288 #[inline]
289 pub(crate) fn parent_link(&self) -> Option<NodeLink> {
290 *self.parent.borrow()
291 }
292
293 pub(crate) fn set_child_link(&self, child: Option<NodeLink>) {
294 *self.child.borrow_mut() = child;
295 }
296
297 #[inline]
298 pub(crate) fn child_link(&self) -> Option<NodeLink> {
299 *self.child.borrow()
300 }
301
302 pub fn set_attached(&self, attached: bool) {
303 self.attached.set(attached);
304 }
305
306 pub fn is_attached(&self) -> bool {
307 self.attached.get()
308 }
309
310 pub fn is_sentinel(&self) -> bool {
311 self.is_sentinel
312 }
313}
314
315pub trait DelegatableNode {
317 fn node_state(&self) -> &NodeState;
318 fn aggregate_child_capabilities(&self) -> NodeCapabilities {
319 self.node_state().aggregate_child_capabilities()
320 }
321}
322
323pub trait ModifierNode: Any + DelegatableNode {
381 fn on_attach(&mut self, _context: &mut dyn ModifierNodeContext) {}
382
383 fn on_detach(&mut self) {}
384
385 fn on_reset(&mut self) {}
386
387 fn as_draw_node(&self) -> Option<&dyn DrawModifierNode> {
389 None
390 }
391
392 fn as_draw_node_mut(&mut self) -> Option<&mut dyn DrawModifierNode> {
394 None
395 }
396
397 fn as_pointer_input_node(&self) -> Option<&dyn PointerInputNode> {
399 None
400 }
401
402 fn as_pointer_input_node_mut(&mut self) -> Option<&mut dyn PointerInputNode> {
404 None
405 }
406
407 fn as_semantics_node(&self) -> Option<&dyn SemanticsNode> {
409 None
410 }
411
412 fn as_semantics_node_mut(&mut self) -> Option<&mut dyn SemanticsNode> {
414 None
415 }
416
417 fn as_focus_node(&self) -> Option<&dyn FocusNode> {
419 None
420 }
421
422 fn as_focus_node_mut(&mut self) -> Option<&mut dyn FocusNode> {
424 None
425 }
426
427 fn as_layout_node(&self) -> Option<&dyn LayoutModifierNode> {
429 None
430 }
431
432 fn as_layout_node_mut(&mut self) -> Option<&mut dyn LayoutModifierNode> {
434 None
435 }
436
437 fn for_each_delegate<'b>(&'b self, _visitor: &mut dyn FnMut(&'b dyn ModifierNode)) {}
439
440 fn for_each_delegate_mut<'b>(&'b mut self, _visitor: &mut dyn FnMut(&'b mut dyn ModifierNode)) {
442 }
443}
444
445pub trait LayoutModifierNode: ModifierNode {
451 fn measure(
473 &self,
474 _context: &mut dyn ModifierNodeContext,
475 measurable: &dyn Measurable,
476 constraints: Constraints,
477 ) -> cranpose_ui_layout::LayoutModifierMeasureResult {
478 let placeable = measurable.measure(constraints);
480 cranpose_ui_layout::LayoutModifierMeasureResult::with_size(Size {
481 width: placeable.width(),
482 height: placeable.height(),
483 })
484 }
485
486 fn min_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
488 0.0
489 }
490
491 fn max_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
493 0.0
494 }
495
496 fn min_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
498 0.0
499 }
500
501 fn max_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
503 0.0
504 }
505}
506
507pub trait DrawModifierNode: ModifierNode {
515 fn draw(&self, _draw_scope: &mut dyn DrawScope) {
524 }
526
527 fn create_draw_closure(
538 &self,
539 ) -> Option<Rc<dyn Fn(Size) -> Vec<cranpose_ui_graphics::DrawPrimitive>>> {
540 None
541 }
542}
543
544pub trait PointerInputNode: ModifierNode {
550 fn on_pointer_event(
553 &mut self,
554 _context: &mut dyn ModifierNodeContext,
555 _event: &PointerEvent,
556 ) -> bool {
557 false
558 }
559
560 fn hit_test(&self, _x: f32, _y: f32) -> bool {
563 true
564 }
565
566 fn pointer_input_handler(&self) -> Option<Rc<dyn Fn(PointerEvent)>> {
568 None
569 }
570}
571
572pub trait SemanticsNode: ModifierNode {
578 fn merge_semantics(&self, _config: &mut SemanticsConfiguration) {
580 }
582}
583
584#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
589pub enum FocusState {
590 Active,
592 ActiveParent,
594 Captured,
598 #[default]
601 Inactive,
602}
603
604impl FocusState {
605 pub fn is_focused(self) -> bool {
607 matches!(self, FocusState::Active | FocusState::Captured)
608 }
609
610 pub fn has_focus(self) -> bool {
612 matches!(
613 self,
614 FocusState::Active | FocusState::ActiveParent | FocusState::Captured
615 )
616 }
617
618 pub fn is_captured(self) -> bool {
620 matches!(self, FocusState::Captured)
621 }
622}
623
624pub trait FocusNode: ModifierNode {
629 fn focus_state(&self) -> FocusState;
631
632 fn on_focus_changed(&mut self, _context: &mut dyn ModifierNodeContext, _state: FocusState) {
634 }
636}
637
638#[derive(Clone, Debug, Default, PartialEq)]
640pub struct SemanticsConfiguration {
641 pub content_description: Option<String>,
642 pub is_button: bool,
643 pub is_clickable: bool,
644 pub is_editable_text: bool,
645 pub text_selection: Option<crate::text::TextRange>,
646}
647
648impl SemanticsConfiguration {
649 pub fn merge(&mut self, other: &SemanticsConfiguration) {
650 if let Some(description) = &other.content_description {
651 self.content_description = Some(description.clone());
652 }
653 self.is_button |= other.is_button;
654 self.is_clickable |= other.is_clickable;
655 self.is_editable_text |= other.is_editable_text;
656 if let Some(selection) = other.text_selection {
657 self.text_selection = Some(selection);
658 }
659 }
660}
661
662impl fmt::Debug for dyn ModifierNode {
663 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
664 f.debug_struct("ModifierNode").finish_non_exhaustive()
665 }
666}
667
668impl dyn ModifierNode {
669 pub fn as_any(&self) -> &dyn Any {
670 self
671 }
672
673 pub fn as_any_mut(&mut self) -> &mut dyn Any {
674 self
675 }
676}
677
678pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
681 type Node: ModifierNode;
682
683 fn create(&self) -> Self::Node;
685
686 fn update(&self, node: &mut Self::Node);
688
689 fn key(&self) -> Option<u64> {
691 None
692 }
693
694 fn inspector_name(&self) -> &'static str {
696 type_name::<Self>()
697 }
698
699 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
701
702 fn capabilities(&self) -> NodeCapabilities {
705 NodeCapabilities::default()
706 }
707
708 fn always_update(&self) -> bool {
714 false
715 }
716}
717
718#[derive(Clone, Copy, PartialEq, Eq, Hash)]
720pub struct NodeCapabilities(u32);
721
722impl NodeCapabilities {
723 pub const NONE: Self = Self(0);
725 pub const LAYOUT: Self = Self(1 << 0);
727 pub const DRAW: Self = Self(1 << 1);
729 pub const POINTER_INPUT: Self = Self(1 << 2);
731 pub const SEMANTICS: Self = Self(1 << 3);
733 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
735 pub const FOCUS: Self = Self(1 << 5);
737
738 pub const fn empty() -> Self {
740 Self::NONE
741 }
742
743 pub const fn contains(self, other: Self) -> bool {
745 (self.0 & other.0) == other.0
746 }
747
748 pub const fn intersects(self, other: Self) -> bool {
750 (self.0 & other.0) != 0
751 }
752
753 pub fn insert(&mut self, other: Self) {
755 self.0 |= other.0;
756 }
757
758 pub const fn bits(self) -> u32 {
760 self.0
761 }
762
763 pub const fn is_empty(self) -> bool {
765 self.0 == 0
766 }
767
768 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
770 match kind {
771 InvalidationKind::Layout => Self::LAYOUT,
772 InvalidationKind::Draw => Self::DRAW,
773 InvalidationKind::PointerInput => Self::POINTER_INPUT,
774 InvalidationKind::Semantics => Self::SEMANTICS,
775 InvalidationKind::Focus => Self::FOCUS,
776 }
777 }
778}
779
780impl Default for NodeCapabilities {
781 fn default() -> Self {
782 Self::NONE
783 }
784}
785
786impl fmt::Debug for NodeCapabilities {
787 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
788 f.debug_struct("NodeCapabilities")
789 .field("layout", &self.contains(Self::LAYOUT))
790 .field("draw", &self.contains(Self::DRAW))
791 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
792 .field("semantics", &self.contains(Self::SEMANTICS))
793 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
794 .field("focus", &self.contains(Self::FOCUS))
795 .finish()
796 }
797}
798
799impl BitOr for NodeCapabilities {
800 type Output = Self;
801
802 fn bitor(self, rhs: Self) -> Self::Output {
803 Self(self.0 | rhs.0)
804 }
805}
806
807impl BitOrAssign for NodeCapabilities {
808 fn bitor_assign(&mut self, rhs: Self) {
809 self.0 |= rhs.0;
810 }
811}
812
813#[derive(Clone, Copy, Debug, PartialEq, Eq)]
815pub struct ModifierInvalidation {
816 kind: InvalidationKind,
817 capabilities: NodeCapabilities,
818}
819
820impl ModifierInvalidation {
821 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
823 Self { kind, capabilities }
824 }
825
826 pub const fn kind(self) -> InvalidationKind {
828 self.kind
829 }
830
831 pub const fn capabilities(self) -> NodeCapabilities {
833 self.capabilities
834 }
835}
836
837pub trait AnyModifierElement: fmt::Debug {
839 fn node_type(&self) -> TypeId;
840
841 fn element_type(&self) -> TypeId;
842
843 fn create_node(&self) -> Box<dyn ModifierNode>;
844
845 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
846
847 fn update_node(&self, node: &mut dyn ModifierNode);
848
849 fn key(&self) -> Option<u64>;
850
851 fn capabilities(&self) -> NodeCapabilities {
852 NodeCapabilities::default()
853 }
854
855 fn hash_code(&self) -> u64;
856
857 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
858
859 fn inspector_name(&self) -> &'static str;
860
861 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
862
863 fn requires_update(&self) -> bool;
864
865 fn as_any(&self) -> &dyn Any;
866}
867
868struct TypedModifierElement<E: ModifierNodeElement> {
869 element: E,
870 cached_hash: u64,
871}
872
873impl<E: ModifierNodeElement> TypedModifierElement<E> {
874 fn new(element: E) -> Self {
875 let mut hasher = default::new();
876 element.hash(&mut hasher);
877 Self {
878 element,
879 cached_hash: hasher.finish(),
880 }
881 }
882}
883
884impl<E> fmt::Debug for TypedModifierElement<E>
885where
886 E: ModifierNodeElement,
887{
888 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
889 f.debug_struct("TypedModifierElement")
890 .field("type", &type_name::<E>())
891 .finish()
892 }
893}
894
895impl<E> AnyModifierElement for TypedModifierElement<E>
896where
897 E: ModifierNodeElement,
898{
899 fn node_type(&self) -> TypeId {
900 TypeId::of::<E::Node>()
901 }
902
903 fn element_type(&self) -> TypeId {
904 TypeId::of::<E>()
905 }
906
907 fn create_node(&self) -> Box<dyn ModifierNode> {
908 Box::new(self.element.create())
909 }
910
911 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
912 node.as_any().is::<E::Node>()
913 }
914
915 fn update_node(&self, node: &mut dyn ModifierNode) {
916 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
917 self.element.update(typed);
918 }
919 }
920
921 fn key(&self) -> Option<u64> {
922 self.element.key()
923 }
924
925 fn capabilities(&self) -> NodeCapabilities {
926 self.element.capabilities()
927 }
928
929 fn hash_code(&self) -> u64 {
930 self.cached_hash
931 }
932
933 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
934 other
935 .as_any()
936 .downcast_ref::<Self>()
937 .map(|typed| typed.element == self.element)
938 .unwrap_or(false)
939 }
940
941 fn inspector_name(&self) -> &'static str {
942 self.element.inspector_name()
943 }
944
945 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
946 self.element.inspector_properties(visitor);
947 }
948
949 fn requires_update(&self) -> bool {
950 self.element.always_update()
951 }
952
953 fn as_any(&self) -> &dyn Any {
954 self
955 }
956}
957
958pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
961 Rc::new(TypedModifierElement::new(element))
962}
963
964pub type DynModifierElement = Rc<dyn AnyModifierElement>;
966
967#[derive(Clone, Copy, Debug, PartialEq, Eq)]
968enum TraversalDirection {
969 Forward,
970 Backward,
971}
972
973pub struct ModifierChainIter<'a> {
978 chain: &'a ModifierNodeChain,
979 cursor: usize,
982 remaining: usize,
984 direction: TraversalDirection,
985}
986
987impl<'a> ModifierChainIter<'a> {
988 fn forward(chain: &'a ModifierNodeChain) -> Self {
989 Self {
990 chain,
991 cursor: 0,
992 remaining: chain.ordered_nodes.len(),
993 direction: TraversalDirection::Forward,
994 }
995 }
996
997 fn backward(chain: &'a ModifierNodeChain) -> Self {
998 let len = chain.ordered_nodes.len();
999 Self {
1000 chain,
1001 cursor: len.wrapping_sub(1),
1002 remaining: len,
1003 direction: TraversalDirection::Backward,
1004 }
1005 }
1006}
1007
1008impl<'a> Iterator for ModifierChainIter<'a> {
1009 type Item = ModifierChainNodeRef<'a>;
1010
1011 #[inline]
1012 fn next(&mut self) -> Option<Self::Item> {
1013 if self.remaining == 0 {
1014 return None;
1015 }
1016 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
1017 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
1018 self.remaining -= 1;
1019 match self.direction {
1020 TraversalDirection::Forward => self.cursor += 1,
1021 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
1022 }
1023 Some(node_ref)
1024 }
1025
1026 #[inline]
1027 fn size_hint(&self) -> (usize, Option<usize>) {
1028 (self.remaining, Some(self.remaining))
1029 }
1030}
1031
1032impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
1033impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
1034
1035#[derive(Debug)]
1036struct ModifierNodeEntry {
1037 element_type: TypeId,
1038 node_type: TypeId,
1039 key: Option<u64>,
1040 hash_code: u64,
1041 element: DynModifierElement,
1042 node: Rc<RefCell<Box<dyn ModifierNode>>>,
1043 capabilities: NodeCapabilities,
1044}
1045
1046impl ModifierNodeEntry {
1047 fn new(
1048 element_type: TypeId,
1049 node_type: TypeId,
1050 key: Option<u64>,
1051 element: DynModifierElement,
1052 node: Box<dyn ModifierNode>,
1053 hash_code: u64,
1054 capabilities: NodeCapabilities,
1055 ) -> Self {
1056 let node_rc = Rc::new(RefCell::new(node));
1058 let entry = Self {
1059 element_type,
1060 node_type,
1061 key,
1062 hash_code,
1063 element,
1064 node: Rc::clone(&node_rc),
1065 capabilities,
1066 };
1067 entry
1068 .node
1069 .borrow()
1070 .node_state()
1071 .set_capabilities(entry.capabilities);
1072 entry
1073 }
1074}
1075
1076fn visit_node_tree_mut(
1077 node: &mut dyn ModifierNode,
1078 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
1079) {
1080 visitor(node);
1081 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
1082}
1083
1084fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
1085 let mut current = 0usize;
1086 let mut result: Option<&dyn ModifierNode> = None;
1087 node.for_each_delegate(&mut |child| {
1088 if result.is_none() && current == target {
1089 result = Some(child);
1090 }
1091 current += 1;
1092 });
1093 result
1094}
1095
1096fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
1097 let mut current = 0usize;
1098 let mut result: Option<&mut dyn ModifierNode> = None;
1099 node.for_each_delegate_mut(&mut |child| {
1100 if result.is_none() && current == target {
1101 result = Some(child);
1102 }
1103 current += 1;
1104 });
1105 result
1106}
1107
1108fn with_node_context<F, R>(
1109 node: &mut dyn ModifierNode,
1110 context: &mut dyn ModifierNodeContext,
1111 f: F,
1112) -> R
1113where
1114 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
1115{
1116 context.push_active_capabilities(node.node_state().capabilities());
1117 let result = f(node, context);
1118 context.pop_active_capabilities();
1119 result
1120}
1121
1122fn request_auto_invalidations(
1123 context: &mut dyn ModifierNodeContext,
1124 capabilities: NodeCapabilities,
1125) {
1126 if capabilities.is_empty() {
1127 return;
1128 }
1129
1130 context.push_active_capabilities(capabilities);
1131
1132 if capabilities.contains(NodeCapabilities::LAYOUT) {
1133 context.invalidate(InvalidationKind::Layout);
1134 }
1135 if capabilities.contains(NodeCapabilities::DRAW) {
1136 context.invalidate(InvalidationKind::Draw);
1137 }
1138 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
1139 context.invalidate(InvalidationKind::PointerInput);
1140 }
1141 if capabilities.contains(NodeCapabilities::SEMANTICS) {
1142 context.invalidate(InvalidationKind::Semantics);
1143 }
1144 if capabilities.contains(NodeCapabilities::FOCUS) {
1145 context.invalidate(InvalidationKind::Focus);
1146 }
1147
1148 context.pop_active_capabilities();
1149}
1150
1151fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
1159 visit_node_tree_mut(node, &mut |n| {
1160 if !n.node_state().is_attached() {
1161 n.node_state().set_attached(true);
1162 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
1163 }
1164 });
1165}
1166
1167fn reset_node_tree(node: &mut dyn ModifierNode) {
1168 visit_node_tree_mut(node, &mut |n| n.on_reset());
1169}
1170
1171fn detach_node_tree(node: &mut dyn ModifierNode) {
1172 visit_node_tree_mut(node, &mut |n| {
1173 if n.node_state().is_attached() {
1174 n.on_detach();
1175 n.node_state().set_attached(false);
1176 }
1177 n.node_state().set_parent_link(None);
1178 n.node_state().set_child_link(None);
1179 n.node_state()
1180 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1181 });
1182}
1183
1184pub struct ModifierNodeChain {
1191 entries: Vec<ModifierNodeEntry>,
1192 aggregated_capabilities: NodeCapabilities,
1193 head_aggregate_child_capabilities: NodeCapabilities,
1194 head_sentinel: Box<SentinelNode>,
1195 tail_sentinel: Box<SentinelNode>,
1196 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
1198 scratch_old_used: Vec<bool>,
1200 scratch_match_order: Vec<Option<usize>>,
1201 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
1202 scratch_elements: Vec<DynModifierElement>,
1203}
1204
1205struct SentinelNode {
1206 state: NodeState,
1207}
1208
1209impl SentinelNode {
1210 fn new() -> Self {
1211 Self {
1212 state: NodeState::sentinel(),
1213 }
1214 }
1215}
1216
1217impl DelegatableNode for SentinelNode {
1218 fn node_state(&self) -> &NodeState {
1219 &self.state
1220 }
1221}
1222
1223impl ModifierNode for SentinelNode {}
1224
1225#[derive(Clone)]
1226pub struct ModifierChainNodeRef<'a> {
1227 chain: &'a ModifierNodeChain,
1228 link: NodeLink,
1229 cached_capabilities: Option<NodeCapabilities>,
1231 cached_aggregate_child: Option<NodeCapabilities>,
1233}
1234
1235impl Default for ModifierNodeChain {
1236 fn default() -> Self {
1237 Self::new()
1238 }
1239}
1240
1241struct EntryIndex {
1246 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1248 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1250 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
1252}
1253
1254struct EntryMatchQuery<'a> {
1255 element_type: TypeId,
1256 node_type: TypeId,
1257 key: Option<u64>,
1258 hash_code: u64,
1259 element: &'a DynModifierElement,
1260}
1261
1262impl EntryIndex {
1263 fn build(entries: &[ModifierNodeEntry]) -> Self {
1264 let mut keyed = HashMap::default();
1265 let mut hashed = HashMap::default();
1266 let mut typed = HashMap::default();
1267
1268 for (i, entry) in entries.iter().enumerate() {
1269 if let Some(key_value) = entry.key {
1270 keyed
1272 .entry((entry.element_type, entry.node_type, key_value))
1273 .or_insert_with(Vec::new)
1274 .push(i);
1275 } else {
1276 hashed
1278 .entry((entry.element_type, entry.node_type, entry.hash_code))
1279 .or_insert_with(Vec::new)
1280 .push(i);
1281 typed
1282 .entry((entry.element_type, entry.node_type))
1283 .or_insert_with(Vec::new)
1284 .push(i);
1285 }
1286 }
1287
1288 Self {
1289 keyed,
1290 hashed,
1291 typed,
1292 }
1293 }
1294
1295 fn find_match(
1302 &self,
1303 entries: &[ModifierNodeEntry],
1304 used: &[bool],
1305 query: EntryMatchQuery<'_>,
1306 ) -> Option<usize> {
1307 if let Some(key_value) = query.key {
1308 if let Some(candidates) =
1310 self.keyed
1311 .get(&(query.element_type, query.node_type, key_value))
1312 {
1313 for &i in candidates {
1314 if !used[i] {
1315 return Some(i);
1316 }
1317 }
1318 }
1319 } else {
1320 if let Some(candidates) =
1322 self.hashed
1323 .get(&(query.element_type, query.node_type, query.hash_code))
1324 {
1325 for &i in candidates {
1326 if !used[i]
1327 && entries[i]
1328 .element
1329 .as_ref()
1330 .equals_element(query.element.as_ref())
1331 {
1332 return Some(i);
1333 }
1334 }
1335 }
1336
1337 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
1339 for &i in candidates {
1340 if !used[i] {
1341 return Some(i);
1342 }
1343 }
1344 }
1345 }
1346
1347 None
1348 }
1349}
1350
1351impl ModifierNodeChain {
1352 pub fn new() -> Self {
1353 let mut chain = Self {
1354 entries: Vec::new(),
1355 aggregated_capabilities: NodeCapabilities::empty(),
1356 head_aggregate_child_capabilities: NodeCapabilities::empty(),
1357 head_sentinel: Box::new(SentinelNode::new()),
1358 tail_sentinel: Box::new(SentinelNode::new()),
1359 ordered_nodes: Vec::new(),
1360 scratch_old_used: Vec::new(),
1361 scratch_match_order: Vec::new(),
1362 scratch_final_slots: Vec::new(),
1363 scratch_elements: Vec::new(),
1364 };
1365 chain.sync_chain_links();
1366 chain
1367 }
1368
1369 pub fn detach_nodes(&mut self) {
1371 for entry in &self.entries {
1372 detach_node_tree(&mut **entry.node.borrow_mut());
1373 }
1374 }
1375
1376 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
1378 for entry in &self.entries {
1379 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1380 }
1381 }
1382
1383 pub fn repair_chain(&mut self) {
1386 self.sync_chain_links();
1387 }
1388
1389 pub fn update_from_slice(
1395 &mut self,
1396 elements: &[DynModifierElement],
1397 context: &mut dyn ModifierNodeContext,
1398 ) {
1399 self.update_from_ref_iter(elements.iter(), context);
1400 }
1401
1402 pub fn update_from_ref_iter<'a, I>(
1407 &mut self,
1408 elements: I,
1409 context: &mut dyn ModifierNodeContext,
1410 ) where
1411 I: Iterator<Item = &'a DynModifierElement>,
1412 {
1413 let old_len = self.entries.len();
1417 let mut fast_path_failed_at: Option<usize> = None;
1418 let mut elements_count = 0;
1419
1420 self.scratch_elements.clear();
1422
1423 for (idx, element) in elements.enumerate() {
1424 elements_count = idx + 1;
1425
1426 if fast_path_failed_at.is_none() && idx < old_len {
1427 let entry = &mut self.entries[idx];
1428 let same_type = entry.element_type == element.element_type();
1429 let same_node_type = entry.node_type == element.node_type();
1430 let same_key = entry.key == element.key();
1431 let same_hash = entry.hash_code == element.hash_code();
1432
1433 let positional_update = element.requires_update();
1436 if same_type && same_node_type && same_key && (same_hash || positional_update) {
1437 let can_update_node = {
1438 let node_borrow = entry.node.borrow();
1439 element.can_update_node(&**node_borrow)
1440 };
1441 if !can_update_node {
1442 fast_path_failed_at = Some(idx);
1443 self.scratch_elements.push(element.clone());
1444 continue;
1445 }
1446
1447 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1449 let capabilities = element.capabilities();
1450
1451 {
1453 let node_borrow = entry.node.borrow();
1454 if !node_borrow.node_state().is_attached() {
1455 drop(node_borrow);
1456 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1457 }
1458 }
1459
1460 let needs_update = !same_element || element.requires_update();
1462 if needs_update {
1463 element.update_node(&mut **entry.node.borrow_mut());
1464 entry.element = element.clone();
1465 entry.hash_code = element.hash_code();
1466 request_auto_invalidations(context, capabilities);
1467 }
1468
1469 entry.capabilities = capabilities;
1471 entry
1472 .node
1473 .borrow()
1474 .node_state()
1475 .set_capabilities(capabilities);
1476 continue;
1477 }
1478 fast_path_failed_at = Some(idx);
1480 }
1481
1482 self.scratch_elements.push(element.clone());
1484 }
1485
1486 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
1491 if elements_count < self.entries.len() {
1493 for entry in self.entries.drain(elements_count..) {
1494 request_auto_invalidations(context, entry.capabilities);
1495 detach_node_tree(&mut **entry.node.borrow_mut());
1496 }
1497 }
1498 self.sync_chain_links();
1499 return;
1500 }
1501
1502 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
1505
1506 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
1508 let processed_entries_len = self.entries.len();
1509 let old_len = old_entries.len();
1510
1511 self.scratch_old_used.clear();
1513 self.scratch_old_used.resize(old_len, false);
1514
1515 self.scratch_match_order.clear();
1516 self.scratch_match_order.resize(old_len, None);
1517
1518 let index = EntryIndex::build(&old_entries);
1520
1521 let new_elements_count = self.scratch_elements.len();
1522 self.scratch_final_slots.clear();
1523 self.scratch_final_slots.reserve(new_elements_count);
1524
1525 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
1527 self.scratch_final_slots.push(None);
1528 let element_type = element.element_type();
1529 let node_type = element.node_type();
1530 let key = element.key();
1531 let hash_code = element.hash_code();
1532 let capabilities = element.capabilities();
1533
1534 let matched_idx = index.find_match(
1536 &old_entries,
1537 &self.scratch_old_used,
1538 EntryMatchQuery {
1539 element_type,
1540 node_type,
1541 key,
1542 hash_code,
1543 element: &element,
1544 },
1545 );
1546
1547 if let Some(idx) = matched_idx {
1548 let entry = &mut old_entries[idx];
1550 let can_update_node = {
1551 let node_borrow = entry.node.borrow();
1552 element.can_update_node(&**node_borrow)
1553 };
1554 if !can_update_node {
1555 let replacement = ModifierNodeEntry::new(
1556 element_type,
1557 node_type,
1558 key,
1559 element.clone(),
1560 element.create_node(),
1561 hash_code,
1562 capabilities,
1563 );
1564 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
1565 element.update_node(&mut **replacement.node.borrow_mut());
1566 request_auto_invalidations(context, capabilities);
1567 self.scratch_final_slots[new_pos] = Some(replacement);
1568 continue;
1569 }
1570
1571 self.scratch_old_used[idx] = true;
1572 self.scratch_match_order[idx] = Some(new_pos);
1573 let moved = idx != new_pos;
1574
1575 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1577
1578 {
1580 let node_borrow = entry.node.borrow();
1581 if !node_borrow.node_state().is_attached() {
1582 drop(node_borrow);
1583 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1584 }
1585 }
1586
1587 let needs_update = !same_element || element.requires_update();
1589 if needs_update {
1590 element.update_node(&mut **entry.node.borrow_mut());
1591 entry.element = element;
1592 entry.hash_code = hash_code;
1593 request_auto_invalidations(context, capabilities);
1594 }
1595 if moved {
1596 request_auto_invalidations(context, capabilities);
1597 }
1598
1599 entry.key = key;
1601 entry.element_type = element_type;
1602 entry.node_type = node_type;
1603 entry.capabilities = capabilities;
1604 entry
1605 .node
1606 .borrow()
1607 .node_state()
1608 .set_capabilities(capabilities);
1609 } else {
1610 let entry = ModifierNodeEntry::new(
1612 element_type,
1613 node_type,
1614 key,
1615 element.clone(),
1616 element.create_node(),
1617 hash_code,
1618 capabilities,
1619 );
1620 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1621 element.update_node(&mut **entry.node.borrow_mut());
1622 request_auto_invalidations(context, capabilities);
1623 self.scratch_final_slots[new_pos] = Some(entry);
1624 }
1625 }
1626
1627 for (i, entry) in old_entries.into_iter().enumerate() {
1629 if self.scratch_old_used[i] {
1630 if let Some(pos) = self.scratch_match_order[i] {
1631 self.scratch_final_slots[pos] = Some(entry);
1632 } else {
1633 request_auto_invalidations(context, entry.capabilities);
1634 detach_node_tree(&mut **entry.node.borrow_mut());
1635 }
1636 } else {
1637 request_auto_invalidations(context, entry.capabilities);
1638 detach_node_tree(&mut **entry.node.borrow_mut());
1639 }
1640 }
1641
1642 self.entries.reserve(self.scratch_final_slots.len());
1644 for slot in self.scratch_final_slots.drain(..) {
1645 if let Some(entry) = slot {
1646 self.entries.push(entry);
1647 } else {
1648 log::error!("modifier reconciliation produced an empty final slot");
1649 }
1650 }
1651
1652 debug_assert_eq!(
1653 self.entries.len(),
1654 processed_entries_len + new_elements_count
1655 );
1656 self.sync_chain_links();
1657 }
1658
1659 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
1663 where
1664 I: IntoIterator<Item = DynModifierElement>,
1665 {
1666 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
1667 self.update_from_slice(&collected, context);
1668 }
1669
1670 pub fn reset(&mut self) {
1673 for entry in &mut self.entries {
1674 reset_node_tree(&mut **entry.node.borrow_mut());
1675 }
1676 }
1677
1678 pub fn detach_all(&mut self) {
1680 for entry in std::mem::take(&mut self.entries) {
1681 detach_node_tree(&mut **entry.node.borrow_mut());
1682 {
1683 let node_borrow = entry.node.borrow();
1684 let state = node_borrow.node_state();
1685 state.set_capabilities(NodeCapabilities::empty());
1686 }
1687 }
1688 self.aggregated_capabilities = NodeCapabilities::empty();
1689 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
1690 self.ordered_nodes.clear();
1691 self.sync_chain_links();
1692 }
1693
1694 pub fn len(&self) -> usize {
1695 self.entries.len()
1696 }
1697
1698 pub fn is_empty(&self) -> bool {
1699 self.entries.is_empty()
1700 }
1701
1702 pub fn capabilities(&self) -> NodeCapabilities {
1704 self.aggregated_capabilities
1705 }
1706
1707 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
1709 self.aggregated_capabilities.contains(capability)
1710 }
1711
1712 pub fn head(&self) -> ModifierChainNodeRef<'_> {
1714 self.make_node_ref(NodeLink::Head)
1715 }
1716
1717 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
1719 self.make_node_ref(NodeLink::Tail)
1720 }
1721
1722 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
1724 ModifierChainIter::forward(self)
1725 }
1726
1727 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
1729 ModifierChainIter::backward(self)
1730 }
1731
1732 pub fn for_each_forward<F>(&self, mut f: F)
1734 where
1735 F: FnMut(ModifierChainNodeRef<'_>),
1736 {
1737 for node in self.head_to_tail() {
1738 f(node);
1739 }
1740 }
1741
1742 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
1744 where
1745 F: FnMut(ModifierChainNodeRef<'_>),
1746 {
1747 if mask.is_empty() {
1748 self.for_each_forward(f);
1749 return;
1750 }
1751
1752 if !self.head().aggregate_child_capabilities().intersects(mask) {
1753 return;
1754 }
1755
1756 for node in self.head_to_tail() {
1757 if node.kind_set().intersects(mask) {
1758 f(node);
1759 }
1760 }
1761 }
1762
1763 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
1765 where
1766 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
1767 {
1768 self.for_each_forward_matching(mask, |node_ref| {
1769 node_ref.with_node(|node| f(node_ref.clone(), node));
1770 });
1771 }
1772
1773 pub fn for_each_backward<F>(&self, mut f: F)
1775 where
1776 F: FnMut(ModifierChainNodeRef<'_>),
1777 {
1778 for node in self.tail_to_head() {
1779 f(node);
1780 }
1781 }
1782
1783 pub fn for_each_backward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
1785 where
1786 F: FnMut(ModifierChainNodeRef<'_>),
1787 {
1788 if mask.is_empty() {
1789 self.for_each_backward(f);
1790 return;
1791 }
1792
1793 if !self.head().aggregate_child_capabilities().intersects(mask) {
1794 return;
1795 }
1796
1797 for node in self.tail_to_head() {
1798 if node.kind_set().intersects(mask) {
1799 f(node);
1800 }
1801 }
1802 }
1803
1804 pub fn node_ref_at(&self, index: usize) -> Option<ModifierChainNodeRef<'_>> {
1806 if index >= self.entries.len() {
1807 None
1808 } else {
1809 Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))))
1810 }
1811 }
1812
1813 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
1815 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
1816 node as *const dyn ModifierNode as *const ()
1817 }
1818
1819 let target = node_data_ptr(node);
1820 for (index, entry) in self.entries.iter().enumerate() {
1821 if node_data_ptr(&**entry.node.borrow()) == target {
1822 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
1823 }
1824 }
1825
1826 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
1827 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
1828 return None;
1829 }
1830 let matches_target = match link {
1831 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
1832 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
1833 NodeLink::Entry(path) => {
1834 let node_borrow = self.entries[path.entry()].node.borrow();
1835 node_data_ptr(&**node_borrow) == target
1836 }
1837 };
1838 if matches_target {
1839 Some(self.make_node_ref(*link))
1840 } else {
1841 None
1842 }
1843 })
1844 }
1845
1846 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
1849 self.entries.get(index).and_then(|entry| {
1850 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
1851 boxed_node.as_any().downcast_ref::<N>()
1852 })
1853 .ok()
1854 })
1855 }
1856
1857 pub fn node_mut<N: ModifierNode + 'static>(
1860 &self,
1861 index: usize,
1862 ) -> Option<std::cell::RefMut<'_, N>> {
1863 self.entries.get(index).and_then(|entry| {
1864 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
1865 boxed_node.as_any_mut().downcast_mut::<N>()
1866 })
1867 .ok()
1868 })
1869 }
1870
1871 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
1874 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
1875 }
1876
1877 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
1879 self.aggregated_capabilities
1880 .contains(NodeCapabilities::for_invalidation(kind))
1881 }
1882
1883 pub fn visit_nodes<F>(&self, mut f: F)
1885 where
1886 F: FnMut(&dyn ModifierNode, NodeCapabilities),
1887 {
1888 for (link, cached_caps, _agg) in &self.ordered_nodes {
1889 match link {
1890 NodeLink::Head => {
1891 f(self.head_sentinel.as_ref(), *cached_caps);
1892 }
1893 NodeLink::Tail => {
1894 f(self.tail_sentinel.as_ref(), *cached_caps);
1895 }
1896 NodeLink::Entry(path) => {
1897 let node_borrow = self.entries[path.entry()].node.borrow();
1898 if path.delegates().is_empty() {
1899 f(&**node_borrow, *cached_caps);
1900 } else {
1901 let mut current: &dyn ModifierNode = &**node_borrow;
1902 for &delegate_index in path.delegates() {
1903 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
1904 current = delegate;
1905 } else {
1906 return; }
1908 }
1909 f(current, *cached_caps);
1910 }
1911 }
1912 }
1913 }
1914 }
1915
1916 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
1918 where
1919 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
1920 {
1921 for index in 0..self.ordered_nodes.len() {
1922 let (link, cached_caps, _agg) = self.ordered_nodes[index];
1923 match link {
1924 NodeLink::Head => {
1925 f(self.head_sentinel.as_mut(), cached_caps);
1926 }
1927 NodeLink::Tail => {
1928 f(self.tail_sentinel.as_mut(), cached_caps);
1929 }
1930 NodeLink::Entry(path) => {
1931 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
1932 if path.delegates().is_empty() {
1933 f(&mut **node_borrow, cached_caps);
1934 } else {
1935 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
1936 for &delegate_index in path.delegates() {
1937 if let Some(delegate) =
1938 nth_delegate_mut(current, delegate_index as usize)
1939 {
1940 current = delegate;
1941 } else {
1942 return; }
1944 }
1945 f(current, cached_caps);
1946 }
1947 }
1948 }
1949 }
1950 }
1951
1952 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
1953 ModifierChainNodeRef {
1954 chain: self,
1955 link,
1956 cached_capabilities: None,
1957 cached_aggregate_child: None,
1958 }
1959 }
1960
1961 fn make_node_ref_with_caps(
1962 &self,
1963 link: NodeLink,
1964 caps: NodeCapabilities,
1965 aggregate_child: NodeCapabilities,
1966 ) -> ModifierChainNodeRef<'_> {
1967 ModifierChainNodeRef {
1968 chain: self,
1969 link,
1970 cached_capabilities: Some(caps),
1971 cached_aggregate_child: Some(aggregate_child),
1972 }
1973 }
1974
1975 fn sync_chain_links(&mut self) {
1976 self.rebuild_ordered_nodes();
1977
1978 self.head_sentinel.node_state().set_parent_link(None);
1979 self.tail_sentinel.node_state().set_child_link(None);
1980
1981 if self.ordered_nodes.is_empty() {
1982 self.head_sentinel
1983 .node_state()
1984 .set_child_link(Some(NodeLink::Tail));
1985 self.tail_sentinel
1986 .node_state()
1987 .set_parent_link(Some(NodeLink::Head));
1988 self.aggregated_capabilities = NodeCapabilities::empty();
1989 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
1990 self.head_sentinel
1991 .node_state()
1992 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1993 self.tail_sentinel
1994 .node_state()
1995 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1996 return;
1997 }
1998
1999 let mut previous = NodeLink::Head;
2000 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
2001 match &previous {
2003 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
2004 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
2005 NodeLink::Entry(path) => {
2006 let node_borrow = self.entries[path.entry()].node.borrow();
2007 if path.delegates().is_empty() {
2009 node_borrow.node_state().set_child_link(Some(link));
2010 } else {
2011 let mut current: &dyn ModifierNode = &**node_borrow;
2012 for &delegate_index in path.delegates() {
2013 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2014 current = delegate;
2015 }
2016 }
2017 current.node_state().set_child_link(Some(link));
2018 }
2019 }
2020 }
2021 match &link {
2023 NodeLink::Head => self
2024 .head_sentinel
2025 .node_state()
2026 .set_parent_link(Some(previous)),
2027 NodeLink::Tail => self
2028 .tail_sentinel
2029 .node_state()
2030 .set_parent_link(Some(previous)),
2031 NodeLink::Entry(path) => {
2032 let node_borrow = self.entries[path.entry()].node.borrow();
2033 if path.delegates().is_empty() {
2035 node_borrow.node_state().set_parent_link(Some(previous));
2036 } else {
2037 let mut current: &dyn ModifierNode = &**node_borrow;
2038 for &delegate_index in path.delegates() {
2039 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2040 current = delegate;
2041 }
2042 }
2043 current.node_state().set_parent_link(Some(previous));
2044 }
2045 }
2046 }
2047 previous = link;
2048 }
2049
2050 match &previous {
2052 NodeLink::Head => self
2053 .head_sentinel
2054 .node_state()
2055 .set_child_link(Some(NodeLink::Tail)),
2056 NodeLink::Tail => self
2057 .tail_sentinel
2058 .node_state()
2059 .set_child_link(Some(NodeLink::Tail)),
2060 NodeLink::Entry(path) => {
2061 let node_borrow = self.entries[path.entry()].node.borrow();
2062 if path.delegates().is_empty() {
2064 node_borrow
2065 .node_state()
2066 .set_child_link(Some(NodeLink::Tail));
2067 } else {
2068 let mut current: &dyn ModifierNode = &**node_borrow;
2069 for &delegate_index in path.delegates() {
2070 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2071 current = delegate;
2072 }
2073 }
2074 current.node_state().set_child_link(Some(NodeLink::Tail));
2075 }
2076 }
2077 }
2078 self.tail_sentinel
2079 .node_state()
2080 .set_parent_link(Some(previous));
2081 self.tail_sentinel.node_state().set_child_link(None);
2082
2083 let mut aggregate = NodeCapabilities::empty();
2084 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
2085 aggregate |= *cached_caps;
2086 *cached_aggregate = aggregate;
2087 match link {
2089 NodeLink::Head => {
2090 self.head_sentinel
2091 .node_state()
2092 .set_aggregate_child_capabilities(aggregate);
2093 }
2094 NodeLink::Tail => {
2095 self.tail_sentinel
2096 .node_state()
2097 .set_aggregate_child_capabilities(aggregate);
2098 }
2099 NodeLink::Entry(path) => {
2100 let node_borrow = self.entries[path.entry()].node.borrow();
2101 let state = if path.delegates().is_empty() {
2102 node_borrow.node_state()
2103 } else {
2104 let mut current: &dyn ModifierNode = &**node_borrow;
2105 for &delegate_index in path.delegates() {
2106 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2107 current = delegate;
2108 }
2109 }
2110 current.node_state()
2111 };
2112 state.set_aggregate_child_capabilities(aggregate);
2113 }
2114 }
2115 }
2116
2117 self.aggregated_capabilities = aggregate;
2118 self.head_aggregate_child_capabilities = aggregate;
2119 self.head_sentinel
2120 .node_state()
2121 .set_aggregate_child_capabilities(aggregate);
2122 self.tail_sentinel
2123 .node_state()
2124 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2125 }
2126
2127 fn rebuild_ordered_nodes(&mut self) {
2128 self.ordered_nodes.clear();
2129 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
2130 for (index, entry) in self.entries.iter().enumerate() {
2131 let node_borrow = entry.node.borrow();
2132 Self::enumerate_link_order(
2133 &**node_borrow,
2134 index,
2135 &mut path_buf,
2136 0,
2137 &mut self.ordered_nodes,
2138 );
2139 }
2140 }
2141
2142 fn enumerate_link_order(
2143 node: &dyn ModifierNode,
2144 entry: usize,
2145 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
2146 path_len: usize,
2147 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2148 ) {
2149 let caps = node.node_state().capabilities();
2150 out.push((
2151 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
2152 caps,
2153 NodeCapabilities::empty(),
2154 ));
2155 let mut delegate_index = 0usize;
2156 node.for_each_delegate(&mut |child| {
2157 if path_len < MAX_DELEGATE_DEPTH {
2158 path_buf[path_len] = delegate_index;
2159 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
2160 }
2161 delegate_index += 1;
2162 });
2163 }
2164}
2165
2166impl<'a> ModifierChainNodeRef<'a> {
2167 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
2170 match &self.link {
2171 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
2172 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
2173 NodeLink::Entry(path) => {
2174 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2175 if path.delegates().is_empty() {
2177 f(node_borrow.node_state())
2178 } else {
2179 let mut current: &dyn ModifierNode = &**node_borrow;
2181 for &delegate_index in path.delegates() {
2182 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2183 current = delegate;
2184 } else {
2185 return f(node_borrow.node_state());
2187 }
2188 }
2189 f(current.node_state())
2190 }
2191 }
2192 }
2193 }
2194
2195 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
2198 match &self.link {
2199 NodeLink::Head => None, NodeLink::Tail => None, NodeLink::Entry(path) => {
2202 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2203 if path.delegates().is_empty() {
2205 Some(f(&**node_borrow))
2206 } else {
2207 let mut current: &dyn ModifierNode = &**node_borrow;
2209 for &delegate_index in path.delegates() {
2210 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2211 current = delegate;
2212 } else {
2213 return None;
2215 }
2216 }
2217 Some(f(current))
2218 }
2219 }
2220 }
2221 }
2222
2223 #[inline]
2225 pub fn parent(&self) -> Option<Self> {
2226 self.with_state(|state| state.parent_link())
2227 .map(|link| self.chain.make_node_ref(link))
2228 }
2229
2230 #[inline]
2232 pub fn child(&self) -> Option<Self> {
2233 self.with_state(|state| state.child_link())
2234 .map(|link| self.chain.make_node_ref(link))
2235 }
2236
2237 #[inline]
2239 pub fn kind_set(&self) -> NodeCapabilities {
2240 if let Some(caps) = self.cached_capabilities {
2241 return caps;
2242 }
2243 match &self.link {
2244 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
2245 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
2246 }
2247 }
2248
2249 pub fn entry_index(&self) -> Option<usize> {
2251 match &self.link {
2252 NodeLink::Entry(path) => Some(path.entry()),
2253 _ => None,
2254 }
2255 }
2256
2257 pub fn delegate_depth(&self) -> usize {
2259 match &self.link {
2260 NodeLink::Entry(path) => path.delegates().len(),
2261 _ => 0,
2262 }
2263 }
2264
2265 #[inline]
2267 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
2268 if let Some(agg) = self.cached_aggregate_child {
2269 return agg;
2270 }
2271 if self.is_tail() {
2272 NodeCapabilities::empty()
2273 } else {
2274 self.with_state(|state| state.aggregate_child_capabilities())
2275 }
2276 }
2277
2278 pub fn is_head(&self) -> bool {
2280 matches!(self.link, NodeLink::Head)
2281 }
2282
2283 pub fn is_tail(&self) -> bool {
2285 matches!(self.link, NodeLink::Tail)
2286 }
2287
2288 pub fn is_sentinel(&self) -> bool {
2290 matches!(self.link, NodeLink::Head | NodeLink::Tail)
2291 }
2292
2293 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
2295 !mask.is_empty() && self.kind_set().intersects(mask)
2296 }
2297
2298 pub fn visit_descendants<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.child()
2307 };
2308 while let Some(node) = current {
2309 if node.is_tail() {
2310 break;
2311 }
2312 if !node.is_sentinel() {
2313 f(node.clone());
2314 }
2315 current = node.child();
2316 }
2317 }
2318
2319 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2321 where
2322 F: FnMut(ModifierChainNodeRef<'a>),
2323 {
2324 if mask.is_empty() {
2325 self.visit_descendants(include_self, f);
2326 return;
2327 }
2328
2329 if !self.aggregate_child_capabilities().intersects(mask) {
2330 return;
2331 }
2332
2333 self.visit_descendants(include_self, |node| {
2334 if node.kind_set().intersects(mask) {
2335 f(node);
2336 }
2337 });
2338 }
2339
2340 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
2342 where
2343 F: FnMut(ModifierChainNodeRef<'a>),
2344 {
2345 let mut current = if include_self {
2346 Some(self)
2347 } else {
2348 self.parent()
2349 };
2350 while let Some(node) = current {
2351 if node.is_head() {
2352 break;
2353 }
2354 f(node.clone());
2355 current = node.parent();
2356 }
2357 }
2358
2359 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2361 where
2362 F: FnMut(ModifierChainNodeRef<'a>),
2363 {
2364 if mask.is_empty() {
2365 self.visit_ancestors(include_self, f);
2366 return;
2367 }
2368
2369 self.visit_ancestors(include_self, |node| {
2370 if node.kind_set().intersects(mask) {
2371 f(node);
2372 }
2373 });
2374 }
2375
2376 pub fn find_parent_focus_target(&self) -> Option<ModifierChainNodeRef<'a>> {
2381 let mut result = None;
2382 self.clone()
2383 .visit_ancestors_matching(false, NodeCapabilities::FOCUS, |node| {
2384 if result.is_none() {
2385 result = Some(node);
2386 }
2387 });
2388 result
2389 }
2390
2391 pub fn find_first_focus_target(&self) -> Option<ModifierChainNodeRef<'a>> {
2396 let mut result = None;
2397 self.clone()
2398 .visit_descendants_matching(false, NodeCapabilities::FOCUS, |node| {
2399 if result.is_none() {
2400 result = Some(node);
2401 }
2402 });
2403 result
2404 }
2405
2406 pub fn has_focus_capability_in_ancestors(&self) -> bool {
2408 let mut found = false;
2409 self.clone()
2410 .visit_ancestors_matching(true, NodeCapabilities::FOCUS, |_| {
2411 found = true;
2412 });
2413 found
2414 }
2415}
2416
2417#[cfg(test)]
2418#[path = "tests/modifier_tests.rs"]
2419mod tests;