1use std::{
9 any::{Any, TypeId, type_name},
10 cell::{Cell, RefCell},
11 fmt,
12 hash::{Hash, Hasher},
13 ops::{BitOr, BitOrAssign},
14 rc::Rc,
15};
16
17use cranpose_core::{ProvidedValue, collections::map::HashMap, hash::default};
18pub use cranpose_ui_graphics::{DrawScope, Size};
19pub use cranpose_ui_layout::{Constraints, Measurable};
20
21use crate::nodes::input::types::PointerEvent;
22
23#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
26pub enum InvalidationKind {
27 Layout,
28 Draw,
29 PointerInput,
30 Semantics,
31 Focus,
32}
33
34pub trait ModifierNodeContext {
36 fn invalidate(&mut self, _kind: InvalidationKind) {}
38
39 fn request_update(&mut self) {}
42
43 fn node_id(&self) -> Option<cranpose_core::NodeId> {
46 None
47 }
48
49 fn push_active_capabilities(&mut self, _capabilities: NodeCapabilities) {}
51
52 fn pop_active_capabilities(&mut self) {}
54
55 fn density(&self) -> f32 {
60 1.0
61 }
62}
63
64#[derive(Default, Debug, Clone)]
73pub struct BasicModifierNodeContext {
74 invalidations: ModifierInvalidations,
75 update_requested: bool,
76 active_capabilities: Vec<NodeCapabilities>,
77 node_id: Option<cranpose_core::NodeId>,
78}
79
80impl BasicModifierNodeContext {
81 pub fn new() -> Self {
83 Self::default()
84 }
85
86 pub fn invalidations(&self) -> &[ModifierInvalidation] {
90 &self.invalidations
91 }
92
93 pub fn clear_invalidations(&mut self) {
95 self.invalidations.clear();
96 }
97
98 pub fn take_invalidations(&mut self) -> ModifierInvalidations {
100 std::mem::take(&mut self.invalidations)
101 }
102
103 pub fn update_requested(&self) -> bool {
106 self.update_requested
107 }
108
109 pub fn take_update_requested(&mut self) -> bool {
111 std::mem::take(&mut self.update_requested)
112 }
113
114 pub fn set_node_id(&mut self, id: Option<cranpose_core::NodeId>) {
116 self.node_id = id;
117 }
118
119 fn push_invalidation(&mut self, kind: InvalidationKind) {
120 let mut capabilities = self.current_capabilities();
121 capabilities.insert(NodeCapabilities::for_invalidation(kind));
122 if let Some(existing) = self
123 .invalidations
124 .iter_mut()
125 .find(|entry| entry.kind() == kind)
126 {
127 let updated = existing.capabilities() | capabilities;
128 *existing = ModifierInvalidation::new(kind, updated);
129 } else {
130 self.invalidations
131 .push(ModifierInvalidation::new(kind, capabilities));
132 }
133 }
134
135 fn current_capabilities(&self) -> NodeCapabilities {
136 self.active_capabilities
137 .last()
138 .copied()
139 .unwrap_or_else(NodeCapabilities::empty)
140 }
141}
142
143impl ModifierNodeContext for BasicModifierNodeContext {
144 fn invalidate(&mut self, kind: InvalidationKind) {
145 self.push_invalidation(kind);
146 }
147
148 fn request_update(&mut self) {
149 self.update_requested = true;
150 }
151
152 fn push_active_capabilities(&mut self, capabilities: NodeCapabilities) {
153 self.active_capabilities.push(capabilities);
154 }
155
156 fn pop_active_capabilities(&mut self) {
157 self.active_capabilities.pop();
158 }
159
160 fn node_id(&self) -> Option<cranpose_core::NodeId> {
161 self.node_id
162 }
163}
164
165const MAX_DELEGATE_DEPTH: usize = 3;
166
167#[derive(Copy, Clone, Debug, PartialEq, Eq)]
168pub(crate) struct NodePath {
169 entry: usize,
170 delegate_buf: [u8; MAX_DELEGATE_DEPTH],
171 delegate_len: u8,
172}
173
174impl NodePath {
175 #[inline]
176 fn root(entry: usize) -> Self {
177 Self {
178 entry,
179 delegate_buf: [0; MAX_DELEGATE_DEPTH],
180 delegate_len: 0,
181 }
182 }
183
184 #[inline]
185 fn from_slice(entry: usize, path: &[usize]) -> Self {
186 debug_assert!(
187 path.len() <= MAX_DELEGATE_DEPTH,
188 "delegate depth {} exceeds MAX_DELEGATE_DEPTH {}",
189 path.len(),
190 MAX_DELEGATE_DEPTH
191 );
192 debug_assert!(
193 path.iter().all(|&i| i <= u8::MAX as usize),
194 "delegate index exceeds u8 range"
195 );
196 let mut delegate_buf = [0u8; MAX_DELEGATE_DEPTH];
197 for (i, &v) in path.iter().enumerate().take(MAX_DELEGATE_DEPTH) {
198 delegate_buf[i] = v as u8;
199 }
200 Self {
201 entry,
202 delegate_buf,
203 delegate_len: path.len().min(MAX_DELEGATE_DEPTH) as u8,
204 }
205 }
206
207 #[inline]
208 fn entry(&self) -> usize {
209 self.entry
210 }
211
212 #[inline]
213 fn delegates(&self) -> &[u8] {
214 &self.delegate_buf[..self.delegate_len as usize]
215 }
216}
217
218#[derive(Copy, Clone, Debug, PartialEq, Eq)]
219pub(crate) enum NodeLink {
220 Head,
221 Tail,
222 Entry(NodePath),
223}
224
225#[derive(Debug)]
231pub struct NodeState {
232 aggregate_child_capabilities: Cell<NodeCapabilities>,
233 capabilities: Cell<NodeCapabilities>,
234 parent: RefCell<Option<NodeLink>>,
235 child: RefCell<Option<NodeLink>>,
236 attached: Cell<bool>,
237 is_sentinel: bool,
238}
239
240impl Default for NodeState {
241 fn default() -> Self {
242 Self::new()
243 }
244}
245
246impl NodeState {
247 pub const fn new() -> Self {
248 Self {
249 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
250 capabilities: Cell::new(NodeCapabilities::empty()),
251 parent: RefCell::new(None),
252 child: RefCell::new(None),
253 attached: Cell::new(false),
254 is_sentinel: false,
255 }
256 }
257
258 pub const fn sentinel() -> Self {
259 Self {
260 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
261 capabilities: Cell::new(NodeCapabilities::empty()),
262 parent: RefCell::new(None),
263 child: RefCell::new(None),
264 attached: Cell::new(true),
265 is_sentinel: true,
266 }
267 }
268
269 pub fn set_capabilities(&self, capabilities: NodeCapabilities) {
270 self.capabilities.set(capabilities);
271 }
272
273 #[inline]
274 pub fn capabilities(&self) -> NodeCapabilities {
275 self.capabilities.get()
276 }
277
278 pub fn set_aggregate_child_capabilities(&self, capabilities: NodeCapabilities) {
279 self.aggregate_child_capabilities.set(capabilities);
280 }
281
282 #[inline]
283 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
284 self.aggregate_child_capabilities.get()
285 }
286
287 pub(crate) fn set_parent_link(&self, parent: Option<NodeLink>) {
288 *self.parent.borrow_mut() = parent;
289 }
290
291 #[inline]
292 pub(crate) fn parent_link(&self) -> Option<NodeLink> {
293 *self.parent.borrow()
294 }
295
296 pub(crate) fn set_child_link(&self, child: Option<NodeLink>) {
297 *self.child.borrow_mut() = child;
298 }
299
300 #[inline]
301 pub(crate) fn child_link(&self) -> Option<NodeLink> {
302 *self.child.borrow()
303 }
304
305 pub fn set_attached(&self, attached: bool) {
306 self.attached.set(attached);
307 }
308
309 pub fn is_attached(&self) -> bool {
310 self.attached.get()
311 }
312
313 pub fn is_sentinel(&self) -> bool {
314 self.is_sentinel
315 }
316}
317
318pub trait DelegatableNode {
320 fn node_state(&self) -> &NodeState;
321 fn aggregate_child_capabilities(&self) -> NodeCapabilities {
322 self.node_state().aggregate_child_capabilities()
323 }
324}
325
326pub trait ModifierNode: Any + DelegatableNode {
384 fn on_attach(&mut self, _context: &mut dyn ModifierNodeContext) {}
385
386 fn on_detach(&mut self) {}
387
388 fn on_reset(&mut self) {}
389
390 fn as_draw_node(&self) -> Option<&dyn DrawModifierNode> {
392 None
393 }
394
395 fn as_draw_node_mut(&mut self) -> Option<&mut dyn DrawModifierNode> {
397 None
398 }
399
400 fn as_pointer_input_node(&self) -> Option<&dyn PointerInputNode> {
402 None
403 }
404
405 fn as_pointer_input_node_mut(&mut self) -> Option<&mut dyn PointerInputNode> {
407 None
408 }
409
410 fn as_semantics_node(&self) -> Option<&dyn SemanticsNode> {
412 None
413 }
414
415 fn as_semantics_node_mut(&mut self) -> Option<&mut dyn SemanticsNode> {
417 None
418 }
419
420 fn as_focus_node(&self) -> Option<&dyn FocusNode> {
422 None
423 }
424
425 fn as_focus_node_mut(&mut self) -> Option<&mut dyn FocusNode> {
427 None
428 }
429
430 fn as_layout_node(&self) -> Option<&dyn LayoutModifierNode> {
432 None
433 }
434
435 fn as_layout_node_mut(&mut self) -> Option<&mut dyn LayoutModifierNode> {
437 None
438 }
439
440 fn for_each_delegate<'b>(&'b self, _visitor: &mut dyn FnMut(&'b dyn ModifierNode)) {}
442
443 fn for_each_delegate_mut<'b>(&'b mut self, _visitor: &mut dyn FnMut(&'b mut dyn ModifierNode)) {
445 }
446}
447
448pub trait LayoutModifierNode: ModifierNode {
454 fn measure(
476 &self,
477 _context: &mut dyn ModifierNodeContext,
478 measurable: &dyn Measurable,
479 constraints: Constraints,
480 ) -> cranpose_ui_layout::LayoutModifierMeasureResult {
481 let placeable = measurable.measure(constraints);
482 cranpose_ui_layout::LayoutModifierMeasureResult::with_size(Size {
483 width: placeable.width(),
484 height: placeable.height(),
485 })
486 }
487
488 fn min_intrinsic_width(
490 &self,
491 _measurable: &dyn Measurable,
492 _height: f32,
493 _density: f32,
494 ) -> f32 {
495 0.0
496 }
497
498 fn max_intrinsic_width(
500 &self,
501 _measurable: &dyn Measurable,
502 _height: f32,
503 _density: f32,
504 ) -> f32 {
505 0.0
506 }
507
508 fn min_intrinsic_height(
510 &self,
511 _measurable: &dyn Measurable,
512 _width: f32,
513 _density: f32,
514 ) -> f32 {
515 0.0
516 }
517
518 fn max_intrinsic_height(
520 &self,
521 _measurable: &dyn Measurable,
522 _width: f32,
523 _density: f32,
524 ) -> f32 {
525 0.0
526 }
527}
528
529pub trait DrawModifierNode: ModifierNode {
536 fn create_draw_closure(&self) -> Option<NodeDrawClosure> {
547 None
548 }
549
550 fn create_behind_draw_closure(&self) -> Option<NodeDrawClosure> {
555 None
556 }
557}
558
559pub type NodeDrawClosure = Rc<dyn Fn(&mut cranpose_ui_graphics::DrawScopeDefault)>;
564
565pub trait PointerInputNode: ModifierNode {
571 fn on_pointer_event(
574 &mut self,
575 _context: &mut dyn ModifierNodeContext,
576 _event: &PointerEvent,
577 ) -> bool {
578 false
579 }
580
581 fn hit_test(&self, _x: f32, _y: f32) -> bool {
584 true
585 }
586
587 fn pointer_input_handler(&self) -> Option<Rc<dyn Fn(PointerEvent)>> {
589 None
590 }
591
592 fn layout_size_sink(&self) -> Option<Rc<Cell<Size>>> {
605 None
606 }
607}
608
609pub trait SemanticsNode: ModifierNode {
615 fn merge_semantics(&self, _config: &mut SemanticsConfiguration) {}
617
618 fn reach(&self) -> SemanticsReach {
622 let mut config = SemanticsConfiguration::default();
623 self.merge_semantics(&mut config);
624 SemanticsReach {
625 is_modal: config.is_modal,
626 hidden: config.hidden,
627 }
628 }
629}
630
631#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
634pub struct SemanticsReach {
635 pub is_modal: bool,
637 pub hidden: bool,
639}
640
641impl SemanticsReach {
642 pub fn union(self, other: Self) -> Self {
644 Self {
645 is_modal: self.is_modal || other.is_modal,
646 hidden: self.hidden || other.hidden,
647 }
648 }
649}
650
651#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
656pub enum FocusState {
657 Active,
659 ActiveParent,
661 Captured,
665 #[default]
668 Inactive,
669}
670
671impl FocusState {
672 pub fn is_focused(self) -> bool {
674 matches!(self, FocusState::Active | FocusState::Captured)
675 }
676
677 pub fn has_focus(self) -> bool {
679 matches!(
680 self,
681 FocusState::Active | FocusState::ActiveParent | FocusState::Captured
682 )
683 }
684
685 pub fn is_captured(self) -> bool {
687 matches!(self, FocusState::Captured)
688 }
689}
690
691pub trait FocusNode: ModifierNode {
696 fn focus_state(&self) -> FocusState;
698
699 fn on_focus_changed(&mut self, _context: &mut dyn ModifierNodeContext, _state: FocusState) {}
701}
702
703#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
714pub enum SemanticsWidgetRole {
715 Button,
716 Checkbox,
717 Switch,
718 RadioButton,
719 Tab,
720 Image,
721 DropdownList,
724 ValuePicker,
727 Header,
732 Dialog,
736 Link,
739 SearchField,
742 ProgressBar,
745 ToggleButton,
748 Alert,
751 Toolbar,
754 Menu,
756 MenuItem,
758 TabBar,
761 List,
763 ListItem,
765 RadioGroup,
767}
768
769#[derive(Clone, Copy, Debug, PartialEq)]
777pub struct ProgressBarRangeInfo {
778 pub current: f32,
779 pub start: f32,
780 pub end: f32,
781 pub steps: u32,
784}
785
786impl ProgressBarRangeInfo {
787 pub fn new(current: f32, start: f32, end: f32, steps: u32) -> Self {
788 Self {
789 current,
790 start,
791 end,
792 steps,
793 }
794 }
795
796 pub fn fraction(&self) -> f32 {
798 let span = self.end - self.start;
799 if span.abs() < f32::EPSILON {
800 return 0.0;
801 }
802 ((self.current - self.start) / span).clamp(0.0, 1.0)
803 }
804
805 pub fn step(&self) -> f32 {
808 let span = self.end - self.start;
809 if self.steps == 0 {
810 span / 10.0
811 } else {
812 span / (self.steps as f32 + 1.0)
813 }
814 }
815}
816
817#[derive(Clone, Copy, Debug, PartialEq, Eq)]
822pub struct CollectionInfo {
823 pub rows: usize,
824 pub columns: usize,
825}
826
827#[derive(Clone, Copy, Debug, PartialEq)]
838pub struct ScrollAxisRange {
839 pub value: f32,
840 pub max_value: f32,
841 pub reverse: bool,
842 pub content_padding_start: f32,
843 pub content_padding_end: f32,
844}
845
846impl ScrollAxisRange {
847 pub fn new(value: f32, max_value: f32, reverse: bool) -> Self {
848 Self {
849 value,
850 max_value,
851 reverse,
852 content_padding_start: 0.0,
853 content_padding_end: 0.0,
854 }
855 }
856
857 pub fn with_content_padding(self, start: f32, end: f32) -> Self {
860 Self {
861 content_padding_start: start,
862 content_padding_end: end,
863 ..self
864 }
865 }
866
867 pub fn can_scroll_forward(&self) -> bool {
868 self.value < self.max_value
869 }
870
871 pub fn can_scroll_backward(&self) -> bool {
872 self.value > 0.0
873 }
874}
875
876#[derive(Clone)]
882pub struct SemanticsScrollBy {
883 handler: Rc<dyn Fn(f32, f32) -> bool>,
884}
885
886impl SemanticsScrollBy {
887 pub fn new(handler: impl Fn(f32, f32) -> bool + 'static) -> Self {
888 Self {
889 handler: Rc::new(handler),
890 }
891 }
892
893 pub fn invoke(&self, dx: f32, dy: f32) -> bool {
894 (self.handler)(dx, dy)
895 }
896}
897
898impl fmt::Debug for SemanticsScrollBy {
899 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
900 f.debug_struct("SemanticsScrollBy").finish_non_exhaustive()
901 }
902}
903
904impl PartialEq for SemanticsScrollBy {
905 fn eq(&self, _other: &Self) -> bool {
906 true
907 }
908}
909
910impl Eq for SemanticsScrollBy {}
911
912#[derive(Clone)]
918pub struct SemanticsScrollToIndex {
919 handler: Rc<dyn Fn(usize) -> bool>,
920}
921
922impl SemanticsScrollToIndex {
923 pub fn new(handler: impl Fn(usize) -> bool + 'static) -> Self {
924 Self {
925 handler: Rc::new(handler),
926 }
927 }
928
929 pub fn invoke(&self, index: usize) -> bool {
930 (self.handler)(index)
931 }
932}
933
934impl fmt::Debug for SemanticsScrollToIndex {
935 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
936 f.debug_struct("SemanticsScrollToIndex")
937 .finish_non_exhaustive()
938 }
939}
940
941impl PartialEq for SemanticsScrollToIndex {
942 fn eq(&self, _other: &Self) -> bool {
943 true
944 }
945}
946
947impl Eq for SemanticsScrollToIndex {}
948
949#[derive(Clone)]
955pub struct SemanticsSetProgress {
956 handler: Rc<dyn Fn(f32) -> bool>,
957}
958
959impl SemanticsSetProgress {
960 pub fn new(handler: impl Fn(f32) -> bool + 'static) -> Self {
961 Self {
962 handler: Rc::new(handler),
963 }
964 }
965
966 pub fn invoke(&self, value: f32) -> bool {
967 (self.handler)(value)
968 }
969}
970
971impl fmt::Debug for SemanticsSetProgress {
972 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
973 f.debug_struct("SemanticsSetProgress")
974 .finish_non_exhaustive()
975 }
976}
977
978#[derive(Clone)]
982pub struct SemanticsSetText(Rc<dyn Fn(&str) -> bool>);
983
984impl SemanticsSetText {
985 pub fn new(handler: impl Fn(&str) -> bool + 'static) -> Self {
986 Self(Rc::new(handler))
987 }
988
989 pub fn invoke(&self, text: &str) -> bool {
990 (self.0)(text)
991 }
992}
993
994impl fmt::Debug for SemanticsSetText {
995 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
996 f.write_str("SemanticsSetText")
997 }
998}
999
1000#[derive(Clone)]
1006pub struct SemanticsSetSelection(Rc<dyn Fn(usize, usize) -> bool>);
1007
1008impl SemanticsSetSelection {
1009 pub fn new(handler: impl Fn(usize, usize) -> bool + 'static) -> Self {
1010 Self(Rc::new(handler))
1011 }
1012
1013 pub fn invoke(&self, anchor: usize, focus: usize) -> bool {
1014 (self.0)(anchor, focus)
1015 }
1016}
1017
1018impl fmt::Debug for SemanticsSetSelection {
1019 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1020 f.write_str("SemanticsSetSelection")
1021 }
1022}
1023
1024#[derive(Clone)]
1027pub struct SemanticsExpand(Rc<dyn Fn() -> bool>);
1028
1029impl SemanticsExpand {
1030 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
1031 Self(Rc::new(handler))
1032 }
1033
1034 pub fn invoke(&self) -> bool {
1035 (self.0)()
1036 }
1037}
1038
1039impl fmt::Debug for SemanticsExpand {
1040 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1041 f.write_str("SemanticsExpand")
1042 }
1043}
1044
1045#[derive(Clone)]
1049pub struct SemanticsLongClick(Rc<dyn Fn() -> bool>);
1050
1051impl SemanticsLongClick {
1052 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
1053 Self(Rc::new(handler))
1054 }
1055
1056 pub fn invoke(&self) -> bool {
1057 (self.0)()
1058 }
1059}
1060
1061impl fmt::Debug for SemanticsLongClick {
1062 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1063 f.write_str("SemanticsLongClick")
1064 }
1065}
1066
1067impl PartialEq for SemanticsLongClick {
1068 fn eq(&self, _other: &Self) -> bool {
1069 true
1070 }
1071}
1072
1073impl PartialEq for SemanticsExpand {
1074 fn eq(&self, _other: &Self) -> bool {
1075 true
1076 }
1077}
1078
1079#[derive(Clone)]
1083pub struct SemanticsDismiss(Rc<dyn Fn() -> bool>);
1084
1085impl SemanticsDismiss {
1086 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
1087 Self(Rc::new(handler))
1088 }
1089
1090 pub fn invoke(&self) -> bool {
1091 (self.0)()
1092 }
1093}
1094
1095impl fmt::Debug for SemanticsDismiss {
1096 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1097 f.write_str("SemanticsDismiss")
1098 }
1099}
1100
1101impl PartialEq for SemanticsDismiss {
1102 fn eq(&self, _other: &Self) -> bool {
1103 true
1104 }
1105}
1106
1107impl PartialEq for SemanticsSetText {
1108 fn eq(&self, _other: &Self) -> bool {
1109 true
1110 }
1111}
1112
1113impl PartialEq for SemanticsSetSelection {
1114 fn eq(&self, _other: &Self) -> bool {
1115 true
1116 }
1117}
1118
1119#[derive(Clone)]
1125pub struct SemanticsMagicTap(Rc<dyn Fn() -> bool>);
1126
1127impl SemanticsMagicTap {
1128 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
1129 Self(Rc::new(handler))
1130 }
1131
1132 pub fn invoke(&self) -> bool {
1133 (self.0)()
1134 }
1135}
1136
1137impl fmt::Debug for SemanticsMagicTap {
1138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1139 f.write_str("SemanticsMagicTap")
1140 }
1141}
1142
1143impl PartialEq for SemanticsMagicTap {
1144 fn eq(&self, _other: &Self) -> bool {
1145 true
1146 }
1147}
1148
1149impl PartialEq for SemanticsSetProgress {
1150 fn eq(&self, _other: &Self) -> bool {
1151 true
1152 }
1153}
1154
1155impl Eq for SemanticsSetProgress {}
1156
1157#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1164pub enum LiveRegionMode {
1165 Polite,
1167 Assertive,
1170}
1171
1172#[derive(Clone)]
1179pub struct SemanticsCustomAction {
1180 pub label: String,
1182 handler: Rc<dyn Fn()>,
1183}
1184
1185impl SemanticsCustomAction {
1186 pub fn new(label: impl Into<String>, handler: impl Fn() + 'static) -> Self {
1187 Self {
1188 label: label.into(),
1189 handler: Rc::new(handler),
1190 }
1191 }
1192
1193 pub fn invoke(&self) {
1194 (self.handler)();
1195 }
1196}
1197
1198impl fmt::Debug for SemanticsCustomAction {
1199 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1200 f.debug_struct("SemanticsCustomAction")
1201 .field("label", &self.label)
1202 .finish_non_exhaustive()
1203 }
1204}
1205
1206impl PartialEq for SemanticsCustomAction {
1207 fn eq(&self, other: &Self) -> bool {
1208 self.label == other.label
1209 }
1210}
1211
1212impl Eq for SemanticsCustomAction {}
1213
1214#[derive(Clone, Debug, PartialEq)]
1229pub struct CanvasSemanticsNode {
1230 pub key: u64,
1237 pub bounds: cranpose_ui_graphics::Rect,
1239 pub label: String,
1240 pub role: Option<SemanticsWidgetRole>,
1241 pub state_description: Option<String>,
1245 pub on_click_label: Option<String>,
1248 pub clickable: bool,
1249 pub selected: Option<bool>,
1251 pub toggled: Option<bool>,
1253 pub enabled: bool,
1254 pub custom_actions: Vec<SemanticsCustomAction>,
1255}
1256
1257impl Default for CanvasSemanticsNode {
1258 fn default() -> Self {
1259 Self {
1260 key: 0,
1261 bounds: cranpose_ui_graphics::Rect {
1262 x: 0.0,
1263 y: 0.0,
1264 width: 0.0,
1265 height: 0.0,
1266 },
1267 label: String::new(),
1268 role: None,
1269 state_description: None,
1270 on_click_label: None,
1271 clickable: false,
1272 selected: None,
1273 toggled: None,
1274 enabled: true,
1275 custom_actions: Vec::new(),
1276 }
1277 }
1278}
1279
1280impl CanvasSemanticsNode {
1281 pub fn control(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1283 Self {
1284 key,
1285 bounds,
1286 label: label.into(),
1287 clickable: true,
1288 ..Self::default()
1289 }
1290 }
1291
1292 pub fn text(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1294 Self {
1295 key,
1296 bounds,
1297 label: label.into(),
1298 ..Self::default()
1299 }
1300 }
1301
1302 pub fn with_role(mut self, role: SemanticsWidgetRole) -> Self {
1303 self.role = Some(role);
1304 self
1305 }
1306
1307 pub fn with_state_description(mut self, state: impl Into<String>) -> Self {
1308 self.state_description = Some(state.into());
1309 self
1310 }
1311
1312 pub fn with_click_label(mut self, label: impl Into<String>) -> Self {
1313 self.on_click_label = Some(label.into());
1314 self.clickable = true;
1315 self
1316 }
1317
1318 pub fn with_selected(mut self, selected: bool) -> Self {
1319 self.selected = Some(selected);
1320 self
1321 }
1322
1323 pub fn with_toggled(mut self, toggled: bool) -> Self {
1324 self.toggled = Some(toggled);
1325 self
1326 }
1327
1328 pub fn with_enabled(mut self, enabled: bool) -> Self {
1329 self.enabled = enabled;
1330 self
1331 }
1332
1333 pub fn with_custom_action(mut self, action: SemanticsCustomAction) -> Self {
1334 self.custom_actions.push(action);
1335 self
1336 }
1337}
1338
1339#[derive(Clone, Debug, PartialEq)]
1341pub struct SemanticsConfiguration {
1342 pub content_description: Option<String>,
1343 pub state_description: Option<String>,
1345 pub on_click_label: Option<String>,
1347 pub on_click: Option<SemanticsCustomAction>,
1350 pub on_long_click: Option<SemanticsLongClick>,
1353 pub on_long_click_label: Option<String>,
1356 pub on_magic_tap: Option<SemanticsMagicTap>,
1360 pub on_magic_tap_label: Option<String>,
1363 pub input_labels: Vec<String>,
1367 pub language: Option<String>,
1371 pub role: Option<SemanticsWidgetRole>,
1373 pub selected: Option<bool>,
1374 pub toggled: Option<bool>,
1375 pub enabled: bool,
1376 pub is_clickable: bool,
1377 pub is_editable_text: bool,
1378 pub multiline: bool,
1380 pub text: Option<String>,
1383 pub text_selection: Option<crate::text::TextRange>,
1384 pub custom_actions: Vec<SemanticsCustomAction>,
1385 pub canvas_children: Vec<CanvasSemanticsNode>,
1388 pub is_modal: bool,
1391 pub hidden: bool,
1395 pub merge_descendants: bool,
1399 pub selectable_group: bool,
1403 pub pane_title: Option<String>,
1406 pub error: Option<String>,
1409 pub password: bool,
1412 pub traversal_index: f32,
1416 pub live_region: Option<LiveRegionMode>,
1419 pub progress: Option<ProgressBarRangeInfo>,
1422 pub set_progress: Option<SemanticsSetProgress>,
1425 pub set_text: Option<SemanticsSetText>,
1428 pub set_selection: Option<SemanticsSetSelection>,
1431 pub expand: Option<SemanticsExpand>,
1434 pub dismiss: Option<SemanticsDismiss>,
1438 pub collapse: Option<SemanticsExpand>,
1441 pub vertical_scroll: Option<ScrollAxisRange>,
1444 pub horizontal_scroll: Option<ScrollAxisRange>,
1447 pub scroll_by: Option<SemanticsScrollBy>,
1450 pub scroll_to_index: Option<SemanticsScrollToIndex>,
1454 pub collection: Option<CollectionInfo>,
1456}
1457
1458impl Default for SemanticsConfiguration {
1459 fn default() -> Self {
1460 Self {
1461 content_description: None,
1462 state_description: None,
1463 on_click_label: None,
1464 on_click: None,
1465 on_long_click: None,
1466 on_long_click_label: None,
1467 on_magic_tap: None,
1468 on_magic_tap_label: None,
1469 input_labels: Vec::new(),
1470 language: None,
1471 role: None,
1472 selected: None,
1473 toggled: None,
1474 enabled: true,
1475 is_clickable: false,
1476 is_editable_text: false,
1477 multiline: false,
1478 text: None,
1479 text_selection: None,
1480 custom_actions: Vec::new(),
1481 canvas_children: Vec::new(),
1482 is_modal: false,
1483 hidden: false,
1484 merge_descendants: false,
1485 selectable_group: false,
1486 pane_title: None,
1487 error: None,
1488 password: false,
1489 traversal_index: 0.0,
1490 live_region: None,
1491 progress: None,
1492 set_progress: None,
1493 set_text: None,
1494 set_selection: None,
1495 expand: None,
1496 dismiss: None,
1497 collapse: None,
1498 vertical_scroll: None,
1499 horizontal_scroll: None,
1500 scroll_by: None,
1501 scroll_to_index: None,
1502 collection: None,
1503 }
1504 }
1505}
1506
1507pub type SemanticsSpec = SemanticsConfiguration;
1516
1517impl SemanticsConfiguration {
1518 pub fn new() -> Self {
1521 Self::default()
1522 }
1523
1524 pub fn content_description(mut self, name: impl Into<String>) -> Self {
1527 self.content_description = Some(name.into());
1528 self
1529 }
1530
1531 pub fn state_description(mut self, state: impl Into<String>) -> Self {
1534 self.state_description = Some(state.into());
1535 self
1536 }
1537
1538 pub fn clickable(mut self) -> Self {
1540 self.is_clickable = true;
1541 self
1542 }
1543
1544 pub fn on_click(mut self, label: impl Into<String>, action: impl Fn() + 'static) -> Self {
1547 self.on_click = Some(SemanticsCustomAction::new(label, action));
1548 self
1549 }
1550
1551 pub fn on_long_click(
1555 mut self,
1556 label: impl Into<String>,
1557 action: impl Fn() -> bool + 'static,
1558 ) -> Self {
1559 self.on_long_click_label = Some(label.into());
1560 self.on_long_click = Some(SemanticsLongClick::new(action));
1561 self
1562 }
1563
1564 pub fn on_magic_tap(
1568 mut self,
1569 label: impl Into<String>,
1570 action: impl Fn() -> bool + 'static,
1571 ) -> Self {
1572 self.on_magic_tap_label = Some(label.into());
1573 self.on_magic_tap = Some(SemanticsMagicTap::new(action));
1574 self
1575 }
1576
1577 pub fn input_labels<S: Into<String>>(mut self, labels: impl IntoIterator<Item = S>) -> Self {
1580 self.input_labels = labels.into_iter().map(Into::into).collect();
1581 self
1582 }
1583
1584 pub fn language(mut self, tag: impl Into<String>) -> Self {
1587 self.language = Some(tag.into());
1588 self
1589 }
1590
1591 pub fn toggled(mut self, toggled: bool) -> Self {
1593 self.toggled = Some(toggled);
1594 self
1595 }
1596
1597 pub fn selected(mut self, selected: bool) -> Self {
1600 self.selected = Some(selected);
1601 self
1602 }
1603
1604 pub fn role(mut self, role: SemanticsWidgetRole) -> Self {
1606 self.role = Some(role);
1607 self
1608 }
1609
1610 pub fn heading(self) -> Self {
1613 self.role(SemanticsWidgetRole::Header)
1614 }
1615
1616 pub fn error(mut self, message: impl Into<String>) -> Self {
1618 self.error = Some(message.into());
1619 self
1620 }
1621
1622 pub fn password(mut self) -> Self {
1624 self.password = true;
1625 self
1626 }
1627
1628 pub fn pane_title(mut self, title: impl Into<String>) -> Self {
1631 self.pane_title = Some(title.into());
1632 self
1633 }
1634
1635 pub fn traversal_index(mut self, index: f32) -> Self {
1638 self.traversal_index = index;
1639 self
1640 }
1641
1642 pub fn hidden(mut self) -> Self {
1645 self.hidden = true;
1646 self
1647 }
1648
1649 pub fn merge_descendants(mut self) -> Self {
1652 self.merge_descendants = true;
1653 self
1654 }
1655
1656 pub fn selectable_group(mut self) -> Self {
1659 self.selectable_group = true;
1660 self
1661 }
1662
1663 pub fn live_region(mut self, mode: LiveRegionMode) -> Self {
1666 self.live_region = Some(mode);
1667 self
1668 }
1669 pub fn merge(&mut self, other: &SemanticsConfiguration) {
1670 if let Some(description) = &other.content_description {
1671 self.content_description = Some(description.clone());
1672 }
1673 if let Some(state) = &other.state_description {
1674 self.state_description = Some(state.clone());
1675 }
1676 if let Some(label) = &other.on_click_label {
1677 self.on_click_label = Some(label.clone());
1678 }
1679 if let Some(label) = &other.on_long_click_label {
1680 self.on_long_click_label = Some(label.clone());
1681 }
1682 if let Some(label) = &other.on_magic_tap_label {
1683 self.on_magic_tap_label = Some(label.clone());
1684 }
1685 if !other.input_labels.is_empty() {
1686 self.input_labels.clone_from(&other.input_labels);
1687 }
1688 if let Some(language) = &other.language {
1689 self.language = Some(language.clone());
1690 }
1691 if let Some(role) = other.role {
1692 self.role = Some(role);
1693 }
1694 if let Some(selected) = other.selected {
1695 self.selected = Some(selected);
1696 }
1697 if let Some(toggled) = other.toggled {
1698 self.toggled = Some(toggled);
1699 }
1700 self.enabled &= other.enabled;
1701 self.is_clickable |= other.is_clickable;
1702 self.is_editable_text |= other.is_editable_text;
1703 self.multiline |= other.multiline;
1704 if let Some(text) = &other.text {
1705 self.text = Some(text.clone());
1706 }
1707 self.is_modal |= other.is_modal;
1708 self.hidden |= other.hidden;
1709 self.merge_descendants |= other.merge_descendants;
1710 self.selectable_group |= other.selectable_group;
1711 self.password |= other.password;
1712 if other.traversal_index != 0.0 {
1713 self.traversal_index = other.traversal_index;
1714 }
1715 if let Some(live_region) = other.live_region {
1716 self.live_region = Some(live_region);
1717 }
1718 self.merge_words(other);
1719 self.merge_actions(other);
1720 self.merge_ranges(other);
1721 }
1722
1723 fn merge_words(&mut self, other: &SemanticsConfiguration) {
1724 if let Some(title) = &other.pane_title {
1725 self.pane_title = Some(title.clone());
1726 }
1727 if let Some(error) = &other.error {
1728 self.error = Some(error.clone());
1729 }
1730 }
1731
1732 fn merge_actions(&mut self, other: &SemanticsConfiguration) {
1733 if let Some(on_click) = &other.on_click {
1734 self.on_click = Some(on_click.clone());
1735 }
1736 self.custom_actions
1737 .extend(other.custom_actions.iter().cloned());
1738 self.canvas_children
1739 .extend(other.canvas_children.iter().cloned());
1740 if let Some(set_progress) = &other.set_progress {
1741 self.set_progress = Some(set_progress.clone());
1742 }
1743 if let Some(set_text) = &other.set_text {
1744 self.set_text = Some(set_text.clone());
1745 }
1746 if let Some(set_selection) = &other.set_selection {
1747 self.set_selection = Some(set_selection.clone());
1748 }
1749 if let Some(expand) = &other.expand {
1750 self.expand = Some(expand.clone());
1751 }
1752 if let Some(collapse) = &other.collapse {
1753 self.collapse = Some(collapse.clone());
1754 }
1755 if let Some(dismiss) = &other.dismiss {
1756 self.dismiss = Some(dismiss.clone());
1757 }
1758 if let Some(long_click) = &other.on_long_click {
1759 self.on_long_click = Some(long_click.clone());
1760 }
1761 if let Some(magic_tap) = &other.on_magic_tap {
1762 self.on_magic_tap = Some(magic_tap.clone());
1763 }
1764 if let Some(scroll_by) = &other.scroll_by {
1765 self.scroll_by = Some(scroll_by.clone());
1766 }
1767 if let Some(scroll_to_index) = &other.scroll_to_index {
1768 self.scroll_to_index = Some(scroll_to_index.clone());
1769 }
1770 }
1771
1772 fn merge_ranges(&mut self, other: &SemanticsConfiguration) {
1773 if let Some(selection) = other.text_selection {
1774 self.text_selection = Some(selection);
1775 }
1776 if let Some(progress) = other.progress {
1777 self.progress = Some(progress);
1778 }
1779 if let Some(range) = other.vertical_scroll {
1780 self.vertical_scroll = Some(range);
1781 }
1782 if let Some(range) = other.horizontal_scroll {
1783 self.horizontal_scroll = Some(range);
1784 }
1785 if let Some(collection) = other.collection {
1786 self.collection = Some(collection);
1787 }
1788 }
1789
1790 pub fn is_activatable(&self) -> bool {
1793 self.is_clickable || self.on_click_label.is_some() || self.on_click.is_some()
1794 }
1795}
1796
1797impl fmt::Debug for dyn ModifierNode {
1798 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1799 f.debug_struct("ModifierNode").finish_non_exhaustive()
1800 }
1801}
1802
1803impl dyn ModifierNode {
1804 pub fn as_any(&self) -> &dyn Any {
1805 self
1806 }
1807
1808 pub fn as_any_mut(&mut self) -> &mut dyn Any {
1809 self
1810 }
1811}
1812
1813pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
1816 type Node: ModifierNode;
1817
1818 fn create(&self) -> Self::Node;
1820
1821 fn update(&self, node: &mut Self::Node);
1823
1824 fn key(&self) -> Option<u64> {
1826 None
1827 }
1828
1829 fn inspector_name(&self) -> &'static str {
1831 type_name::<Self>()
1832 }
1833
1834 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
1836
1837 fn capabilities(&self) -> NodeCapabilities {
1840 NodeCapabilities::default()
1841 }
1842
1843 fn always_update(&self) -> bool {
1849 false
1850 }
1851
1852 fn auto_invalidate_on_update(&self) -> bool {
1855 true
1856 }
1857
1858 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1865 None
1866 }
1867
1868 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
1875 Vec::new()
1876 }
1877}
1878
1879#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1881pub struct NodeCapabilities(u32);
1882
1883impl NodeCapabilities {
1884 pub const NONE: Self = Self(0);
1886 pub const LAYOUT: Self = Self(1 << 0);
1888 pub const DRAW: Self = Self(1 << 1);
1890 pub const POINTER_INPUT: Self = Self(1 << 2);
1892 pub const SEMANTICS: Self = Self(1 << 3);
1894 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1896 pub const FOCUS: Self = Self(1 << 5);
1898 pub const WINDOW_ROOT: Self = Self(1 << 6);
1902
1903 pub const fn empty() -> Self {
1905 Self::NONE
1906 }
1907
1908 pub const fn contains(self, other: Self) -> bool {
1910 (self.0 & other.0) == other.0
1911 }
1912
1913 pub const fn intersects(self, other: Self) -> bool {
1915 (self.0 & other.0) != 0
1916 }
1917
1918 pub fn insert(&mut self, other: Self) {
1920 self.0 |= other.0;
1921 }
1922
1923 pub const fn bits(self) -> u32 {
1925 self.0
1926 }
1927
1928 pub const fn is_empty(self) -> bool {
1930 self.0 == 0
1931 }
1932
1933 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1935 match kind {
1936 InvalidationKind::Layout => Self::LAYOUT,
1937 InvalidationKind::Draw => Self::DRAW,
1938 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1939 InvalidationKind::Semantics => Self::SEMANTICS,
1940 InvalidationKind::Focus => Self::FOCUS,
1941 }
1942 }
1943}
1944
1945impl Default for NodeCapabilities {
1946 fn default() -> Self {
1947 Self::NONE
1948 }
1949}
1950
1951impl fmt::Debug for NodeCapabilities {
1952 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1953 f.debug_struct("NodeCapabilities")
1954 .field("layout", &self.contains(Self::LAYOUT))
1955 .field("draw", &self.contains(Self::DRAW))
1956 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1957 .field("semantics", &self.contains(Self::SEMANTICS))
1958 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1959 .field("focus", &self.contains(Self::FOCUS))
1960 .field("window_root", &self.contains(Self::WINDOW_ROOT))
1961 .finish()
1962 }
1963}
1964
1965impl BitOr for NodeCapabilities {
1966 type Output = Self;
1967
1968 fn bitor(self, rhs: Self) -> Self::Output {
1969 Self(self.0 | rhs.0)
1970 }
1971}
1972
1973impl BitOrAssign for NodeCapabilities {
1974 fn bitor_assign(&mut self, rhs: Self) {
1975 self.0 |= rhs.0;
1976 }
1977}
1978
1979pub type ModifierInvalidations = smallvec::SmallVec<[ModifierInvalidation; 5]>;
1982
1983#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1985pub struct ModifierInvalidation {
1986 kind: InvalidationKind,
1987 capabilities: NodeCapabilities,
1988}
1989
1990impl ModifierInvalidation {
1991 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1993 Self { kind, capabilities }
1994 }
1995
1996 pub const fn kind(self) -> InvalidationKind {
1998 self.kind
1999 }
2000
2001 pub const fn capabilities(self) -> NodeCapabilities {
2003 self.capabilities
2004 }
2005}
2006
2007pub trait AnyModifierElement: fmt::Debug {
2009 fn node_type(&self) -> TypeId;
2010
2011 fn element_type(&self) -> TypeId;
2012
2013 fn create_node(&self) -> Box<dyn ModifierNode>;
2014
2015 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
2016
2017 fn update_node(&self, node: &mut dyn ModifierNode);
2018
2019 fn key(&self) -> Option<u64>;
2020
2021 fn capabilities(&self) -> NodeCapabilities {
2022 NodeCapabilities::default()
2023 }
2024
2025 fn hash_code(&self) -> u64;
2026
2027 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
2028
2029 fn inspector_name(&self) -> &'static str;
2030
2031 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
2032
2033 fn requires_update(&self) -> bool;
2034
2035 fn auto_invalidates_on_update(&self) -> bool;
2036
2037 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
2038
2039 fn provides_composition_locals(&self) -> bool {
2041 false
2042 }
2043
2044 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
2046 Vec::new()
2047 }
2048
2049 fn as_any(&self) -> &dyn Any;
2050}
2051
2052struct TypedModifierElement<E: ModifierNodeElement> {
2053 element: E,
2054 cached_hash: u64,
2055 provides_locals: bool,
2056}
2057
2058impl<E: ModifierNodeElement> TypedModifierElement<E> {
2059 fn new(element: E) -> Self {
2060 let mut hasher = default::new();
2061 element.hash(&mut hasher);
2062 let provides_locals = !element.provided_composition_locals().is_empty();
2063 Self {
2064 element,
2065 cached_hash: hasher.finish(),
2066 provides_locals,
2067 }
2068 }
2069}
2070
2071impl<E> fmt::Debug for TypedModifierElement<E>
2072where
2073 E: ModifierNodeElement,
2074{
2075 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
2076 f.debug_struct("TypedModifierElement")
2077 .field("type", &type_name::<E>())
2078 .finish()
2079 }
2080}
2081
2082impl<E> AnyModifierElement for TypedModifierElement<E>
2083where
2084 E: ModifierNodeElement,
2085{
2086 fn node_type(&self) -> TypeId {
2087 TypeId::of::<E::Node>()
2088 }
2089
2090 fn element_type(&self) -> TypeId {
2091 TypeId::of::<E>()
2092 }
2093
2094 fn create_node(&self) -> Box<dyn ModifierNode> {
2095 Box::new(self.element.create())
2096 }
2097
2098 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
2099 node.as_any().is::<E::Node>()
2100 }
2101
2102 fn update_node(&self, node: &mut dyn ModifierNode) {
2103 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
2104 self.element.update(typed);
2105 }
2106 }
2107
2108 fn key(&self) -> Option<u64> {
2109 self.element.key()
2110 }
2111
2112 fn capabilities(&self) -> NodeCapabilities {
2113 self.element.capabilities()
2114 }
2115
2116 fn provides_composition_locals(&self) -> bool {
2117 self.provides_locals
2118 }
2119
2120 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
2121 self.element.provided_composition_locals()
2122 }
2123
2124 fn hash_code(&self) -> u64 {
2125 self.cached_hash
2126 }
2127
2128 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
2129 other
2130 .as_any()
2131 .downcast_ref::<Self>()
2132 .is_some_and(|typed| typed.element == self.element)
2133 }
2134
2135 fn inspector_name(&self) -> &'static str {
2136 self.element.inspector_name()
2137 }
2138
2139 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
2140 self.element.inspector_properties(visitor);
2141 }
2142
2143 fn requires_update(&self) -> bool {
2144 self.element.always_update()
2145 }
2146
2147 fn auto_invalidates_on_update(&self) -> bool {
2148 self.element.auto_invalidate_on_update()
2149 }
2150
2151 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
2152 self.element.update_invalidation_kind()
2153 }
2154
2155 fn as_any(&self) -> &dyn Any {
2156 self
2157 }
2158}
2159
2160fn request_update_auto_invalidations(
2161 element: &dyn AnyModifierElement,
2162 context: &mut dyn ModifierNodeContext,
2163 capabilities: NodeCapabilities,
2164) {
2165 if let Some(kind) = element.update_invalidation_kind() {
2166 let capabilities = NodeCapabilities::for_invalidation(kind);
2167 context.push_active_capabilities(capabilities);
2168 context.invalidate(kind);
2169 context.pop_active_capabilities();
2170 } else if element.auto_invalidates_on_update() {
2171 request_auto_invalidations(context, capabilities);
2172 }
2173}
2174
2175pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
2178 Rc::new(TypedModifierElement::new(element))
2179}
2180
2181pub type DynModifierElement = Rc<dyn AnyModifierElement>;
2183
2184#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2185enum TraversalDirection {
2186 Forward,
2187 Backward,
2188}
2189
2190pub struct ModifierChainIter<'a> {
2195 chain: &'a ModifierNodeChain,
2196 cursor: usize,
2197 remaining: usize,
2198 direction: TraversalDirection,
2199}
2200
2201impl<'a> ModifierChainIter<'a> {
2202 fn forward(chain: &'a ModifierNodeChain) -> Self {
2203 Self {
2204 chain,
2205 cursor: 0,
2206 remaining: chain.ordered_nodes.len(),
2207 direction: TraversalDirection::Forward,
2208 }
2209 }
2210
2211 fn backward(chain: &'a ModifierNodeChain) -> Self {
2212 let len = chain.ordered_nodes.len();
2213 Self {
2214 chain,
2215 cursor: len.wrapping_sub(1),
2216 remaining: len,
2217 direction: TraversalDirection::Backward,
2218 }
2219 }
2220}
2221
2222impl<'a> Iterator for ModifierChainIter<'a> {
2223 type Item = ModifierChainNodeRef<'a>;
2224
2225 #[inline]
2226 fn next(&mut self) -> Option<Self::Item> {
2227 if self.remaining == 0 {
2228 return None;
2229 }
2230 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
2231 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
2232 self.remaining -= 1;
2233 match self.direction {
2234 TraversalDirection::Forward => self.cursor += 1,
2235 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
2236 }
2237 Some(node_ref)
2238 }
2239
2240 #[inline]
2241 fn size_hint(&self) -> (usize, Option<usize>) {
2242 (self.remaining, Some(self.remaining))
2243 }
2244}
2245
2246impl ExactSizeIterator for ModifierChainIter<'_> {}
2247impl std::iter::FusedIterator for ModifierChainIter<'_> {}
2248
2249#[derive(Debug)]
2250struct ModifierNodeEntry {
2251 element_type: TypeId,
2252 node_type: TypeId,
2253 key: Option<u64>,
2254 hash_code: u64,
2255 element: DynModifierElement,
2256 node: Rc<RefCell<Box<dyn ModifierNode>>>,
2257 capabilities: NodeCapabilities,
2258}
2259
2260impl ModifierNodeEntry {
2261 fn new(
2262 element_type: TypeId,
2263 node_type: TypeId,
2264 key: Option<u64>,
2265 element: DynModifierElement,
2266 node: Box<dyn ModifierNode>,
2267 hash_code: u64,
2268 capabilities: NodeCapabilities,
2269 ) -> Self {
2270 let node_rc = Rc::new(RefCell::new(node));
2271 let entry = Self {
2272 element_type,
2273 node_type,
2274 key,
2275 hash_code,
2276 element,
2277 node: Rc::clone(&node_rc),
2278 capabilities,
2279 };
2280 entry
2281 .node
2282 .borrow()
2283 .node_state()
2284 .set_capabilities(entry.capabilities);
2285 entry
2286 }
2287}
2288
2289fn visit_node_tree_mut(
2290 node: &mut dyn ModifierNode,
2291 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
2292) {
2293 visitor(node);
2294 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
2295}
2296
2297fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
2298 let mut current = 0usize;
2299 let mut result: Option<&dyn ModifierNode> = None;
2300 node.for_each_delegate(&mut |child| {
2301 if result.is_none() && current == target {
2302 result = Some(child);
2303 }
2304 current += 1;
2305 });
2306 result
2307}
2308
2309fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
2310 let mut current = 0usize;
2311 let mut result: Option<&mut dyn ModifierNode> = None;
2312 node.for_each_delegate_mut(&mut |child| {
2313 if result.is_none() && current == target {
2314 result = Some(child);
2315 }
2316 current += 1;
2317 });
2318 result
2319}
2320
2321fn with_node_context<F, R>(
2322 node: &mut dyn ModifierNode,
2323 context: &mut dyn ModifierNodeContext,
2324 f: F,
2325) -> R
2326where
2327 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
2328{
2329 context.push_active_capabilities(node.node_state().capabilities());
2330 let result = f(node, context);
2331 context.pop_active_capabilities();
2332 result
2333}
2334
2335fn request_auto_invalidations(
2336 context: &mut dyn ModifierNodeContext,
2337 capabilities: NodeCapabilities,
2338) {
2339 if capabilities.is_empty() {
2340 return;
2341 }
2342
2343 context.push_active_capabilities(capabilities);
2344
2345 if capabilities.contains(NodeCapabilities::LAYOUT) {
2346 context.invalidate(InvalidationKind::Layout);
2347 }
2348 if capabilities.contains(NodeCapabilities::DRAW) {
2349 context.invalidate(InvalidationKind::Draw);
2350 }
2351 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
2352 context.invalidate(InvalidationKind::PointerInput);
2353 }
2354 if capabilities.contains(NodeCapabilities::SEMANTICS) {
2355 context.invalidate(InvalidationKind::Semantics);
2356 }
2357 if capabilities.contains(NodeCapabilities::FOCUS) {
2358 context.invalidate(InvalidationKind::Focus);
2359 }
2360
2361 context.pop_active_capabilities();
2362}
2363
2364fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
2365 visit_node_tree_mut(node, &mut |n| {
2366 if !n.node_state().is_attached() {
2367 n.node_state().set_attached(true);
2368 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
2369 }
2370 });
2371}
2372
2373fn reset_node_tree(node: &mut dyn ModifierNode) {
2374 visit_node_tree_mut(node, &mut |n| n.on_reset());
2375}
2376
2377fn detach_node_tree(node: &mut dyn ModifierNode) {
2378 visit_node_tree_mut(node, &mut |n| {
2379 if n.node_state().is_attached() {
2380 n.on_detach();
2381 n.node_state().set_attached(false);
2382 }
2383 n.node_state().set_parent_link(None);
2384 n.node_state().set_child_link(None);
2385 n.node_state()
2386 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2387 });
2388}
2389
2390pub struct ModifierNodeChain {
2397 entries: Vec<ModifierNodeEntry>,
2398 aggregated_capabilities: NodeCapabilities,
2399 head_aggregate_child_capabilities: NodeCapabilities,
2400 head_sentinel: Box<SentinelNode>,
2401 tail_sentinel: Box<SentinelNode>,
2402 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2403 scratch_old_used: Vec<bool>,
2404 scratch_match_order: Vec<Option<usize>>,
2405 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
2406 scratch_elements: Vec<DynModifierElement>,
2407}
2408
2409struct SentinelNode {
2410 state: NodeState,
2411}
2412
2413impl SentinelNode {
2414 fn new() -> Self {
2415 Self {
2416 state: NodeState::sentinel(),
2417 }
2418 }
2419}
2420
2421impl DelegatableNode for SentinelNode {
2422 fn node_state(&self) -> &NodeState {
2423 &self.state
2424 }
2425}
2426
2427impl ModifierNode for SentinelNode {}
2428
2429#[derive(Clone)]
2430pub struct ModifierChainNodeRef<'a> {
2431 chain: &'a ModifierNodeChain,
2432 link: NodeLink,
2433 cached_capabilities: Option<NodeCapabilities>,
2434 cached_aggregate_child: Option<NodeCapabilities>,
2435}
2436
2437impl Default for ModifierNodeChain {
2438 fn default() -> Self {
2439 Self::new()
2440 }
2441}
2442
2443struct EntryIndex {
2444 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2445 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2446 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
2447}
2448
2449struct EntryMatchQuery<'a> {
2450 element_type: TypeId,
2451 node_type: TypeId,
2452 key: Option<u64>,
2453 hash_code: u64,
2454 element: &'a DynModifierElement,
2455}
2456
2457impl EntryIndex {
2458 fn build(entries: &[ModifierNodeEntry]) -> Self {
2459 let mut keyed = HashMap::default();
2460 let mut hashed = HashMap::default();
2461 let mut typed = HashMap::default();
2462
2463 for (i, entry) in entries.iter().enumerate() {
2464 if let Some(key_value) = entry.key {
2465 keyed
2466 .entry((entry.element_type, entry.node_type, key_value))
2467 .or_insert_with(Vec::new)
2468 .push(i);
2469 } else {
2470 hashed
2471 .entry((entry.element_type, entry.node_type, entry.hash_code))
2472 .or_insert_with(Vec::new)
2473 .push(i);
2474 typed
2475 .entry((entry.element_type, entry.node_type))
2476 .or_insert_with(Vec::new)
2477 .push(i);
2478 }
2479 }
2480
2481 Self {
2482 keyed,
2483 hashed,
2484 typed,
2485 }
2486 }
2487
2488 fn find_match(
2489 &self,
2490 entries: &[ModifierNodeEntry],
2491 used: &[bool],
2492 query: EntryMatchQuery<'_>,
2493 ) -> Option<usize> {
2494 if let Some(key_value) = query.key {
2495 if let Some(candidates) =
2496 self.keyed
2497 .get(&(query.element_type, query.node_type, key_value))
2498 {
2499 for &i in candidates {
2500 if !used[i] {
2501 return Some(i);
2502 }
2503 }
2504 }
2505 } else {
2506 if let Some(candidates) =
2507 self.hashed
2508 .get(&(query.element_type, query.node_type, query.hash_code))
2509 {
2510 for &i in candidates {
2511 if !used[i]
2512 && entries[i]
2513 .element
2514 .as_ref()
2515 .equals_element(query.element.as_ref())
2516 {
2517 return Some(i);
2518 }
2519 }
2520 }
2521
2522 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
2523 for &i in candidates {
2524 if !used[i] {
2525 return Some(i);
2526 }
2527 }
2528 }
2529 }
2530
2531 None
2532 }
2533}
2534
2535impl ModifierNodeChain {
2536 pub fn new() -> Self {
2537 let mut chain = Self {
2538 entries: Vec::new(),
2539 aggregated_capabilities: NodeCapabilities::empty(),
2540 head_aggregate_child_capabilities: NodeCapabilities::empty(),
2541 head_sentinel: Box::new(SentinelNode::new()),
2542 tail_sentinel: Box::new(SentinelNode::new()),
2543 ordered_nodes: Vec::new(),
2544 scratch_old_used: Vec::new(),
2545 scratch_match_order: Vec::new(),
2546 scratch_final_slots: Vec::new(),
2547 scratch_elements: Vec::new(),
2548 };
2549 chain.sync_chain_links();
2550 chain
2551 }
2552
2553 pub fn detach_nodes(&mut self) {
2555 for entry in &self.entries {
2556 detach_node_tree(&mut **entry.node.borrow_mut());
2557 }
2558 }
2559
2560 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
2562 for entry in &self.entries {
2563 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2564 }
2565 }
2566
2567 pub fn repair_chain(&mut self) {
2570 self.sync_chain_links();
2571 }
2572
2573 pub fn update_from_slice(
2579 &mut self,
2580 elements: &[DynModifierElement],
2581 context: &mut dyn ModifierNodeContext,
2582 ) {
2583 self.update_from_ref_iter(elements.iter(), context);
2584 }
2585
2586 pub fn update_from_ref_iter<'a, I>(
2591 &mut self,
2592 elements: I,
2593 context: &mut dyn ModifierNodeContext,
2594 ) where
2595 I: Iterator<Item = &'a DynModifierElement>,
2596 {
2597 let old_len = self.entries.len();
2598 let mut fast_path_failed_at: Option<usize> = None;
2599 let mut elements_count = 0;
2600
2601 self.scratch_elements.clear();
2602
2603 for (idx, element) in elements.enumerate() {
2604 elements_count = idx + 1;
2605
2606 if fast_path_failed_at.is_none() && idx < old_len {
2607 let entry = &mut self.entries[idx];
2608 let same_type = entry.element_type == element.element_type();
2611 let same_node_type = entry.node_type == element.node_type();
2612 let same_key = entry.key == element.key();
2613 if same_type && same_node_type && same_key {
2614 let can_update_node = {
2615 let node_borrow = entry.node.borrow();
2616 element.can_update_node(&**node_borrow)
2617 };
2618 if !can_update_node {
2619 fast_path_failed_at = Some(idx);
2620 self.scratch_elements.push(element.clone());
2621 continue;
2622 }
2623
2624 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2625 let capabilities = element.capabilities();
2626
2627 {
2628 let node_borrow = entry.node.borrow();
2629 if !node_borrow.node_state().is_attached() {
2630 drop(node_borrow);
2631 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2632 }
2633 }
2634
2635 let needs_update = !same_element || element.requires_update();
2636 if needs_update {
2637 element.update_node(&mut **entry.node.borrow_mut());
2638 entry.element = element.clone();
2639 entry.hash_code = element.hash_code();
2640 request_update_auto_invalidations(element.as_ref(), context, capabilities);
2641 }
2642
2643 entry.capabilities = capabilities;
2644 entry
2645 .node
2646 .borrow()
2647 .node_state()
2648 .set_capabilities(capabilities);
2649 continue;
2650 }
2651 fast_path_failed_at = Some(idx);
2652 }
2653
2654 self.scratch_elements.push(element.clone());
2655 }
2656
2657 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
2658 if elements_count < self.entries.len() {
2659 for entry in self.entries.drain(elements_count..) {
2660 request_auto_invalidations(context, entry.capabilities);
2661 detach_node_tree(&mut **entry.node.borrow_mut());
2662 }
2663 }
2664 self.sync_chain_links();
2665 return;
2666 }
2667
2668 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
2669
2670 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
2671 let processed_entries_len = self.entries.len();
2672 let old_len = old_entries.len();
2673
2674 self.scratch_old_used.clear();
2675 self.scratch_old_used.resize(old_len, false);
2676
2677 self.scratch_match_order.clear();
2678 self.scratch_match_order.resize(old_len, None);
2679
2680 let index = EntryIndex::build(&old_entries);
2681
2682 let new_elements_count = self.scratch_elements.len();
2683 self.scratch_final_slots.clear();
2684 self.scratch_final_slots.reserve(new_elements_count);
2685
2686 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
2687 self.scratch_final_slots.push(None);
2688 let element_type = element.element_type();
2689 let node_type = element.node_type();
2690 let key = element.key();
2691 let hash_code = element.hash_code();
2692 let capabilities = element.capabilities();
2693
2694 let matched_idx = index.find_match(
2695 &old_entries,
2696 &self.scratch_old_used,
2697 EntryMatchQuery {
2698 element_type,
2699 node_type,
2700 key,
2701 hash_code,
2702 element: &element,
2703 },
2704 );
2705
2706 if let Some(idx) = matched_idx {
2707 let entry = &mut old_entries[idx];
2708 let can_update_node = {
2709 let node_borrow = entry.node.borrow();
2710 element.can_update_node(&**node_borrow)
2711 };
2712 if !can_update_node {
2713 let replacement = ModifierNodeEntry::new(
2714 element_type,
2715 node_type,
2716 key,
2717 element.clone(),
2718 element.create_node(),
2719 hash_code,
2720 capabilities,
2721 );
2722 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
2723 element.update_node(&mut **replacement.node.borrow_mut());
2724 request_auto_invalidations(context, capabilities);
2725 self.scratch_final_slots[new_pos] = Some(replacement);
2726 continue;
2727 }
2728
2729 self.scratch_old_used[idx] = true;
2730 self.scratch_match_order[idx] = Some(new_pos);
2731 let moved = idx != new_pos;
2732
2733 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2734
2735 {
2736 let node_borrow = entry.node.borrow();
2737 if !node_borrow.node_state().is_attached() {
2738 drop(node_borrow);
2739 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2740 }
2741 }
2742
2743 let needs_update = !same_element || element.requires_update();
2744 if needs_update {
2745 element.update_node(&mut **entry.node.borrow_mut());
2746 entry.element = element;
2747 entry.hash_code = hash_code;
2748 request_update_auto_invalidations(
2749 entry.element.as_ref(),
2750 context,
2751 capabilities,
2752 );
2753 }
2754 if moved {
2755 request_auto_invalidations(context, capabilities);
2756 }
2757
2758 entry.key = key;
2759 entry.element_type = element_type;
2760 entry.node_type = node_type;
2761 entry.capabilities = capabilities;
2762 entry
2763 .node
2764 .borrow()
2765 .node_state()
2766 .set_capabilities(capabilities);
2767 } else {
2768 let entry = ModifierNodeEntry::new(
2769 element_type,
2770 node_type,
2771 key,
2772 element.clone(),
2773 element.create_node(),
2774 hash_code,
2775 capabilities,
2776 );
2777 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2778 element.update_node(&mut **entry.node.borrow_mut());
2779 request_auto_invalidations(context, capabilities);
2780 self.scratch_final_slots[new_pos] = Some(entry);
2781 }
2782 }
2783
2784 for (i, entry) in old_entries.into_iter().enumerate() {
2785 if self.scratch_old_used[i] {
2786 if let Some(pos) = self.scratch_match_order[i] {
2787 self.scratch_final_slots[pos] = Some(entry);
2788 } else {
2789 request_auto_invalidations(context, entry.capabilities);
2790 detach_node_tree(&mut **entry.node.borrow_mut());
2791 }
2792 } else {
2793 request_auto_invalidations(context, entry.capabilities);
2794 detach_node_tree(&mut **entry.node.borrow_mut());
2795 }
2796 }
2797
2798 self.entries.reserve(self.scratch_final_slots.len());
2799 for slot in self.scratch_final_slots.drain(..) {
2800 if let Some(entry) = slot {
2801 self.entries.push(entry);
2802 } else {
2803 log::error!("modifier reconciliation produced an empty final slot");
2804 }
2805 }
2806
2807 debug_assert_eq!(
2808 self.entries.len(),
2809 processed_entries_len + new_elements_count
2810 );
2811 self.sync_chain_links();
2812 }
2813
2814 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2818 where
2819 I: IntoIterator<Item = DynModifierElement>,
2820 {
2821 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2822 self.update_from_slice(&collected, context);
2823 }
2824
2825 pub fn reset(&mut self) {
2828 for entry in &mut self.entries {
2829 reset_node_tree(&mut **entry.node.borrow_mut());
2830 }
2831 }
2832
2833 pub fn detach_all(&mut self) {
2835 for entry in std::mem::take(&mut self.entries) {
2836 detach_node_tree(&mut **entry.node.borrow_mut());
2837 {
2838 let node_borrow = entry.node.borrow();
2839 let state = node_borrow.node_state();
2840 state.set_capabilities(NodeCapabilities::empty());
2841 }
2842 }
2843 self.aggregated_capabilities = NodeCapabilities::empty();
2844 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2845 self.ordered_nodes.clear();
2846 self.sync_chain_links();
2847 }
2848
2849 pub fn len(&self) -> usize {
2850 self.entries.len()
2851 }
2852
2853 pub fn is_empty(&self) -> bool {
2854 self.entries.is_empty()
2855 }
2856
2857 pub fn capabilities(&self) -> NodeCapabilities {
2859 self.aggregated_capabilities
2860 }
2861
2862 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2864 self.aggregated_capabilities.contains(capability)
2865 }
2866
2867 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2869 self.make_node_ref(NodeLink::Head)
2870 }
2871
2872 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2874 self.make_node_ref(NodeLink::Tail)
2875 }
2876
2877 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2879 ModifierChainIter::forward(self)
2880 }
2881
2882 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2884 ModifierChainIter::backward(self)
2885 }
2886
2887 pub fn for_each_forward<F>(&self, mut f: F)
2889 where
2890 F: FnMut(ModifierChainNodeRef<'_>),
2891 {
2892 for node in self.head_to_tail() {
2893 f(node);
2894 }
2895 }
2896
2897 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2899 where
2900 F: FnMut(ModifierChainNodeRef<'_>),
2901 {
2902 if mask.is_empty() {
2903 self.for_each_forward(f);
2904 return;
2905 }
2906
2907 if !self.head().aggregate_child_capabilities().intersects(mask) {
2908 return;
2909 }
2910
2911 for node in self.head_to_tail() {
2912 if node.kind_set().intersects(mask) {
2913 f(node);
2914 }
2915 }
2916 }
2917
2918 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2920 where
2921 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2922 {
2923 self.for_each_forward_matching(mask, |node_ref| {
2924 node_ref.with_node(|node| f(node_ref.clone(), node));
2925 });
2926 }
2927
2928 pub fn for_each_backward<F>(&self, mut f: F)
2930 where
2931 F: FnMut(ModifierChainNodeRef<'_>),
2932 {
2933 for node in self.tail_to_head() {
2934 f(node);
2935 }
2936 }
2937
2938 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2940 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2941 node as *const dyn ModifierNode as *const ()
2942 }
2943
2944 let target = node_data_ptr(node);
2945 for (index, entry) in self.entries.iter().enumerate() {
2946 if node_data_ptr(&**entry.node.borrow()) == target {
2947 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2948 }
2949 }
2950
2951 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2952 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2953 return None;
2954 }
2955 let matches_target = match link {
2956 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2957 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2958 NodeLink::Entry(path) => {
2959 let node_borrow = self.entries[path.entry()].node.borrow();
2960 node_data_ptr(&**node_borrow) == target
2961 }
2962 };
2963 if matches_target {
2964 Some(self.make_node_ref(*link))
2965 } else {
2966 None
2967 }
2968 })
2969 }
2970
2971 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2974 self.entries.get(index).and_then(|entry| {
2975 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2976 boxed_node.as_any().downcast_ref::<N>()
2977 })
2978 .ok()
2979 })
2980 }
2981
2982 pub fn node_mut<N: ModifierNode + 'static>(
2985 &self,
2986 index: usize,
2987 ) -> Option<std::cell::RefMut<'_, N>> {
2988 self.entries.get(index).and_then(|entry| {
2989 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2990 boxed_node.as_any_mut().downcast_mut::<N>()
2991 })
2992 .ok()
2993 })
2994 }
2995
2996 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2999 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
3000 }
3001
3002 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
3004 self.aggregated_capabilities
3005 .contains(NodeCapabilities::for_invalidation(kind))
3006 }
3007
3008 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
3010 where
3011 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
3012 {
3013 for index in 0..self.ordered_nodes.len() {
3014 let (link, cached_caps, _agg) = self.ordered_nodes[index];
3015 match link {
3016 NodeLink::Head => {
3017 f(self.head_sentinel.as_mut(), cached_caps);
3018 }
3019 NodeLink::Tail => {
3020 f(self.tail_sentinel.as_mut(), cached_caps);
3021 }
3022 NodeLink::Entry(path) => {
3023 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
3024 if path.delegates().is_empty() {
3025 f(&mut **node_borrow, cached_caps);
3026 } else {
3027 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
3028 for &delegate_index in path.delegates() {
3029 if let Some(delegate) =
3030 nth_delegate_mut(current, delegate_index as usize)
3031 {
3032 current = delegate;
3033 } else {
3034 return;
3035 }
3036 }
3037 f(current, cached_caps);
3038 }
3039 }
3040 }
3041 }
3042 }
3043
3044 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
3045 ModifierChainNodeRef {
3046 chain: self,
3047 link,
3048 cached_capabilities: None,
3049 cached_aggregate_child: None,
3050 }
3051 }
3052
3053 fn make_node_ref_with_caps(
3054 &self,
3055 link: NodeLink,
3056 caps: NodeCapabilities,
3057 aggregate_child: NodeCapabilities,
3058 ) -> ModifierChainNodeRef<'_> {
3059 ModifierChainNodeRef {
3060 chain: self,
3061 link,
3062 cached_capabilities: Some(caps),
3063 cached_aggregate_child: Some(aggregate_child),
3064 }
3065 }
3066
3067 fn sync_chain_links(&mut self) {
3068 self.rebuild_ordered_nodes();
3069
3070 self.head_sentinel.node_state().set_parent_link(None);
3071 self.tail_sentinel.node_state().set_child_link(None);
3072
3073 if self.ordered_nodes.is_empty() {
3074 self.head_sentinel
3075 .node_state()
3076 .set_child_link(Some(NodeLink::Tail));
3077 self.tail_sentinel
3078 .node_state()
3079 .set_parent_link(Some(NodeLink::Head));
3080 self.aggregated_capabilities = NodeCapabilities::empty();
3081 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
3082 self.head_sentinel
3083 .node_state()
3084 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3085 self.tail_sentinel
3086 .node_state()
3087 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3088 return;
3089 }
3090
3091 let mut previous = NodeLink::Head;
3092 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
3093 match &previous {
3094 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
3095 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
3096 NodeLink::Entry(path) => {
3097 let node_borrow = self.entries[path.entry()].node.borrow();
3098 if path.delegates().is_empty() {
3099 node_borrow.node_state().set_child_link(Some(link));
3100 } else {
3101 let mut current: &dyn ModifierNode = &**node_borrow;
3102 for &delegate_index in path.delegates() {
3103 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3104 current = delegate;
3105 }
3106 }
3107 current.node_state().set_child_link(Some(link));
3108 }
3109 }
3110 }
3111 match &link {
3112 NodeLink::Head => self
3113 .head_sentinel
3114 .node_state()
3115 .set_parent_link(Some(previous)),
3116 NodeLink::Tail => self
3117 .tail_sentinel
3118 .node_state()
3119 .set_parent_link(Some(previous)),
3120 NodeLink::Entry(path) => {
3121 let node_borrow = self.entries[path.entry()].node.borrow();
3122 if path.delegates().is_empty() {
3123 node_borrow.node_state().set_parent_link(Some(previous));
3124 } else {
3125 let mut current: &dyn ModifierNode = &**node_borrow;
3126 for &delegate_index in path.delegates() {
3127 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3128 current = delegate;
3129 }
3130 }
3131 current.node_state().set_parent_link(Some(previous));
3132 }
3133 }
3134 }
3135 previous = link;
3136 }
3137
3138 match &previous {
3139 NodeLink::Head => self
3140 .head_sentinel
3141 .node_state()
3142 .set_child_link(Some(NodeLink::Tail)),
3143 NodeLink::Tail => self
3144 .tail_sentinel
3145 .node_state()
3146 .set_child_link(Some(NodeLink::Tail)),
3147 NodeLink::Entry(path) => {
3148 let node_borrow = self.entries[path.entry()].node.borrow();
3149 if path.delegates().is_empty() {
3150 node_borrow
3151 .node_state()
3152 .set_child_link(Some(NodeLink::Tail));
3153 } else {
3154 let mut current: &dyn ModifierNode = &**node_borrow;
3155 for &delegate_index in path.delegates() {
3156 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3157 current = delegate;
3158 }
3159 }
3160 current.node_state().set_child_link(Some(NodeLink::Tail));
3161 }
3162 }
3163 }
3164 self.tail_sentinel
3165 .node_state()
3166 .set_parent_link(Some(previous));
3167 self.tail_sentinel.node_state().set_child_link(None);
3168
3169 let mut aggregate = NodeCapabilities::empty();
3170 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
3171 aggregate |= *cached_caps;
3172 *cached_aggregate = aggregate;
3173 match link {
3174 NodeLink::Head => {
3175 self.head_sentinel
3176 .node_state()
3177 .set_aggregate_child_capabilities(aggregate);
3178 }
3179 NodeLink::Tail => {
3180 self.tail_sentinel
3181 .node_state()
3182 .set_aggregate_child_capabilities(aggregate);
3183 }
3184 NodeLink::Entry(path) => {
3185 let node_borrow = self.entries[path.entry()].node.borrow();
3186 let state = if path.delegates().is_empty() {
3187 node_borrow.node_state()
3188 } else {
3189 let mut current: &dyn ModifierNode = &**node_borrow;
3190 for &delegate_index in path.delegates() {
3191 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3192 current = delegate;
3193 }
3194 }
3195 current.node_state()
3196 };
3197 state.set_aggregate_child_capabilities(aggregate);
3198 }
3199 }
3200 }
3201
3202 self.aggregated_capabilities = aggregate;
3203 self.head_aggregate_child_capabilities = aggregate;
3204 self.head_sentinel
3205 .node_state()
3206 .set_aggregate_child_capabilities(aggregate);
3207 self.tail_sentinel
3208 .node_state()
3209 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3210 }
3211
3212 fn rebuild_ordered_nodes(&mut self) {
3213 self.ordered_nodes.clear();
3214 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
3215 for (index, entry) in self.entries.iter().enumerate() {
3216 let node_borrow = entry.node.borrow();
3217 Self::enumerate_link_order(
3218 &**node_borrow,
3219 index,
3220 &mut path_buf,
3221 0,
3222 &mut self.ordered_nodes,
3223 );
3224 }
3225 }
3226
3227 fn enumerate_link_order(
3228 node: &dyn ModifierNode,
3229 entry: usize,
3230 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
3231 path_len: usize,
3232 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
3233 ) {
3234 let caps = node.node_state().capabilities();
3235 out.push((
3236 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
3237 caps,
3238 NodeCapabilities::empty(),
3239 ));
3240 let mut delegate_index = 0usize;
3241 node.for_each_delegate(&mut |child| {
3242 if path_len < MAX_DELEGATE_DEPTH {
3243 path_buf[path_len] = delegate_index;
3244 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
3245 }
3246 delegate_index += 1;
3247 });
3248 }
3249}
3250
3251impl<'a> ModifierChainNodeRef<'a> {
3252 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
3253 match &self.link {
3254 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
3255 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
3256 NodeLink::Entry(path) => {
3257 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3258 if path.delegates().is_empty() {
3259 f(node_borrow.node_state())
3260 } else {
3261 let mut current: &dyn ModifierNode = &**node_borrow;
3262 for &delegate_index in path.delegates() {
3263 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3264 current = delegate;
3265 } else {
3266 return f(node_borrow.node_state());
3267 }
3268 }
3269 f(current.node_state())
3270 }
3271 }
3272 }
3273 }
3274
3275 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
3278 match &self.link {
3279 NodeLink::Head => None,
3280 NodeLink::Tail => None,
3281 NodeLink::Entry(path) => {
3282 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3283 if path.delegates().is_empty() {
3284 Some(f(&**node_borrow))
3285 } else {
3286 let mut current: &dyn ModifierNode = &**node_borrow;
3287 for &delegate_index in path.delegates() {
3288 current = nth_delegate(current, delegate_index as usize)?;
3289 }
3290 Some(f(current))
3291 }
3292 }
3293 }
3294 }
3295
3296 #[inline]
3298 pub fn parent(&self) -> Option<Self> {
3299 self.with_state(NodeState::parent_link)
3300 .map(|link| self.chain.make_node_ref(link))
3301 }
3302
3303 #[inline]
3305 pub fn child(&self) -> Option<Self> {
3306 self.with_state(NodeState::child_link)
3307 .map(|link| self.chain.make_node_ref(link))
3308 }
3309
3310 #[inline]
3312 pub fn kind_set(&self) -> NodeCapabilities {
3313 if let Some(caps) = self.cached_capabilities {
3314 return caps;
3315 }
3316 match &self.link {
3317 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
3318 NodeLink::Entry(_) => self.with_state(NodeState::capabilities),
3319 }
3320 }
3321
3322 pub fn entry_index(&self) -> Option<usize> {
3324 match &self.link {
3325 NodeLink::Entry(path) => Some(path.entry()),
3326 _ => None,
3327 }
3328 }
3329
3330 pub fn delegate_depth(&self) -> usize {
3332 match &self.link {
3333 NodeLink::Entry(path) => path.delegates().len(),
3334 _ => 0,
3335 }
3336 }
3337
3338 #[inline]
3340 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
3341 if let Some(agg) = self.cached_aggregate_child {
3342 return agg;
3343 }
3344 if self.is_tail() {
3345 NodeCapabilities::empty()
3346 } else {
3347 self.with_state(NodeState::aggregate_child_capabilities)
3348 }
3349 }
3350
3351 pub fn is_head(&self) -> bool {
3353 matches!(self.link, NodeLink::Head)
3354 }
3355
3356 pub fn is_tail(&self) -> bool {
3358 matches!(self.link, NodeLink::Tail)
3359 }
3360
3361 pub fn is_sentinel(&self) -> bool {
3363 matches!(self.link, NodeLink::Head | NodeLink::Tail)
3364 }
3365
3366 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
3368 !mask.is_empty() && self.kind_set().intersects(mask)
3369 }
3370
3371 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
3373 where
3374 F: FnMut(ModifierChainNodeRef<'a>),
3375 {
3376 let mut current = if include_self {
3377 Some(self)
3378 } else {
3379 self.child()
3380 };
3381 while let Some(node) = current {
3382 if node.is_tail() {
3383 break;
3384 }
3385 if !node.is_sentinel() {
3386 f(node.clone());
3387 }
3388 current = node.child();
3389 }
3390 }
3391
3392 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3394 where
3395 F: FnMut(ModifierChainNodeRef<'a>),
3396 {
3397 if mask.is_empty() {
3398 self.visit_descendants(include_self, f);
3399 return;
3400 }
3401
3402 if !self.aggregate_child_capabilities().intersects(mask) {
3403 return;
3404 }
3405
3406 self.visit_descendants(include_self, |node| {
3407 if node.kind_set().intersects(mask) {
3408 f(node);
3409 }
3410 });
3411 }
3412
3413 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
3415 where
3416 F: FnMut(ModifierChainNodeRef<'a>),
3417 {
3418 let mut current = if include_self {
3419 Some(self)
3420 } else {
3421 self.parent()
3422 };
3423 while let Some(node) = current {
3424 if node.is_head() {
3425 break;
3426 }
3427 f(node.clone());
3428 current = node.parent();
3429 }
3430 }
3431
3432 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3434 where
3435 F: FnMut(ModifierChainNodeRef<'a>),
3436 {
3437 if mask.is_empty() {
3438 self.visit_ancestors(include_self, f);
3439 return;
3440 }
3441
3442 self.visit_ancestors(include_self, |node| {
3443 if node.kind_set().intersects(mask) {
3444 f(node);
3445 }
3446 });
3447 }
3448}
3449
3450#[cfg(test)]
3451#[path = "tests/modifier_tests.rs"]
3452mod tests;