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 fn create_behind_draw_closure(
548 &self,
549 ) -> Option<Rc<dyn Fn(Size) -> Vec<cranpose_ui_graphics::DrawPrimitive>>> {
550 None
551 }
552}
553
554pub trait PointerInputNode: ModifierNode {
560 fn on_pointer_event(
563 &mut self,
564 _context: &mut dyn ModifierNodeContext,
565 _event: &PointerEvent,
566 ) -> bool {
567 false
568 }
569
570 fn hit_test(&self, _x: f32, _y: f32) -> bool {
573 true
574 }
575
576 fn pointer_input_handler(&self) -> Option<Rc<dyn Fn(PointerEvent)>> {
578 None
579 }
580}
581
582pub trait SemanticsNode: ModifierNode {
588 fn merge_semantics(&self, _config: &mut SemanticsConfiguration) {
590 }
592}
593
594#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
599pub enum FocusState {
600 Active,
602 ActiveParent,
604 Captured,
608 #[default]
611 Inactive,
612}
613
614impl FocusState {
615 pub fn is_focused(self) -> bool {
617 matches!(self, FocusState::Active | FocusState::Captured)
618 }
619
620 pub fn has_focus(self) -> bool {
622 matches!(
623 self,
624 FocusState::Active | FocusState::ActiveParent | FocusState::Captured
625 )
626 }
627
628 pub fn is_captured(self) -> bool {
630 matches!(self, FocusState::Captured)
631 }
632}
633
634pub trait FocusNode: ModifierNode {
639 fn focus_state(&self) -> FocusState;
641
642 fn on_focus_changed(&mut self, _context: &mut dyn ModifierNodeContext, _state: FocusState) {
644 }
646}
647
648#[derive(Clone, Debug, Default, PartialEq)]
650pub struct SemanticsConfiguration {
651 pub content_description: Option<String>,
652 pub is_button: bool,
653 pub is_clickable: bool,
654 pub is_editable_text: bool,
655 pub text_selection: Option<crate::text::TextRange>,
656}
657
658impl SemanticsConfiguration {
659 pub fn merge(&mut self, other: &SemanticsConfiguration) {
660 if let Some(description) = &other.content_description {
661 self.content_description = Some(description.clone());
662 }
663 self.is_button |= other.is_button;
664 self.is_clickable |= other.is_clickable;
665 self.is_editable_text |= other.is_editable_text;
666 if let Some(selection) = other.text_selection {
667 self.text_selection = Some(selection);
668 }
669 }
670}
671
672impl fmt::Debug for dyn ModifierNode {
673 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
674 f.debug_struct("ModifierNode").finish_non_exhaustive()
675 }
676}
677
678impl dyn ModifierNode {
679 pub fn as_any(&self) -> &dyn Any {
680 self
681 }
682
683 pub fn as_any_mut(&mut self) -> &mut dyn Any {
684 self
685 }
686}
687
688pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
691 type Node: ModifierNode;
692
693 fn create(&self) -> Self::Node;
695
696 fn update(&self, node: &mut Self::Node);
698
699 fn key(&self) -> Option<u64> {
701 None
702 }
703
704 fn inspector_name(&self) -> &'static str {
706 type_name::<Self>()
707 }
708
709 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
711
712 fn capabilities(&self) -> NodeCapabilities {
715 NodeCapabilities::default()
716 }
717
718 fn always_update(&self) -> bool {
724 false
725 }
726
727 fn auto_invalidate_on_update(&self) -> bool {
730 true
731 }
732
733 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
740 None
741 }
742}
743
744#[derive(Clone, Copy, PartialEq, Eq, Hash)]
746pub struct NodeCapabilities(u32);
747
748impl NodeCapabilities {
749 pub const NONE: Self = Self(0);
751 pub const LAYOUT: Self = Self(1 << 0);
753 pub const DRAW: Self = Self(1 << 1);
755 pub const POINTER_INPUT: Self = Self(1 << 2);
757 pub const SEMANTICS: Self = Self(1 << 3);
759 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
761 pub const FOCUS: Self = Self(1 << 5);
763
764 pub const fn empty() -> Self {
766 Self::NONE
767 }
768
769 pub const fn contains(self, other: Self) -> bool {
771 (self.0 & other.0) == other.0
772 }
773
774 pub const fn intersects(self, other: Self) -> bool {
776 (self.0 & other.0) != 0
777 }
778
779 pub fn insert(&mut self, other: Self) {
781 self.0 |= other.0;
782 }
783
784 pub const fn bits(self) -> u32 {
786 self.0
787 }
788
789 pub const fn is_empty(self) -> bool {
791 self.0 == 0
792 }
793
794 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
796 match kind {
797 InvalidationKind::Layout => Self::LAYOUT,
798 InvalidationKind::Draw => Self::DRAW,
799 InvalidationKind::PointerInput => Self::POINTER_INPUT,
800 InvalidationKind::Semantics => Self::SEMANTICS,
801 InvalidationKind::Focus => Self::FOCUS,
802 }
803 }
804}
805
806impl Default for NodeCapabilities {
807 fn default() -> Self {
808 Self::NONE
809 }
810}
811
812impl fmt::Debug for NodeCapabilities {
813 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
814 f.debug_struct("NodeCapabilities")
815 .field("layout", &self.contains(Self::LAYOUT))
816 .field("draw", &self.contains(Self::DRAW))
817 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
818 .field("semantics", &self.contains(Self::SEMANTICS))
819 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
820 .field("focus", &self.contains(Self::FOCUS))
821 .finish()
822 }
823}
824
825impl BitOr for NodeCapabilities {
826 type Output = Self;
827
828 fn bitor(self, rhs: Self) -> Self::Output {
829 Self(self.0 | rhs.0)
830 }
831}
832
833impl BitOrAssign for NodeCapabilities {
834 fn bitor_assign(&mut self, rhs: Self) {
835 self.0 |= rhs.0;
836 }
837}
838
839#[derive(Clone, Copy, Debug, PartialEq, Eq)]
841pub struct ModifierInvalidation {
842 kind: InvalidationKind,
843 capabilities: NodeCapabilities,
844}
845
846impl ModifierInvalidation {
847 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
849 Self { kind, capabilities }
850 }
851
852 pub const fn kind(self) -> InvalidationKind {
854 self.kind
855 }
856
857 pub const fn capabilities(self) -> NodeCapabilities {
859 self.capabilities
860 }
861}
862
863pub trait AnyModifierElement: fmt::Debug {
865 fn node_type(&self) -> TypeId;
866
867 fn element_type(&self) -> TypeId;
868
869 fn create_node(&self) -> Box<dyn ModifierNode>;
870
871 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
872
873 fn update_node(&self, node: &mut dyn ModifierNode);
874
875 fn key(&self) -> Option<u64>;
876
877 fn capabilities(&self) -> NodeCapabilities {
878 NodeCapabilities::default()
879 }
880
881 fn hash_code(&self) -> u64;
882
883 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
884
885 fn inspector_name(&self) -> &'static str;
886
887 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
888
889 fn requires_update(&self) -> bool;
890
891 fn auto_invalidates_on_update(&self) -> bool;
892
893 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
894
895 fn as_any(&self) -> &dyn Any;
896}
897
898struct TypedModifierElement<E: ModifierNodeElement> {
899 element: E,
900 cached_hash: u64,
901}
902
903impl<E: ModifierNodeElement> TypedModifierElement<E> {
904 fn new(element: E) -> Self {
905 let mut hasher = default::new();
906 element.hash(&mut hasher);
907 Self {
908 element,
909 cached_hash: hasher.finish(),
910 }
911 }
912}
913
914impl<E> fmt::Debug for TypedModifierElement<E>
915where
916 E: ModifierNodeElement,
917{
918 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
919 f.debug_struct("TypedModifierElement")
920 .field("type", &type_name::<E>())
921 .finish()
922 }
923}
924
925impl<E> AnyModifierElement for TypedModifierElement<E>
926where
927 E: ModifierNodeElement,
928{
929 fn node_type(&self) -> TypeId {
930 TypeId::of::<E::Node>()
931 }
932
933 fn element_type(&self) -> TypeId {
934 TypeId::of::<E>()
935 }
936
937 fn create_node(&self) -> Box<dyn ModifierNode> {
938 Box::new(self.element.create())
939 }
940
941 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
942 node.as_any().is::<E::Node>()
943 }
944
945 fn update_node(&self, node: &mut dyn ModifierNode) {
946 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
947 self.element.update(typed);
948 }
949 }
950
951 fn key(&self) -> Option<u64> {
952 self.element.key()
953 }
954
955 fn capabilities(&self) -> NodeCapabilities {
956 self.element.capabilities()
957 }
958
959 fn hash_code(&self) -> u64 {
960 self.cached_hash
961 }
962
963 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
964 other
965 .as_any()
966 .downcast_ref::<Self>()
967 .map(|typed| typed.element == self.element)
968 .unwrap_or(false)
969 }
970
971 fn inspector_name(&self) -> &'static str {
972 self.element.inspector_name()
973 }
974
975 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
976 self.element.inspector_properties(visitor);
977 }
978
979 fn requires_update(&self) -> bool {
980 self.element.always_update()
981 }
982
983 fn auto_invalidates_on_update(&self) -> bool {
984 self.element.auto_invalidate_on_update()
985 }
986
987 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
988 self.element.update_invalidation_kind()
989 }
990
991 fn as_any(&self) -> &dyn Any {
992 self
993 }
994}
995
996fn request_update_auto_invalidations(
997 element: &dyn AnyModifierElement,
998 context: &mut dyn ModifierNodeContext,
999 capabilities: NodeCapabilities,
1000) {
1001 if let Some(kind) = element.update_invalidation_kind() {
1002 let capabilities = NodeCapabilities::for_invalidation(kind);
1003 context.push_active_capabilities(capabilities);
1004 context.invalidate(kind);
1005 context.pop_active_capabilities();
1006 } else if element.auto_invalidates_on_update() {
1007 request_auto_invalidations(context, capabilities);
1008 }
1009}
1010
1011pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
1014 Rc::new(TypedModifierElement::new(element))
1015}
1016
1017pub type DynModifierElement = Rc<dyn AnyModifierElement>;
1019
1020#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1021enum TraversalDirection {
1022 Forward,
1023 Backward,
1024}
1025
1026pub struct ModifierChainIter<'a> {
1031 chain: &'a ModifierNodeChain,
1032 cursor: usize,
1035 remaining: usize,
1037 direction: TraversalDirection,
1038}
1039
1040impl<'a> ModifierChainIter<'a> {
1041 fn forward(chain: &'a ModifierNodeChain) -> Self {
1042 Self {
1043 chain,
1044 cursor: 0,
1045 remaining: chain.ordered_nodes.len(),
1046 direction: TraversalDirection::Forward,
1047 }
1048 }
1049
1050 fn backward(chain: &'a ModifierNodeChain) -> Self {
1051 let len = chain.ordered_nodes.len();
1052 Self {
1053 chain,
1054 cursor: len.wrapping_sub(1),
1055 remaining: len,
1056 direction: TraversalDirection::Backward,
1057 }
1058 }
1059}
1060
1061impl<'a> Iterator for ModifierChainIter<'a> {
1062 type Item = ModifierChainNodeRef<'a>;
1063
1064 #[inline]
1065 fn next(&mut self) -> Option<Self::Item> {
1066 if self.remaining == 0 {
1067 return None;
1068 }
1069 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
1070 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
1071 self.remaining -= 1;
1072 match self.direction {
1073 TraversalDirection::Forward => self.cursor += 1,
1074 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
1075 }
1076 Some(node_ref)
1077 }
1078
1079 #[inline]
1080 fn size_hint(&self) -> (usize, Option<usize>) {
1081 (self.remaining, Some(self.remaining))
1082 }
1083}
1084
1085impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
1086impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
1087
1088#[derive(Debug)]
1089struct ModifierNodeEntry {
1090 element_type: TypeId,
1091 node_type: TypeId,
1092 key: Option<u64>,
1093 hash_code: u64,
1094 element: DynModifierElement,
1095 node: Rc<RefCell<Box<dyn ModifierNode>>>,
1096 capabilities: NodeCapabilities,
1097}
1098
1099impl ModifierNodeEntry {
1100 fn new(
1101 element_type: TypeId,
1102 node_type: TypeId,
1103 key: Option<u64>,
1104 element: DynModifierElement,
1105 node: Box<dyn ModifierNode>,
1106 hash_code: u64,
1107 capabilities: NodeCapabilities,
1108 ) -> Self {
1109 let node_rc = Rc::new(RefCell::new(node));
1111 let entry = Self {
1112 element_type,
1113 node_type,
1114 key,
1115 hash_code,
1116 element,
1117 node: Rc::clone(&node_rc),
1118 capabilities,
1119 };
1120 entry
1121 .node
1122 .borrow()
1123 .node_state()
1124 .set_capabilities(entry.capabilities);
1125 entry
1126 }
1127}
1128
1129fn visit_node_tree_mut(
1130 node: &mut dyn ModifierNode,
1131 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
1132) {
1133 visitor(node);
1134 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
1135}
1136
1137fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
1138 let mut current = 0usize;
1139 let mut result: Option<&dyn ModifierNode> = None;
1140 node.for_each_delegate(&mut |child| {
1141 if result.is_none() && current == target {
1142 result = Some(child);
1143 }
1144 current += 1;
1145 });
1146 result
1147}
1148
1149fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
1150 let mut current = 0usize;
1151 let mut result: Option<&mut dyn ModifierNode> = None;
1152 node.for_each_delegate_mut(&mut |child| {
1153 if result.is_none() && current == target {
1154 result = Some(child);
1155 }
1156 current += 1;
1157 });
1158 result
1159}
1160
1161fn with_node_context<F, R>(
1162 node: &mut dyn ModifierNode,
1163 context: &mut dyn ModifierNodeContext,
1164 f: F,
1165) -> R
1166where
1167 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
1168{
1169 context.push_active_capabilities(node.node_state().capabilities());
1170 let result = f(node, context);
1171 context.pop_active_capabilities();
1172 result
1173}
1174
1175fn request_auto_invalidations(
1176 context: &mut dyn ModifierNodeContext,
1177 capabilities: NodeCapabilities,
1178) {
1179 if capabilities.is_empty() {
1180 return;
1181 }
1182
1183 context.push_active_capabilities(capabilities);
1184
1185 if capabilities.contains(NodeCapabilities::LAYOUT) {
1186 context.invalidate(InvalidationKind::Layout);
1187 }
1188 if capabilities.contains(NodeCapabilities::DRAW) {
1189 context.invalidate(InvalidationKind::Draw);
1190 }
1191 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
1192 context.invalidate(InvalidationKind::PointerInput);
1193 }
1194 if capabilities.contains(NodeCapabilities::SEMANTICS) {
1195 context.invalidate(InvalidationKind::Semantics);
1196 }
1197 if capabilities.contains(NodeCapabilities::FOCUS) {
1198 context.invalidate(InvalidationKind::Focus);
1199 }
1200
1201 context.pop_active_capabilities();
1202}
1203
1204fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
1212 visit_node_tree_mut(node, &mut |n| {
1213 if !n.node_state().is_attached() {
1214 n.node_state().set_attached(true);
1215 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
1216 }
1217 });
1218}
1219
1220fn reset_node_tree(node: &mut dyn ModifierNode) {
1221 visit_node_tree_mut(node, &mut |n| n.on_reset());
1222}
1223
1224fn detach_node_tree(node: &mut dyn ModifierNode) {
1225 visit_node_tree_mut(node, &mut |n| {
1226 if n.node_state().is_attached() {
1227 n.on_detach();
1228 n.node_state().set_attached(false);
1229 }
1230 n.node_state().set_parent_link(None);
1231 n.node_state().set_child_link(None);
1232 n.node_state()
1233 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1234 });
1235}
1236
1237pub struct ModifierNodeChain {
1244 entries: Vec<ModifierNodeEntry>,
1245 aggregated_capabilities: NodeCapabilities,
1246 head_aggregate_child_capabilities: NodeCapabilities,
1247 head_sentinel: Box<SentinelNode>,
1248 tail_sentinel: Box<SentinelNode>,
1249 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
1251 scratch_old_used: Vec<bool>,
1253 scratch_match_order: Vec<Option<usize>>,
1254 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
1255 scratch_elements: Vec<DynModifierElement>,
1256}
1257
1258struct SentinelNode {
1259 state: NodeState,
1260}
1261
1262impl SentinelNode {
1263 fn new() -> Self {
1264 Self {
1265 state: NodeState::sentinel(),
1266 }
1267 }
1268}
1269
1270impl DelegatableNode for SentinelNode {
1271 fn node_state(&self) -> &NodeState {
1272 &self.state
1273 }
1274}
1275
1276impl ModifierNode for SentinelNode {}
1277
1278#[derive(Clone)]
1279pub struct ModifierChainNodeRef<'a> {
1280 chain: &'a ModifierNodeChain,
1281 link: NodeLink,
1282 cached_capabilities: Option<NodeCapabilities>,
1284 cached_aggregate_child: Option<NodeCapabilities>,
1286}
1287
1288impl Default for ModifierNodeChain {
1289 fn default() -> Self {
1290 Self::new()
1291 }
1292}
1293
1294struct EntryIndex {
1299 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1301 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1303 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
1305}
1306
1307struct EntryMatchQuery<'a> {
1308 element_type: TypeId,
1309 node_type: TypeId,
1310 key: Option<u64>,
1311 hash_code: u64,
1312 element: &'a DynModifierElement,
1313}
1314
1315impl EntryIndex {
1316 fn build(entries: &[ModifierNodeEntry]) -> Self {
1317 let mut keyed = HashMap::default();
1318 let mut hashed = HashMap::default();
1319 let mut typed = HashMap::default();
1320
1321 for (i, entry) in entries.iter().enumerate() {
1322 if let Some(key_value) = entry.key {
1323 keyed
1325 .entry((entry.element_type, entry.node_type, key_value))
1326 .or_insert_with(Vec::new)
1327 .push(i);
1328 } else {
1329 hashed
1331 .entry((entry.element_type, entry.node_type, entry.hash_code))
1332 .or_insert_with(Vec::new)
1333 .push(i);
1334 typed
1335 .entry((entry.element_type, entry.node_type))
1336 .or_insert_with(Vec::new)
1337 .push(i);
1338 }
1339 }
1340
1341 Self {
1342 keyed,
1343 hashed,
1344 typed,
1345 }
1346 }
1347
1348 fn find_match(
1355 &self,
1356 entries: &[ModifierNodeEntry],
1357 used: &[bool],
1358 query: EntryMatchQuery<'_>,
1359 ) -> Option<usize> {
1360 if let Some(key_value) = query.key {
1361 if let Some(candidates) =
1363 self.keyed
1364 .get(&(query.element_type, query.node_type, key_value))
1365 {
1366 for &i in candidates {
1367 if !used[i] {
1368 return Some(i);
1369 }
1370 }
1371 }
1372 } else {
1373 if let Some(candidates) =
1375 self.hashed
1376 .get(&(query.element_type, query.node_type, query.hash_code))
1377 {
1378 for &i in candidates {
1379 if !used[i]
1380 && entries[i]
1381 .element
1382 .as_ref()
1383 .equals_element(query.element.as_ref())
1384 {
1385 return Some(i);
1386 }
1387 }
1388 }
1389
1390 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
1392 for &i in candidates {
1393 if !used[i] {
1394 return Some(i);
1395 }
1396 }
1397 }
1398 }
1399
1400 None
1401 }
1402}
1403
1404impl ModifierNodeChain {
1405 pub fn new() -> Self {
1406 let mut chain = Self {
1407 entries: Vec::new(),
1408 aggregated_capabilities: NodeCapabilities::empty(),
1409 head_aggregate_child_capabilities: NodeCapabilities::empty(),
1410 head_sentinel: Box::new(SentinelNode::new()),
1411 tail_sentinel: Box::new(SentinelNode::new()),
1412 ordered_nodes: Vec::new(),
1413 scratch_old_used: Vec::new(),
1414 scratch_match_order: Vec::new(),
1415 scratch_final_slots: Vec::new(),
1416 scratch_elements: Vec::new(),
1417 };
1418 chain.sync_chain_links();
1419 chain
1420 }
1421
1422 pub fn detach_nodes(&mut self) {
1424 for entry in &self.entries {
1425 detach_node_tree(&mut **entry.node.borrow_mut());
1426 }
1427 }
1428
1429 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
1431 for entry in &self.entries {
1432 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1433 }
1434 }
1435
1436 pub fn repair_chain(&mut self) {
1439 self.sync_chain_links();
1440 }
1441
1442 pub fn update_from_slice(
1448 &mut self,
1449 elements: &[DynModifierElement],
1450 context: &mut dyn ModifierNodeContext,
1451 ) {
1452 self.update_from_ref_iter(elements.iter(), context);
1453 }
1454
1455 pub fn update_from_ref_iter<'a, I>(
1460 &mut self,
1461 elements: I,
1462 context: &mut dyn ModifierNodeContext,
1463 ) where
1464 I: Iterator<Item = &'a DynModifierElement>,
1465 {
1466 let old_len = self.entries.len();
1470 let mut fast_path_failed_at: Option<usize> = None;
1471 let mut elements_count = 0;
1472
1473 self.scratch_elements.clear();
1475
1476 for (idx, element) in elements.enumerate() {
1477 elements_count = idx + 1;
1478
1479 if fast_path_failed_at.is_none() && idx < old_len {
1480 let entry = &mut self.entries[idx];
1481 let same_type = entry.element_type == element.element_type();
1482 let same_node_type = entry.node_type == element.node_type();
1483 let same_key = entry.key == element.key();
1484 let same_hash = entry.hash_code == element.hash_code();
1485
1486 let positional_update = element.requires_update();
1489 if same_type && same_node_type && same_key && (same_hash || positional_update) {
1490 let can_update_node = {
1491 let node_borrow = entry.node.borrow();
1492 element.can_update_node(&**node_borrow)
1493 };
1494 if !can_update_node {
1495 fast_path_failed_at = Some(idx);
1496 self.scratch_elements.push(element.clone());
1497 continue;
1498 }
1499
1500 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1502 let capabilities = element.capabilities();
1503
1504 {
1506 let node_borrow = entry.node.borrow();
1507 if !node_borrow.node_state().is_attached() {
1508 drop(node_borrow);
1509 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1510 }
1511 }
1512
1513 let needs_update = !same_element || element.requires_update();
1515 if needs_update {
1516 element.update_node(&mut **entry.node.borrow_mut());
1517 entry.element = element.clone();
1518 entry.hash_code = element.hash_code();
1519 request_update_auto_invalidations(element.as_ref(), context, capabilities);
1520 }
1521
1522 entry.capabilities = capabilities;
1524 entry
1525 .node
1526 .borrow()
1527 .node_state()
1528 .set_capabilities(capabilities);
1529 continue;
1530 }
1531 fast_path_failed_at = Some(idx);
1533 }
1534
1535 self.scratch_elements.push(element.clone());
1537 }
1538
1539 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
1544 if elements_count < self.entries.len() {
1546 for entry in self.entries.drain(elements_count..) {
1547 request_auto_invalidations(context, entry.capabilities);
1548 detach_node_tree(&mut **entry.node.borrow_mut());
1549 }
1550 }
1551 self.sync_chain_links();
1552 return;
1553 }
1554
1555 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
1558
1559 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
1561 let processed_entries_len = self.entries.len();
1562 let old_len = old_entries.len();
1563
1564 self.scratch_old_used.clear();
1566 self.scratch_old_used.resize(old_len, false);
1567
1568 self.scratch_match_order.clear();
1569 self.scratch_match_order.resize(old_len, None);
1570
1571 let index = EntryIndex::build(&old_entries);
1573
1574 let new_elements_count = self.scratch_elements.len();
1575 self.scratch_final_slots.clear();
1576 self.scratch_final_slots.reserve(new_elements_count);
1577
1578 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
1580 self.scratch_final_slots.push(None);
1581 let element_type = element.element_type();
1582 let node_type = element.node_type();
1583 let key = element.key();
1584 let hash_code = element.hash_code();
1585 let capabilities = element.capabilities();
1586
1587 let matched_idx = index.find_match(
1589 &old_entries,
1590 &self.scratch_old_used,
1591 EntryMatchQuery {
1592 element_type,
1593 node_type,
1594 key,
1595 hash_code,
1596 element: &element,
1597 },
1598 );
1599
1600 if let Some(idx) = matched_idx {
1601 let entry = &mut old_entries[idx];
1603 let can_update_node = {
1604 let node_borrow = entry.node.borrow();
1605 element.can_update_node(&**node_borrow)
1606 };
1607 if !can_update_node {
1608 let replacement = ModifierNodeEntry::new(
1609 element_type,
1610 node_type,
1611 key,
1612 element.clone(),
1613 element.create_node(),
1614 hash_code,
1615 capabilities,
1616 );
1617 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
1618 element.update_node(&mut **replacement.node.borrow_mut());
1619 request_auto_invalidations(context, capabilities);
1620 self.scratch_final_slots[new_pos] = Some(replacement);
1621 continue;
1622 }
1623
1624 self.scratch_old_used[idx] = true;
1625 self.scratch_match_order[idx] = Some(new_pos);
1626 let moved = idx != new_pos;
1627
1628 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1630
1631 {
1633 let node_borrow = entry.node.borrow();
1634 if !node_borrow.node_state().is_attached() {
1635 drop(node_borrow);
1636 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1637 }
1638 }
1639
1640 let needs_update = !same_element || element.requires_update();
1642 if needs_update {
1643 element.update_node(&mut **entry.node.borrow_mut());
1644 entry.element = element;
1645 entry.hash_code = hash_code;
1646 request_update_auto_invalidations(
1647 entry.element.as_ref(),
1648 context,
1649 capabilities,
1650 );
1651 }
1652 if moved {
1653 request_auto_invalidations(context, capabilities);
1654 }
1655
1656 entry.key = key;
1658 entry.element_type = element_type;
1659 entry.node_type = node_type;
1660 entry.capabilities = capabilities;
1661 entry
1662 .node
1663 .borrow()
1664 .node_state()
1665 .set_capabilities(capabilities);
1666 } else {
1667 let entry = ModifierNodeEntry::new(
1669 element_type,
1670 node_type,
1671 key,
1672 element.clone(),
1673 element.create_node(),
1674 hash_code,
1675 capabilities,
1676 );
1677 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1678 element.update_node(&mut **entry.node.borrow_mut());
1679 request_auto_invalidations(context, capabilities);
1680 self.scratch_final_slots[new_pos] = Some(entry);
1681 }
1682 }
1683
1684 for (i, entry) in old_entries.into_iter().enumerate() {
1686 if self.scratch_old_used[i] {
1687 if let Some(pos) = self.scratch_match_order[i] {
1688 self.scratch_final_slots[pos] = Some(entry);
1689 } else {
1690 request_auto_invalidations(context, entry.capabilities);
1691 detach_node_tree(&mut **entry.node.borrow_mut());
1692 }
1693 } else {
1694 request_auto_invalidations(context, entry.capabilities);
1695 detach_node_tree(&mut **entry.node.borrow_mut());
1696 }
1697 }
1698
1699 self.entries.reserve(self.scratch_final_slots.len());
1701 for slot in self.scratch_final_slots.drain(..) {
1702 if let Some(entry) = slot {
1703 self.entries.push(entry);
1704 } else {
1705 log::error!("modifier reconciliation produced an empty final slot");
1706 }
1707 }
1708
1709 debug_assert_eq!(
1710 self.entries.len(),
1711 processed_entries_len + new_elements_count
1712 );
1713 self.sync_chain_links();
1714 }
1715
1716 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
1720 where
1721 I: IntoIterator<Item = DynModifierElement>,
1722 {
1723 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
1724 self.update_from_slice(&collected, context);
1725 }
1726
1727 pub fn reset(&mut self) {
1730 for entry in &mut self.entries {
1731 reset_node_tree(&mut **entry.node.borrow_mut());
1732 }
1733 }
1734
1735 pub fn detach_all(&mut self) {
1737 for entry in std::mem::take(&mut self.entries) {
1738 detach_node_tree(&mut **entry.node.borrow_mut());
1739 {
1740 let node_borrow = entry.node.borrow();
1741 let state = node_borrow.node_state();
1742 state.set_capabilities(NodeCapabilities::empty());
1743 }
1744 }
1745 self.aggregated_capabilities = NodeCapabilities::empty();
1746 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
1747 self.ordered_nodes.clear();
1748 self.sync_chain_links();
1749 }
1750
1751 pub fn len(&self) -> usize {
1752 self.entries.len()
1753 }
1754
1755 pub fn is_empty(&self) -> bool {
1756 self.entries.is_empty()
1757 }
1758
1759 pub fn capabilities(&self) -> NodeCapabilities {
1761 self.aggregated_capabilities
1762 }
1763
1764 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
1766 self.aggregated_capabilities.contains(capability)
1767 }
1768
1769 pub fn head(&self) -> ModifierChainNodeRef<'_> {
1771 self.make_node_ref(NodeLink::Head)
1772 }
1773
1774 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
1776 self.make_node_ref(NodeLink::Tail)
1777 }
1778
1779 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
1781 ModifierChainIter::forward(self)
1782 }
1783
1784 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
1786 ModifierChainIter::backward(self)
1787 }
1788
1789 pub fn for_each_forward<F>(&self, mut f: F)
1791 where
1792 F: FnMut(ModifierChainNodeRef<'_>),
1793 {
1794 for node in self.head_to_tail() {
1795 f(node);
1796 }
1797 }
1798
1799 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
1801 where
1802 F: FnMut(ModifierChainNodeRef<'_>),
1803 {
1804 if mask.is_empty() {
1805 self.for_each_forward(f);
1806 return;
1807 }
1808
1809 if !self.head().aggregate_child_capabilities().intersects(mask) {
1810 return;
1811 }
1812
1813 for node in self.head_to_tail() {
1814 if node.kind_set().intersects(mask) {
1815 f(node);
1816 }
1817 }
1818 }
1819
1820 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
1822 where
1823 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
1824 {
1825 self.for_each_forward_matching(mask, |node_ref| {
1826 node_ref.with_node(|node| f(node_ref.clone(), node));
1827 });
1828 }
1829
1830 pub fn for_each_backward<F>(&self, mut f: F)
1832 where
1833 F: FnMut(ModifierChainNodeRef<'_>),
1834 {
1835 for node in self.tail_to_head() {
1836 f(node);
1837 }
1838 }
1839
1840 pub fn for_each_backward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
1842 where
1843 F: FnMut(ModifierChainNodeRef<'_>),
1844 {
1845 if mask.is_empty() {
1846 self.for_each_backward(f);
1847 return;
1848 }
1849
1850 if !self.head().aggregate_child_capabilities().intersects(mask) {
1851 return;
1852 }
1853
1854 for node in self.tail_to_head() {
1855 if node.kind_set().intersects(mask) {
1856 f(node);
1857 }
1858 }
1859 }
1860
1861 pub fn node_ref_at(&self, index: usize) -> Option<ModifierChainNodeRef<'_>> {
1863 if index >= self.entries.len() {
1864 None
1865 } else {
1866 Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))))
1867 }
1868 }
1869
1870 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
1872 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
1873 node as *const dyn ModifierNode as *const ()
1874 }
1875
1876 let target = node_data_ptr(node);
1877 for (index, entry) in self.entries.iter().enumerate() {
1878 if node_data_ptr(&**entry.node.borrow()) == target {
1879 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
1880 }
1881 }
1882
1883 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
1884 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
1885 return None;
1886 }
1887 let matches_target = match link {
1888 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
1889 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
1890 NodeLink::Entry(path) => {
1891 let node_borrow = self.entries[path.entry()].node.borrow();
1892 node_data_ptr(&**node_borrow) == target
1893 }
1894 };
1895 if matches_target {
1896 Some(self.make_node_ref(*link))
1897 } else {
1898 None
1899 }
1900 })
1901 }
1902
1903 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
1906 self.entries.get(index).and_then(|entry| {
1907 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
1908 boxed_node.as_any().downcast_ref::<N>()
1909 })
1910 .ok()
1911 })
1912 }
1913
1914 pub fn node_mut<N: ModifierNode + 'static>(
1917 &self,
1918 index: usize,
1919 ) -> Option<std::cell::RefMut<'_, N>> {
1920 self.entries.get(index).and_then(|entry| {
1921 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
1922 boxed_node.as_any_mut().downcast_mut::<N>()
1923 })
1924 .ok()
1925 })
1926 }
1927
1928 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
1931 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
1932 }
1933
1934 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
1936 self.aggregated_capabilities
1937 .contains(NodeCapabilities::for_invalidation(kind))
1938 }
1939
1940 pub fn visit_nodes<F>(&self, mut f: F)
1942 where
1943 F: FnMut(&dyn ModifierNode, NodeCapabilities),
1944 {
1945 for (link, cached_caps, _agg) in &self.ordered_nodes {
1946 match link {
1947 NodeLink::Head => {
1948 f(self.head_sentinel.as_ref(), *cached_caps);
1949 }
1950 NodeLink::Tail => {
1951 f(self.tail_sentinel.as_ref(), *cached_caps);
1952 }
1953 NodeLink::Entry(path) => {
1954 let node_borrow = self.entries[path.entry()].node.borrow();
1955 if path.delegates().is_empty() {
1956 f(&**node_borrow, *cached_caps);
1957 } else {
1958 let mut current: &dyn ModifierNode = &**node_borrow;
1959 for &delegate_index in path.delegates() {
1960 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
1961 current = delegate;
1962 } else {
1963 return; }
1965 }
1966 f(current, *cached_caps);
1967 }
1968 }
1969 }
1970 }
1971 }
1972
1973 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
1975 where
1976 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
1977 {
1978 for index in 0..self.ordered_nodes.len() {
1979 let (link, cached_caps, _agg) = self.ordered_nodes[index];
1980 match link {
1981 NodeLink::Head => {
1982 f(self.head_sentinel.as_mut(), cached_caps);
1983 }
1984 NodeLink::Tail => {
1985 f(self.tail_sentinel.as_mut(), cached_caps);
1986 }
1987 NodeLink::Entry(path) => {
1988 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
1989 if path.delegates().is_empty() {
1990 f(&mut **node_borrow, cached_caps);
1991 } else {
1992 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
1993 for &delegate_index in path.delegates() {
1994 if let Some(delegate) =
1995 nth_delegate_mut(current, delegate_index as usize)
1996 {
1997 current = delegate;
1998 } else {
1999 return; }
2001 }
2002 f(current, cached_caps);
2003 }
2004 }
2005 }
2006 }
2007 }
2008
2009 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2010 ModifierChainNodeRef {
2011 chain: self,
2012 link,
2013 cached_capabilities: None,
2014 cached_aggregate_child: None,
2015 }
2016 }
2017
2018 fn make_node_ref_with_caps(
2019 &self,
2020 link: NodeLink,
2021 caps: NodeCapabilities,
2022 aggregate_child: NodeCapabilities,
2023 ) -> ModifierChainNodeRef<'_> {
2024 ModifierChainNodeRef {
2025 chain: self,
2026 link,
2027 cached_capabilities: Some(caps),
2028 cached_aggregate_child: Some(aggregate_child),
2029 }
2030 }
2031
2032 fn sync_chain_links(&mut self) {
2033 self.rebuild_ordered_nodes();
2034
2035 self.head_sentinel.node_state().set_parent_link(None);
2036 self.tail_sentinel.node_state().set_child_link(None);
2037
2038 if self.ordered_nodes.is_empty() {
2039 self.head_sentinel
2040 .node_state()
2041 .set_child_link(Some(NodeLink::Tail));
2042 self.tail_sentinel
2043 .node_state()
2044 .set_parent_link(Some(NodeLink::Head));
2045 self.aggregated_capabilities = NodeCapabilities::empty();
2046 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2047 self.head_sentinel
2048 .node_state()
2049 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2050 self.tail_sentinel
2051 .node_state()
2052 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2053 return;
2054 }
2055
2056 let mut previous = NodeLink::Head;
2057 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
2058 match &previous {
2060 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
2061 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
2062 NodeLink::Entry(path) => {
2063 let node_borrow = self.entries[path.entry()].node.borrow();
2064 if path.delegates().is_empty() {
2066 node_borrow.node_state().set_child_link(Some(link));
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(link));
2075 }
2076 }
2077 }
2078 match &link {
2080 NodeLink::Head => self
2081 .head_sentinel
2082 .node_state()
2083 .set_parent_link(Some(previous)),
2084 NodeLink::Tail => self
2085 .tail_sentinel
2086 .node_state()
2087 .set_parent_link(Some(previous)),
2088 NodeLink::Entry(path) => {
2089 let node_borrow = self.entries[path.entry()].node.borrow();
2090 if path.delegates().is_empty() {
2092 node_borrow.node_state().set_parent_link(Some(previous));
2093 } else {
2094 let mut current: &dyn ModifierNode = &**node_borrow;
2095 for &delegate_index in path.delegates() {
2096 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2097 current = delegate;
2098 }
2099 }
2100 current.node_state().set_parent_link(Some(previous));
2101 }
2102 }
2103 }
2104 previous = link;
2105 }
2106
2107 match &previous {
2109 NodeLink::Head => self
2110 .head_sentinel
2111 .node_state()
2112 .set_child_link(Some(NodeLink::Tail)),
2113 NodeLink::Tail => self
2114 .tail_sentinel
2115 .node_state()
2116 .set_child_link(Some(NodeLink::Tail)),
2117 NodeLink::Entry(path) => {
2118 let node_borrow = self.entries[path.entry()].node.borrow();
2119 if path.delegates().is_empty() {
2121 node_borrow
2122 .node_state()
2123 .set_child_link(Some(NodeLink::Tail));
2124 } else {
2125 let mut current: &dyn ModifierNode = &**node_borrow;
2126 for &delegate_index in path.delegates() {
2127 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2128 current = delegate;
2129 }
2130 }
2131 current.node_state().set_child_link(Some(NodeLink::Tail));
2132 }
2133 }
2134 }
2135 self.tail_sentinel
2136 .node_state()
2137 .set_parent_link(Some(previous));
2138 self.tail_sentinel.node_state().set_child_link(None);
2139
2140 let mut aggregate = NodeCapabilities::empty();
2141 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
2142 aggregate |= *cached_caps;
2143 *cached_aggregate = aggregate;
2144 match link {
2146 NodeLink::Head => {
2147 self.head_sentinel
2148 .node_state()
2149 .set_aggregate_child_capabilities(aggregate);
2150 }
2151 NodeLink::Tail => {
2152 self.tail_sentinel
2153 .node_state()
2154 .set_aggregate_child_capabilities(aggregate);
2155 }
2156 NodeLink::Entry(path) => {
2157 let node_borrow = self.entries[path.entry()].node.borrow();
2158 let state = if path.delegates().is_empty() {
2159 node_borrow.node_state()
2160 } else {
2161 let mut current: &dyn ModifierNode = &**node_borrow;
2162 for &delegate_index in path.delegates() {
2163 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2164 current = delegate;
2165 }
2166 }
2167 current.node_state()
2168 };
2169 state.set_aggregate_child_capabilities(aggregate);
2170 }
2171 }
2172 }
2173
2174 self.aggregated_capabilities = aggregate;
2175 self.head_aggregate_child_capabilities = aggregate;
2176 self.head_sentinel
2177 .node_state()
2178 .set_aggregate_child_capabilities(aggregate);
2179 self.tail_sentinel
2180 .node_state()
2181 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2182 }
2183
2184 fn rebuild_ordered_nodes(&mut self) {
2185 self.ordered_nodes.clear();
2186 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
2187 for (index, entry) in self.entries.iter().enumerate() {
2188 let node_borrow = entry.node.borrow();
2189 Self::enumerate_link_order(
2190 &**node_borrow,
2191 index,
2192 &mut path_buf,
2193 0,
2194 &mut self.ordered_nodes,
2195 );
2196 }
2197 }
2198
2199 fn enumerate_link_order(
2200 node: &dyn ModifierNode,
2201 entry: usize,
2202 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
2203 path_len: usize,
2204 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2205 ) {
2206 let caps = node.node_state().capabilities();
2207 out.push((
2208 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
2209 caps,
2210 NodeCapabilities::empty(),
2211 ));
2212 let mut delegate_index = 0usize;
2213 node.for_each_delegate(&mut |child| {
2214 if path_len < MAX_DELEGATE_DEPTH {
2215 path_buf[path_len] = delegate_index;
2216 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
2217 }
2218 delegate_index += 1;
2219 });
2220 }
2221}
2222
2223impl<'a> ModifierChainNodeRef<'a> {
2224 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
2227 match &self.link {
2228 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
2229 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
2230 NodeLink::Entry(path) => {
2231 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2232 if path.delegates().is_empty() {
2234 f(node_borrow.node_state())
2235 } else {
2236 let mut current: &dyn ModifierNode = &**node_borrow;
2238 for &delegate_index in path.delegates() {
2239 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2240 current = delegate;
2241 } else {
2242 return f(node_borrow.node_state());
2244 }
2245 }
2246 f(current.node_state())
2247 }
2248 }
2249 }
2250 }
2251
2252 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
2255 match &self.link {
2256 NodeLink::Head => None, NodeLink::Tail => None, NodeLink::Entry(path) => {
2259 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2260 if path.delegates().is_empty() {
2262 Some(f(&**node_borrow))
2263 } else {
2264 let mut current: &dyn ModifierNode = &**node_borrow;
2266 for &delegate_index in path.delegates() {
2267 current = nth_delegate(current, delegate_index as usize)?;
2269 }
2270 Some(f(current))
2271 }
2272 }
2273 }
2274 }
2275
2276 #[inline]
2278 pub fn parent(&self) -> Option<Self> {
2279 self.with_state(|state| state.parent_link())
2280 .map(|link| self.chain.make_node_ref(link))
2281 }
2282
2283 #[inline]
2285 pub fn child(&self) -> Option<Self> {
2286 self.with_state(|state| state.child_link())
2287 .map(|link| self.chain.make_node_ref(link))
2288 }
2289
2290 #[inline]
2292 pub fn kind_set(&self) -> NodeCapabilities {
2293 if let Some(caps) = self.cached_capabilities {
2294 return caps;
2295 }
2296 match &self.link {
2297 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
2298 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
2299 }
2300 }
2301
2302 pub fn entry_index(&self) -> Option<usize> {
2304 match &self.link {
2305 NodeLink::Entry(path) => Some(path.entry()),
2306 _ => None,
2307 }
2308 }
2309
2310 pub fn delegate_depth(&self) -> usize {
2312 match &self.link {
2313 NodeLink::Entry(path) => path.delegates().len(),
2314 _ => 0,
2315 }
2316 }
2317
2318 #[inline]
2320 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
2321 if let Some(agg) = self.cached_aggregate_child {
2322 return agg;
2323 }
2324 if self.is_tail() {
2325 NodeCapabilities::empty()
2326 } else {
2327 self.with_state(|state| state.aggregate_child_capabilities())
2328 }
2329 }
2330
2331 pub fn is_head(&self) -> bool {
2333 matches!(self.link, NodeLink::Head)
2334 }
2335
2336 pub fn is_tail(&self) -> bool {
2338 matches!(self.link, NodeLink::Tail)
2339 }
2340
2341 pub fn is_sentinel(&self) -> bool {
2343 matches!(self.link, NodeLink::Head | NodeLink::Tail)
2344 }
2345
2346 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
2348 !mask.is_empty() && self.kind_set().intersects(mask)
2349 }
2350
2351 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
2353 where
2354 F: FnMut(ModifierChainNodeRef<'a>),
2355 {
2356 let mut current = if include_self {
2357 Some(self)
2358 } else {
2359 self.child()
2360 };
2361 while let Some(node) = current {
2362 if node.is_tail() {
2363 break;
2364 }
2365 if !node.is_sentinel() {
2366 f(node.clone());
2367 }
2368 current = node.child();
2369 }
2370 }
2371
2372 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2374 where
2375 F: FnMut(ModifierChainNodeRef<'a>),
2376 {
2377 if mask.is_empty() {
2378 self.visit_descendants(include_self, f);
2379 return;
2380 }
2381
2382 if !self.aggregate_child_capabilities().intersects(mask) {
2383 return;
2384 }
2385
2386 self.visit_descendants(include_self, |node| {
2387 if node.kind_set().intersects(mask) {
2388 f(node);
2389 }
2390 });
2391 }
2392
2393 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
2395 where
2396 F: FnMut(ModifierChainNodeRef<'a>),
2397 {
2398 let mut current = if include_self {
2399 Some(self)
2400 } else {
2401 self.parent()
2402 };
2403 while let Some(node) = current {
2404 if node.is_head() {
2405 break;
2406 }
2407 f(node.clone());
2408 current = node.parent();
2409 }
2410 }
2411
2412 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2414 where
2415 F: FnMut(ModifierChainNodeRef<'a>),
2416 {
2417 if mask.is_empty() {
2418 self.visit_ancestors(include_self, f);
2419 return;
2420 }
2421
2422 self.visit_ancestors(include_self, |node| {
2423 if node.kind_set().intersects(mask) {
2424 f(node);
2425 }
2426 });
2427 }
2428
2429 pub fn find_parent_focus_target(&self) -> Option<ModifierChainNodeRef<'a>> {
2434 let mut result = None;
2435 self.clone()
2436 .visit_ancestors_matching(false, NodeCapabilities::FOCUS, |node| {
2437 if result.is_none() {
2438 result = Some(node);
2439 }
2440 });
2441 result
2442 }
2443
2444 pub fn find_first_focus_target(&self) -> Option<ModifierChainNodeRef<'a>> {
2449 let mut result = None;
2450 self.clone()
2451 .visit_descendants_matching(false, NodeCapabilities::FOCUS, |node| {
2452 if result.is_none() {
2453 result = Some(node);
2454 }
2455 });
2456 result
2457 }
2458
2459 pub fn has_focus_capability_in_ancestors(&self) -> bool {
2461 let mut found = false;
2462 self.clone()
2463 .visit_ancestors_matching(true, NodeCapabilities::FOCUS, |_| {
2464 found = true;
2465 });
2466 found
2467 }
2468}
2469
2470#[cfg(test)]
2471#[path = "tests/modifier_tests.rs"]
2472mod tests;