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