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 multiline: bool,
1309 pub text: Option<String>,
1312 pub text_selection: Option<crate::text::TextRange>,
1313 pub custom_actions: Vec<SemanticsCustomAction>,
1314 pub canvas_children: Vec<CanvasSemanticsNode>,
1317 pub is_modal: bool,
1320 pub hidden: bool,
1324 pub merge_descendants: bool,
1328 pub selectable_group: bool,
1332 pub pane_title: Option<String>,
1335 pub error: Option<String>,
1338 pub password: bool,
1341 pub traversal_index: f32,
1345 pub live_region: Option<LiveRegionMode>,
1348 pub progress: Option<ProgressBarRangeInfo>,
1351 pub set_progress: Option<SemanticsSetProgress>,
1354 pub set_text: Option<SemanticsSetText>,
1357 pub set_selection: Option<SemanticsSetSelection>,
1360 pub expand: Option<SemanticsExpand>,
1363 pub dismiss: Option<SemanticsDismiss>,
1367 pub collapse: Option<SemanticsExpand>,
1370 pub vertical_scroll: Option<ScrollAxisRange>,
1373 pub horizontal_scroll: Option<ScrollAxisRange>,
1376 pub scroll_by: Option<SemanticsScrollBy>,
1379 pub scroll_to_index: Option<SemanticsScrollToIndex>,
1383 pub collection: Option<CollectionInfo>,
1385}
1386
1387impl Default for SemanticsConfiguration {
1388 fn default() -> Self {
1389 Self {
1390 content_description: None,
1391 state_description: None,
1392 on_click_label: None,
1393 on_long_click: None,
1394 on_long_click_label: None,
1395 on_magic_tap: None,
1396 on_magic_tap_label: None,
1397 input_labels: Vec::new(),
1398 language: None,
1399 role: None,
1400 selected: None,
1401 toggled: None,
1402 enabled: true,
1403 is_clickable: false,
1404 is_editable_text: false,
1405 multiline: false,
1406 text: None,
1407 text_selection: None,
1408 custom_actions: Vec::new(),
1409 canvas_children: Vec::new(),
1410 is_modal: false,
1411 hidden: false,
1412 merge_descendants: false,
1413 selectable_group: false,
1414 pane_title: None,
1415 error: None,
1416 password: false,
1417 traversal_index: 0.0,
1418 live_region: None,
1419 progress: None,
1420 set_progress: None,
1421 set_text: None,
1422 set_selection: None,
1423 expand: None,
1424 dismiss: None,
1425 collapse: None,
1426 vertical_scroll: None,
1427 horizontal_scroll: None,
1428 scroll_by: None,
1429 scroll_to_index: None,
1430 collection: None,
1431 }
1432 }
1433}
1434
1435pub type SemanticsSpec = SemanticsConfiguration;
1444
1445impl SemanticsConfiguration {
1446 pub fn new() -> Self {
1449 Self::default()
1450 }
1451
1452 pub fn content_description(mut self, name: impl Into<String>) -> Self {
1455 self.content_description = Some(name.into());
1456 self
1457 }
1458
1459 pub fn state_description(mut self, state: impl Into<String>) -> Self {
1462 self.state_description = Some(state.into());
1463 self
1464 }
1465
1466 pub fn clickable(mut self) -> Self {
1468 self.is_clickable = true;
1469 self
1470 }
1471
1472 pub fn on_long_click(
1476 mut self,
1477 label: impl Into<String>,
1478 action: impl Fn() -> bool + 'static,
1479 ) -> Self {
1480 self.on_long_click_label = Some(label.into());
1481 self.on_long_click = Some(SemanticsLongClick::new(action));
1482 self
1483 }
1484
1485 pub fn on_magic_tap(
1489 mut self,
1490 label: impl Into<String>,
1491 action: impl Fn() -> bool + 'static,
1492 ) -> Self {
1493 self.on_magic_tap_label = Some(label.into());
1494 self.on_magic_tap = Some(SemanticsMagicTap::new(action));
1495 self
1496 }
1497
1498 pub fn input_labels<S: Into<String>>(mut self, labels: impl IntoIterator<Item = S>) -> Self {
1501 self.input_labels = labels.into_iter().map(Into::into).collect();
1502 self
1503 }
1504
1505 pub fn language(mut self, tag: impl Into<String>) -> Self {
1508 self.language = Some(tag.into());
1509 self
1510 }
1511
1512 pub fn toggled(mut self, toggled: bool) -> Self {
1514 self.toggled = Some(toggled);
1515 self
1516 }
1517
1518 pub fn selected(mut self, selected: bool) -> Self {
1521 self.selected = Some(selected);
1522 self
1523 }
1524
1525 pub fn role(mut self, role: SemanticsWidgetRole) -> Self {
1527 self.role = Some(role);
1528 self
1529 }
1530
1531 pub fn heading(self) -> Self {
1534 self.role(SemanticsWidgetRole::Header)
1535 }
1536
1537 pub fn error(mut self, message: impl Into<String>) -> Self {
1539 self.error = Some(message.into());
1540 self
1541 }
1542
1543 pub fn password(mut self) -> Self {
1545 self.password = true;
1546 self
1547 }
1548
1549 pub fn pane_title(mut self, title: impl Into<String>) -> Self {
1552 self.pane_title = Some(title.into());
1553 self
1554 }
1555
1556 pub fn traversal_index(mut self, index: f32) -> Self {
1559 self.traversal_index = index;
1560 self
1561 }
1562
1563 pub fn hidden(mut self) -> Self {
1566 self.hidden = true;
1567 self
1568 }
1569
1570 pub fn merge_descendants(mut self) -> Self {
1573 self.merge_descendants = true;
1574 self
1575 }
1576
1577 pub fn selectable_group(mut self) -> Self {
1580 self.selectable_group = true;
1581 self
1582 }
1583
1584 pub fn live_region(mut self, mode: LiveRegionMode) -> Self {
1587 self.live_region = Some(mode);
1588 self
1589 }
1590 pub fn merge(&mut self, other: &SemanticsConfiguration) {
1591 if let Some(description) = &other.content_description {
1592 self.content_description = Some(description.clone());
1593 }
1594 if let Some(state) = &other.state_description {
1595 self.state_description = Some(state.clone());
1596 }
1597 if let Some(label) = &other.on_click_label {
1598 self.on_click_label = Some(label.clone());
1599 }
1600 if let Some(label) = &other.on_long_click_label {
1601 self.on_long_click_label = Some(label.clone());
1602 }
1603 if let Some(label) = &other.on_magic_tap_label {
1604 self.on_magic_tap_label = Some(label.clone());
1605 }
1606 if !other.input_labels.is_empty() {
1607 self.input_labels.clone_from(&other.input_labels);
1608 }
1609 if let Some(language) = &other.language {
1610 self.language = Some(language.clone());
1611 }
1612 if let Some(role) = other.role {
1613 self.role = Some(role);
1614 }
1615 if let Some(selected) = other.selected {
1616 self.selected = Some(selected);
1617 }
1618 if let Some(toggled) = other.toggled {
1619 self.toggled = Some(toggled);
1620 }
1621 self.enabled &= other.enabled;
1622 self.is_clickable |= other.is_clickable;
1623 self.is_editable_text |= other.is_editable_text;
1624 self.multiline |= other.multiline;
1625 if let Some(text) = &other.text {
1626 self.text = Some(text.clone());
1627 }
1628 self.is_modal |= other.is_modal;
1629 self.hidden |= other.hidden;
1630 self.merge_descendants |= other.merge_descendants;
1631 self.selectable_group |= other.selectable_group;
1632 self.password |= other.password;
1633 if other.traversal_index != 0.0 {
1634 self.traversal_index = other.traversal_index;
1635 }
1636 if let Some(live_region) = other.live_region {
1637 self.live_region = Some(live_region);
1638 }
1639 self.merge_words(other);
1640 self.merge_actions(other);
1641 self.merge_ranges(other);
1642 }
1643
1644 fn merge_words(&mut self, other: &SemanticsConfiguration) {
1645 if let Some(title) = &other.pane_title {
1646 self.pane_title = Some(title.clone());
1647 }
1648 if let Some(error) = &other.error {
1649 self.error = Some(error.clone());
1650 }
1651 }
1652
1653 fn merge_actions(&mut self, other: &SemanticsConfiguration) {
1654 self.custom_actions
1655 .extend(other.custom_actions.iter().cloned());
1656 self.canvas_children
1657 .extend(other.canvas_children.iter().cloned());
1658 if let Some(set_progress) = &other.set_progress {
1659 self.set_progress = Some(set_progress.clone());
1660 }
1661 if let Some(set_text) = &other.set_text {
1662 self.set_text = Some(set_text.clone());
1663 }
1664 if let Some(set_selection) = &other.set_selection {
1665 self.set_selection = Some(set_selection.clone());
1666 }
1667 if let Some(expand) = &other.expand {
1668 self.expand = Some(expand.clone());
1669 }
1670 if let Some(collapse) = &other.collapse {
1671 self.collapse = Some(collapse.clone());
1672 }
1673 if let Some(dismiss) = &other.dismiss {
1674 self.dismiss = Some(dismiss.clone());
1675 }
1676 if let Some(long_click) = &other.on_long_click {
1677 self.on_long_click = Some(long_click.clone());
1678 }
1679 if let Some(magic_tap) = &other.on_magic_tap {
1680 self.on_magic_tap = Some(magic_tap.clone());
1681 }
1682 if let Some(scroll_by) = &other.scroll_by {
1683 self.scroll_by = Some(scroll_by.clone());
1684 }
1685 if let Some(scroll_to_index) = &other.scroll_to_index {
1686 self.scroll_to_index = Some(scroll_to_index.clone());
1687 }
1688 }
1689
1690 fn merge_ranges(&mut self, other: &SemanticsConfiguration) {
1691 if let Some(selection) = other.text_selection {
1692 self.text_selection = Some(selection);
1693 }
1694 if let Some(progress) = other.progress {
1695 self.progress = Some(progress);
1696 }
1697 if let Some(range) = other.vertical_scroll {
1698 self.vertical_scroll = Some(range);
1699 }
1700 if let Some(range) = other.horizontal_scroll {
1701 self.horizontal_scroll = Some(range);
1702 }
1703 if let Some(collection) = other.collection {
1704 self.collection = Some(collection);
1705 }
1706 }
1707
1708 pub fn is_activatable(&self) -> bool {
1711 self.is_clickable || self.on_click_label.is_some()
1712 }
1713}
1714
1715impl fmt::Debug for dyn ModifierNode {
1716 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1717 f.debug_struct("ModifierNode").finish_non_exhaustive()
1718 }
1719}
1720
1721impl dyn ModifierNode {
1722 pub fn as_any(&self) -> &dyn Any {
1723 self
1724 }
1725
1726 pub fn as_any_mut(&mut self) -> &mut dyn Any {
1727 self
1728 }
1729}
1730
1731pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
1734 type Node: ModifierNode;
1735
1736 fn create(&self) -> Self::Node;
1738
1739 fn update(&self, node: &mut Self::Node);
1741
1742 fn key(&self) -> Option<u64> {
1744 None
1745 }
1746
1747 fn inspector_name(&self) -> &'static str {
1749 type_name::<Self>()
1750 }
1751
1752 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
1754
1755 fn capabilities(&self) -> NodeCapabilities {
1758 NodeCapabilities::default()
1759 }
1760
1761 fn always_update(&self) -> bool {
1767 false
1768 }
1769
1770 fn auto_invalidate_on_update(&self) -> bool {
1773 true
1774 }
1775
1776 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1783 None
1784 }
1785
1786 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
1793 Vec::new()
1794 }
1795}
1796
1797#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1799pub struct NodeCapabilities(u32);
1800
1801impl NodeCapabilities {
1802 pub const NONE: Self = Self(0);
1804 pub const LAYOUT: Self = Self(1 << 0);
1806 pub const DRAW: Self = Self(1 << 1);
1808 pub const POINTER_INPUT: Self = Self(1 << 2);
1810 pub const SEMANTICS: Self = Self(1 << 3);
1812 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1814 pub const FOCUS: Self = Self(1 << 5);
1816 pub const WINDOW_ROOT: Self = Self(1 << 6);
1820
1821 pub const fn empty() -> Self {
1823 Self::NONE
1824 }
1825
1826 pub const fn contains(self, other: Self) -> bool {
1828 (self.0 & other.0) == other.0
1829 }
1830
1831 pub const fn intersects(self, other: Self) -> bool {
1833 (self.0 & other.0) != 0
1834 }
1835
1836 pub fn insert(&mut self, other: Self) {
1838 self.0 |= other.0;
1839 }
1840
1841 pub const fn bits(self) -> u32 {
1843 self.0
1844 }
1845
1846 pub const fn is_empty(self) -> bool {
1848 self.0 == 0
1849 }
1850
1851 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1853 match kind {
1854 InvalidationKind::Layout => Self::LAYOUT,
1855 InvalidationKind::Draw => Self::DRAW,
1856 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1857 InvalidationKind::Semantics => Self::SEMANTICS,
1858 InvalidationKind::Focus => Self::FOCUS,
1859 }
1860 }
1861}
1862
1863impl Default for NodeCapabilities {
1864 fn default() -> Self {
1865 Self::NONE
1866 }
1867}
1868
1869impl fmt::Debug for NodeCapabilities {
1870 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1871 f.debug_struct("NodeCapabilities")
1872 .field("layout", &self.contains(Self::LAYOUT))
1873 .field("draw", &self.contains(Self::DRAW))
1874 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1875 .field("semantics", &self.contains(Self::SEMANTICS))
1876 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1877 .field("focus", &self.contains(Self::FOCUS))
1878 .field("window_root", &self.contains(Self::WINDOW_ROOT))
1879 .finish()
1880 }
1881}
1882
1883impl BitOr for NodeCapabilities {
1884 type Output = Self;
1885
1886 fn bitor(self, rhs: Self) -> Self::Output {
1887 Self(self.0 | rhs.0)
1888 }
1889}
1890
1891impl BitOrAssign for NodeCapabilities {
1892 fn bitor_assign(&mut self, rhs: Self) {
1893 self.0 |= rhs.0;
1894 }
1895}
1896
1897#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1899pub struct ModifierInvalidation {
1900 kind: InvalidationKind,
1901 capabilities: NodeCapabilities,
1902}
1903
1904impl ModifierInvalidation {
1905 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1907 Self { kind, capabilities }
1908 }
1909
1910 pub const fn kind(self) -> InvalidationKind {
1912 self.kind
1913 }
1914
1915 pub const fn capabilities(self) -> NodeCapabilities {
1917 self.capabilities
1918 }
1919}
1920
1921pub trait AnyModifierElement: fmt::Debug {
1923 fn node_type(&self) -> TypeId;
1924
1925 fn element_type(&self) -> TypeId;
1926
1927 fn create_node(&self) -> Box<dyn ModifierNode>;
1928
1929 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
1930
1931 fn update_node(&self, node: &mut dyn ModifierNode);
1932
1933 fn key(&self) -> Option<u64>;
1934
1935 fn capabilities(&self) -> NodeCapabilities {
1936 NodeCapabilities::default()
1937 }
1938
1939 fn hash_code(&self) -> u64;
1940
1941 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
1942
1943 fn inspector_name(&self) -> &'static str;
1944
1945 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
1946
1947 fn requires_update(&self) -> bool;
1948
1949 fn auto_invalidates_on_update(&self) -> bool;
1950
1951 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
1952
1953 fn provides_composition_locals(&self) -> bool {
1955 false
1956 }
1957
1958 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
1960 Vec::new()
1961 }
1962
1963 fn as_any(&self) -> &dyn Any;
1964}
1965
1966struct TypedModifierElement<E: ModifierNodeElement> {
1967 element: E,
1968 cached_hash: u64,
1969 provides_locals: bool,
1970}
1971
1972impl<E: ModifierNodeElement> TypedModifierElement<E> {
1973 fn new(element: E) -> Self {
1974 let mut hasher = default::new();
1975 element.hash(&mut hasher);
1976 let provides_locals = !element.provided_composition_locals().is_empty();
1977 Self {
1978 element,
1979 cached_hash: hasher.finish(),
1980 provides_locals,
1981 }
1982 }
1983}
1984
1985impl<E> fmt::Debug for TypedModifierElement<E>
1986where
1987 E: ModifierNodeElement,
1988{
1989 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1990 f.debug_struct("TypedModifierElement")
1991 .field("type", &type_name::<E>())
1992 .finish()
1993 }
1994}
1995
1996impl<E> AnyModifierElement for TypedModifierElement<E>
1997where
1998 E: ModifierNodeElement,
1999{
2000 fn node_type(&self) -> TypeId {
2001 TypeId::of::<E::Node>()
2002 }
2003
2004 fn element_type(&self) -> TypeId {
2005 TypeId::of::<E>()
2006 }
2007
2008 fn create_node(&self) -> Box<dyn ModifierNode> {
2009 Box::new(self.element.create())
2010 }
2011
2012 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
2013 node.as_any().is::<E::Node>()
2014 }
2015
2016 fn update_node(&self, node: &mut dyn ModifierNode) {
2017 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
2018 self.element.update(typed);
2019 }
2020 }
2021
2022 fn key(&self) -> Option<u64> {
2023 self.element.key()
2024 }
2025
2026 fn capabilities(&self) -> NodeCapabilities {
2027 self.element.capabilities()
2028 }
2029
2030 fn provides_composition_locals(&self) -> bool {
2031 self.provides_locals
2032 }
2033
2034 fn provided_composition_locals(&self) -> Vec<ProvidedValue> {
2035 self.element.provided_composition_locals()
2036 }
2037
2038 fn hash_code(&self) -> u64 {
2039 self.cached_hash
2040 }
2041
2042 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
2043 other
2044 .as_any()
2045 .downcast_ref::<Self>()
2046 .map(|typed| typed.element == self.element)
2047 .unwrap_or(false)
2048 }
2049
2050 fn inspector_name(&self) -> &'static str {
2051 self.element.inspector_name()
2052 }
2053
2054 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
2055 self.element.inspector_properties(visitor);
2056 }
2057
2058 fn requires_update(&self) -> bool {
2059 self.element.always_update()
2060 }
2061
2062 fn auto_invalidates_on_update(&self) -> bool {
2063 self.element.auto_invalidate_on_update()
2064 }
2065
2066 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
2067 self.element.update_invalidation_kind()
2068 }
2069
2070 fn as_any(&self) -> &dyn Any {
2071 self
2072 }
2073}
2074
2075fn request_update_auto_invalidations(
2076 element: &dyn AnyModifierElement,
2077 context: &mut dyn ModifierNodeContext,
2078 capabilities: NodeCapabilities,
2079) {
2080 if let Some(kind) = element.update_invalidation_kind() {
2081 let capabilities = NodeCapabilities::for_invalidation(kind);
2082 context.push_active_capabilities(capabilities);
2083 context.invalidate(kind);
2084 context.pop_active_capabilities();
2085 } else if element.auto_invalidates_on_update() {
2086 request_auto_invalidations(context, capabilities);
2087 }
2088}
2089
2090pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
2093 Rc::new(TypedModifierElement::new(element))
2094}
2095
2096pub type DynModifierElement = Rc<dyn AnyModifierElement>;
2098
2099#[derive(Clone, Copy, Debug, PartialEq, Eq)]
2100enum TraversalDirection {
2101 Forward,
2102 Backward,
2103}
2104
2105pub struct ModifierChainIter<'a> {
2110 chain: &'a ModifierNodeChain,
2111 cursor: usize,
2112 remaining: usize,
2113 direction: TraversalDirection,
2114}
2115
2116impl<'a> ModifierChainIter<'a> {
2117 fn forward(chain: &'a ModifierNodeChain) -> Self {
2118 Self {
2119 chain,
2120 cursor: 0,
2121 remaining: chain.ordered_nodes.len(),
2122 direction: TraversalDirection::Forward,
2123 }
2124 }
2125
2126 fn backward(chain: &'a ModifierNodeChain) -> Self {
2127 let len = chain.ordered_nodes.len();
2128 Self {
2129 chain,
2130 cursor: len.wrapping_sub(1),
2131 remaining: len,
2132 direction: TraversalDirection::Backward,
2133 }
2134 }
2135}
2136
2137impl<'a> Iterator for ModifierChainIter<'a> {
2138 type Item = ModifierChainNodeRef<'a>;
2139
2140 #[inline]
2141 fn next(&mut self) -> Option<Self::Item> {
2142 if self.remaining == 0 {
2143 return None;
2144 }
2145 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
2146 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
2147 self.remaining -= 1;
2148 match self.direction {
2149 TraversalDirection::Forward => self.cursor += 1,
2150 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
2151 }
2152 Some(node_ref)
2153 }
2154
2155 #[inline]
2156 fn size_hint(&self) -> (usize, Option<usize>) {
2157 (self.remaining, Some(self.remaining))
2158 }
2159}
2160
2161impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
2162impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
2163
2164#[derive(Debug)]
2165struct ModifierNodeEntry {
2166 element_type: TypeId,
2167 node_type: TypeId,
2168 key: Option<u64>,
2169 hash_code: u64,
2170 element: DynModifierElement,
2171 node: Rc<RefCell<Box<dyn ModifierNode>>>,
2172 capabilities: NodeCapabilities,
2173}
2174
2175impl ModifierNodeEntry {
2176 fn new(
2177 element_type: TypeId,
2178 node_type: TypeId,
2179 key: Option<u64>,
2180 element: DynModifierElement,
2181 node: Box<dyn ModifierNode>,
2182 hash_code: u64,
2183 capabilities: NodeCapabilities,
2184 ) -> Self {
2185 let node_rc = Rc::new(RefCell::new(node));
2186 let entry = Self {
2187 element_type,
2188 node_type,
2189 key,
2190 hash_code,
2191 element,
2192 node: Rc::clone(&node_rc),
2193 capabilities,
2194 };
2195 entry
2196 .node
2197 .borrow()
2198 .node_state()
2199 .set_capabilities(entry.capabilities);
2200 entry
2201 }
2202}
2203
2204fn visit_node_tree_mut(
2205 node: &mut dyn ModifierNode,
2206 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
2207) {
2208 visitor(node);
2209 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
2210}
2211
2212fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
2213 let mut current = 0usize;
2214 let mut result: Option<&dyn ModifierNode> = None;
2215 node.for_each_delegate(&mut |child| {
2216 if result.is_none() && current == target {
2217 result = Some(child);
2218 }
2219 current += 1;
2220 });
2221 result
2222}
2223
2224fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
2225 let mut current = 0usize;
2226 let mut result: Option<&mut dyn ModifierNode> = None;
2227 node.for_each_delegate_mut(&mut |child| {
2228 if result.is_none() && current == target {
2229 result = Some(child);
2230 }
2231 current += 1;
2232 });
2233 result
2234}
2235
2236fn with_node_context<F, R>(
2237 node: &mut dyn ModifierNode,
2238 context: &mut dyn ModifierNodeContext,
2239 f: F,
2240) -> R
2241where
2242 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
2243{
2244 context.push_active_capabilities(node.node_state().capabilities());
2245 let result = f(node, context);
2246 context.pop_active_capabilities();
2247 result
2248}
2249
2250fn request_auto_invalidations(
2251 context: &mut dyn ModifierNodeContext,
2252 capabilities: NodeCapabilities,
2253) {
2254 if capabilities.is_empty() {
2255 return;
2256 }
2257
2258 context.push_active_capabilities(capabilities);
2259
2260 if capabilities.contains(NodeCapabilities::LAYOUT) {
2261 context.invalidate(InvalidationKind::Layout);
2262 }
2263 if capabilities.contains(NodeCapabilities::DRAW) {
2264 context.invalidate(InvalidationKind::Draw);
2265 }
2266 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
2267 context.invalidate(InvalidationKind::PointerInput);
2268 }
2269 if capabilities.contains(NodeCapabilities::SEMANTICS) {
2270 context.invalidate(InvalidationKind::Semantics);
2271 }
2272 if capabilities.contains(NodeCapabilities::FOCUS) {
2273 context.invalidate(InvalidationKind::Focus);
2274 }
2275
2276 context.pop_active_capabilities();
2277}
2278
2279fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
2280 visit_node_tree_mut(node, &mut |n| {
2281 if !n.node_state().is_attached() {
2282 n.node_state().set_attached(true);
2283 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
2284 }
2285 });
2286}
2287
2288fn reset_node_tree(node: &mut dyn ModifierNode) {
2289 visit_node_tree_mut(node, &mut |n| n.on_reset());
2290}
2291
2292fn detach_node_tree(node: &mut dyn ModifierNode) {
2293 visit_node_tree_mut(node, &mut |n| {
2294 if n.node_state().is_attached() {
2295 n.on_detach();
2296 n.node_state().set_attached(false);
2297 }
2298 n.node_state().set_parent_link(None);
2299 n.node_state().set_child_link(None);
2300 n.node_state()
2301 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2302 });
2303}
2304
2305pub struct ModifierNodeChain {
2312 entries: Vec<ModifierNodeEntry>,
2313 aggregated_capabilities: NodeCapabilities,
2314 head_aggregate_child_capabilities: NodeCapabilities,
2315 head_sentinel: Box<SentinelNode>,
2316 tail_sentinel: Box<SentinelNode>,
2317 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2318 scratch_old_used: Vec<bool>,
2319 scratch_match_order: Vec<Option<usize>>,
2320 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
2321 scratch_elements: Vec<DynModifierElement>,
2322}
2323
2324struct SentinelNode {
2325 state: NodeState,
2326}
2327
2328impl SentinelNode {
2329 fn new() -> Self {
2330 Self {
2331 state: NodeState::sentinel(),
2332 }
2333 }
2334}
2335
2336impl DelegatableNode for SentinelNode {
2337 fn node_state(&self) -> &NodeState {
2338 &self.state
2339 }
2340}
2341
2342impl ModifierNode for SentinelNode {}
2343
2344#[derive(Clone)]
2345pub struct ModifierChainNodeRef<'a> {
2346 chain: &'a ModifierNodeChain,
2347 link: NodeLink,
2348 cached_capabilities: Option<NodeCapabilities>,
2349 cached_aggregate_child: Option<NodeCapabilities>,
2350}
2351
2352impl Default for ModifierNodeChain {
2353 fn default() -> Self {
2354 Self::new()
2355 }
2356}
2357
2358struct EntryIndex {
2359 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2360 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2361 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
2362}
2363
2364struct EntryMatchQuery<'a> {
2365 element_type: TypeId,
2366 node_type: TypeId,
2367 key: Option<u64>,
2368 hash_code: u64,
2369 element: &'a DynModifierElement,
2370}
2371
2372impl EntryIndex {
2373 fn build(entries: &[ModifierNodeEntry]) -> Self {
2374 let mut keyed = HashMap::default();
2375 let mut hashed = HashMap::default();
2376 let mut typed = HashMap::default();
2377
2378 for (i, entry) in entries.iter().enumerate() {
2379 if let Some(key_value) = entry.key {
2380 keyed
2381 .entry((entry.element_type, entry.node_type, key_value))
2382 .or_insert_with(Vec::new)
2383 .push(i);
2384 } else {
2385 hashed
2386 .entry((entry.element_type, entry.node_type, entry.hash_code))
2387 .or_insert_with(Vec::new)
2388 .push(i);
2389 typed
2390 .entry((entry.element_type, entry.node_type))
2391 .or_insert_with(Vec::new)
2392 .push(i);
2393 }
2394 }
2395
2396 Self {
2397 keyed,
2398 hashed,
2399 typed,
2400 }
2401 }
2402
2403 fn find_match(
2404 &self,
2405 entries: &[ModifierNodeEntry],
2406 used: &[bool],
2407 query: EntryMatchQuery<'_>,
2408 ) -> Option<usize> {
2409 if let Some(key_value) = query.key {
2410 if let Some(candidates) =
2411 self.keyed
2412 .get(&(query.element_type, query.node_type, key_value))
2413 {
2414 for &i in candidates {
2415 if !used[i] {
2416 return Some(i);
2417 }
2418 }
2419 }
2420 } else {
2421 if let Some(candidates) =
2422 self.hashed
2423 .get(&(query.element_type, query.node_type, query.hash_code))
2424 {
2425 for &i in candidates {
2426 if !used[i]
2427 && entries[i]
2428 .element
2429 .as_ref()
2430 .equals_element(query.element.as_ref())
2431 {
2432 return Some(i);
2433 }
2434 }
2435 }
2436
2437 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
2438 for &i in candidates {
2439 if !used[i] {
2440 return Some(i);
2441 }
2442 }
2443 }
2444 }
2445
2446 None
2447 }
2448}
2449
2450impl ModifierNodeChain {
2451 pub fn new() -> Self {
2452 let mut chain = Self {
2453 entries: Vec::new(),
2454 aggregated_capabilities: NodeCapabilities::empty(),
2455 head_aggregate_child_capabilities: NodeCapabilities::empty(),
2456 head_sentinel: Box::new(SentinelNode::new()),
2457 tail_sentinel: Box::new(SentinelNode::new()),
2458 ordered_nodes: Vec::new(),
2459 scratch_old_used: Vec::new(),
2460 scratch_match_order: Vec::new(),
2461 scratch_final_slots: Vec::new(),
2462 scratch_elements: Vec::new(),
2463 };
2464 chain.sync_chain_links();
2465 chain
2466 }
2467
2468 pub fn detach_nodes(&mut self) {
2470 for entry in &self.entries {
2471 detach_node_tree(&mut **entry.node.borrow_mut());
2472 }
2473 }
2474
2475 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
2477 for entry in &self.entries {
2478 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2479 }
2480 }
2481
2482 pub fn repair_chain(&mut self) {
2485 self.sync_chain_links();
2486 }
2487
2488 pub fn update_from_slice(
2494 &mut self,
2495 elements: &[DynModifierElement],
2496 context: &mut dyn ModifierNodeContext,
2497 ) {
2498 self.update_from_ref_iter(elements.iter(), context);
2499 }
2500
2501 pub fn update_from_ref_iter<'a, I>(
2506 &mut self,
2507 elements: I,
2508 context: &mut dyn ModifierNodeContext,
2509 ) where
2510 I: Iterator<Item = &'a DynModifierElement>,
2511 {
2512 let old_len = self.entries.len();
2513 let mut fast_path_failed_at: Option<usize> = None;
2514 let mut elements_count = 0;
2515
2516 self.scratch_elements.clear();
2517
2518 for (idx, element) in elements.enumerate() {
2519 elements_count = idx + 1;
2520
2521 if fast_path_failed_at.is_none() && idx < old_len {
2522 let entry = &mut self.entries[idx];
2523 let same_type = entry.element_type == element.element_type();
2524 let same_node_type = entry.node_type == element.node_type();
2525 let same_key = entry.key == element.key();
2526 let same_hash = entry.hash_code == element.hash_code();
2527
2528 let positional_update = element.requires_update();
2529 if same_type && same_node_type && same_key && (same_hash || positional_update) {
2530 let can_update_node = {
2531 let node_borrow = entry.node.borrow();
2532 element.can_update_node(&**node_borrow)
2533 };
2534 if !can_update_node {
2535 fast_path_failed_at = Some(idx);
2536 self.scratch_elements.push(element.clone());
2537 continue;
2538 }
2539
2540 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2541 let capabilities = element.capabilities();
2542
2543 {
2544 let node_borrow = entry.node.borrow();
2545 if !node_borrow.node_state().is_attached() {
2546 drop(node_borrow);
2547 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2548 }
2549 }
2550
2551 let needs_update = !same_element || element.requires_update();
2552 if needs_update {
2553 element.update_node(&mut **entry.node.borrow_mut());
2554 entry.element = element.clone();
2555 entry.hash_code = element.hash_code();
2556 request_update_auto_invalidations(element.as_ref(), context, capabilities);
2557 }
2558
2559 entry.capabilities = capabilities;
2560 entry
2561 .node
2562 .borrow()
2563 .node_state()
2564 .set_capabilities(capabilities);
2565 continue;
2566 }
2567 fast_path_failed_at = Some(idx);
2568 }
2569
2570 self.scratch_elements.push(element.clone());
2571 }
2572
2573 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
2574 if elements_count < self.entries.len() {
2575 for entry in self.entries.drain(elements_count..) {
2576 request_auto_invalidations(context, entry.capabilities);
2577 detach_node_tree(&mut **entry.node.borrow_mut());
2578 }
2579 }
2580 self.sync_chain_links();
2581 return;
2582 }
2583
2584 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
2585
2586 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
2587 let processed_entries_len = self.entries.len();
2588 let old_len = old_entries.len();
2589
2590 self.scratch_old_used.clear();
2591 self.scratch_old_used.resize(old_len, false);
2592
2593 self.scratch_match_order.clear();
2594 self.scratch_match_order.resize(old_len, None);
2595
2596 let index = EntryIndex::build(&old_entries);
2597
2598 let new_elements_count = self.scratch_elements.len();
2599 self.scratch_final_slots.clear();
2600 self.scratch_final_slots.reserve(new_elements_count);
2601
2602 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
2603 self.scratch_final_slots.push(None);
2604 let element_type = element.element_type();
2605 let node_type = element.node_type();
2606 let key = element.key();
2607 let hash_code = element.hash_code();
2608 let capabilities = element.capabilities();
2609
2610 let matched_idx = index.find_match(
2611 &old_entries,
2612 &self.scratch_old_used,
2613 EntryMatchQuery {
2614 element_type,
2615 node_type,
2616 key,
2617 hash_code,
2618 element: &element,
2619 },
2620 );
2621
2622 if let Some(idx) = matched_idx {
2623 let entry = &mut old_entries[idx];
2624 let can_update_node = {
2625 let node_borrow = entry.node.borrow();
2626 element.can_update_node(&**node_borrow)
2627 };
2628 if !can_update_node {
2629 let replacement = ModifierNodeEntry::new(
2630 element_type,
2631 node_type,
2632 key,
2633 element.clone(),
2634 element.create_node(),
2635 hash_code,
2636 capabilities,
2637 );
2638 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
2639 element.update_node(&mut **replacement.node.borrow_mut());
2640 request_auto_invalidations(context, capabilities);
2641 self.scratch_final_slots[new_pos] = Some(replacement);
2642 continue;
2643 }
2644
2645 self.scratch_old_used[idx] = true;
2646 self.scratch_match_order[idx] = Some(new_pos);
2647 let moved = idx != new_pos;
2648
2649 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2650
2651 {
2652 let node_borrow = entry.node.borrow();
2653 if !node_borrow.node_state().is_attached() {
2654 drop(node_borrow);
2655 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2656 }
2657 }
2658
2659 let needs_update = !same_element || element.requires_update();
2660 if needs_update {
2661 element.update_node(&mut **entry.node.borrow_mut());
2662 entry.element = element;
2663 entry.hash_code = hash_code;
2664 request_update_auto_invalidations(
2665 entry.element.as_ref(),
2666 context,
2667 capabilities,
2668 );
2669 }
2670 if moved {
2671 request_auto_invalidations(context, capabilities);
2672 }
2673
2674 entry.key = key;
2675 entry.element_type = element_type;
2676 entry.node_type = node_type;
2677 entry.capabilities = capabilities;
2678 entry
2679 .node
2680 .borrow()
2681 .node_state()
2682 .set_capabilities(capabilities);
2683 } else {
2684 let entry = ModifierNodeEntry::new(
2685 element_type,
2686 node_type,
2687 key,
2688 element.clone(),
2689 element.create_node(),
2690 hash_code,
2691 capabilities,
2692 );
2693 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2694 element.update_node(&mut **entry.node.borrow_mut());
2695 request_auto_invalidations(context, capabilities);
2696 self.scratch_final_slots[new_pos] = Some(entry);
2697 }
2698 }
2699
2700 for (i, entry) in old_entries.into_iter().enumerate() {
2701 if self.scratch_old_used[i] {
2702 if let Some(pos) = self.scratch_match_order[i] {
2703 self.scratch_final_slots[pos] = Some(entry);
2704 } else {
2705 request_auto_invalidations(context, entry.capabilities);
2706 detach_node_tree(&mut **entry.node.borrow_mut());
2707 }
2708 } else {
2709 request_auto_invalidations(context, entry.capabilities);
2710 detach_node_tree(&mut **entry.node.borrow_mut());
2711 }
2712 }
2713
2714 self.entries.reserve(self.scratch_final_slots.len());
2715 for slot in self.scratch_final_slots.drain(..) {
2716 if let Some(entry) = slot {
2717 self.entries.push(entry);
2718 } else {
2719 log::error!("modifier reconciliation produced an empty final slot");
2720 }
2721 }
2722
2723 debug_assert_eq!(
2724 self.entries.len(),
2725 processed_entries_len + new_elements_count
2726 );
2727 self.sync_chain_links();
2728 }
2729
2730 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2734 where
2735 I: IntoIterator<Item = DynModifierElement>,
2736 {
2737 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2738 self.update_from_slice(&collected, context);
2739 }
2740
2741 pub fn reset(&mut self) {
2744 for entry in &mut self.entries {
2745 reset_node_tree(&mut **entry.node.borrow_mut());
2746 }
2747 }
2748
2749 pub fn detach_all(&mut self) {
2751 for entry in std::mem::take(&mut self.entries) {
2752 detach_node_tree(&mut **entry.node.borrow_mut());
2753 {
2754 let node_borrow = entry.node.borrow();
2755 let state = node_borrow.node_state();
2756 state.set_capabilities(NodeCapabilities::empty());
2757 }
2758 }
2759 self.aggregated_capabilities = NodeCapabilities::empty();
2760 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2761 self.ordered_nodes.clear();
2762 self.sync_chain_links();
2763 }
2764
2765 pub fn len(&self) -> usize {
2766 self.entries.len()
2767 }
2768
2769 pub fn is_empty(&self) -> bool {
2770 self.entries.is_empty()
2771 }
2772
2773 pub fn capabilities(&self) -> NodeCapabilities {
2775 self.aggregated_capabilities
2776 }
2777
2778 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2780 self.aggregated_capabilities.contains(capability)
2781 }
2782
2783 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2785 self.make_node_ref(NodeLink::Head)
2786 }
2787
2788 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2790 self.make_node_ref(NodeLink::Tail)
2791 }
2792
2793 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2795 ModifierChainIter::forward(self)
2796 }
2797
2798 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2800 ModifierChainIter::backward(self)
2801 }
2802
2803 pub fn for_each_forward<F>(&self, mut f: F)
2805 where
2806 F: FnMut(ModifierChainNodeRef<'_>),
2807 {
2808 for node in self.head_to_tail() {
2809 f(node);
2810 }
2811 }
2812
2813 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2815 where
2816 F: FnMut(ModifierChainNodeRef<'_>),
2817 {
2818 if mask.is_empty() {
2819 self.for_each_forward(f);
2820 return;
2821 }
2822
2823 if !self.head().aggregate_child_capabilities().intersects(mask) {
2824 return;
2825 }
2826
2827 for node in self.head_to_tail() {
2828 if node.kind_set().intersects(mask) {
2829 f(node);
2830 }
2831 }
2832 }
2833
2834 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2836 where
2837 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2838 {
2839 self.for_each_forward_matching(mask, |node_ref| {
2840 node_ref.with_node(|node| f(node_ref.clone(), node));
2841 });
2842 }
2843
2844 pub fn for_each_backward<F>(&self, mut f: F)
2846 where
2847 F: FnMut(ModifierChainNodeRef<'_>),
2848 {
2849 for node in self.tail_to_head() {
2850 f(node);
2851 }
2852 }
2853
2854 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2856 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2857 node as *const dyn ModifierNode as *const ()
2858 }
2859
2860 let target = node_data_ptr(node);
2861 for (index, entry) in self.entries.iter().enumerate() {
2862 if node_data_ptr(&**entry.node.borrow()) == target {
2863 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2864 }
2865 }
2866
2867 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2868 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2869 return None;
2870 }
2871 let matches_target = match link {
2872 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2873 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2874 NodeLink::Entry(path) => {
2875 let node_borrow = self.entries[path.entry()].node.borrow();
2876 node_data_ptr(&**node_borrow) == target
2877 }
2878 };
2879 if matches_target {
2880 Some(self.make_node_ref(*link))
2881 } else {
2882 None
2883 }
2884 })
2885 }
2886
2887 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2890 self.entries.get(index).and_then(|entry| {
2891 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2892 boxed_node.as_any().downcast_ref::<N>()
2893 })
2894 .ok()
2895 })
2896 }
2897
2898 pub fn node_mut<N: ModifierNode + 'static>(
2901 &self,
2902 index: usize,
2903 ) -> Option<std::cell::RefMut<'_, N>> {
2904 self.entries.get(index).and_then(|entry| {
2905 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2906 boxed_node.as_any_mut().downcast_mut::<N>()
2907 })
2908 .ok()
2909 })
2910 }
2911
2912 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2915 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
2916 }
2917
2918 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
2920 self.aggregated_capabilities
2921 .contains(NodeCapabilities::for_invalidation(kind))
2922 }
2923
2924 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
2926 where
2927 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
2928 {
2929 for index in 0..self.ordered_nodes.len() {
2930 let (link, cached_caps, _agg) = self.ordered_nodes[index];
2931 match link {
2932 NodeLink::Head => {
2933 f(self.head_sentinel.as_mut(), cached_caps);
2934 }
2935 NodeLink::Tail => {
2936 f(self.tail_sentinel.as_mut(), cached_caps);
2937 }
2938 NodeLink::Entry(path) => {
2939 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
2940 if path.delegates().is_empty() {
2941 f(&mut **node_borrow, cached_caps);
2942 } else {
2943 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
2944 for &delegate_index in path.delegates() {
2945 if let Some(delegate) =
2946 nth_delegate_mut(current, delegate_index as usize)
2947 {
2948 current = delegate;
2949 } else {
2950 return;
2951 }
2952 }
2953 f(current, cached_caps);
2954 }
2955 }
2956 }
2957 }
2958 }
2959
2960 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2961 ModifierChainNodeRef {
2962 chain: self,
2963 link,
2964 cached_capabilities: None,
2965 cached_aggregate_child: None,
2966 }
2967 }
2968
2969 fn make_node_ref_with_caps(
2970 &self,
2971 link: NodeLink,
2972 caps: NodeCapabilities,
2973 aggregate_child: NodeCapabilities,
2974 ) -> ModifierChainNodeRef<'_> {
2975 ModifierChainNodeRef {
2976 chain: self,
2977 link,
2978 cached_capabilities: Some(caps),
2979 cached_aggregate_child: Some(aggregate_child),
2980 }
2981 }
2982
2983 fn sync_chain_links(&mut self) {
2984 self.rebuild_ordered_nodes();
2985
2986 self.head_sentinel.node_state().set_parent_link(None);
2987 self.tail_sentinel.node_state().set_child_link(None);
2988
2989 if self.ordered_nodes.is_empty() {
2990 self.head_sentinel
2991 .node_state()
2992 .set_child_link(Some(NodeLink::Tail));
2993 self.tail_sentinel
2994 .node_state()
2995 .set_parent_link(Some(NodeLink::Head));
2996 self.aggregated_capabilities = NodeCapabilities::empty();
2997 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2998 self.head_sentinel
2999 .node_state()
3000 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3001 self.tail_sentinel
3002 .node_state()
3003 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3004 return;
3005 }
3006
3007 let mut previous = NodeLink::Head;
3008 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
3009 match &previous {
3010 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
3011 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
3012 NodeLink::Entry(path) => {
3013 let node_borrow = self.entries[path.entry()].node.borrow();
3014 if path.delegates().is_empty() {
3015 node_borrow.node_state().set_child_link(Some(link));
3016 } else {
3017 let mut current: &dyn ModifierNode = &**node_borrow;
3018 for &delegate_index in path.delegates() {
3019 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3020 current = delegate;
3021 }
3022 }
3023 current.node_state().set_child_link(Some(link));
3024 }
3025 }
3026 }
3027 match &link {
3028 NodeLink::Head => self
3029 .head_sentinel
3030 .node_state()
3031 .set_parent_link(Some(previous)),
3032 NodeLink::Tail => self
3033 .tail_sentinel
3034 .node_state()
3035 .set_parent_link(Some(previous)),
3036 NodeLink::Entry(path) => {
3037 let node_borrow = self.entries[path.entry()].node.borrow();
3038 if path.delegates().is_empty() {
3039 node_borrow.node_state().set_parent_link(Some(previous));
3040 } else {
3041 let mut current: &dyn ModifierNode = &**node_borrow;
3042 for &delegate_index in path.delegates() {
3043 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3044 current = delegate;
3045 }
3046 }
3047 current.node_state().set_parent_link(Some(previous));
3048 }
3049 }
3050 }
3051 previous = link;
3052 }
3053
3054 match &previous {
3055 NodeLink::Head => self
3056 .head_sentinel
3057 .node_state()
3058 .set_child_link(Some(NodeLink::Tail)),
3059 NodeLink::Tail => self
3060 .tail_sentinel
3061 .node_state()
3062 .set_child_link(Some(NodeLink::Tail)),
3063 NodeLink::Entry(path) => {
3064 let node_borrow = self.entries[path.entry()].node.borrow();
3065 if path.delegates().is_empty() {
3066 node_borrow
3067 .node_state()
3068 .set_child_link(Some(NodeLink::Tail));
3069 } else {
3070 let mut current: &dyn ModifierNode = &**node_borrow;
3071 for &delegate_index in path.delegates() {
3072 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3073 current = delegate;
3074 }
3075 }
3076 current.node_state().set_child_link(Some(NodeLink::Tail));
3077 }
3078 }
3079 }
3080 self.tail_sentinel
3081 .node_state()
3082 .set_parent_link(Some(previous));
3083 self.tail_sentinel.node_state().set_child_link(None);
3084
3085 let mut aggregate = NodeCapabilities::empty();
3086 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
3087 aggregate |= *cached_caps;
3088 *cached_aggregate = aggregate;
3089 match link {
3090 NodeLink::Head => {
3091 self.head_sentinel
3092 .node_state()
3093 .set_aggregate_child_capabilities(aggregate);
3094 }
3095 NodeLink::Tail => {
3096 self.tail_sentinel
3097 .node_state()
3098 .set_aggregate_child_capabilities(aggregate);
3099 }
3100 NodeLink::Entry(path) => {
3101 let node_borrow = self.entries[path.entry()].node.borrow();
3102 let state = if path.delegates().is_empty() {
3103 node_borrow.node_state()
3104 } else {
3105 let mut current: &dyn ModifierNode = &**node_borrow;
3106 for &delegate_index in path.delegates() {
3107 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3108 current = delegate;
3109 }
3110 }
3111 current.node_state()
3112 };
3113 state.set_aggregate_child_capabilities(aggregate);
3114 }
3115 }
3116 }
3117
3118 self.aggregated_capabilities = aggregate;
3119 self.head_aggregate_child_capabilities = aggregate;
3120 self.head_sentinel
3121 .node_state()
3122 .set_aggregate_child_capabilities(aggregate);
3123 self.tail_sentinel
3124 .node_state()
3125 .set_aggregate_child_capabilities(NodeCapabilities::empty());
3126 }
3127
3128 fn rebuild_ordered_nodes(&mut self) {
3129 self.ordered_nodes.clear();
3130 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
3131 for (index, entry) in self.entries.iter().enumerate() {
3132 let node_borrow = entry.node.borrow();
3133 Self::enumerate_link_order(
3134 &**node_borrow,
3135 index,
3136 &mut path_buf,
3137 0,
3138 &mut self.ordered_nodes,
3139 );
3140 }
3141 }
3142
3143 fn enumerate_link_order(
3144 node: &dyn ModifierNode,
3145 entry: usize,
3146 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
3147 path_len: usize,
3148 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
3149 ) {
3150 let caps = node.node_state().capabilities();
3151 out.push((
3152 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
3153 caps,
3154 NodeCapabilities::empty(),
3155 ));
3156 let mut delegate_index = 0usize;
3157 node.for_each_delegate(&mut |child| {
3158 if path_len < MAX_DELEGATE_DEPTH {
3159 path_buf[path_len] = delegate_index;
3160 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
3161 }
3162 delegate_index += 1;
3163 });
3164 }
3165}
3166
3167impl<'a> ModifierChainNodeRef<'a> {
3168 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
3169 match &self.link {
3170 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
3171 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
3172 NodeLink::Entry(path) => {
3173 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3174 if path.delegates().is_empty() {
3175 f(node_borrow.node_state())
3176 } else {
3177 let mut current: &dyn ModifierNode = &**node_borrow;
3178 for &delegate_index in path.delegates() {
3179 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3180 current = delegate;
3181 } else {
3182 return f(node_borrow.node_state());
3183 }
3184 }
3185 f(current.node_state())
3186 }
3187 }
3188 }
3189 }
3190
3191 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
3194 match &self.link {
3195 NodeLink::Head => None,
3196 NodeLink::Tail => None,
3197 NodeLink::Entry(path) => {
3198 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3199 if path.delegates().is_empty() {
3200 Some(f(&**node_borrow))
3201 } else {
3202 let mut current: &dyn ModifierNode = &**node_borrow;
3203 for &delegate_index in path.delegates() {
3204 current = nth_delegate(current, delegate_index as usize)?;
3205 }
3206 Some(f(current))
3207 }
3208 }
3209 }
3210 }
3211
3212 #[inline]
3214 pub fn parent(&self) -> Option<Self> {
3215 self.with_state(|state| state.parent_link())
3216 .map(|link| self.chain.make_node_ref(link))
3217 }
3218
3219 #[inline]
3221 pub fn child(&self) -> Option<Self> {
3222 self.with_state(|state| state.child_link())
3223 .map(|link| self.chain.make_node_ref(link))
3224 }
3225
3226 #[inline]
3228 pub fn kind_set(&self) -> NodeCapabilities {
3229 if let Some(caps) = self.cached_capabilities {
3230 return caps;
3231 }
3232 match &self.link {
3233 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
3234 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
3235 }
3236 }
3237
3238 pub fn entry_index(&self) -> Option<usize> {
3240 match &self.link {
3241 NodeLink::Entry(path) => Some(path.entry()),
3242 _ => None,
3243 }
3244 }
3245
3246 pub fn delegate_depth(&self) -> usize {
3248 match &self.link {
3249 NodeLink::Entry(path) => path.delegates().len(),
3250 _ => 0,
3251 }
3252 }
3253
3254 #[inline]
3256 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
3257 if let Some(agg) = self.cached_aggregate_child {
3258 return agg;
3259 }
3260 if self.is_tail() {
3261 NodeCapabilities::empty()
3262 } else {
3263 self.with_state(|state| state.aggregate_child_capabilities())
3264 }
3265 }
3266
3267 pub fn is_head(&self) -> bool {
3269 matches!(self.link, NodeLink::Head)
3270 }
3271
3272 pub fn is_tail(&self) -> bool {
3274 matches!(self.link, NodeLink::Tail)
3275 }
3276
3277 pub fn is_sentinel(&self) -> bool {
3279 matches!(self.link, NodeLink::Head | NodeLink::Tail)
3280 }
3281
3282 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
3284 !mask.is_empty() && self.kind_set().intersects(mask)
3285 }
3286
3287 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
3289 where
3290 F: FnMut(ModifierChainNodeRef<'a>),
3291 {
3292 let mut current = if include_self {
3293 Some(self)
3294 } else {
3295 self.child()
3296 };
3297 while let Some(node) = current {
3298 if node.is_tail() {
3299 break;
3300 }
3301 if !node.is_sentinel() {
3302 f(node.clone());
3303 }
3304 current = node.child();
3305 }
3306 }
3307
3308 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3310 where
3311 F: FnMut(ModifierChainNodeRef<'a>),
3312 {
3313 if mask.is_empty() {
3314 self.visit_descendants(include_self, f);
3315 return;
3316 }
3317
3318 if !self.aggregate_child_capabilities().intersects(mask) {
3319 return;
3320 }
3321
3322 self.visit_descendants(include_self, |node| {
3323 if node.kind_set().intersects(mask) {
3324 f(node);
3325 }
3326 });
3327 }
3328
3329 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
3331 where
3332 F: FnMut(ModifierChainNodeRef<'a>),
3333 {
3334 let mut current = if include_self {
3335 Some(self)
3336 } else {
3337 self.parent()
3338 };
3339 while let Some(node) = current {
3340 if node.is_head() {
3341 break;
3342 }
3343 f(node.clone());
3344 current = node.parent();
3345 }
3346 }
3347
3348 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3350 where
3351 F: FnMut(ModifierChainNodeRef<'a>),
3352 {
3353 if mask.is_empty() {
3354 self.visit_ancestors(include_self, f);
3355 return;
3356 }
3357
3358 self.visit_ancestors(include_self, |node| {
3359 if node.kind_set().intersects(mask) {
3360 f(node);
3361 }
3362 });
3363 }
3364}
3365
3366#[cfg(test)]
3367#[path = "tests/modifier_tests.rs"]
3368mod tests;