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 RadioGroup,
718}
719
720#[derive(Clone, Copy, Debug, PartialEq)]
728pub struct ProgressBarRangeInfo {
729 pub current: f32,
730 pub start: f32,
731 pub end: f32,
732 pub steps: u32,
735}
736
737impl ProgressBarRangeInfo {
738 pub fn new(current: f32, start: f32, end: f32, steps: u32) -> Self {
739 Self {
740 current,
741 start,
742 end,
743 steps,
744 }
745 }
746
747 pub fn fraction(&self) -> f32 {
749 let span = self.end - self.start;
750 if span.abs() < f32::EPSILON {
751 return 0.0;
752 }
753 ((self.current - self.start) / span).clamp(0.0, 1.0)
754 }
755
756 pub fn step(&self) -> f32 {
759 let span = self.end - self.start;
760 if self.steps == 0 {
761 span / 10.0
762 } else {
763 span / (self.steps as f32 + 1.0)
764 }
765 }
766}
767
768#[derive(Clone, Copy, Debug, PartialEq, Eq)]
773pub struct CollectionInfo {
774 pub rows: usize,
775 pub columns: usize,
776}
777
778#[derive(Clone, Copy, Debug, PartialEq)]
784pub struct ScrollAxisRange {
785 pub value: f32,
786 pub max_value: f32,
787 pub reverse: bool,
788}
789
790impl ScrollAxisRange {
791 pub fn new(value: f32, max_value: f32, reverse: bool) -> Self {
792 Self {
793 value,
794 max_value,
795 reverse,
796 }
797 }
798
799 pub fn can_scroll_forward(&self) -> bool {
800 self.value < self.max_value
801 }
802
803 pub fn can_scroll_backward(&self) -> bool {
804 self.value > 0.0
805 }
806}
807
808#[derive(Clone)]
814pub struct SemanticsScrollBy {
815 handler: Rc<dyn Fn(f32, f32) -> bool>,
816}
817
818impl SemanticsScrollBy {
819 pub fn new(handler: impl Fn(f32, f32) -> bool + 'static) -> Self {
820 Self {
821 handler: Rc::new(handler),
822 }
823 }
824
825 pub fn invoke(&self, dx: f32, dy: f32) -> bool {
826 (self.handler)(dx, dy)
827 }
828}
829
830impl fmt::Debug for SemanticsScrollBy {
831 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
832 f.debug_struct("SemanticsScrollBy").finish_non_exhaustive()
833 }
834}
835
836impl PartialEq for SemanticsScrollBy {
837 fn eq(&self, _other: &Self) -> bool {
838 true
839 }
840}
841
842impl Eq for SemanticsScrollBy {}
843
844#[derive(Clone)]
850pub struct SemanticsScrollToIndex {
851 handler: Rc<dyn Fn(usize) -> bool>,
852}
853
854impl SemanticsScrollToIndex {
855 pub fn new(handler: impl Fn(usize) -> bool + 'static) -> Self {
856 Self {
857 handler: Rc::new(handler),
858 }
859 }
860
861 pub fn invoke(&self, index: usize) -> bool {
862 (self.handler)(index)
863 }
864}
865
866impl fmt::Debug for SemanticsScrollToIndex {
867 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
868 f.debug_struct("SemanticsScrollToIndex")
869 .finish_non_exhaustive()
870 }
871}
872
873impl PartialEq for SemanticsScrollToIndex {
874 fn eq(&self, _other: &Self) -> bool {
875 true
876 }
877}
878
879impl Eq for SemanticsScrollToIndex {}
880
881#[derive(Clone)]
887pub struct SemanticsSetProgress {
888 handler: Rc<dyn Fn(f32) -> bool>,
889}
890
891impl SemanticsSetProgress {
892 pub fn new(handler: impl Fn(f32) -> bool + 'static) -> Self {
893 Self {
894 handler: Rc::new(handler),
895 }
896 }
897
898 pub fn invoke(&self, value: f32) -> bool {
899 (self.handler)(value)
900 }
901}
902
903impl fmt::Debug for SemanticsSetProgress {
904 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
905 f.debug_struct("SemanticsSetProgress")
906 .finish_non_exhaustive()
907 }
908}
909
910#[derive(Clone)]
914pub struct SemanticsSetText(Rc<dyn Fn(&str) -> bool>);
915
916impl SemanticsSetText {
917 pub fn new(handler: impl Fn(&str) -> bool + 'static) -> Self {
918 Self(Rc::new(handler))
919 }
920
921 pub fn invoke(&self, text: &str) -> bool {
922 (self.0)(text)
923 }
924}
925
926impl fmt::Debug for SemanticsSetText {
927 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
928 f.write_str("SemanticsSetText")
929 }
930}
931
932#[derive(Clone)]
938pub struct SemanticsSetSelection(Rc<dyn Fn(usize, usize) -> bool>);
939
940impl SemanticsSetSelection {
941 pub fn new(handler: impl Fn(usize, usize) -> bool + 'static) -> Self {
942 Self(Rc::new(handler))
943 }
944
945 pub fn invoke(&self, anchor: usize, focus: usize) -> bool {
946 (self.0)(anchor, focus)
947 }
948}
949
950impl fmt::Debug for SemanticsSetSelection {
951 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
952 f.write_str("SemanticsSetSelection")
953 }
954}
955
956#[derive(Clone)]
959pub struct SemanticsExpand(Rc<dyn Fn() -> bool>);
960
961impl SemanticsExpand {
962 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
963 Self(Rc::new(handler))
964 }
965
966 pub fn invoke(&self) -> bool {
967 (self.0)()
968 }
969}
970
971impl fmt::Debug for SemanticsExpand {
972 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
973 f.write_str("SemanticsExpand")
974 }
975}
976
977#[derive(Clone)]
981pub struct SemanticsLongClick(Rc<dyn Fn() -> bool>);
982
983impl SemanticsLongClick {
984 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
985 Self(Rc::new(handler))
986 }
987
988 pub fn invoke(&self) -> bool {
989 (self.0)()
990 }
991}
992
993impl fmt::Debug for SemanticsLongClick {
994 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
995 f.write_str("SemanticsLongClick")
996 }
997}
998
999impl PartialEq for SemanticsLongClick {
1000 fn eq(&self, _other: &Self) -> bool {
1001 true
1002 }
1003}
1004
1005impl PartialEq for SemanticsExpand {
1006 fn eq(&self, _other: &Self) -> bool {
1007 true
1008 }
1009}
1010
1011#[derive(Clone)]
1015pub struct SemanticsDismiss(Rc<dyn Fn() -> bool>);
1016
1017impl SemanticsDismiss {
1018 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
1019 Self(Rc::new(handler))
1020 }
1021
1022 pub fn invoke(&self) -> bool {
1023 (self.0)()
1024 }
1025}
1026
1027impl fmt::Debug for SemanticsDismiss {
1028 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1029 f.write_str("SemanticsDismiss")
1030 }
1031}
1032
1033impl PartialEq for SemanticsDismiss {
1034 fn eq(&self, _other: &Self) -> bool {
1035 true
1036 }
1037}
1038
1039impl PartialEq for SemanticsSetText {
1040 fn eq(&self, _other: &Self) -> bool {
1041 true
1042 }
1043}
1044
1045impl PartialEq for SemanticsSetSelection {
1046 fn eq(&self, _other: &Self) -> bool {
1047 true
1048 }
1049}
1050
1051#[derive(Clone)]
1057pub struct SemanticsMagicTap(Rc<dyn Fn() -> bool>);
1058
1059impl SemanticsMagicTap {
1060 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
1061 Self(Rc::new(handler))
1062 }
1063
1064 pub fn invoke(&self) -> bool {
1065 (self.0)()
1066 }
1067}
1068
1069impl fmt::Debug for SemanticsMagicTap {
1070 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1071 f.write_str("SemanticsMagicTap")
1072 }
1073}
1074
1075impl PartialEq for SemanticsMagicTap {
1076 fn eq(&self, _other: &Self) -> bool {
1077 true
1078 }
1079}
1080
1081impl PartialEq for SemanticsSetProgress {
1082 fn eq(&self, _other: &Self) -> bool {
1083 true
1084 }
1085}
1086
1087impl Eq for SemanticsSetProgress {}
1088
1089#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1096pub enum LiveRegionMode {
1097 Polite,
1099 Assertive,
1102}
1103
1104#[derive(Clone)]
1111pub struct SemanticsCustomAction {
1112 pub label: String,
1114 handler: Rc<dyn Fn()>,
1115}
1116
1117impl SemanticsCustomAction {
1118 pub fn new(label: impl Into<String>, handler: impl Fn() + 'static) -> Self {
1119 Self {
1120 label: label.into(),
1121 handler: Rc::new(handler),
1122 }
1123 }
1124
1125 pub fn invoke(&self) {
1126 (self.handler)();
1127 }
1128}
1129
1130impl fmt::Debug for SemanticsCustomAction {
1131 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1132 f.debug_struct("SemanticsCustomAction")
1133 .field("label", &self.label)
1134 .finish_non_exhaustive()
1135 }
1136}
1137
1138impl PartialEq for SemanticsCustomAction {
1139 fn eq(&self, other: &Self) -> bool {
1140 self.label == other.label
1141 }
1142}
1143
1144impl Eq for SemanticsCustomAction {}
1145
1146#[derive(Clone, Debug, PartialEq)]
1161pub struct CanvasSemanticsNode {
1162 pub key: u64,
1169 pub bounds: cranpose_ui_graphics::Rect,
1171 pub label: String,
1172 pub role: Option<SemanticsWidgetRole>,
1173 pub state_description: Option<String>,
1177 pub on_click_label: Option<String>,
1180 pub clickable: bool,
1181 pub selected: Option<bool>,
1183 pub toggled: Option<bool>,
1185 pub enabled: bool,
1186 pub custom_actions: Vec<SemanticsCustomAction>,
1187}
1188
1189impl Default for CanvasSemanticsNode {
1190 fn default() -> Self {
1191 Self {
1192 key: 0,
1193 bounds: cranpose_ui_graphics::Rect {
1194 x: 0.0,
1195 y: 0.0,
1196 width: 0.0,
1197 height: 0.0,
1198 },
1199 label: String::new(),
1200 role: None,
1201 state_description: None,
1202 on_click_label: None,
1203 clickable: false,
1204 selected: None,
1205 toggled: None,
1206 enabled: true,
1207 custom_actions: Vec::new(),
1208 }
1209 }
1210}
1211
1212impl CanvasSemanticsNode {
1213 pub fn control(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1215 Self {
1216 key,
1217 bounds,
1218 label: label.into(),
1219 clickable: true,
1220 ..Self::default()
1221 }
1222 }
1223
1224 pub fn text(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1226 Self {
1227 key,
1228 bounds,
1229 label: label.into(),
1230 ..Self::default()
1231 }
1232 }
1233
1234 pub fn with_role(mut self, role: SemanticsWidgetRole) -> Self {
1235 self.role = Some(role);
1236 self
1237 }
1238
1239 pub fn with_state_description(mut self, state: impl Into<String>) -> Self {
1240 self.state_description = Some(state.into());
1241 self
1242 }
1243
1244 pub fn with_click_label(mut self, label: impl Into<String>) -> Self {
1245 self.on_click_label = Some(label.into());
1246 self.clickable = true;
1247 self
1248 }
1249
1250 pub fn with_selected(mut self, selected: bool) -> Self {
1251 self.selected = Some(selected);
1252 self
1253 }
1254
1255 pub fn with_toggled(mut self, toggled: bool) -> Self {
1256 self.toggled = Some(toggled);
1257 self
1258 }
1259
1260 pub fn with_enabled(mut self, enabled: bool) -> Self {
1261 self.enabled = enabled;
1262 self
1263 }
1264
1265 pub fn with_custom_action(mut self, action: SemanticsCustomAction) -> Self {
1266 self.custom_actions.push(action);
1267 self
1268 }
1269}
1270
1271#[derive(Clone, Debug, PartialEq)]
1273pub struct SemanticsConfiguration {
1274 pub content_description: Option<String>,
1275 pub state_description: Option<String>,
1277 pub on_click_label: Option<String>,
1279 pub on_long_click: Option<SemanticsLongClick>,
1282 pub on_long_click_label: Option<String>,
1285 pub on_magic_tap: Option<SemanticsMagicTap>,
1289 pub on_magic_tap_label: Option<String>,
1292 pub input_labels: Vec<String>,
1296 pub language: Option<String>,
1300 pub role: Option<SemanticsWidgetRole>,
1302 pub selected: Option<bool>,
1303 pub toggled: Option<bool>,
1304 pub enabled: bool,
1305 pub is_clickable: bool,
1306 pub is_editable_text: bool,
1307 pub text: Option<String>,
1310 pub text_selection: Option<crate::text::TextRange>,
1311 pub custom_actions: Vec<SemanticsCustomAction>,
1312 pub canvas_children: Vec<CanvasSemanticsNode>,
1315 pub is_modal: bool,
1318 pub hidden: bool,
1322 pub merge_descendants: bool,
1326 pub selectable_group: bool,
1330 pub pane_title: Option<String>,
1333 pub error: Option<String>,
1336 pub password: bool,
1339 pub traversal_index: f32,
1343 pub live_region: Option<LiveRegionMode>,
1346 pub progress: Option<ProgressBarRangeInfo>,
1349 pub set_progress: Option<SemanticsSetProgress>,
1352 pub set_text: Option<SemanticsSetText>,
1355 pub set_selection: Option<SemanticsSetSelection>,
1358 pub expand: Option<SemanticsExpand>,
1361 pub dismiss: Option<SemanticsDismiss>,
1365 pub collapse: Option<SemanticsExpand>,
1368 pub vertical_scroll: Option<ScrollAxisRange>,
1371 pub horizontal_scroll: Option<ScrollAxisRange>,
1374 pub scroll_by: Option<SemanticsScrollBy>,
1377 pub scroll_to_index: Option<SemanticsScrollToIndex>,
1381 pub collection: Option<CollectionInfo>,
1383}
1384
1385impl Default for SemanticsConfiguration {
1386 fn default() -> Self {
1387 Self {
1388 content_description: None,
1389 state_description: None,
1390 on_click_label: None,
1391 on_long_click: None,
1392 on_long_click_label: None,
1393 on_magic_tap: None,
1394 on_magic_tap_label: None,
1395 input_labels: Vec::new(),
1396 language: None,
1397 role: None,
1398 selected: None,
1399 toggled: None,
1400 enabled: true,
1401 is_clickable: false,
1402 is_editable_text: false,
1403 text: None,
1404 text_selection: None,
1405 custom_actions: Vec::new(),
1406 canvas_children: Vec::new(),
1407 is_modal: false,
1408 hidden: false,
1409 merge_descendants: false,
1410 selectable_group: false,
1411 pane_title: None,
1412 error: None,
1413 password: false,
1414 traversal_index: 0.0,
1415 live_region: None,
1416 progress: None,
1417 set_progress: None,
1418 set_text: None,
1419 set_selection: None,
1420 expand: None,
1421 dismiss: None,
1422 collapse: None,
1423 vertical_scroll: None,
1424 horizontal_scroll: None,
1425 scroll_by: None,
1426 scroll_to_index: None,
1427 collection: None,
1428 }
1429 }
1430}
1431
1432pub type SemanticsSpec = SemanticsConfiguration;
1441
1442impl SemanticsConfiguration {
1443 pub fn new() -> Self {
1446 Self::default()
1447 }
1448
1449 pub fn content_description(mut self, name: impl Into<String>) -> Self {
1452 self.content_description = Some(name.into());
1453 self
1454 }
1455
1456 pub fn state_description(mut self, state: impl Into<String>) -> Self {
1459 self.state_description = Some(state.into());
1460 self
1461 }
1462
1463 pub fn clickable(mut self) -> Self {
1465 self.is_clickable = true;
1466 self
1467 }
1468
1469 pub fn on_long_click(
1473 mut self,
1474 label: impl Into<String>,
1475 action: impl Fn() -> bool + 'static,
1476 ) -> Self {
1477 self.on_long_click_label = Some(label.into());
1478 self.on_long_click = Some(SemanticsLongClick::new(action));
1479 self
1480 }
1481
1482 pub fn on_magic_tap(
1486 mut self,
1487 label: impl Into<String>,
1488 action: impl Fn() -> bool + 'static,
1489 ) -> Self {
1490 self.on_magic_tap_label = Some(label.into());
1491 self.on_magic_tap = Some(SemanticsMagicTap::new(action));
1492 self
1493 }
1494
1495 pub fn input_labels<S: Into<String>>(mut self, labels: impl IntoIterator<Item = S>) -> Self {
1498 self.input_labels = labels.into_iter().map(Into::into).collect();
1499 self
1500 }
1501
1502 pub fn language(mut self, tag: impl Into<String>) -> Self {
1505 self.language = Some(tag.into());
1506 self
1507 }
1508
1509 pub fn toggled(mut self, toggled: bool) -> Self {
1511 self.toggled = Some(toggled);
1512 self
1513 }
1514
1515 pub fn selected(mut self, selected: bool) -> Self {
1518 self.selected = Some(selected);
1519 self
1520 }
1521
1522 pub fn role(mut self, role: SemanticsWidgetRole) -> Self {
1524 self.role = Some(role);
1525 self
1526 }
1527
1528 pub fn heading(self) -> Self {
1531 self.role(SemanticsWidgetRole::Header)
1532 }
1533
1534 pub fn error(mut self, message: impl Into<String>) -> Self {
1536 self.error = Some(message.into());
1537 self
1538 }
1539
1540 pub fn password(mut self) -> Self {
1542 self.password = true;
1543 self
1544 }
1545
1546 pub fn pane_title(mut self, title: impl Into<String>) -> Self {
1549 self.pane_title = Some(title.into());
1550 self
1551 }
1552
1553 pub fn traversal_index(mut self, index: f32) -> Self {
1556 self.traversal_index = index;
1557 self
1558 }
1559
1560 pub fn hidden(mut self) -> Self {
1563 self.hidden = true;
1564 self
1565 }
1566
1567 pub fn merge_descendants(mut self) -> Self {
1570 self.merge_descendants = true;
1571 self
1572 }
1573
1574 pub fn selectable_group(mut self) -> Self {
1577 self.selectable_group = true;
1578 self
1579 }
1580
1581 pub fn live_region(mut self, mode: LiveRegionMode) -> Self {
1584 self.live_region = Some(mode);
1585 self
1586 }
1587 pub fn merge(&mut self, other: &SemanticsConfiguration) {
1588 if let Some(description) = &other.content_description {
1589 self.content_description = Some(description.clone());
1590 }
1591 if let Some(state) = &other.state_description {
1592 self.state_description = Some(state.clone());
1593 }
1594 if let Some(label) = &other.on_click_label {
1595 self.on_click_label = Some(label.clone());
1596 }
1597 if let Some(label) = &other.on_long_click_label {
1598 self.on_long_click_label = Some(label.clone());
1599 }
1600 if let Some(label) = &other.on_magic_tap_label {
1601 self.on_magic_tap_label = Some(label.clone());
1602 }
1603 if !other.input_labels.is_empty() {
1604 self.input_labels.clone_from(&other.input_labels);
1605 }
1606 if let Some(language) = &other.language {
1607 self.language = Some(language.clone());
1608 }
1609 if let Some(role) = other.role {
1610 self.role = Some(role);
1611 }
1612 if let Some(selected) = other.selected {
1613 self.selected = Some(selected);
1614 }
1615 if let Some(toggled) = other.toggled {
1616 self.toggled = Some(toggled);
1617 }
1618 self.enabled &= other.enabled;
1619 self.is_clickable |= other.is_clickable;
1620 self.is_editable_text |= other.is_editable_text;
1621 if let Some(text) = &other.text {
1622 self.text = Some(text.clone());
1623 }
1624 self.is_modal |= other.is_modal;
1625 self.hidden |= other.hidden;
1626 self.merge_descendants |= other.merge_descendants;
1627 self.selectable_group |= other.selectable_group;
1628 self.password |= other.password;
1629 if other.traversal_index != 0.0 {
1630 self.traversal_index = other.traversal_index;
1631 }
1632 if let Some(live_region) = other.live_region {
1633 self.live_region = Some(live_region);
1634 }
1635 self.merge_words(other);
1636 self.merge_actions(other);
1637 self.merge_ranges(other);
1638 }
1639
1640 fn merge_words(&mut self, other: &SemanticsConfiguration) {
1641 if let Some(title) = &other.pane_title {
1642 self.pane_title = Some(title.clone());
1643 }
1644 if let Some(error) = &other.error {
1645 self.error = Some(error.clone());
1646 }
1647 }
1648
1649 fn merge_actions(&mut self, other: &SemanticsConfiguration) {
1650 self.custom_actions
1651 .extend(other.custom_actions.iter().cloned());
1652 self.canvas_children
1653 .extend(other.canvas_children.iter().cloned());
1654 if let Some(set_progress) = &other.set_progress {
1655 self.set_progress = Some(set_progress.clone());
1656 }
1657 if let Some(set_text) = &other.set_text {
1658 self.set_text = Some(set_text.clone());
1659 }
1660 if let Some(set_selection) = &other.set_selection {
1661 self.set_selection = Some(set_selection.clone());
1662 }
1663 if let Some(expand) = &other.expand {
1664 self.expand = Some(expand.clone());
1665 }
1666 if let Some(collapse) = &other.collapse {
1667 self.collapse = Some(collapse.clone());
1668 }
1669 if let Some(dismiss) = &other.dismiss {
1670 self.dismiss = Some(dismiss.clone());
1671 }
1672 if let Some(long_click) = &other.on_long_click {
1673 self.on_long_click = Some(long_click.clone());
1674 }
1675 if let Some(magic_tap) = &other.on_magic_tap {
1676 self.on_magic_tap = Some(magic_tap.clone());
1677 }
1678 if let Some(scroll_by) = &other.scroll_by {
1679 self.scroll_by = Some(scroll_by.clone());
1680 }
1681 if let Some(scroll_to_index) = &other.scroll_to_index {
1682 self.scroll_to_index = Some(scroll_to_index.clone());
1683 }
1684 }
1685
1686 fn merge_ranges(&mut self, other: &SemanticsConfiguration) {
1687 if let Some(selection) = other.text_selection {
1688 self.text_selection = Some(selection);
1689 }
1690 if let Some(progress) = other.progress {
1691 self.progress = Some(progress);
1692 }
1693 if let Some(range) = other.vertical_scroll {
1694 self.vertical_scroll = Some(range);
1695 }
1696 if let Some(range) = other.horizontal_scroll {
1697 self.horizontal_scroll = Some(range);
1698 }
1699 if let Some(collection) = other.collection {
1700 self.collection = Some(collection);
1701 }
1702 }
1703
1704 pub fn is_activatable(&self) -> bool {
1707 self.is_clickable || self.on_click_label.is_some()
1708 }
1709}
1710
1711impl fmt::Debug for dyn ModifierNode {
1712 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1713 f.debug_struct("ModifierNode").finish_non_exhaustive()
1714 }
1715}
1716
1717impl dyn ModifierNode {
1718 pub fn as_any(&self) -> &dyn Any {
1719 self
1720 }
1721
1722 pub fn as_any_mut(&mut self) -> &mut dyn Any {
1723 self
1724 }
1725}
1726
1727pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
1730 type Node: ModifierNode;
1731
1732 fn create(&self) -> Self::Node;
1734
1735 fn update(&self, node: &mut Self::Node);
1737
1738 fn key(&self) -> Option<u64> {
1740 None
1741 }
1742
1743 fn inspector_name(&self) -> &'static str {
1745 type_name::<Self>()
1746 }
1747
1748 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
1750
1751 fn capabilities(&self) -> NodeCapabilities {
1754 NodeCapabilities::default()
1755 }
1756
1757 fn always_update(&self) -> bool {
1763 false
1764 }
1765
1766 fn auto_invalidate_on_update(&self) -> bool {
1769 true
1770 }
1771
1772 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1779 None
1780 }
1781
1782 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
1789 Vec::new()
1790 }
1791}
1792
1793#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1795pub struct NodeCapabilities(u32);
1796
1797impl NodeCapabilities {
1798 pub const NONE: Self = Self(0);
1800 pub const LAYOUT: Self = Self(1 << 0);
1802 pub const DRAW: Self = Self(1 << 1);
1804 pub const POINTER_INPUT: Self = Self(1 << 2);
1806 pub const SEMANTICS: Self = Self(1 << 3);
1808 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1810 pub const FOCUS: Self = Self(1 << 5);
1812 pub const WINDOW_ROOT: Self = Self(1 << 6);
1816
1817 pub const fn empty() -> Self {
1819 Self::NONE
1820 }
1821
1822 pub const fn contains(self, other: Self) -> bool {
1824 (self.0 & other.0) == other.0
1825 }
1826
1827 pub const fn intersects(self, other: Self) -> bool {
1829 (self.0 & other.0) != 0
1830 }
1831
1832 pub fn insert(&mut self, other: Self) {
1834 self.0 |= other.0;
1835 }
1836
1837 pub const fn bits(self) -> u32 {
1839 self.0
1840 }
1841
1842 pub const fn is_empty(self) -> bool {
1844 self.0 == 0
1845 }
1846
1847 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1849 match kind {
1850 InvalidationKind::Layout => Self::LAYOUT,
1851 InvalidationKind::Draw => Self::DRAW,
1852 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1853 InvalidationKind::Semantics => Self::SEMANTICS,
1854 InvalidationKind::Focus => Self::FOCUS,
1855 }
1856 }
1857}
1858
1859impl Default for NodeCapabilities {
1860 fn default() -> Self {
1861 Self::NONE
1862 }
1863}
1864
1865impl fmt::Debug for NodeCapabilities {
1866 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1867 f.debug_struct("NodeCapabilities")
1868 .field("layout", &self.contains(Self::LAYOUT))
1869 .field("draw", &self.contains(Self::DRAW))
1870 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1871 .field("semantics", &self.contains(Self::SEMANTICS))
1872 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1873 .field("focus", &self.contains(Self::FOCUS))
1874 .field("window_root", &self.contains(Self::WINDOW_ROOT))
1875 .finish()
1876 }
1877}
1878
1879impl BitOr for NodeCapabilities {
1880 type Output = Self;
1881
1882 fn bitor(self, rhs: Self) -> Self::Output {
1883 Self(self.0 | rhs.0)
1884 }
1885}
1886
1887impl BitOrAssign for NodeCapabilities {
1888 fn bitor_assign(&mut self, rhs: Self) {
1889 self.0 |= rhs.0;
1890 }
1891}
1892
1893#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1895pub struct ModifierInvalidation {
1896 kind: InvalidationKind,
1897 capabilities: NodeCapabilities,
1898}
1899
1900impl ModifierInvalidation {
1901 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1903 Self { kind, capabilities }
1904 }
1905
1906 pub const fn kind(self) -> InvalidationKind {
1908 self.kind
1909 }
1910
1911 pub const fn capabilities(self) -> NodeCapabilities {
1913 self.capabilities
1914 }
1915}
1916
1917pub trait AnyModifierElement: fmt::Debug {
1919 fn node_type(&self) -> TypeId;
1920
1921 fn element_type(&self) -> TypeId;
1922
1923 fn create_node(&self) -> Box<dyn ModifierNode>;
1924
1925 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
1926
1927 fn update_node(&self, node: &mut dyn ModifierNode);
1928
1929 fn key(&self) -> Option<u64>;
1930
1931 fn capabilities(&self) -> NodeCapabilities {
1932 NodeCapabilities::default()
1933 }
1934
1935 fn hash_code(&self) -> u64;
1936
1937 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
1938
1939 fn inspector_name(&self) -> &'static str;
1940
1941 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
1942
1943 fn requires_update(&self) -> bool;
1944
1945 fn auto_invalidates_on_update(&self) -> bool;
1946
1947 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
1948
1949 fn provides_composition_locals(&self) -> bool {
1951 false
1952 }
1953
1954 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
1956 Vec::new()
1957 }
1958
1959 fn as_any(&self) -> &dyn Any;
1960}
1961
1962struct TypedModifierElement<E: ModifierNodeElement> {
1963 element: E,
1964 cached_hash: u64,
1965 provides_locals: bool,
1966}
1967
1968impl<E: ModifierNodeElement> TypedModifierElement<E> {
1969 fn new(element: E) -> Self {
1970 let mut hasher = default::new();
1971 element.hash(&mut hasher);
1972 let provides_locals = !element.provided_composition_locals().is_empty();
1973 Self {
1974 element,
1975 cached_hash: hasher.finish(),
1976 provides_locals,
1977 }
1978 }
1979}
1980
1981impl<E> fmt::Debug for TypedModifierElement<E>
1982where
1983 E: ModifierNodeElement,
1984{
1985 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1986 f.debug_struct("TypedModifierElement")
1987 .field("type", &type_name::<E>())
1988 .finish()
1989 }
1990}
1991
1992impl<E> AnyModifierElement for TypedModifierElement<E>
1993where
1994 E: ModifierNodeElement,
1995{
1996 fn node_type(&self) -> TypeId {
1997 TypeId::of::<E::Node>()
1998 }
1999
2000 fn element_type(&self) -> TypeId {
2001 TypeId::of::<E>()
2002 }
2003
2004 fn create_node(&self) -> Box<dyn ModifierNode> {
2005 Box::new(self.element.create())
2006 }
2007
2008 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
2009 node.as_any().is::<E::Node>()
2010 }
2011
2012 fn update_node(&self, node: &mut dyn ModifierNode) {
2013 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
2014 self.element.update(typed);
2015 }
2016 }
2017
2018 fn key(&self) -> Option<u64> {
2019 self.element.key()
2020 }
2021
2022 fn capabilities(&self) -> NodeCapabilities {
2023 self.element.capabilities()
2024 }
2025
2026 fn provides_composition_locals(&self) -> bool {
2027 self.provides_locals
2028 }
2029
2030 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
2031 self.element.provided_composition_locals()
2032 }
2033
2034 fn hash_code(&self) -> u64 {
2035 self.cached_hash
2036 }
2037
2038 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
2039 other
2040 .as_any()
2041 .downcast_ref::<Self>()
2042 .map(|typed| typed.element == self.element)
2043 .unwrap_or(false)
2044 }
2045
2046 fn inspector_name(&self) -> &'static str {
2047 self.element.inspector_name()
2048 }
2049
2050 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
2051 self.element.inspector_properties(visitor);
2052 }
2053
2054 fn requires_update(&self) -> bool {
2055 self.element.always_update()
2056 }
2057
2058 fn auto_invalidates_on_update(&self) -> bool {
2059 self.element.auto_invalidate_on_update()
2060 }
2061
2062 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
2063 self.element.update_invalidation_kind()
2064 }
2065
2066 fn as_any(&self) -> &dyn Any {
2067 self
2068 }
2069}
2070
2071fn request_update_auto_invalidations(
2072 element: &dyn AnyModifierElement,
2073 context: &mut dyn ModifierNodeContext,
2074 capabilities: NodeCapabilities,
2075) {
2076 if let Some(kind) = element.update_invalidation_kind() {
2077 let capabilities = NodeCapabilities::for_invalidation(kind);
2078 context.push_active_capabilities(capabilities);
2079 context.invalidate(kind);
2080 context.pop_active_capabilities();
2081 } else if element.auto_invalidates_on_update() {
2082 request_auto_invalidations(context, capabilities);
2083 }
2084}
2085
2086pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
2089 Rc::new(TypedModifierElement::new(element))
2090}
2091
2092pub type DynModifierElement = Rc<dyn AnyModifierElement>;
2094
2095#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2096enum TraversalDirection {
2097 Forward,
2098 Backward,
2099}
2100
2101pub struct ModifierChainIter<'a> {
2106 chain: &'a ModifierNodeChain,
2107 cursor: usize,
2108 remaining: usize,
2109 direction: TraversalDirection,
2110}
2111
2112impl<'a> ModifierChainIter<'a> {
2113 fn forward(chain: &'a ModifierNodeChain) -> Self {
2114 Self {
2115 chain,
2116 cursor: 0,
2117 remaining: chain.ordered_nodes.len(),
2118 direction: TraversalDirection::Forward,
2119 }
2120 }
2121
2122 fn backward(chain: &'a ModifierNodeChain) -> Self {
2123 let len = chain.ordered_nodes.len();
2124 Self {
2125 chain,
2126 cursor: len.wrapping_sub(1),
2127 remaining: len,
2128 direction: TraversalDirection::Backward,
2129 }
2130 }
2131}
2132
2133impl<'a> Iterator for ModifierChainIter<'a> {
2134 type Item = ModifierChainNodeRef<'a>;
2135
2136 #[inline]
2137 fn next(&mut self) -> Option<Self::Item> {
2138 if self.remaining == 0 {
2139 return None;
2140 }
2141 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
2142 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
2143 self.remaining -= 1;
2144 match self.direction {
2145 TraversalDirection::Forward => self.cursor += 1,
2146 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
2147 }
2148 Some(node_ref)
2149 }
2150
2151 #[inline]
2152 fn size_hint(&self) -> (usize, Option<usize>) {
2153 (self.remaining, Some(self.remaining))
2154 }
2155}
2156
2157impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
2158impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
2159
2160#[derive(Debug)]
2161struct ModifierNodeEntry {
2162 element_type: TypeId,
2163 node_type: TypeId,
2164 key: Option<u64>,
2165 hash_code: u64,
2166 element: DynModifierElement,
2167 node: Rc<RefCell<Box<dyn ModifierNode>>>,
2168 capabilities: NodeCapabilities,
2169}
2170
2171impl ModifierNodeEntry {
2172 fn new(
2173 element_type: TypeId,
2174 node_type: TypeId,
2175 key: Option<u64>,
2176 element: DynModifierElement,
2177 node: Box<dyn ModifierNode>,
2178 hash_code: u64,
2179 capabilities: NodeCapabilities,
2180 ) -> Self {
2181 let node_rc = Rc::new(RefCell::new(node));
2182 let entry = Self {
2183 element_type,
2184 node_type,
2185 key,
2186 hash_code,
2187 element,
2188 node: Rc::clone(&node_rc),
2189 capabilities,
2190 };
2191 entry
2192 .node
2193 .borrow()
2194 .node_state()
2195 .set_capabilities(entry.capabilities);
2196 entry
2197 }
2198}
2199
2200fn visit_node_tree_mut(
2201 node: &mut dyn ModifierNode,
2202 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
2203) {
2204 visitor(node);
2205 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
2206}
2207
2208fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
2209 let mut current = 0usize;
2210 let mut result: Option<&dyn ModifierNode> = None;
2211 node.for_each_delegate(&mut |child| {
2212 if result.is_none() && current == target {
2213 result = Some(child);
2214 }
2215 current += 1;
2216 });
2217 result
2218}
2219
2220fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
2221 let mut current = 0usize;
2222 let mut result: Option<&mut dyn ModifierNode> = None;
2223 node.for_each_delegate_mut(&mut |child| {
2224 if result.is_none() && current == target {
2225 result = Some(child);
2226 }
2227 current += 1;
2228 });
2229 result
2230}
2231
2232fn with_node_context<F, R>(
2233 node: &mut dyn ModifierNode,
2234 context: &mut dyn ModifierNodeContext,
2235 f: F,
2236) -> R
2237where
2238 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
2239{
2240 context.push_active_capabilities(node.node_state().capabilities());
2241 let result = f(node, context);
2242 context.pop_active_capabilities();
2243 result
2244}
2245
2246fn request_auto_invalidations(
2247 context: &mut dyn ModifierNodeContext,
2248 capabilities: NodeCapabilities,
2249) {
2250 if capabilities.is_empty() {
2251 return;
2252 }
2253
2254 context.push_active_capabilities(capabilities);
2255
2256 if capabilities.contains(NodeCapabilities::LAYOUT) {
2257 context.invalidate(InvalidationKind::Layout);
2258 }
2259 if capabilities.contains(NodeCapabilities::DRAW) {
2260 context.invalidate(InvalidationKind::Draw);
2261 }
2262 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
2263 context.invalidate(InvalidationKind::PointerInput);
2264 }
2265 if capabilities.contains(NodeCapabilities::SEMANTICS) {
2266 context.invalidate(InvalidationKind::Semantics);
2267 }
2268 if capabilities.contains(NodeCapabilities::FOCUS) {
2269 context.invalidate(InvalidationKind::Focus);
2270 }
2271
2272 context.pop_active_capabilities();
2273}
2274
2275fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
2276 visit_node_tree_mut(node, &mut |n| {
2277 if !n.node_state().is_attached() {
2278 n.node_state().set_attached(true);
2279 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
2280 }
2281 });
2282}
2283
2284fn reset_node_tree(node: &mut dyn ModifierNode) {
2285 visit_node_tree_mut(node, &mut |n| n.on_reset());
2286}
2287
2288fn detach_node_tree(node: &mut dyn ModifierNode) {
2289 visit_node_tree_mut(node, &mut |n| {
2290 if n.node_state().is_attached() {
2291 n.on_detach();
2292 n.node_state().set_attached(false);
2293 }
2294 n.node_state().set_parent_link(None);
2295 n.node_state().set_child_link(None);
2296 n.node_state()
2297 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2298 });
2299}
2300
2301pub struct ModifierNodeChain {
2308 entries: Vec<ModifierNodeEntry>,
2309 aggregated_capabilities: NodeCapabilities,
2310 head_aggregate_child_capabilities: NodeCapabilities,
2311 head_sentinel: Box<SentinelNode>,
2312 tail_sentinel: Box<SentinelNode>,
2313 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2314 scratch_old_used: Vec<bool>,
2315 scratch_match_order: Vec<Option<usize>>,
2316 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
2317 scratch_elements: Vec<DynModifierElement>,
2318}
2319
2320struct SentinelNode {
2321 state: NodeState,
2322}
2323
2324impl SentinelNode {
2325 fn new() -> Self {
2326 Self {
2327 state: NodeState::sentinel(),
2328 }
2329 }
2330}
2331
2332impl DelegatableNode for SentinelNode {
2333 fn node_state(&self) -> &NodeState {
2334 &self.state
2335 }
2336}
2337
2338impl ModifierNode for SentinelNode {}
2339
2340#[derive(Clone)]
2341pub struct ModifierChainNodeRef<'a> {
2342 chain: &'a ModifierNodeChain,
2343 link: NodeLink,
2344 cached_capabilities: Option<NodeCapabilities>,
2345 cached_aggregate_child: Option<NodeCapabilities>,
2346}
2347
2348impl Default for ModifierNodeChain {
2349 fn default() -> Self {
2350 Self::new()
2351 }
2352}
2353
2354struct EntryIndex {
2355 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2356 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2357 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
2358}
2359
2360struct EntryMatchQuery<'a> {
2361 element_type: TypeId,
2362 node_type: TypeId,
2363 key: Option<u64>,
2364 hash_code: u64,
2365 element: &'a DynModifierElement,
2366}
2367
2368impl EntryIndex {
2369 fn build(entries: &[ModifierNodeEntry]) -> Self {
2370 let mut keyed = HashMap::default();
2371 let mut hashed = HashMap::default();
2372 let mut typed = HashMap::default();
2373
2374 for (i, entry) in entries.iter().enumerate() {
2375 if let Some(key_value) = entry.key {
2376 keyed
2377 .entry((entry.element_type, entry.node_type, key_value))
2378 .or_insert_with(Vec::new)
2379 .push(i);
2380 } else {
2381 hashed
2382 .entry((entry.element_type, entry.node_type, entry.hash_code))
2383 .or_insert_with(Vec::new)
2384 .push(i);
2385 typed
2386 .entry((entry.element_type, entry.node_type))
2387 .or_insert_with(Vec::new)
2388 .push(i);
2389 }
2390 }
2391
2392 Self {
2393 keyed,
2394 hashed,
2395 typed,
2396 }
2397 }
2398
2399 fn find_match(
2400 &self,
2401 entries: &[ModifierNodeEntry],
2402 used: &[bool],
2403 query: EntryMatchQuery<'_>,
2404 ) -> Option<usize> {
2405 if let Some(key_value) = query.key {
2406 if let Some(candidates) =
2407 self.keyed
2408 .get(&(query.element_type, query.node_type, key_value))
2409 {
2410 for &i in candidates {
2411 if !used[i] {
2412 return Some(i);
2413 }
2414 }
2415 }
2416 } else {
2417 if let Some(candidates) =
2418 self.hashed
2419 .get(&(query.element_type, query.node_type, query.hash_code))
2420 {
2421 for &i in candidates {
2422 if !used[i]
2423 && entries[i]
2424 .element
2425 .as_ref()
2426 .equals_element(query.element.as_ref())
2427 {
2428 return Some(i);
2429 }
2430 }
2431 }
2432
2433 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
2434 for &i in candidates {
2435 if !used[i] {
2436 return Some(i);
2437 }
2438 }
2439 }
2440 }
2441
2442 None
2443 }
2444}
2445
2446impl ModifierNodeChain {
2447 pub fn new() -> Self {
2448 let mut chain = Self {
2449 entries: Vec::new(),
2450 aggregated_capabilities: NodeCapabilities::empty(),
2451 head_aggregate_child_capabilities: NodeCapabilities::empty(),
2452 head_sentinel: Box::new(SentinelNode::new()),
2453 tail_sentinel: Box::new(SentinelNode::new()),
2454 ordered_nodes: Vec::new(),
2455 scratch_old_used: Vec::new(),
2456 scratch_match_order: Vec::new(),
2457 scratch_final_slots: Vec::new(),
2458 scratch_elements: Vec::new(),
2459 };
2460 chain.sync_chain_links();
2461 chain
2462 }
2463
2464 pub fn detach_nodes(&mut self) {
2466 for entry in &self.entries {
2467 detach_node_tree(&mut **entry.node.borrow_mut());
2468 }
2469 }
2470
2471 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
2473 for entry in &self.entries {
2474 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2475 }
2476 }
2477
2478 pub fn repair_chain(&mut self) {
2481 self.sync_chain_links();
2482 }
2483
2484 pub fn update_from_slice(
2490 &mut self,
2491 elements: &[DynModifierElement],
2492 context: &mut dyn ModifierNodeContext,
2493 ) {
2494 self.update_from_ref_iter(elements.iter(), context);
2495 }
2496
2497 pub fn update_from_ref_iter<'a, I>(
2502 &mut self,
2503 elements: I,
2504 context: &mut dyn ModifierNodeContext,
2505 ) where
2506 I: Iterator<Item = &'a DynModifierElement>,
2507 {
2508 let old_len = self.entries.len();
2509 let mut fast_path_failed_at: Option<usize> = None;
2510 let mut elements_count = 0;
2511
2512 self.scratch_elements.clear();
2513
2514 for (idx, element) in elements.enumerate() {
2515 elements_count = idx + 1;
2516
2517 if fast_path_failed_at.is_none() && idx < old_len {
2518 let entry = &mut self.entries[idx];
2519 let same_type = entry.element_type == element.element_type();
2520 let same_node_type = entry.node_type == element.node_type();
2521 let same_key = entry.key == element.key();
2522 let same_hash = entry.hash_code == element.hash_code();
2523
2524 let positional_update = element.requires_update();
2525 if same_type && same_node_type && same_key && (same_hash || positional_update) {
2526 let can_update_node = {
2527 let node_borrow = entry.node.borrow();
2528 element.can_update_node(&**node_borrow)
2529 };
2530 if !can_update_node {
2531 fast_path_failed_at = Some(idx);
2532 self.scratch_elements.push(element.clone());
2533 continue;
2534 }
2535
2536 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2537 let capabilities = element.capabilities();
2538
2539 {
2540 let node_borrow = entry.node.borrow();
2541 if !node_borrow.node_state().is_attached() {
2542 drop(node_borrow);
2543 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2544 }
2545 }
2546
2547 let needs_update = !same_element || element.requires_update();
2548 if needs_update {
2549 element.update_node(&mut **entry.node.borrow_mut());
2550 entry.element = element.clone();
2551 entry.hash_code = element.hash_code();
2552 request_update_auto_invalidations(element.as_ref(), context, capabilities);
2553 }
2554
2555 entry.capabilities = capabilities;
2556 entry
2557 .node
2558 .borrow()
2559 .node_state()
2560 .set_capabilities(capabilities);
2561 continue;
2562 }
2563 fast_path_failed_at = Some(idx);
2564 }
2565
2566 self.scratch_elements.push(element.clone());
2567 }
2568
2569 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
2570 if elements_count < self.entries.len() {
2571 for entry in self.entries.drain(elements_count..) {
2572 request_auto_invalidations(context, entry.capabilities);
2573 detach_node_tree(&mut **entry.node.borrow_mut());
2574 }
2575 }
2576 self.sync_chain_links();
2577 return;
2578 }
2579
2580 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
2581
2582 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
2583 let processed_entries_len = self.entries.len();
2584 let old_len = old_entries.len();
2585
2586 self.scratch_old_used.clear();
2587 self.scratch_old_used.resize(old_len, false);
2588
2589 self.scratch_match_order.clear();
2590 self.scratch_match_order.resize(old_len, None);
2591
2592 let index = EntryIndex::build(&old_entries);
2593
2594 let new_elements_count = self.scratch_elements.len();
2595 self.scratch_final_slots.clear();
2596 self.scratch_final_slots.reserve(new_elements_count);
2597
2598 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
2599 self.scratch_final_slots.push(None);
2600 let element_type = element.element_type();
2601 let node_type = element.node_type();
2602 let key = element.key();
2603 let hash_code = element.hash_code();
2604 let capabilities = element.capabilities();
2605
2606 let matched_idx = index.find_match(
2607 &old_entries,
2608 &self.scratch_old_used,
2609 EntryMatchQuery {
2610 element_type,
2611 node_type,
2612 key,
2613 hash_code,
2614 element: &element,
2615 },
2616 );
2617
2618 if let Some(idx) = matched_idx {
2619 let entry = &mut old_entries[idx];
2620 let can_update_node = {
2621 let node_borrow = entry.node.borrow();
2622 element.can_update_node(&**node_borrow)
2623 };
2624 if !can_update_node {
2625 let replacement = ModifierNodeEntry::new(
2626 element_type,
2627 node_type,
2628 key,
2629 element.clone(),
2630 element.create_node(),
2631 hash_code,
2632 capabilities,
2633 );
2634 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
2635 element.update_node(&mut **replacement.node.borrow_mut());
2636 request_auto_invalidations(context, capabilities);
2637 self.scratch_final_slots[new_pos] = Some(replacement);
2638 continue;
2639 }
2640
2641 self.scratch_old_used[idx] = true;
2642 self.scratch_match_order[idx] = Some(new_pos);
2643 let moved = idx != new_pos;
2644
2645 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2646
2647 {
2648 let node_borrow = entry.node.borrow();
2649 if !node_borrow.node_state().is_attached() {
2650 drop(node_borrow);
2651 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2652 }
2653 }
2654
2655 let needs_update = !same_element || element.requires_update();
2656 if needs_update {
2657 element.update_node(&mut **entry.node.borrow_mut());
2658 entry.element = element;
2659 entry.hash_code = hash_code;
2660 request_update_auto_invalidations(
2661 entry.element.as_ref(),
2662 context,
2663 capabilities,
2664 );
2665 }
2666 if moved {
2667 request_auto_invalidations(context, capabilities);
2668 }
2669
2670 entry.key = key;
2671 entry.element_type = element_type;
2672 entry.node_type = node_type;
2673 entry.capabilities = capabilities;
2674 entry
2675 .node
2676 .borrow()
2677 .node_state()
2678 .set_capabilities(capabilities);
2679 } else {
2680 let entry = ModifierNodeEntry::new(
2681 element_type,
2682 node_type,
2683 key,
2684 element.clone(),
2685 element.create_node(),
2686 hash_code,
2687 capabilities,
2688 );
2689 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2690 element.update_node(&mut **entry.node.borrow_mut());
2691 request_auto_invalidations(context, capabilities);
2692 self.scratch_final_slots[new_pos] = Some(entry);
2693 }
2694 }
2695
2696 for (i, entry) in old_entries.into_iter().enumerate() {
2697 if self.scratch_old_used[i] {
2698 if let Some(pos) = self.scratch_match_order[i] {
2699 self.scratch_final_slots[pos] = Some(entry);
2700 } else {
2701 request_auto_invalidations(context, entry.capabilities);
2702 detach_node_tree(&mut **entry.node.borrow_mut());
2703 }
2704 } else {
2705 request_auto_invalidations(context, entry.capabilities);
2706 detach_node_tree(&mut **entry.node.borrow_mut());
2707 }
2708 }
2709
2710 self.entries.reserve(self.scratch_final_slots.len());
2711 for slot in self.scratch_final_slots.drain(..) {
2712 if let Some(entry) = slot {
2713 self.entries.push(entry);
2714 } else {
2715 log::error!("modifier reconciliation produced an empty final slot");
2716 }
2717 }
2718
2719 debug_assert_eq!(
2720 self.entries.len(),
2721 processed_entries_len + new_elements_count
2722 );
2723 self.sync_chain_links();
2724 }
2725
2726 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2730 where
2731 I: IntoIterator<Item = DynModifierElement>,
2732 {
2733 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2734 self.update_from_slice(&collected, context);
2735 }
2736
2737 pub fn reset(&mut self) {
2740 for entry in &mut self.entries {
2741 reset_node_tree(&mut **entry.node.borrow_mut());
2742 }
2743 }
2744
2745 pub fn detach_all(&mut self) {
2747 for entry in std::mem::take(&mut self.entries) {
2748 detach_node_tree(&mut **entry.node.borrow_mut());
2749 {
2750 let node_borrow = entry.node.borrow();
2751 let state = node_borrow.node_state();
2752 state.set_capabilities(NodeCapabilities::empty());
2753 }
2754 }
2755 self.aggregated_capabilities = NodeCapabilities::empty();
2756 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2757 self.ordered_nodes.clear();
2758 self.sync_chain_links();
2759 }
2760
2761 pub fn len(&self) -> usize {
2762 self.entries.len()
2763 }
2764
2765 pub fn is_empty(&self) -> bool {
2766 self.entries.is_empty()
2767 }
2768
2769 pub fn capabilities(&self) -> NodeCapabilities {
2771 self.aggregated_capabilities
2772 }
2773
2774 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2776 self.aggregated_capabilities.contains(capability)
2777 }
2778
2779 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2781 self.make_node_ref(NodeLink::Head)
2782 }
2783
2784 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2786 self.make_node_ref(NodeLink::Tail)
2787 }
2788
2789 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2791 ModifierChainIter::forward(self)
2792 }
2793
2794 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2796 ModifierChainIter::backward(self)
2797 }
2798
2799 pub fn for_each_forward<F>(&self, mut f: F)
2801 where
2802 F: FnMut(ModifierChainNodeRef<'_>),
2803 {
2804 for node in self.head_to_tail() {
2805 f(node);
2806 }
2807 }
2808
2809 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2811 where
2812 F: FnMut(ModifierChainNodeRef<'_>),
2813 {
2814 if mask.is_empty() {
2815 self.for_each_forward(f);
2816 return;
2817 }
2818
2819 if !self.head().aggregate_child_capabilities().intersects(mask) {
2820 return;
2821 }
2822
2823 for node in self.head_to_tail() {
2824 if node.kind_set().intersects(mask) {
2825 f(node);
2826 }
2827 }
2828 }
2829
2830 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2832 where
2833 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2834 {
2835 self.for_each_forward_matching(mask, |node_ref| {
2836 node_ref.with_node(|node| f(node_ref.clone(), node));
2837 });
2838 }
2839
2840 pub fn for_each_backward<F>(&self, mut f: F)
2842 where
2843 F: FnMut(ModifierChainNodeRef<'_>),
2844 {
2845 for node in self.tail_to_head() {
2846 f(node);
2847 }
2848 }
2849
2850 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2852 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2853 node as *const dyn ModifierNode as *const ()
2854 }
2855
2856 let target = node_data_ptr(node);
2857 for (index, entry) in self.entries.iter().enumerate() {
2858 if node_data_ptr(&**entry.node.borrow()) == target {
2859 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2860 }
2861 }
2862
2863 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2864 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2865 return None;
2866 }
2867 let matches_target = match link {
2868 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2869 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2870 NodeLink::Entry(path) => {
2871 let node_borrow = self.entries[path.entry()].node.borrow();
2872 node_data_ptr(&**node_borrow) == target
2873 }
2874 };
2875 if matches_target {
2876 Some(self.make_node_ref(*link))
2877 } else {
2878 None
2879 }
2880 })
2881 }
2882
2883 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2886 self.entries.get(index).and_then(|entry| {
2887 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2888 boxed_node.as_any().downcast_ref::<N>()
2889 })
2890 .ok()
2891 })
2892 }
2893
2894 pub fn node_mut<N: ModifierNode + 'static>(
2897 &self,
2898 index: usize,
2899 ) -> Option<std::cell::RefMut<'_, N>> {
2900 self.entries.get(index).and_then(|entry| {
2901 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2902 boxed_node.as_any_mut().downcast_mut::<N>()
2903 })
2904 .ok()
2905 })
2906 }
2907
2908 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2911 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
2912 }
2913
2914 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
2916 self.aggregated_capabilities
2917 .contains(NodeCapabilities::for_invalidation(kind))
2918 }
2919
2920 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
2922 where
2923 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
2924 {
2925 for index in 0..self.ordered_nodes.len() {
2926 let (link, cached_caps, _agg) = self.ordered_nodes[index];
2927 match link {
2928 NodeLink::Head => {
2929 f(self.head_sentinel.as_mut(), cached_caps);
2930 }
2931 NodeLink::Tail => {
2932 f(self.tail_sentinel.as_mut(), cached_caps);
2933 }
2934 NodeLink::Entry(path) => {
2935 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
2936 if path.delegates().is_empty() {
2937 f(&mut **node_borrow, cached_caps);
2938 } else {
2939 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
2940 for &delegate_index in path.delegates() {
2941 if let Some(delegate) =
2942 nth_delegate_mut(current, delegate_index as usize)
2943 {
2944 current = delegate;
2945 } else {
2946 return;
2947 }
2948 }
2949 f(current, cached_caps);
2950 }
2951 }
2952 }
2953 }
2954 }
2955
2956 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2957 ModifierChainNodeRef {
2958 chain: self,
2959 link,
2960 cached_capabilities: None,
2961 cached_aggregate_child: None,
2962 }
2963 }
2964
2965 fn make_node_ref_with_caps(
2966 &self,
2967 link: NodeLink,
2968 caps: NodeCapabilities,
2969 aggregate_child: NodeCapabilities,
2970 ) -> ModifierChainNodeRef<'_> {
2971 ModifierChainNodeRef {
2972 chain: self,
2973 link,
2974 cached_capabilities: Some(caps),
2975 cached_aggregate_child: Some(aggregate_child),
2976 }
2977 }
2978
2979 fn sync_chain_links(&mut self) {
2980 self.rebuild_ordered_nodes();
2981
2982 self.head_sentinel.node_state().set_parent_link(None);
2983 self.tail_sentinel.node_state().set_child_link(None);
2984
2985 if self.ordered_nodes.is_empty() {
2986 self.head_sentinel
2987 .node_state()
2988 .set_child_link(Some(NodeLink::Tail));
2989 self.tail_sentinel
2990 .node_state()
2991 .set_parent_link(Some(NodeLink::Head));
2992 self.aggregated_capabilities = NodeCapabilities::empty();
2993 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2994 self.head_sentinel
2995 .node_state()
2996 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2997 self.tail_sentinel
2998 .node_state()
2999 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3000 return;
3001 }
3002
3003 let mut previous = NodeLink::Head;
3004 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
3005 match &previous {
3006 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
3007 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
3008 NodeLink::Entry(path) => {
3009 let node_borrow = self.entries[path.entry()].node.borrow();
3010 if path.delegates().is_empty() {
3011 node_borrow.node_state().set_child_link(Some(link));
3012 } else {
3013 let mut current: &dyn ModifierNode = &**node_borrow;
3014 for &delegate_index in path.delegates() {
3015 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3016 current = delegate;
3017 }
3018 }
3019 current.node_state().set_child_link(Some(link));
3020 }
3021 }
3022 }
3023 match &link {
3024 NodeLink::Head => self
3025 .head_sentinel
3026 .node_state()
3027 .set_parent_link(Some(previous)),
3028 NodeLink::Tail => self
3029 .tail_sentinel
3030 .node_state()
3031 .set_parent_link(Some(previous)),
3032 NodeLink::Entry(path) => {
3033 let node_borrow = self.entries[path.entry()].node.borrow();
3034 if path.delegates().is_empty() {
3035 node_borrow.node_state().set_parent_link(Some(previous));
3036 } else {
3037 let mut current: &dyn ModifierNode = &**node_borrow;
3038 for &delegate_index in path.delegates() {
3039 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3040 current = delegate;
3041 }
3042 }
3043 current.node_state().set_parent_link(Some(previous));
3044 }
3045 }
3046 }
3047 previous = link;
3048 }
3049
3050 match &previous {
3051 NodeLink::Head => self
3052 .head_sentinel
3053 .node_state()
3054 .set_child_link(Some(NodeLink::Tail)),
3055 NodeLink::Tail => self
3056 .tail_sentinel
3057 .node_state()
3058 .set_child_link(Some(NodeLink::Tail)),
3059 NodeLink::Entry(path) => {
3060 let node_borrow = self.entries[path.entry()].node.borrow();
3061 if path.delegates().is_empty() {
3062 node_borrow
3063 .node_state()
3064 .set_child_link(Some(NodeLink::Tail));
3065 } else {
3066 let mut current: &dyn ModifierNode = &**node_borrow;
3067 for &delegate_index in path.delegates() {
3068 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3069 current = delegate;
3070 }
3071 }
3072 current.node_state().set_child_link(Some(NodeLink::Tail));
3073 }
3074 }
3075 }
3076 self.tail_sentinel
3077 .node_state()
3078 .set_parent_link(Some(previous));
3079 self.tail_sentinel.node_state().set_child_link(None);
3080
3081 let mut aggregate = NodeCapabilities::empty();
3082 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
3083 aggregate |= *cached_caps;
3084 *cached_aggregate = aggregate;
3085 match link {
3086 NodeLink::Head => {
3087 self.head_sentinel
3088 .node_state()
3089 .set_aggregate_child_capabilities(aggregate);
3090 }
3091 NodeLink::Tail => {
3092 self.tail_sentinel
3093 .node_state()
3094 .set_aggregate_child_capabilities(aggregate);
3095 }
3096 NodeLink::Entry(path) => {
3097 let node_borrow = self.entries[path.entry()].node.borrow();
3098 let state = if path.delegates().is_empty() {
3099 node_borrow.node_state()
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()
3108 };
3109 state.set_aggregate_child_capabilities(aggregate);
3110 }
3111 }
3112 }
3113
3114 self.aggregated_capabilities = aggregate;
3115 self.head_aggregate_child_capabilities = aggregate;
3116 self.head_sentinel
3117 .node_state()
3118 .set_aggregate_child_capabilities(aggregate);
3119 self.tail_sentinel
3120 .node_state()
3121 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3122 }
3123
3124 fn rebuild_ordered_nodes(&mut self) {
3125 self.ordered_nodes.clear();
3126 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
3127 for (index, entry) in self.entries.iter().enumerate() {
3128 let node_borrow = entry.node.borrow();
3129 Self::enumerate_link_order(
3130 &**node_borrow,
3131 index,
3132 &mut path_buf,
3133 0,
3134 &mut self.ordered_nodes,
3135 );
3136 }
3137 }
3138
3139 fn enumerate_link_order(
3140 node: &dyn ModifierNode,
3141 entry: usize,
3142 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
3143 path_len: usize,
3144 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
3145 ) {
3146 let caps = node.node_state().capabilities();
3147 out.push((
3148 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
3149 caps,
3150 NodeCapabilities::empty(),
3151 ));
3152 let mut delegate_index = 0usize;
3153 node.for_each_delegate(&mut |child| {
3154 if path_len < MAX_DELEGATE_DEPTH {
3155 path_buf[path_len] = delegate_index;
3156 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
3157 }
3158 delegate_index += 1;
3159 });
3160 }
3161}
3162
3163impl<'a> ModifierChainNodeRef<'a> {
3164 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
3165 match &self.link {
3166 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
3167 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
3168 NodeLink::Entry(path) => {
3169 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3170 if path.delegates().is_empty() {
3171 f(node_borrow.node_state())
3172 } else {
3173 let mut current: &dyn ModifierNode = &**node_borrow;
3174 for &delegate_index in path.delegates() {
3175 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3176 current = delegate;
3177 } else {
3178 return f(node_borrow.node_state());
3179 }
3180 }
3181 f(current.node_state())
3182 }
3183 }
3184 }
3185 }
3186
3187 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
3190 match &self.link {
3191 NodeLink::Head => None,
3192 NodeLink::Tail => None,
3193 NodeLink::Entry(path) => {
3194 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3195 if path.delegates().is_empty() {
3196 Some(f(&**node_borrow))
3197 } else {
3198 let mut current: &dyn ModifierNode = &**node_borrow;
3199 for &delegate_index in path.delegates() {
3200 current = nth_delegate(current, delegate_index as usize)?;
3201 }
3202 Some(f(current))
3203 }
3204 }
3205 }
3206 }
3207
3208 #[inline]
3210 pub fn parent(&self) -> Option<Self> {
3211 self.with_state(|state| state.parent_link())
3212 .map(|link| self.chain.make_node_ref(link))
3213 }
3214
3215 #[inline]
3217 pub fn child(&self) -> Option<Self> {
3218 self.with_state(|state| state.child_link())
3219 .map(|link| self.chain.make_node_ref(link))
3220 }
3221
3222 #[inline]
3224 pub fn kind_set(&self) -> NodeCapabilities {
3225 if let Some(caps) = self.cached_capabilities {
3226 return caps;
3227 }
3228 match &self.link {
3229 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
3230 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
3231 }
3232 }
3233
3234 pub fn entry_index(&self) -> Option<usize> {
3236 match &self.link {
3237 NodeLink::Entry(path) => Some(path.entry()),
3238 _ => None,
3239 }
3240 }
3241
3242 pub fn delegate_depth(&self) -> usize {
3244 match &self.link {
3245 NodeLink::Entry(path) => path.delegates().len(),
3246 _ => 0,
3247 }
3248 }
3249
3250 #[inline]
3252 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
3253 if let Some(agg) = self.cached_aggregate_child {
3254 return agg;
3255 }
3256 if self.is_tail() {
3257 NodeCapabilities::empty()
3258 } else {
3259 self.with_state(|state| state.aggregate_child_capabilities())
3260 }
3261 }
3262
3263 pub fn is_head(&self) -> bool {
3265 matches!(self.link, NodeLink::Head)
3266 }
3267
3268 pub fn is_tail(&self) -> bool {
3270 matches!(self.link, NodeLink::Tail)
3271 }
3272
3273 pub fn is_sentinel(&self) -> bool {
3275 matches!(self.link, NodeLink::Head | NodeLink::Tail)
3276 }
3277
3278 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
3280 !mask.is_empty() && self.kind_set().intersects(mask)
3281 }
3282
3283 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
3285 where
3286 F: FnMut(ModifierChainNodeRef<'a>),
3287 {
3288 let mut current = if include_self {
3289 Some(self)
3290 } else {
3291 self.child()
3292 };
3293 while let Some(node) = current {
3294 if node.is_tail() {
3295 break;
3296 }
3297 if !node.is_sentinel() {
3298 f(node.clone());
3299 }
3300 current = node.child();
3301 }
3302 }
3303
3304 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3306 where
3307 F: FnMut(ModifierChainNodeRef<'a>),
3308 {
3309 if mask.is_empty() {
3310 self.visit_descendants(include_self, f);
3311 return;
3312 }
3313
3314 if !self.aggregate_child_capabilities().intersects(mask) {
3315 return;
3316 }
3317
3318 self.visit_descendants(include_self, |node| {
3319 if node.kind_set().intersects(mask) {
3320 f(node);
3321 }
3322 });
3323 }
3324
3325 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
3327 where
3328 F: FnMut(ModifierChainNodeRef<'a>),
3329 {
3330 let mut current = if include_self {
3331 Some(self)
3332 } else {
3333 self.parent()
3334 };
3335 while let Some(node) = current {
3336 if node.is_head() {
3337 break;
3338 }
3339 f(node.clone());
3340 current = node.parent();
3341 }
3342 }
3343
3344 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3346 where
3347 F: FnMut(ModifierChainNodeRef<'a>),
3348 {
3349 if mask.is_empty() {
3350 self.visit_ancestors(include_self, f);
3351 return;
3352 }
3353
3354 self.visit_ancestors(include_self, |node| {
3355 if node.kind_set().intersects(mask) {
3356 f(node);
3357 }
3358 });
3359 }
3360}
3361
3362#[cfg(test)]
3363#[path = "tests/modifier_tests.rs"]
3364mod tests;