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
56#[derive(Default, Debug, Clone)]
65pub struct BasicModifierNodeContext {
66 invalidations: Vec<ModifierInvalidation>,
67 update_requested: bool,
68 active_capabilities: Vec<NodeCapabilities>,
69 node_id: Option<cranpose_core::NodeId>,
70}
71
72impl BasicModifierNodeContext {
73 pub fn new() -> Self {
75 Self::default()
76 }
77
78 pub fn invalidations(&self) -> &[ModifierInvalidation] {
82 &self.invalidations
83 }
84
85 pub fn clear_invalidations(&mut self) {
87 self.invalidations.clear();
88 }
89
90 pub fn take_invalidations(&mut self) -> Vec<ModifierInvalidation> {
92 std::mem::take(&mut self.invalidations)
93 }
94
95 pub fn update_requested(&self) -> bool {
98 self.update_requested
99 }
100
101 pub fn take_update_requested(&mut self) -> bool {
103 std::mem::take(&mut self.update_requested)
104 }
105
106 pub fn set_node_id(&mut self, id: Option<cranpose_core::NodeId>) {
108 self.node_id = id;
109 }
110
111 fn push_invalidation(&mut self, kind: InvalidationKind) {
112 let mut capabilities = self.current_capabilities();
113 capabilities.insert(NodeCapabilities::for_invalidation(kind));
114 if let Some(existing) = self
115 .invalidations
116 .iter_mut()
117 .find(|entry| entry.kind() == kind)
118 {
119 let updated = existing.capabilities() | capabilities;
120 *existing = ModifierInvalidation::new(kind, updated);
121 } else {
122 self.invalidations
123 .push(ModifierInvalidation::new(kind, capabilities));
124 }
125 }
126
127 fn current_capabilities(&self) -> NodeCapabilities {
128 self.active_capabilities
129 .last()
130 .copied()
131 .unwrap_or_else(NodeCapabilities::empty)
132 }
133}
134
135impl ModifierNodeContext for BasicModifierNodeContext {
136 fn invalidate(&mut self, kind: InvalidationKind) {
137 self.push_invalidation(kind);
138 }
139
140 fn request_update(&mut self) {
141 self.update_requested = true;
142 }
143
144 fn push_active_capabilities(&mut self, capabilities: NodeCapabilities) {
145 self.active_capabilities.push(capabilities);
146 }
147
148 fn pop_active_capabilities(&mut self) {
149 self.active_capabilities.pop();
150 }
151
152 fn node_id(&self) -> Option<cranpose_core::NodeId> {
153 self.node_id
154 }
155}
156
157const MAX_DELEGATE_DEPTH: usize = 3;
158
159#[derive(Copy, Clone, Debug, PartialEq, Eq)]
160pub(crate) struct NodePath {
161 entry: usize,
162 delegate_buf: [u8; MAX_DELEGATE_DEPTH],
163 delegate_len: u8,
164}
165
166impl NodePath {
167 #[inline]
168 fn root(entry: usize) -> Self {
169 Self {
170 entry,
171 delegate_buf: [0; MAX_DELEGATE_DEPTH],
172 delegate_len: 0,
173 }
174 }
175
176 #[inline]
177 fn from_slice(entry: usize, path: &[usize]) -> Self {
178 debug_assert!(
179 path.len() <= MAX_DELEGATE_DEPTH,
180 "delegate depth {} exceeds MAX_DELEGATE_DEPTH {}",
181 path.len(),
182 MAX_DELEGATE_DEPTH
183 );
184 debug_assert!(
185 path.iter().all(|&i| i <= u8::MAX as usize),
186 "delegate index exceeds u8 range"
187 );
188 let mut delegate_buf = [0u8; MAX_DELEGATE_DEPTH];
189 for (i, &v) in path.iter().enumerate().take(MAX_DELEGATE_DEPTH) {
190 delegate_buf[i] = v as u8;
191 }
192 Self {
193 entry,
194 delegate_buf,
195 delegate_len: path.len().min(MAX_DELEGATE_DEPTH) as u8,
196 }
197 }
198
199 #[inline]
200 fn entry(&self) -> usize {
201 self.entry
202 }
203
204 #[inline]
205 fn delegates(&self) -> &[u8] {
206 &self.delegate_buf[..self.delegate_len as usize]
207 }
208}
209
210#[derive(Copy, Clone, Debug, PartialEq, Eq)]
211pub(crate) enum NodeLink {
212 Head,
213 Tail,
214 Entry(NodePath),
215}
216
217#[derive(Debug)]
223pub struct NodeState {
224 aggregate_child_capabilities: Cell<NodeCapabilities>,
225 capabilities: Cell<NodeCapabilities>,
226 parent: RefCell<Option<NodeLink>>,
227 child: RefCell<Option<NodeLink>>,
228 attached: Cell<bool>,
229 is_sentinel: bool,
230}
231
232impl Default for NodeState {
233 fn default() -> Self {
234 Self::new()
235 }
236}
237
238impl NodeState {
239 pub const fn new() -> Self {
240 Self {
241 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
242 capabilities: Cell::new(NodeCapabilities::empty()),
243 parent: RefCell::new(None),
244 child: RefCell::new(None),
245 attached: Cell::new(false),
246 is_sentinel: false,
247 }
248 }
249
250 pub const fn sentinel() -> Self {
251 Self {
252 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
253 capabilities: Cell::new(NodeCapabilities::empty()),
254 parent: RefCell::new(None),
255 child: RefCell::new(None),
256 attached: Cell::new(true),
257 is_sentinel: true,
258 }
259 }
260
261 pub fn set_capabilities(&self, capabilities: NodeCapabilities) {
262 self.capabilities.set(capabilities);
263 }
264
265 #[inline]
266 pub fn capabilities(&self) -> NodeCapabilities {
267 self.capabilities.get()
268 }
269
270 pub fn set_aggregate_child_capabilities(&self, capabilities: NodeCapabilities) {
271 self.aggregate_child_capabilities.set(capabilities);
272 }
273
274 #[inline]
275 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
276 self.aggregate_child_capabilities.get()
277 }
278
279 pub(crate) fn set_parent_link(&self, parent: Option<NodeLink>) {
280 *self.parent.borrow_mut() = parent;
281 }
282
283 #[inline]
284 pub(crate) fn parent_link(&self) -> Option<NodeLink> {
285 *self.parent.borrow()
286 }
287
288 pub(crate) fn set_child_link(&self, child: Option<NodeLink>) {
289 *self.child.borrow_mut() = child;
290 }
291
292 #[inline]
293 pub(crate) fn child_link(&self) -> Option<NodeLink> {
294 *self.child.borrow()
295 }
296
297 pub fn set_attached(&self, attached: bool) {
298 self.attached.set(attached);
299 }
300
301 pub fn is_attached(&self) -> bool {
302 self.attached.get()
303 }
304
305 pub fn is_sentinel(&self) -> bool {
306 self.is_sentinel
307 }
308}
309
310pub trait DelegatableNode {
312 fn node_state(&self) -> &NodeState;
313 fn aggregate_child_capabilities(&self) -> NodeCapabilities {
314 self.node_state().aggregate_child_capabilities()
315 }
316}
317
318pub trait ModifierNode: Any + DelegatableNode {
376 fn on_attach(&mut self, _context: &mut dyn ModifierNodeContext) {}
377
378 fn on_detach(&mut self) {}
379
380 fn on_reset(&mut self) {}
381
382 fn as_draw_node(&self) -> Option<&dyn DrawModifierNode> {
384 None
385 }
386
387 fn as_draw_node_mut(&mut self) -> Option<&mut dyn DrawModifierNode> {
389 None
390 }
391
392 fn as_pointer_input_node(&self) -> Option<&dyn PointerInputNode> {
394 None
395 }
396
397 fn as_pointer_input_node_mut(&mut self) -> Option<&mut dyn PointerInputNode> {
399 None
400 }
401
402 fn as_semantics_node(&self) -> Option<&dyn SemanticsNode> {
404 None
405 }
406
407 fn as_semantics_node_mut(&mut self) -> Option<&mut dyn SemanticsNode> {
409 None
410 }
411
412 fn as_focus_node(&self) -> Option<&dyn FocusNode> {
414 None
415 }
416
417 fn as_focus_node_mut(&mut self) -> Option<&mut dyn FocusNode> {
419 None
420 }
421
422 fn as_layout_node(&self) -> Option<&dyn LayoutModifierNode> {
424 None
425 }
426
427 fn as_layout_node_mut(&mut self) -> Option<&mut dyn LayoutModifierNode> {
429 None
430 }
431
432 fn for_each_delegate<'b>(&'b self, _visitor: &mut dyn FnMut(&'b dyn ModifierNode)) {}
434
435 fn for_each_delegate_mut<'b>(&'b mut self, _visitor: &mut dyn FnMut(&'b mut dyn ModifierNode)) {
437 }
438}
439
440pub trait LayoutModifierNode: ModifierNode {
446 fn measure(
468 &self,
469 _context: &mut dyn ModifierNodeContext,
470 measurable: &dyn Measurable,
471 constraints: Constraints,
472 ) -> cranpose_ui_layout::LayoutModifierMeasureResult {
473 let placeable = measurable.measure(constraints);
474 cranpose_ui_layout::LayoutModifierMeasureResult::with_size(Size {
475 width: placeable.width(),
476 height: placeable.height(),
477 })
478 }
479
480 fn min_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
482 0.0
483 }
484
485 fn max_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
487 0.0
488 }
489
490 fn min_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
492 0.0
493 }
494
495 fn max_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
497 0.0
498 }
499}
500
501pub trait DrawModifierNode: ModifierNode {
509 fn draw(&self, _draw_scope: &mut dyn DrawScope) {}
518
519 fn create_draw_closure(&self) -> Option<NodeDrawClosure> {
530 None
531 }
532
533 fn create_behind_draw_closure(&self) -> Option<NodeDrawClosure> {
538 None
539 }
540}
541
542pub type NodeDrawClosure = Rc<dyn Fn(&mut cranpose_ui_graphics::DrawScopeDefault)>;
547
548pub trait PointerInputNode: ModifierNode {
554 fn on_pointer_event(
557 &mut self,
558 _context: &mut dyn ModifierNodeContext,
559 _event: &PointerEvent,
560 ) -> bool {
561 false
562 }
563
564 fn hit_test(&self, _x: f32, _y: f32) -> bool {
567 true
568 }
569
570 fn pointer_input_handler(&self) -> Option<Rc<dyn Fn(PointerEvent)>> {
572 None
573 }
574
575 fn layout_size_sink(&self) -> Option<Rc<Cell<Size>>> {
588 None
589 }
590}
591
592pub trait SemanticsNode: ModifierNode {
598 fn merge_semantics(&self, _config: &mut SemanticsConfiguration) {}
600}
601
602#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
607pub enum FocusState {
608 Active,
610 ActiveParent,
612 Captured,
616 #[default]
619 Inactive,
620}
621
622impl FocusState {
623 pub fn is_focused(self) -> bool {
625 matches!(self, FocusState::Active | FocusState::Captured)
626 }
627
628 pub fn has_focus(self) -> bool {
630 matches!(
631 self,
632 FocusState::Active | FocusState::ActiveParent | FocusState::Captured
633 )
634 }
635
636 pub fn is_captured(self) -> bool {
638 matches!(self, FocusState::Captured)
639 }
640}
641
642pub trait FocusNode: ModifierNode {
647 fn focus_state(&self) -> FocusState;
649
650 fn on_focus_changed(&mut self, _context: &mut dyn ModifierNodeContext, _state: FocusState) {}
652}
653
654#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
665pub enum SemanticsWidgetRole {
666 Button,
667 Checkbox,
668 Switch,
669 RadioButton,
670 Tab,
671 Image,
672 DropdownList,
675 ValuePicker,
678 Header,
683 Dialog,
687 Link,
690 SearchField,
693 ProgressBar,
696 ToggleButton,
699 Alert,
702 Toolbar,
705 Menu,
707 MenuItem,
709 TabBar,
712 List,
714 ListItem,
716}
717
718#[derive(Clone, Copy, Debug, PartialEq)]
726pub struct ProgressBarRangeInfo {
727 pub current: f32,
728 pub start: f32,
729 pub end: f32,
730 pub steps: u32,
733}
734
735impl ProgressBarRangeInfo {
736 pub fn new(current: f32, start: f32, end: f32, steps: u32) -> Self {
737 Self {
738 current,
739 start,
740 end,
741 steps,
742 }
743 }
744
745 pub fn fraction(&self) -> f32 {
747 let span = self.end - self.start;
748 if span.abs() < f32::EPSILON {
749 return 0.0;
750 }
751 ((self.current - self.start) / span).clamp(0.0, 1.0)
752 }
753
754 pub fn step(&self) -> f32 {
757 let span = self.end - self.start;
758 if self.steps == 0 {
759 span / 10.0
760 } else {
761 span / (self.steps as f32 + 1.0)
762 }
763 }
764}
765
766#[derive(Clone, Copy, Debug, PartialEq, Eq)]
771pub struct CollectionInfo {
772 pub rows: usize,
773 pub columns: usize,
774}
775
776#[derive(Clone, Copy, Debug, PartialEq)]
782pub struct ScrollAxisRange {
783 pub value: f32,
784 pub max_value: f32,
785 pub reverse: bool,
786}
787
788impl ScrollAxisRange {
789 pub fn new(value: f32, max_value: f32, reverse: bool) -> Self {
790 Self {
791 value,
792 max_value,
793 reverse,
794 }
795 }
796
797 pub fn can_scroll_forward(&self) -> bool {
798 self.value < self.max_value
799 }
800
801 pub fn can_scroll_backward(&self) -> bool {
802 self.value > 0.0
803 }
804}
805
806#[derive(Clone)]
812pub struct SemanticsScrollBy {
813 handler: Rc<dyn Fn(f32, f32) -> bool>,
814}
815
816impl SemanticsScrollBy {
817 pub fn new(handler: impl Fn(f32, f32) -> bool + 'static) -> Self {
818 Self {
819 handler: Rc::new(handler),
820 }
821 }
822
823 pub fn invoke(&self, dx: f32, dy: f32) -> bool {
824 (self.handler)(dx, dy)
825 }
826}
827
828impl fmt::Debug for SemanticsScrollBy {
829 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
830 f.debug_struct("SemanticsScrollBy").finish_non_exhaustive()
831 }
832}
833
834impl PartialEq for SemanticsScrollBy {
835 fn eq(&self, _other: &Self) -> bool {
836 true
837 }
838}
839
840impl Eq for SemanticsScrollBy {}
841
842#[derive(Clone)]
848pub struct SemanticsScrollToIndex {
849 handler: Rc<dyn Fn(usize) -> bool>,
850}
851
852impl SemanticsScrollToIndex {
853 pub fn new(handler: impl Fn(usize) -> bool + 'static) -> Self {
854 Self {
855 handler: Rc::new(handler),
856 }
857 }
858
859 pub fn invoke(&self, index: usize) -> bool {
860 (self.handler)(index)
861 }
862}
863
864impl fmt::Debug for SemanticsScrollToIndex {
865 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
866 f.debug_struct("SemanticsScrollToIndex")
867 .finish_non_exhaustive()
868 }
869}
870
871impl PartialEq for SemanticsScrollToIndex {
872 fn eq(&self, _other: &Self) -> bool {
873 true
874 }
875}
876
877impl Eq for SemanticsScrollToIndex {}
878
879#[derive(Clone)]
885pub struct SemanticsSetProgress {
886 handler: Rc<dyn Fn(f32) -> bool>,
887}
888
889impl SemanticsSetProgress {
890 pub fn new(handler: impl Fn(f32) -> bool + 'static) -> Self {
891 Self {
892 handler: Rc::new(handler),
893 }
894 }
895
896 pub fn invoke(&self, value: f32) -> bool {
897 (self.handler)(value)
898 }
899}
900
901impl fmt::Debug for SemanticsSetProgress {
902 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
903 f.debug_struct("SemanticsSetProgress")
904 .finish_non_exhaustive()
905 }
906}
907
908#[derive(Clone)]
912pub struct SemanticsSetText(Rc<dyn Fn(&str) -> bool>);
913
914impl SemanticsSetText {
915 pub fn new(handler: impl Fn(&str) -> bool + 'static) -> Self {
916 Self(Rc::new(handler))
917 }
918
919 pub fn invoke(&self, text: &str) -> bool {
920 (self.0)(text)
921 }
922}
923
924impl fmt::Debug for SemanticsSetText {
925 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
926 f.write_str("SemanticsSetText")
927 }
928}
929
930#[derive(Clone)]
936pub struct SemanticsSetSelection(Rc<dyn Fn(usize, usize) -> bool>);
937
938impl SemanticsSetSelection {
939 pub fn new(handler: impl Fn(usize, usize) -> bool + 'static) -> Self {
940 Self(Rc::new(handler))
941 }
942
943 pub fn invoke(&self, anchor: usize, focus: usize) -> bool {
944 (self.0)(anchor, focus)
945 }
946}
947
948impl fmt::Debug for SemanticsSetSelection {
949 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
950 f.write_str("SemanticsSetSelection")
951 }
952}
953
954#[derive(Clone)]
957pub struct SemanticsExpand(Rc<dyn Fn() -> bool>);
958
959impl SemanticsExpand {
960 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
961 Self(Rc::new(handler))
962 }
963
964 pub fn invoke(&self) -> bool {
965 (self.0)()
966 }
967}
968
969impl fmt::Debug for SemanticsExpand {
970 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
971 f.write_str("SemanticsExpand")
972 }
973}
974
975#[derive(Clone)]
979pub struct SemanticsLongClick(Rc<dyn Fn() -> bool>);
980
981impl SemanticsLongClick {
982 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
983 Self(Rc::new(handler))
984 }
985
986 pub fn invoke(&self) -> bool {
987 (self.0)()
988 }
989}
990
991impl fmt::Debug for SemanticsLongClick {
992 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
993 f.write_str("SemanticsLongClick")
994 }
995}
996
997impl PartialEq for SemanticsLongClick {
998 fn eq(&self, _other: &Self) -> bool {
999 true
1000 }
1001}
1002
1003impl PartialEq for SemanticsExpand {
1004 fn eq(&self, _other: &Self) -> bool {
1005 true
1006 }
1007}
1008
1009#[derive(Clone)]
1013pub struct SemanticsDismiss(Rc<dyn Fn() -> bool>);
1014
1015impl SemanticsDismiss {
1016 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
1017 Self(Rc::new(handler))
1018 }
1019
1020 pub fn invoke(&self) -> bool {
1021 (self.0)()
1022 }
1023}
1024
1025impl fmt::Debug for SemanticsDismiss {
1026 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1027 f.write_str("SemanticsDismiss")
1028 }
1029}
1030
1031impl PartialEq for SemanticsDismiss {
1032 fn eq(&self, _other: &Self) -> bool {
1033 true
1034 }
1035}
1036
1037impl PartialEq for SemanticsSetText {
1038 fn eq(&self, _other: &Self) -> bool {
1039 true
1040 }
1041}
1042
1043impl PartialEq for SemanticsSetSelection {
1044 fn eq(&self, _other: &Self) -> bool {
1045 true
1046 }
1047}
1048
1049#[derive(Clone)]
1055pub struct SemanticsMagicTap(Rc<dyn Fn() -> bool>);
1056
1057impl SemanticsMagicTap {
1058 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
1059 Self(Rc::new(handler))
1060 }
1061
1062 pub fn invoke(&self) -> bool {
1063 (self.0)()
1064 }
1065}
1066
1067impl fmt::Debug for SemanticsMagicTap {
1068 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1069 f.write_str("SemanticsMagicTap")
1070 }
1071}
1072
1073impl PartialEq for SemanticsMagicTap {
1074 fn eq(&self, _other: &Self) -> bool {
1075 true
1076 }
1077}
1078
1079impl PartialEq for SemanticsSetProgress {
1080 fn eq(&self, _other: &Self) -> bool {
1081 true
1082 }
1083}
1084
1085impl Eq for SemanticsSetProgress {}
1086
1087#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1094pub enum LiveRegionMode {
1095 Polite,
1097 Assertive,
1100}
1101
1102#[derive(Clone)]
1109pub struct SemanticsCustomAction {
1110 pub label: String,
1112 handler: Rc<dyn Fn()>,
1113}
1114
1115impl SemanticsCustomAction {
1116 pub fn new(label: impl Into<String>, handler: impl Fn() + 'static) -> Self {
1117 Self {
1118 label: label.into(),
1119 handler: Rc::new(handler),
1120 }
1121 }
1122
1123 pub fn invoke(&self) {
1124 (self.handler)();
1125 }
1126}
1127
1128impl fmt::Debug for SemanticsCustomAction {
1129 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1130 f.debug_struct("SemanticsCustomAction")
1131 .field("label", &self.label)
1132 .finish_non_exhaustive()
1133 }
1134}
1135
1136impl PartialEq for SemanticsCustomAction {
1137 fn eq(&self, other: &Self) -> bool {
1138 self.label == other.label
1139 }
1140}
1141
1142impl Eq for SemanticsCustomAction {}
1143
1144#[derive(Clone, Debug, PartialEq)]
1159pub struct CanvasSemanticsNode {
1160 pub key: u64,
1167 pub bounds: cranpose_ui_graphics::Rect,
1169 pub label: String,
1170 pub role: Option<SemanticsWidgetRole>,
1171 pub state_description: Option<String>,
1175 pub on_click_label: Option<String>,
1178 pub clickable: bool,
1179 pub selected: Option<bool>,
1181 pub toggled: Option<bool>,
1183 pub enabled: bool,
1184 pub custom_actions: Vec<SemanticsCustomAction>,
1185}
1186
1187impl Default for CanvasSemanticsNode {
1188 fn default() -> Self {
1189 Self {
1190 key: 0,
1191 bounds: cranpose_ui_graphics::Rect {
1192 x: 0.0,
1193 y: 0.0,
1194 width: 0.0,
1195 height: 0.0,
1196 },
1197 label: String::new(),
1198 role: None,
1199 state_description: None,
1200 on_click_label: None,
1201 clickable: false,
1202 selected: None,
1203 toggled: None,
1204 enabled: true,
1205 custom_actions: Vec::new(),
1206 }
1207 }
1208}
1209
1210impl CanvasSemanticsNode {
1211 pub fn control(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1213 Self {
1214 key,
1215 bounds,
1216 label: label.into(),
1217 clickable: true,
1218 ..Self::default()
1219 }
1220 }
1221
1222 pub fn text(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1224 Self {
1225 key,
1226 bounds,
1227 label: label.into(),
1228 ..Self::default()
1229 }
1230 }
1231
1232 pub fn with_role(mut self, role: SemanticsWidgetRole) -> Self {
1233 self.role = Some(role);
1234 self
1235 }
1236
1237 pub fn with_state_description(mut self, state: impl Into<String>) -> Self {
1238 self.state_description = Some(state.into());
1239 self
1240 }
1241
1242 pub fn with_click_label(mut self, label: impl Into<String>) -> Self {
1243 self.on_click_label = Some(label.into());
1244 self.clickable = true;
1245 self
1246 }
1247
1248 pub fn with_selected(mut self, selected: bool) -> Self {
1249 self.selected = Some(selected);
1250 self
1251 }
1252
1253 pub fn with_toggled(mut self, toggled: bool) -> Self {
1254 self.toggled = Some(toggled);
1255 self
1256 }
1257
1258 pub fn with_enabled(mut self, enabled: bool) -> Self {
1259 self.enabled = enabled;
1260 self
1261 }
1262
1263 pub fn with_custom_action(mut self, action: SemanticsCustomAction) -> Self {
1264 self.custom_actions.push(action);
1265 self
1266 }
1267}
1268
1269#[derive(Clone, Debug, PartialEq)]
1271pub struct SemanticsConfiguration {
1272 pub content_description: Option<String>,
1273 pub state_description: Option<String>,
1275 pub on_click_label: Option<String>,
1277 pub on_long_click: Option<SemanticsLongClick>,
1280 pub on_long_click_label: Option<String>,
1283 pub on_magic_tap: Option<SemanticsMagicTap>,
1287 pub on_magic_tap_label: Option<String>,
1290 pub input_labels: Vec<String>,
1294 pub language: Option<String>,
1298 pub role: Option<SemanticsWidgetRole>,
1300 pub selected: Option<bool>,
1301 pub toggled: Option<bool>,
1302 pub enabled: bool,
1303 pub is_clickable: bool,
1304 pub is_editable_text: bool,
1305 pub text: Option<String>,
1308 pub text_selection: Option<crate::text::TextRange>,
1309 pub custom_actions: Vec<SemanticsCustomAction>,
1310 pub canvas_children: Vec<CanvasSemanticsNode>,
1313 pub is_modal: bool,
1316 pub hidden: bool,
1320 pub merge_descendants: bool,
1324 pub selectable_group: bool,
1328 pub pane_title: Option<String>,
1331 pub error: Option<String>,
1334 pub password: bool,
1337 pub traversal_index: f32,
1341 pub live_region: Option<LiveRegionMode>,
1344 pub progress: Option<ProgressBarRangeInfo>,
1347 pub set_progress: Option<SemanticsSetProgress>,
1350 pub set_text: Option<SemanticsSetText>,
1353 pub set_selection: Option<SemanticsSetSelection>,
1356 pub expand: Option<SemanticsExpand>,
1359 pub dismiss: Option<SemanticsDismiss>,
1363 pub collapse: Option<SemanticsExpand>,
1366 pub vertical_scroll: Option<ScrollAxisRange>,
1369 pub horizontal_scroll: Option<ScrollAxisRange>,
1372 pub scroll_by: Option<SemanticsScrollBy>,
1375 pub scroll_to_index: Option<SemanticsScrollToIndex>,
1379 pub collection: Option<CollectionInfo>,
1381}
1382
1383impl Default for SemanticsConfiguration {
1384 fn default() -> Self {
1385 Self {
1386 content_description: None,
1387 state_description: None,
1388 on_click_label: None,
1389 on_long_click: None,
1390 on_long_click_label: None,
1391 on_magic_tap: None,
1392 on_magic_tap_label: None,
1393 input_labels: Vec::new(),
1394 language: None,
1395 role: None,
1396 selected: None,
1397 toggled: None,
1398 enabled: true,
1399 is_clickable: false,
1400 is_editable_text: false,
1401 text: None,
1402 text_selection: None,
1403 custom_actions: Vec::new(),
1404 canvas_children: Vec::new(),
1405 is_modal: false,
1406 hidden: false,
1407 merge_descendants: false,
1408 selectable_group: false,
1409 pane_title: None,
1410 error: None,
1411 password: false,
1412 traversal_index: 0.0,
1413 live_region: None,
1414 progress: None,
1415 set_progress: None,
1416 set_text: None,
1417 set_selection: None,
1418 expand: None,
1419 dismiss: None,
1420 collapse: None,
1421 vertical_scroll: None,
1422 horizontal_scroll: None,
1423 scroll_by: None,
1424 scroll_to_index: None,
1425 collection: None,
1426 }
1427 }
1428}
1429
1430pub type SemanticsSpec = SemanticsConfiguration;
1439
1440impl SemanticsConfiguration {
1441 pub fn new() -> Self {
1444 Self::default()
1445 }
1446
1447 pub fn content_description(mut self, name: impl Into<String>) -> Self {
1450 self.content_description = Some(name.into());
1451 self
1452 }
1453
1454 pub fn state_description(mut self, state: impl Into<String>) -> Self {
1457 self.state_description = Some(state.into());
1458 self
1459 }
1460
1461 pub fn clickable(mut self) -> Self {
1463 self.is_clickable = true;
1464 self
1465 }
1466
1467 pub fn on_long_click(
1471 mut self,
1472 label: impl Into<String>,
1473 action: impl Fn() -> bool + 'static,
1474 ) -> Self {
1475 self.on_long_click_label = Some(label.into());
1476 self.on_long_click = Some(SemanticsLongClick::new(action));
1477 self
1478 }
1479
1480 pub fn on_magic_tap(
1484 mut self,
1485 label: impl Into<String>,
1486 action: impl Fn() -> bool + 'static,
1487 ) -> Self {
1488 self.on_magic_tap_label = Some(label.into());
1489 self.on_magic_tap = Some(SemanticsMagicTap::new(action));
1490 self
1491 }
1492
1493 pub fn input_labels<S: Into<String>>(mut self, labels: impl IntoIterator<Item = S>) -> Self {
1496 self.input_labels = labels.into_iter().map(Into::into).collect();
1497 self
1498 }
1499
1500 pub fn language(mut self, tag: impl Into<String>) -> Self {
1503 self.language = Some(tag.into());
1504 self
1505 }
1506
1507 pub fn toggled(mut self, toggled: bool) -> Self {
1509 self.toggled = Some(toggled);
1510 self
1511 }
1512
1513 pub fn selected(mut self, selected: bool) -> Self {
1516 self.selected = Some(selected);
1517 self
1518 }
1519
1520 pub fn role(mut self, role: SemanticsWidgetRole) -> Self {
1522 self.role = Some(role);
1523 self
1524 }
1525
1526 pub fn heading(self) -> Self {
1529 self.role(SemanticsWidgetRole::Header)
1530 }
1531
1532 pub fn error(mut self, message: impl Into<String>) -> Self {
1534 self.error = Some(message.into());
1535 self
1536 }
1537
1538 pub fn password(mut self) -> Self {
1540 self.password = true;
1541 self
1542 }
1543
1544 pub fn pane_title(mut self, title: impl Into<String>) -> Self {
1547 self.pane_title = Some(title.into());
1548 self
1549 }
1550
1551 pub fn traversal_index(mut self, index: f32) -> Self {
1554 self.traversal_index = index;
1555 self
1556 }
1557
1558 pub fn hidden(mut self) -> Self {
1561 self.hidden = true;
1562 self
1563 }
1564
1565 pub fn merge_descendants(mut self) -> Self {
1568 self.merge_descendants = true;
1569 self
1570 }
1571
1572 pub fn selectable_group(mut self) -> Self {
1575 self.selectable_group = true;
1576 self
1577 }
1578
1579 pub fn live_region(mut self, mode: LiveRegionMode) -> Self {
1582 self.live_region = Some(mode);
1583 self
1584 }
1585 pub fn merge(&mut self, other: &SemanticsConfiguration) {
1586 if let Some(description) = &other.content_description {
1587 self.content_description = Some(description.clone());
1588 }
1589 if let Some(state) = &other.state_description {
1590 self.state_description = Some(state.clone());
1591 }
1592 if let Some(label) = &other.on_click_label {
1593 self.on_click_label = Some(label.clone());
1594 }
1595 if let Some(label) = &other.on_long_click_label {
1596 self.on_long_click_label = Some(label.clone());
1597 }
1598 if let Some(label) = &other.on_magic_tap_label {
1599 self.on_magic_tap_label = Some(label.clone());
1600 }
1601 if !other.input_labels.is_empty() {
1602 self.input_labels.clone_from(&other.input_labels);
1603 }
1604 if let Some(language) = &other.language {
1605 self.language = Some(language.clone());
1606 }
1607 if let Some(role) = other.role {
1608 self.role = Some(role);
1609 }
1610 if let Some(selected) = other.selected {
1611 self.selected = Some(selected);
1612 }
1613 if let Some(toggled) = other.toggled {
1614 self.toggled = Some(toggled);
1615 }
1616 self.enabled &= other.enabled;
1617 self.is_clickable |= other.is_clickable;
1618 self.is_editable_text |= other.is_editable_text;
1619 if let Some(text) = &other.text {
1620 self.text = Some(text.clone());
1621 }
1622 self.is_modal |= other.is_modal;
1623 self.hidden |= other.hidden;
1624 self.merge_descendants |= other.merge_descendants;
1625 self.selectable_group |= other.selectable_group;
1626 self.password |= other.password;
1627 if other.traversal_index != 0.0 {
1628 self.traversal_index = other.traversal_index;
1629 }
1630 if let Some(live_region) = other.live_region {
1631 self.live_region = Some(live_region);
1632 }
1633 self.merge_words(other);
1634 self.merge_actions(other);
1635 self.merge_ranges(other);
1636 }
1637
1638 fn merge_words(&mut self, other: &SemanticsConfiguration) {
1639 if let Some(title) = &other.pane_title {
1640 self.pane_title = Some(title.clone());
1641 }
1642 if let Some(error) = &other.error {
1643 self.error = Some(error.clone());
1644 }
1645 }
1646
1647 fn merge_actions(&mut self, other: &SemanticsConfiguration) {
1648 self.custom_actions
1649 .extend(other.custom_actions.iter().cloned());
1650 self.canvas_children
1651 .extend(other.canvas_children.iter().cloned());
1652 if let Some(set_progress) = &other.set_progress {
1653 self.set_progress = Some(set_progress.clone());
1654 }
1655 if let Some(set_text) = &other.set_text {
1656 self.set_text = Some(set_text.clone());
1657 }
1658 if let Some(set_selection) = &other.set_selection {
1659 self.set_selection = Some(set_selection.clone());
1660 }
1661 if let Some(expand) = &other.expand {
1662 self.expand = Some(expand.clone());
1663 }
1664 if let Some(collapse) = &other.collapse {
1665 self.collapse = Some(collapse.clone());
1666 }
1667 if let Some(dismiss) = &other.dismiss {
1668 self.dismiss = Some(dismiss.clone());
1669 }
1670 if let Some(long_click) = &other.on_long_click {
1671 self.on_long_click = Some(long_click.clone());
1672 }
1673 if let Some(magic_tap) = &other.on_magic_tap {
1674 self.on_magic_tap = Some(magic_tap.clone());
1675 }
1676 if let Some(scroll_by) = &other.scroll_by {
1677 self.scroll_by = Some(scroll_by.clone());
1678 }
1679 if let Some(scroll_to_index) = &other.scroll_to_index {
1680 self.scroll_to_index = Some(scroll_to_index.clone());
1681 }
1682 }
1683
1684 fn merge_ranges(&mut self, other: &SemanticsConfiguration) {
1685 if let Some(selection) = other.text_selection {
1686 self.text_selection = Some(selection);
1687 }
1688 if let Some(progress) = other.progress {
1689 self.progress = Some(progress);
1690 }
1691 if let Some(range) = other.vertical_scroll {
1692 self.vertical_scroll = Some(range);
1693 }
1694 if let Some(range) = other.horizontal_scroll {
1695 self.horizontal_scroll = Some(range);
1696 }
1697 if let Some(collection) = other.collection {
1698 self.collection = Some(collection);
1699 }
1700 }
1701
1702 pub fn is_activatable(&self) -> bool {
1705 self.is_clickable || self.on_click_label.is_some()
1706 }
1707}
1708
1709impl fmt::Debug for dyn ModifierNode {
1710 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1711 f.debug_struct("ModifierNode").finish_non_exhaustive()
1712 }
1713}
1714
1715impl dyn ModifierNode {
1716 pub fn as_any(&self) -> &dyn Any {
1717 self
1718 }
1719
1720 pub fn as_any_mut(&mut self) -> &mut dyn Any {
1721 self
1722 }
1723}
1724
1725pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
1728 type Node: ModifierNode;
1729
1730 fn create(&self) -> Self::Node;
1732
1733 fn update(&self, node: &mut Self::Node);
1735
1736 fn key(&self) -> Option<u64> {
1738 None
1739 }
1740
1741 fn inspector_name(&self) -> &'static str {
1743 type_name::<Self>()
1744 }
1745
1746 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
1748
1749 fn capabilities(&self) -> NodeCapabilities {
1752 NodeCapabilities::default()
1753 }
1754
1755 fn always_update(&self) -> bool {
1761 false
1762 }
1763
1764 fn auto_invalidate_on_update(&self) -> bool {
1767 true
1768 }
1769
1770 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1777 None
1778 }
1779
1780 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
1787 Vec::new()
1788 }
1789}
1790
1791#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1793pub struct NodeCapabilities(u32);
1794
1795impl NodeCapabilities {
1796 pub const NONE: Self = Self(0);
1798 pub const LAYOUT: Self = Self(1 << 0);
1800 pub const DRAW: Self = Self(1 << 1);
1802 pub const POINTER_INPUT: Self = Self(1 << 2);
1804 pub const SEMANTICS: Self = Self(1 << 3);
1806 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1808 pub const FOCUS: Self = Self(1 << 5);
1810 pub const WINDOW_ROOT: Self = Self(1 << 6);
1814
1815 pub const fn empty() -> Self {
1817 Self::NONE
1818 }
1819
1820 pub const fn contains(self, other: Self) -> bool {
1822 (self.0 & other.0) == other.0
1823 }
1824
1825 pub const fn intersects(self, other: Self) -> bool {
1827 (self.0 & other.0) != 0
1828 }
1829
1830 pub fn insert(&mut self, other: Self) {
1832 self.0 |= other.0;
1833 }
1834
1835 pub const fn bits(self) -> u32 {
1837 self.0
1838 }
1839
1840 pub const fn is_empty(self) -> bool {
1842 self.0 == 0
1843 }
1844
1845 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1847 match kind {
1848 InvalidationKind::Layout => Self::LAYOUT,
1849 InvalidationKind::Draw => Self::DRAW,
1850 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1851 InvalidationKind::Semantics => Self::SEMANTICS,
1852 InvalidationKind::Focus => Self::FOCUS,
1853 }
1854 }
1855}
1856
1857impl Default for NodeCapabilities {
1858 fn default() -> Self {
1859 Self::NONE
1860 }
1861}
1862
1863impl fmt::Debug for NodeCapabilities {
1864 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1865 f.debug_struct("NodeCapabilities")
1866 .field("layout", &self.contains(Self::LAYOUT))
1867 .field("draw", &self.contains(Self::DRAW))
1868 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1869 .field("semantics", &self.contains(Self::SEMANTICS))
1870 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1871 .field("focus", &self.contains(Self::FOCUS))
1872 .field("window_root", &self.contains(Self::WINDOW_ROOT))
1873 .finish()
1874 }
1875}
1876
1877impl BitOr for NodeCapabilities {
1878 type Output = Self;
1879
1880 fn bitor(self, rhs: Self) -> Self::Output {
1881 Self(self.0 | rhs.0)
1882 }
1883}
1884
1885impl BitOrAssign for NodeCapabilities {
1886 fn bitor_assign(&mut self, rhs: Self) {
1887 self.0 |= rhs.0;
1888 }
1889}
1890
1891#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1893pub struct ModifierInvalidation {
1894 kind: InvalidationKind,
1895 capabilities: NodeCapabilities,
1896}
1897
1898impl ModifierInvalidation {
1899 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1901 Self { kind, capabilities }
1902 }
1903
1904 pub const fn kind(self) -> InvalidationKind {
1906 self.kind
1907 }
1908
1909 pub const fn capabilities(self) -> NodeCapabilities {
1911 self.capabilities
1912 }
1913}
1914
1915pub trait AnyModifierElement: fmt::Debug {
1917 fn node_type(&self) -> TypeId;
1918
1919 fn element_type(&self) -> TypeId;
1920
1921 fn create_node(&self) -> Box<dyn ModifierNode>;
1922
1923 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
1924
1925 fn update_node(&self, node: &mut dyn ModifierNode);
1926
1927 fn key(&self) -> Option<u64>;
1928
1929 fn capabilities(&self) -> NodeCapabilities {
1930 NodeCapabilities::default()
1931 }
1932
1933 fn hash_code(&self) -> u64;
1934
1935 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
1936
1937 fn inspector_name(&self) -> &'static str;
1938
1939 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
1940
1941 fn requires_update(&self) -> bool;
1942
1943 fn auto_invalidates_on_update(&self) -> bool;
1944
1945 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
1946
1947 fn provides_composition_locals(&self) -> bool {
1949 false
1950 }
1951
1952 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
1954 Vec::new()
1955 }
1956
1957 fn as_any(&self) -> &dyn Any;
1958}
1959
1960struct TypedModifierElement<E: ModifierNodeElement> {
1961 element: E,
1962 cached_hash: u64,
1963 provides_locals: bool,
1964}
1965
1966impl<E: ModifierNodeElement> TypedModifierElement<E> {
1967 fn new(element: E) -> Self {
1968 let mut hasher = default::new();
1969 element.hash(&mut hasher);
1970 let provides_locals = !element.provided_composition_locals().is_empty();
1971 Self {
1972 element,
1973 cached_hash: hasher.finish(),
1974 provides_locals,
1975 }
1976 }
1977}
1978
1979impl<E> fmt::Debug for TypedModifierElement<E>
1980where
1981 E: ModifierNodeElement,
1982{
1983 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1984 f.debug_struct("TypedModifierElement")
1985 .field("type", &type_name::<E>())
1986 .finish()
1987 }
1988}
1989
1990impl<E> AnyModifierElement for TypedModifierElement<E>
1991where
1992 E: ModifierNodeElement,
1993{
1994 fn node_type(&self) -> TypeId {
1995 TypeId::of::<E::Node>()
1996 }
1997
1998 fn element_type(&self) -> TypeId {
1999 TypeId::of::<E>()
2000 }
2001
2002 fn create_node(&self) -> Box<dyn ModifierNode> {
2003 Box::new(self.element.create())
2004 }
2005
2006 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
2007 node.as_any().is::<E::Node>()
2008 }
2009
2010 fn update_node(&self, node: &mut dyn ModifierNode) {
2011 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
2012 self.element.update(typed);
2013 }
2014 }
2015
2016 fn key(&self) -> Option<u64> {
2017 self.element.key()
2018 }
2019
2020 fn capabilities(&self) -> NodeCapabilities {
2021 self.element.capabilities()
2022 }
2023
2024 fn provides_composition_locals(&self) -> bool {
2025 self.provides_locals
2026 }
2027
2028 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
2029 self.element.provided_composition_locals()
2030 }
2031
2032 fn hash_code(&self) -> u64 {
2033 self.cached_hash
2034 }
2035
2036 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
2037 other
2038 .as_any()
2039 .downcast_ref::<Self>()
2040 .map(|typed| typed.element == self.element)
2041 .unwrap_or(false)
2042 }
2043
2044 fn inspector_name(&self) -> &'static str {
2045 self.element.inspector_name()
2046 }
2047
2048 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
2049 self.element.inspector_properties(visitor);
2050 }
2051
2052 fn requires_update(&self) -> bool {
2053 self.element.always_update()
2054 }
2055
2056 fn auto_invalidates_on_update(&self) -> bool {
2057 self.element.auto_invalidate_on_update()
2058 }
2059
2060 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
2061 self.element.update_invalidation_kind()
2062 }
2063
2064 fn as_any(&self) -> &dyn Any {
2065 self
2066 }
2067}
2068
2069fn request_update_auto_invalidations(
2070 element: &dyn AnyModifierElement,
2071 context: &mut dyn ModifierNodeContext,
2072 capabilities: NodeCapabilities,
2073) {
2074 if let Some(kind) = element.update_invalidation_kind() {
2075 let capabilities = NodeCapabilities::for_invalidation(kind);
2076 context.push_active_capabilities(capabilities);
2077 context.invalidate(kind);
2078 context.pop_active_capabilities();
2079 } else if element.auto_invalidates_on_update() {
2080 request_auto_invalidations(context, capabilities);
2081 }
2082}
2083
2084pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
2087 Rc::new(TypedModifierElement::new(element))
2088}
2089
2090pub type DynModifierElement = Rc<dyn AnyModifierElement>;
2092
2093#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2094enum TraversalDirection {
2095 Forward,
2096 Backward,
2097}
2098
2099pub struct ModifierChainIter<'a> {
2104 chain: &'a ModifierNodeChain,
2105 cursor: usize,
2106 remaining: usize,
2107 direction: TraversalDirection,
2108}
2109
2110impl<'a> ModifierChainIter<'a> {
2111 fn forward(chain: &'a ModifierNodeChain) -> Self {
2112 Self {
2113 chain,
2114 cursor: 0,
2115 remaining: chain.ordered_nodes.len(),
2116 direction: TraversalDirection::Forward,
2117 }
2118 }
2119
2120 fn backward(chain: &'a ModifierNodeChain) -> Self {
2121 let len = chain.ordered_nodes.len();
2122 Self {
2123 chain,
2124 cursor: len.wrapping_sub(1),
2125 remaining: len,
2126 direction: TraversalDirection::Backward,
2127 }
2128 }
2129}
2130
2131impl<'a> Iterator for ModifierChainIter<'a> {
2132 type Item = ModifierChainNodeRef<'a>;
2133
2134 #[inline]
2135 fn next(&mut self) -> Option<Self::Item> {
2136 if self.remaining == 0 {
2137 return None;
2138 }
2139 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
2140 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
2141 self.remaining -= 1;
2142 match self.direction {
2143 TraversalDirection::Forward => self.cursor += 1,
2144 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
2145 }
2146 Some(node_ref)
2147 }
2148
2149 #[inline]
2150 fn size_hint(&self) -> (usize, Option<usize>) {
2151 (self.remaining, Some(self.remaining))
2152 }
2153}
2154
2155impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
2156impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
2157
2158#[derive(Debug)]
2159struct ModifierNodeEntry {
2160 element_type: TypeId,
2161 node_type: TypeId,
2162 key: Option<u64>,
2163 hash_code: u64,
2164 element: DynModifierElement,
2165 node: Rc<RefCell<Box<dyn ModifierNode>>>,
2166 capabilities: NodeCapabilities,
2167}
2168
2169impl ModifierNodeEntry {
2170 fn new(
2171 element_type: TypeId,
2172 node_type: TypeId,
2173 key: Option<u64>,
2174 element: DynModifierElement,
2175 node: Box<dyn ModifierNode>,
2176 hash_code: u64,
2177 capabilities: NodeCapabilities,
2178 ) -> Self {
2179 let node_rc = Rc::new(RefCell::new(node));
2180 let entry = Self {
2181 element_type,
2182 node_type,
2183 key,
2184 hash_code,
2185 element,
2186 node: Rc::clone(&node_rc),
2187 capabilities,
2188 };
2189 entry
2190 .node
2191 .borrow()
2192 .node_state()
2193 .set_capabilities(entry.capabilities);
2194 entry
2195 }
2196}
2197
2198fn visit_node_tree_mut(
2199 node: &mut dyn ModifierNode,
2200 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
2201) {
2202 visitor(node);
2203 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
2204}
2205
2206fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
2207 let mut current = 0usize;
2208 let mut result: Option<&dyn ModifierNode> = None;
2209 node.for_each_delegate(&mut |child| {
2210 if result.is_none() && current == target {
2211 result = Some(child);
2212 }
2213 current += 1;
2214 });
2215 result
2216}
2217
2218fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
2219 let mut current = 0usize;
2220 let mut result: Option<&mut dyn ModifierNode> = None;
2221 node.for_each_delegate_mut(&mut |child| {
2222 if result.is_none() && current == target {
2223 result = Some(child);
2224 }
2225 current += 1;
2226 });
2227 result
2228}
2229
2230fn with_node_context<F, R>(
2231 node: &mut dyn ModifierNode,
2232 context: &mut dyn ModifierNodeContext,
2233 f: F,
2234) -> R
2235where
2236 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
2237{
2238 context.push_active_capabilities(node.node_state().capabilities());
2239 let result = f(node, context);
2240 context.pop_active_capabilities();
2241 result
2242}
2243
2244fn request_auto_invalidations(
2245 context: &mut dyn ModifierNodeContext,
2246 capabilities: NodeCapabilities,
2247) {
2248 if capabilities.is_empty() {
2249 return;
2250 }
2251
2252 context.push_active_capabilities(capabilities);
2253
2254 if capabilities.contains(NodeCapabilities::LAYOUT) {
2255 context.invalidate(InvalidationKind::Layout);
2256 }
2257 if capabilities.contains(NodeCapabilities::DRAW) {
2258 context.invalidate(InvalidationKind::Draw);
2259 }
2260 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
2261 context.invalidate(InvalidationKind::PointerInput);
2262 }
2263 if capabilities.contains(NodeCapabilities::SEMANTICS) {
2264 context.invalidate(InvalidationKind::Semantics);
2265 }
2266 if capabilities.contains(NodeCapabilities::FOCUS) {
2267 context.invalidate(InvalidationKind::Focus);
2268 }
2269
2270 context.pop_active_capabilities();
2271}
2272
2273fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
2274 visit_node_tree_mut(node, &mut |n| {
2275 if !n.node_state().is_attached() {
2276 n.node_state().set_attached(true);
2277 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
2278 }
2279 });
2280}
2281
2282fn reset_node_tree(node: &mut dyn ModifierNode) {
2283 visit_node_tree_mut(node, &mut |n| n.on_reset());
2284}
2285
2286fn detach_node_tree(node: &mut dyn ModifierNode) {
2287 visit_node_tree_mut(node, &mut |n| {
2288 if n.node_state().is_attached() {
2289 n.on_detach();
2290 n.node_state().set_attached(false);
2291 }
2292 n.node_state().set_parent_link(None);
2293 n.node_state().set_child_link(None);
2294 n.node_state()
2295 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2296 });
2297}
2298
2299pub struct ModifierNodeChain {
2306 entries: Vec<ModifierNodeEntry>,
2307 aggregated_capabilities: NodeCapabilities,
2308 head_aggregate_child_capabilities: NodeCapabilities,
2309 head_sentinel: Box<SentinelNode>,
2310 tail_sentinel: Box<SentinelNode>,
2311 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2312 scratch_old_used: Vec<bool>,
2313 scratch_match_order: Vec<Option<usize>>,
2314 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
2315 scratch_elements: Vec<DynModifierElement>,
2316}
2317
2318struct SentinelNode {
2319 state: NodeState,
2320}
2321
2322impl SentinelNode {
2323 fn new() -> Self {
2324 Self {
2325 state: NodeState::sentinel(),
2326 }
2327 }
2328}
2329
2330impl DelegatableNode for SentinelNode {
2331 fn node_state(&self) -> &NodeState {
2332 &self.state
2333 }
2334}
2335
2336impl ModifierNode for SentinelNode {}
2337
2338#[derive(Clone)]
2339pub struct ModifierChainNodeRef<'a> {
2340 chain: &'a ModifierNodeChain,
2341 link: NodeLink,
2342 cached_capabilities: Option<NodeCapabilities>,
2343 cached_aggregate_child: Option<NodeCapabilities>,
2344}
2345
2346impl Default for ModifierNodeChain {
2347 fn default() -> Self {
2348 Self::new()
2349 }
2350}
2351
2352struct EntryIndex {
2353 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2354 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2355 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
2356}
2357
2358struct EntryMatchQuery<'a> {
2359 element_type: TypeId,
2360 node_type: TypeId,
2361 key: Option<u64>,
2362 hash_code: u64,
2363 element: &'a DynModifierElement,
2364}
2365
2366impl EntryIndex {
2367 fn build(entries: &[ModifierNodeEntry]) -> Self {
2368 let mut keyed = HashMap::default();
2369 let mut hashed = HashMap::default();
2370 let mut typed = HashMap::default();
2371
2372 for (i, entry) in entries.iter().enumerate() {
2373 if let Some(key_value) = entry.key {
2374 keyed
2375 .entry((entry.element_type, entry.node_type, key_value))
2376 .or_insert_with(Vec::new)
2377 .push(i);
2378 } else {
2379 hashed
2380 .entry((entry.element_type, entry.node_type, entry.hash_code))
2381 .or_insert_with(Vec::new)
2382 .push(i);
2383 typed
2384 .entry((entry.element_type, entry.node_type))
2385 .or_insert_with(Vec::new)
2386 .push(i);
2387 }
2388 }
2389
2390 Self {
2391 keyed,
2392 hashed,
2393 typed,
2394 }
2395 }
2396
2397 fn find_match(
2398 &self,
2399 entries: &[ModifierNodeEntry],
2400 used: &[bool],
2401 query: EntryMatchQuery<'_>,
2402 ) -> Option<usize> {
2403 if let Some(key_value) = query.key {
2404 if let Some(candidates) =
2405 self.keyed
2406 .get(&(query.element_type, query.node_type, key_value))
2407 {
2408 for &i in candidates {
2409 if !used[i] {
2410 return Some(i);
2411 }
2412 }
2413 }
2414 } else {
2415 if let Some(candidates) =
2416 self.hashed
2417 .get(&(query.element_type, query.node_type, query.hash_code))
2418 {
2419 for &i in candidates {
2420 if !used[i]
2421 && entries[i]
2422 .element
2423 .as_ref()
2424 .equals_element(query.element.as_ref())
2425 {
2426 return Some(i);
2427 }
2428 }
2429 }
2430
2431 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
2432 for &i in candidates {
2433 if !used[i] {
2434 return Some(i);
2435 }
2436 }
2437 }
2438 }
2439
2440 None
2441 }
2442}
2443
2444impl ModifierNodeChain {
2445 pub fn new() -> Self {
2446 let mut chain = Self {
2447 entries: Vec::new(),
2448 aggregated_capabilities: NodeCapabilities::empty(),
2449 head_aggregate_child_capabilities: NodeCapabilities::empty(),
2450 head_sentinel: Box::new(SentinelNode::new()),
2451 tail_sentinel: Box::new(SentinelNode::new()),
2452 ordered_nodes: Vec::new(),
2453 scratch_old_used: Vec::new(),
2454 scratch_match_order: Vec::new(),
2455 scratch_final_slots: Vec::new(),
2456 scratch_elements: Vec::new(),
2457 };
2458 chain.sync_chain_links();
2459 chain
2460 }
2461
2462 pub fn detach_nodes(&mut self) {
2464 for entry in &self.entries {
2465 detach_node_tree(&mut **entry.node.borrow_mut());
2466 }
2467 }
2468
2469 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
2471 for entry in &self.entries {
2472 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2473 }
2474 }
2475
2476 pub fn repair_chain(&mut self) {
2479 self.sync_chain_links();
2480 }
2481
2482 pub fn update_from_slice(
2488 &mut self,
2489 elements: &[DynModifierElement],
2490 context: &mut dyn ModifierNodeContext,
2491 ) {
2492 self.update_from_ref_iter(elements.iter(), context);
2493 }
2494
2495 pub fn update_from_ref_iter<'a, I>(
2500 &mut self,
2501 elements: I,
2502 context: &mut dyn ModifierNodeContext,
2503 ) where
2504 I: Iterator<Item = &'a DynModifierElement>,
2505 {
2506 let old_len = self.entries.len();
2507 let mut fast_path_failed_at: Option<usize> = None;
2508 let mut elements_count = 0;
2509
2510 self.scratch_elements.clear();
2511
2512 for (idx, element) in elements.enumerate() {
2513 elements_count = idx + 1;
2514
2515 if fast_path_failed_at.is_none() && idx < old_len {
2516 let entry = &mut self.entries[idx];
2517 let same_type = entry.element_type == element.element_type();
2518 let same_node_type = entry.node_type == element.node_type();
2519 let same_key = entry.key == element.key();
2520 let same_hash = entry.hash_code == element.hash_code();
2521
2522 let positional_update = element.requires_update();
2523 if same_type && same_node_type && same_key && (same_hash || positional_update) {
2524 let can_update_node = {
2525 let node_borrow = entry.node.borrow();
2526 element.can_update_node(&**node_borrow)
2527 };
2528 if !can_update_node {
2529 fast_path_failed_at = Some(idx);
2530 self.scratch_elements.push(element.clone());
2531 continue;
2532 }
2533
2534 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2535 let capabilities = element.capabilities();
2536
2537 {
2538 let node_borrow = entry.node.borrow();
2539 if !node_borrow.node_state().is_attached() {
2540 drop(node_borrow);
2541 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2542 }
2543 }
2544
2545 let needs_update = !same_element || element.requires_update();
2546 if needs_update {
2547 element.update_node(&mut **entry.node.borrow_mut());
2548 entry.element = element.clone();
2549 entry.hash_code = element.hash_code();
2550 request_update_auto_invalidations(element.as_ref(), context, capabilities);
2551 }
2552
2553 entry.capabilities = capabilities;
2554 entry
2555 .node
2556 .borrow()
2557 .node_state()
2558 .set_capabilities(capabilities);
2559 continue;
2560 }
2561 fast_path_failed_at = Some(idx);
2562 }
2563
2564 self.scratch_elements.push(element.clone());
2565 }
2566
2567 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
2568 if elements_count < self.entries.len() {
2569 for entry in self.entries.drain(elements_count..) {
2570 request_auto_invalidations(context, entry.capabilities);
2571 detach_node_tree(&mut **entry.node.borrow_mut());
2572 }
2573 }
2574 self.sync_chain_links();
2575 return;
2576 }
2577
2578 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
2579
2580 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
2581 let processed_entries_len = self.entries.len();
2582 let old_len = old_entries.len();
2583
2584 self.scratch_old_used.clear();
2585 self.scratch_old_used.resize(old_len, false);
2586
2587 self.scratch_match_order.clear();
2588 self.scratch_match_order.resize(old_len, None);
2589
2590 let index = EntryIndex::build(&old_entries);
2591
2592 let new_elements_count = self.scratch_elements.len();
2593 self.scratch_final_slots.clear();
2594 self.scratch_final_slots.reserve(new_elements_count);
2595
2596 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
2597 self.scratch_final_slots.push(None);
2598 let element_type = element.element_type();
2599 let node_type = element.node_type();
2600 let key = element.key();
2601 let hash_code = element.hash_code();
2602 let capabilities = element.capabilities();
2603
2604 let matched_idx = index.find_match(
2605 &old_entries,
2606 &self.scratch_old_used,
2607 EntryMatchQuery {
2608 element_type,
2609 node_type,
2610 key,
2611 hash_code,
2612 element: &element,
2613 },
2614 );
2615
2616 if let Some(idx) = matched_idx {
2617 let entry = &mut old_entries[idx];
2618 let can_update_node = {
2619 let node_borrow = entry.node.borrow();
2620 element.can_update_node(&**node_borrow)
2621 };
2622 if !can_update_node {
2623 let replacement = ModifierNodeEntry::new(
2624 element_type,
2625 node_type,
2626 key,
2627 element.clone(),
2628 element.create_node(),
2629 hash_code,
2630 capabilities,
2631 );
2632 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
2633 element.update_node(&mut **replacement.node.borrow_mut());
2634 request_auto_invalidations(context, capabilities);
2635 self.scratch_final_slots[new_pos] = Some(replacement);
2636 continue;
2637 }
2638
2639 self.scratch_old_used[idx] = true;
2640 self.scratch_match_order[idx] = Some(new_pos);
2641 let moved = idx != new_pos;
2642
2643 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2644
2645 {
2646 let node_borrow = entry.node.borrow();
2647 if !node_borrow.node_state().is_attached() {
2648 drop(node_borrow);
2649 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2650 }
2651 }
2652
2653 let needs_update = !same_element || element.requires_update();
2654 if needs_update {
2655 element.update_node(&mut **entry.node.borrow_mut());
2656 entry.element = element;
2657 entry.hash_code = hash_code;
2658 request_update_auto_invalidations(
2659 entry.element.as_ref(),
2660 context,
2661 capabilities,
2662 );
2663 }
2664 if moved {
2665 request_auto_invalidations(context, capabilities);
2666 }
2667
2668 entry.key = key;
2669 entry.element_type = element_type;
2670 entry.node_type = node_type;
2671 entry.capabilities = capabilities;
2672 entry
2673 .node
2674 .borrow()
2675 .node_state()
2676 .set_capabilities(capabilities);
2677 } else {
2678 let entry = ModifierNodeEntry::new(
2679 element_type,
2680 node_type,
2681 key,
2682 element.clone(),
2683 element.create_node(),
2684 hash_code,
2685 capabilities,
2686 );
2687 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2688 element.update_node(&mut **entry.node.borrow_mut());
2689 request_auto_invalidations(context, capabilities);
2690 self.scratch_final_slots[new_pos] = Some(entry);
2691 }
2692 }
2693
2694 for (i, entry) in old_entries.into_iter().enumerate() {
2695 if self.scratch_old_used[i] {
2696 if let Some(pos) = self.scratch_match_order[i] {
2697 self.scratch_final_slots[pos] = Some(entry);
2698 } else {
2699 request_auto_invalidations(context, entry.capabilities);
2700 detach_node_tree(&mut **entry.node.borrow_mut());
2701 }
2702 } else {
2703 request_auto_invalidations(context, entry.capabilities);
2704 detach_node_tree(&mut **entry.node.borrow_mut());
2705 }
2706 }
2707
2708 self.entries.reserve(self.scratch_final_slots.len());
2709 for slot in self.scratch_final_slots.drain(..) {
2710 if let Some(entry) = slot {
2711 self.entries.push(entry);
2712 } else {
2713 log::error!("modifier reconciliation produced an empty final slot");
2714 }
2715 }
2716
2717 debug_assert_eq!(
2718 self.entries.len(),
2719 processed_entries_len + new_elements_count
2720 );
2721 self.sync_chain_links();
2722 }
2723
2724 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2728 where
2729 I: IntoIterator<Item = DynModifierElement>,
2730 {
2731 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2732 self.update_from_slice(&collected, context);
2733 }
2734
2735 pub fn reset(&mut self) {
2738 for entry in &mut self.entries {
2739 reset_node_tree(&mut **entry.node.borrow_mut());
2740 }
2741 }
2742
2743 pub fn detach_all(&mut self) {
2745 for entry in std::mem::take(&mut self.entries) {
2746 detach_node_tree(&mut **entry.node.borrow_mut());
2747 {
2748 let node_borrow = entry.node.borrow();
2749 let state = node_borrow.node_state();
2750 state.set_capabilities(NodeCapabilities::empty());
2751 }
2752 }
2753 self.aggregated_capabilities = NodeCapabilities::empty();
2754 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2755 self.ordered_nodes.clear();
2756 self.sync_chain_links();
2757 }
2758
2759 pub fn len(&self) -> usize {
2760 self.entries.len()
2761 }
2762
2763 pub fn is_empty(&self) -> bool {
2764 self.entries.is_empty()
2765 }
2766
2767 pub fn capabilities(&self) -> NodeCapabilities {
2769 self.aggregated_capabilities
2770 }
2771
2772 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2774 self.aggregated_capabilities.contains(capability)
2775 }
2776
2777 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2779 self.make_node_ref(NodeLink::Head)
2780 }
2781
2782 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2784 self.make_node_ref(NodeLink::Tail)
2785 }
2786
2787 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2789 ModifierChainIter::forward(self)
2790 }
2791
2792 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2794 ModifierChainIter::backward(self)
2795 }
2796
2797 pub fn for_each_forward<F>(&self, mut f: F)
2799 where
2800 F: FnMut(ModifierChainNodeRef<'_>),
2801 {
2802 for node in self.head_to_tail() {
2803 f(node);
2804 }
2805 }
2806
2807 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2809 where
2810 F: FnMut(ModifierChainNodeRef<'_>),
2811 {
2812 if mask.is_empty() {
2813 self.for_each_forward(f);
2814 return;
2815 }
2816
2817 if !self.head().aggregate_child_capabilities().intersects(mask) {
2818 return;
2819 }
2820
2821 for node in self.head_to_tail() {
2822 if node.kind_set().intersects(mask) {
2823 f(node);
2824 }
2825 }
2826 }
2827
2828 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2830 where
2831 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2832 {
2833 self.for_each_forward_matching(mask, |node_ref| {
2834 node_ref.with_node(|node| f(node_ref.clone(), node));
2835 });
2836 }
2837
2838 pub fn for_each_backward<F>(&self, mut f: F)
2840 where
2841 F: FnMut(ModifierChainNodeRef<'_>),
2842 {
2843 for node in self.tail_to_head() {
2844 f(node);
2845 }
2846 }
2847
2848 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2850 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2851 node as *const dyn ModifierNode as *const ()
2852 }
2853
2854 let target = node_data_ptr(node);
2855 for (index, entry) in self.entries.iter().enumerate() {
2856 if node_data_ptr(&**entry.node.borrow()) == target {
2857 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2858 }
2859 }
2860
2861 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2862 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2863 return None;
2864 }
2865 let matches_target = match link {
2866 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2867 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2868 NodeLink::Entry(path) => {
2869 let node_borrow = self.entries[path.entry()].node.borrow();
2870 node_data_ptr(&**node_borrow) == target
2871 }
2872 };
2873 if matches_target {
2874 Some(self.make_node_ref(*link))
2875 } else {
2876 None
2877 }
2878 })
2879 }
2880
2881 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2884 self.entries.get(index).and_then(|entry| {
2885 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2886 boxed_node.as_any().downcast_ref::<N>()
2887 })
2888 .ok()
2889 })
2890 }
2891
2892 pub fn node_mut<N: ModifierNode + 'static>(
2895 &self,
2896 index: usize,
2897 ) -> Option<std::cell::RefMut<'_, N>> {
2898 self.entries.get(index).and_then(|entry| {
2899 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2900 boxed_node.as_any_mut().downcast_mut::<N>()
2901 })
2902 .ok()
2903 })
2904 }
2905
2906 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2909 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
2910 }
2911
2912 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
2914 self.aggregated_capabilities
2915 .contains(NodeCapabilities::for_invalidation(kind))
2916 }
2917
2918 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
2920 where
2921 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
2922 {
2923 for index in 0..self.ordered_nodes.len() {
2924 let (link, cached_caps, _agg) = self.ordered_nodes[index];
2925 match link {
2926 NodeLink::Head => {
2927 f(self.head_sentinel.as_mut(), cached_caps);
2928 }
2929 NodeLink::Tail => {
2930 f(self.tail_sentinel.as_mut(), cached_caps);
2931 }
2932 NodeLink::Entry(path) => {
2933 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
2934 if path.delegates().is_empty() {
2935 f(&mut **node_borrow, cached_caps);
2936 } else {
2937 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
2938 for &delegate_index in path.delegates() {
2939 if let Some(delegate) =
2940 nth_delegate_mut(current, delegate_index as usize)
2941 {
2942 current = delegate;
2943 } else {
2944 return;
2945 }
2946 }
2947 f(current, cached_caps);
2948 }
2949 }
2950 }
2951 }
2952 }
2953
2954 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2955 ModifierChainNodeRef {
2956 chain: self,
2957 link,
2958 cached_capabilities: None,
2959 cached_aggregate_child: None,
2960 }
2961 }
2962
2963 fn make_node_ref_with_caps(
2964 &self,
2965 link: NodeLink,
2966 caps: NodeCapabilities,
2967 aggregate_child: NodeCapabilities,
2968 ) -> ModifierChainNodeRef<'_> {
2969 ModifierChainNodeRef {
2970 chain: self,
2971 link,
2972 cached_capabilities: Some(caps),
2973 cached_aggregate_child: Some(aggregate_child),
2974 }
2975 }
2976
2977 fn sync_chain_links(&mut self) {
2978 self.rebuild_ordered_nodes();
2979
2980 self.head_sentinel.node_state().set_parent_link(None);
2981 self.tail_sentinel.node_state().set_child_link(None);
2982
2983 if self.ordered_nodes.is_empty() {
2984 self.head_sentinel
2985 .node_state()
2986 .set_child_link(Some(NodeLink::Tail));
2987 self.tail_sentinel
2988 .node_state()
2989 .set_parent_link(Some(NodeLink::Head));
2990 self.aggregated_capabilities = NodeCapabilities::empty();
2991 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2992 self.head_sentinel
2993 .node_state()
2994 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2995 self.tail_sentinel
2996 .node_state()
2997 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2998 return;
2999 }
3000
3001 let mut previous = NodeLink::Head;
3002 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
3003 match &previous {
3004 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
3005 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
3006 NodeLink::Entry(path) => {
3007 let node_borrow = self.entries[path.entry()].node.borrow();
3008 if path.delegates().is_empty() {
3009 node_borrow.node_state().set_child_link(Some(link));
3010 } else {
3011 let mut current: &dyn ModifierNode = &**node_borrow;
3012 for &delegate_index in path.delegates() {
3013 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3014 current = delegate;
3015 }
3016 }
3017 current.node_state().set_child_link(Some(link));
3018 }
3019 }
3020 }
3021 match &link {
3022 NodeLink::Head => self
3023 .head_sentinel
3024 .node_state()
3025 .set_parent_link(Some(previous)),
3026 NodeLink::Tail => self
3027 .tail_sentinel
3028 .node_state()
3029 .set_parent_link(Some(previous)),
3030 NodeLink::Entry(path) => {
3031 let node_borrow = self.entries[path.entry()].node.borrow();
3032 if path.delegates().is_empty() {
3033 node_borrow.node_state().set_parent_link(Some(previous));
3034 } else {
3035 let mut current: &dyn ModifierNode = &**node_borrow;
3036 for &delegate_index in path.delegates() {
3037 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3038 current = delegate;
3039 }
3040 }
3041 current.node_state().set_parent_link(Some(previous));
3042 }
3043 }
3044 }
3045 previous = link;
3046 }
3047
3048 match &previous {
3049 NodeLink::Head => self
3050 .head_sentinel
3051 .node_state()
3052 .set_child_link(Some(NodeLink::Tail)),
3053 NodeLink::Tail => self
3054 .tail_sentinel
3055 .node_state()
3056 .set_child_link(Some(NodeLink::Tail)),
3057 NodeLink::Entry(path) => {
3058 let node_borrow = self.entries[path.entry()].node.borrow();
3059 if path.delegates().is_empty() {
3060 node_borrow
3061 .node_state()
3062 .set_child_link(Some(NodeLink::Tail));
3063 } else {
3064 let mut current: &dyn ModifierNode = &**node_borrow;
3065 for &delegate_index in path.delegates() {
3066 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3067 current = delegate;
3068 }
3069 }
3070 current.node_state().set_child_link(Some(NodeLink::Tail));
3071 }
3072 }
3073 }
3074 self.tail_sentinel
3075 .node_state()
3076 .set_parent_link(Some(previous));
3077 self.tail_sentinel.node_state().set_child_link(None);
3078
3079 let mut aggregate = NodeCapabilities::empty();
3080 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
3081 aggregate |= *cached_caps;
3082 *cached_aggregate = aggregate;
3083 match link {
3084 NodeLink::Head => {
3085 self.head_sentinel
3086 .node_state()
3087 .set_aggregate_child_capabilities(aggregate);
3088 }
3089 NodeLink::Tail => {
3090 self.tail_sentinel
3091 .node_state()
3092 .set_aggregate_child_capabilities(aggregate);
3093 }
3094 NodeLink::Entry(path) => {
3095 let node_borrow = self.entries[path.entry()].node.borrow();
3096 let state = if path.delegates().is_empty() {
3097 node_borrow.node_state()
3098 } else {
3099 let mut current: &dyn ModifierNode = &**node_borrow;
3100 for &delegate_index in path.delegates() {
3101 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3102 current = delegate;
3103 }
3104 }
3105 current.node_state()
3106 };
3107 state.set_aggregate_child_capabilities(aggregate);
3108 }
3109 }
3110 }
3111
3112 self.aggregated_capabilities = aggregate;
3113 self.head_aggregate_child_capabilities = aggregate;
3114 self.head_sentinel
3115 .node_state()
3116 .set_aggregate_child_capabilities(aggregate);
3117 self.tail_sentinel
3118 .node_state()
3119 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3120 }
3121
3122 fn rebuild_ordered_nodes(&mut self) {
3123 self.ordered_nodes.clear();
3124 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
3125 for (index, entry) in self.entries.iter().enumerate() {
3126 let node_borrow = entry.node.borrow();
3127 Self::enumerate_link_order(
3128 &**node_borrow,
3129 index,
3130 &mut path_buf,
3131 0,
3132 &mut self.ordered_nodes,
3133 );
3134 }
3135 }
3136
3137 fn enumerate_link_order(
3138 node: &dyn ModifierNode,
3139 entry: usize,
3140 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
3141 path_len: usize,
3142 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
3143 ) {
3144 let caps = node.node_state().capabilities();
3145 out.push((
3146 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
3147 caps,
3148 NodeCapabilities::empty(),
3149 ));
3150 let mut delegate_index = 0usize;
3151 node.for_each_delegate(&mut |child| {
3152 if path_len < MAX_DELEGATE_DEPTH {
3153 path_buf[path_len] = delegate_index;
3154 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
3155 }
3156 delegate_index += 1;
3157 });
3158 }
3159}
3160
3161impl<'a> ModifierChainNodeRef<'a> {
3162 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
3163 match &self.link {
3164 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
3165 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
3166 NodeLink::Entry(path) => {
3167 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3168 if path.delegates().is_empty() {
3169 f(node_borrow.node_state())
3170 } else {
3171 let mut current: &dyn ModifierNode = &**node_borrow;
3172 for &delegate_index in path.delegates() {
3173 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3174 current = delegate;
3175 } else {
3176 return f(node_borrow.node_state());
3177 }
3178 }
3179 f(current.node_state())
3180 }
3181 }
3182 }
3183 }
3184
3185 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
3188 match &self.link {
3189 NodeLink::Head => None,
3190 NodeLink::Tail => None,
3191 NodeLink::Entry(path) => {
3192 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3193 if path.delegates().is_empty() {
3194 Some(f(&**node_borrow))
3195 } else {
3196 let mut current: &dyn ModifierNode = &**node_borrow;
3197 for &delegate_index in path.delegates() {
3198 current = nth_delegate(current, delegate_index as usize)?;
3199 }
3200 Some(f(current))
3201 }
3202 }
3203 }
3204 }
3205
3206 #[inline]
3208 pub fn parent(&self) -> Option<Self> {
3209 self.with_state(|state| state.parent_link())
3210 .map(|link| self.chain.make_node_ref(link))
3211 }
3212
3213 #[inline]
3215 pub fn child(&self) -> Option<Self> {
3216 self.with_state(|state| state.child_link())
3217 .map(|link| self.chain.make_node_ref(link))
3218 }
3219
3220 #[inline]
3222 pub fn kind_set(&self) -> NodeCapabilities {
3223 if let Some(caps) = self.cached_capabilities {
3224 return caps;
3225 }
3226 match &self.link {
3227 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
3228 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
3229 }
3230 }
3231
3232 pub fn entry_index(&self) -> Option<usize> {
3234 match &self.link {
3235 NodeLink::Entry(path) => Some(path.entry()),
3236 _ => None,
3237 }
3238 }
3239
3240 pub fn delegate_depth(&self) -> usize {
3242 match &self.link {
3243 NodeLink::Entry(path) => path.delegates().len(),
3244 _ => 0,
3245 }
3246 }
3247
3248 #[inline]
3250 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
3251 if let Some(agg) = self.cached_aggregate_child {
3252 return agg;
3253 }
3254 if self.is_tail() {
3255 NodeCapabilities::empty()
3256 } else {
3257 self.with_state(|state| state.aggregate_child_capabilities())
3258 }
3259 }
3260
3261 pub fn is_head(&self) -> bool {
3263 matches!(self.link, NodeLink::Head)
3264 }
3265
3266 pub fn is_tail(&self) -> bool {
3268 matches!(self.link, NodeLink::Tail)
3269 }
3270
3271 pub fn is_sentinel(&self) -> bool {
3273 matches!(self.link, NodeLink::Head | NodeLink::Tail)
3274 }
3275
3276 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
3278 !mask.is_empty() && self.kind_set().intersects(mask)
3279 }
3280
3281 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
3283 where
3284 F: FnMut(ModifierChainNodeRef<'a>),
3285 {
3286 let mut current = if include_self {
3287 Some(self)
3288 } else {
3289 self.child()
3290 };
3291 while let Some(node) = current {
3292 if node.is_tail() {
3293 break;
3294 }
3295 if !node.is_sentinel() {
3296 f(node.clone());
3297 }
3298 current = node.child();
3299 }
3300 }
3301
3302 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3304 where
3305 F: FnMut(ModifierChainNodeRef<'a>),
3306 {
3307 if mask.is_empty() {
3308 self.visit_descendants(include_self, f);
3309 return;
3310 }
3311
3312 if !self.aggregate_child_capabilities().intersects(mask) {
3313 return;
3314 }
3315
3316 self.visit_descendants(include_self, |node| {
3317 if node.kind_set().intersects(mask) {
3318 f(node);
3319 }
3320 });
3321 }
3322
3323 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
3325 where
3326 F: FnMut(ModifierChainNodeRef<'a>),
3327 {
3328 let mut current = if include_self {
3329 Some(self)
3330 } else {
3331 self.parent()
3332 };
3333 while let Some(node) = current {
3334 if node.is_head() {
3335 break;
3336 }
3337 f(node.clone());
3338 current = node.parent();
3339 }
3340 }
3341
3342 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3344 where
3345 F: FnMut(ModifierChainNodeRef<'a>),
3346 {
3347 if mask.is_empty() {
3348 self.visit_ancestors(include_self, f);
3349 return;
3350 }
3351
3352 self.visit_ancestors(include_self, |node| {
3353 if node.kind_set().intersects(mask) {
3354 f(node);
3355 }
3356 });
3357 }
3358}
3359
3360#[cfg(test)]
3361#[path = "tests/modifier_tests.rs"]
3362mod tests;