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