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::{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;
161
162#[derive(Copy, Clone, Debug, PartialEq, Eq)]
163pub(crate) struct NodePath {
164 entry: usize,
165 delegate_buf: [u8; MAX_DELEGATE_DEPTH],
166 delegate_len: u8,
167}
168
169impl NodePath {
170 #[inline]
171 fn root(entry: usize) -> Self {
172 Self {
173 entry,
174 delegate_buf: [0; MAX_DELEGATE_DEPTH],
175 delegate_len: 0,
176 }
177 }
178
179 #[inline]
180 fn from_slice(entry: usize, path: &[usize]) -> Self {
181 debug_assert!(
182 path.len() <= MAX_DELEGATE_DEPTH,
183 "delegate depth {} exceeds MAX_DELEGATE_DEPTH {}",
184 path.len(),
185 MAX_DELEGATE_DEPTH
186 );
187 debug_assert!(
188 path.iter().all(|&i| i <= u8::MAX as usize),
189 "delegate index exceeds u8 range"
190 );
191 let mut delegate_buf = [0u8; MAX_DELEGATE_DEPTH];
192 for (i, &v) in path.iter().enumerate().take(MAX_DELEGATE_DEPTH) {
193 delegate_buf[i] = v as u8;
194 }
195 Self {
196 entry,
197 delegate_buf,
198 delegate_len: path.len().min(MAX_DELEGATE_DEPTH) as u8,
199 }
200 }
201
202 #[inline]
203 fn entry(&self) -> usize {
204 self.entry
205 }
206
207 #[inline]
208 fn delegates(&self) -> &[u8] {
209 &self.delegate_buf[..self.delegate_len as usize]
210 }
211}
212
213#[derive(Copy, Clone, Debug, PartialEq, Eq)]
214pub(crate) enum NodeLink {
215 Head,
216 Tail,
217 Entry(NodePath),
218}
219
220#[derive(Debug)]
226pub struct NodeState {
227 aggregate_child_capabilities: Cell<NodeCapabilities>,
228 capabilities: Cell<NodeCapabilities>,
229 parent: RefCell<Option<NodeLink>>,
230 child: RefCell<Option<NodeLink>>,
231 attached: Cell<bool>,
232 is_sentinel: bool,
233}
234
235impl Default for NodeState {
236 fn default() -> Self {
237 Self::new()
238 }
239}
240
241impl NodeState {
242 pub const fn new() -> Self {
243 Self {
244 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
245 capabilities: Cell::new(NodeCapabilities::empty()),
246 parent: RefCell::new(None),
247 child: RefCell::new(None),
248 attached: Cell::new(false),
249 is_sentinel: false,
250 }
251 }
252
253 pub const fn sentinel() -> Self {
254 Self {
255 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
256 capabilities: Cell::new(NodeCapabilities::empty()),
257 parent: RefCell::new(None),
258 child: RefCell::new(None),
259 attached: Cell::new(true),
260 is_sentinel: true,
261 }
262 }
263
264 pub fn set_capabilities(&self, capabilities: NodeCapabilities) {
265 self.capabilities.set(capabilities);
266 }
267
268 #[inline]
269 pub fn capabilities(&self) -> NodeCapabilities {
270 self.capabilities.get()
271 }
272
273 pub fn set_aggregate_child_capabilities(&self, capabilities: NodeCapabilities) {
274 self.aggregate_child_capabilities.set(capabilities);
275 }
276
277 #[inline]
278 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
279 self.aggregate_child_capabilities.get()
280 }
281
282 pub(crate) fn set_parent_link(&self, parent: Option<NodeLink>) {
283 *self.parent.borrow_mut() = parent;
284 }
285
286 #[inline]
287 pub(crate) fn parent_link(&self) -> Option<NodeLink> {
288 *self.parent.borrow()
289 }
290
291 pub(crate) fn set_child_link(&self, child: Option<NodeLink>) {
292 *self.child.borrow_mut() = child;
293 }
294
295 #[inline]
296 pub(crate) fn child_link(&self) -> Option<NodeLink> {
297 *self.child.borrow()
298 }
299
300 pub fn set_attached(&self, attached: bool) {
301 self.attached.set(attached);
302 }
303
304 pub fn is_attached(&self) -> bool {
305 self.attached.get()
306 }
307
308 pub fn is_sentinel(&self) -> bool {
309 self.is_sentinel
310 }
311}
312
313pub trait DelegatableNode {
315 fn node_state(&self) -> &NodeState;
316 fn aggregate_child_capabilities(&self) -> NodeCapabilities {
317 self.node_state().aggregate_child_capabilities()
318 }
319}
320
321pub trait ModifierNode: Any + DelegatableNode {
379 fn on_attach(&mut self, _context: &mut dyn ModifierNodeContext) {}
380
381 fn on_detach(&mut self) {}
382
383 fn on_reset(&mut self) {}
384
385 fn as_draw_node(&self) -> Option<&dyn DrawModifierNode> {
387 None
388 }
389
390 fn as_draw_node_mut(&mut self) -> Option<&mut dyn DrawModifierNode> {
392 None
393 }
394
395 fn as_pointer_input_node(&self) -> Option<&dyn PointerInputNode> {
397 None
398 }
399
400 fn as_pointer_input_node_mut(&mut self) -> Option<&mut dyn PointerInputNode> {
402 None
403 }
404
405 fn as_semantics_node(&self) -> Option<&dyn SemanticsNode> {
407 None
408 }
409
410 fn as_semantics_node_mut(&mut self) -> Option<&mut dyn SemanticsNode> {
412 None
413 }
414
415 fn as_focus_node(&self) -> Option<&dyn FocusNode> {
417 None
418 }
419
420 fn as_focus_node_mut(&mut self) -> Option<&mut dyn FocusNode> {
422 None
423 }
424
425 fn as_layout_node(&self) -> Option<&dyn LayoutModifierNode> {
427 None
428 }
429
430 fn as_layout_node_mut(&mut self) -> Option<&mut dyn LayoutModifierNode> {
432 None
433 }
434
435 fn for_each_delegate<'b>(&'b self, _visitor: &mut dyn FnMut(&'b dyn ModifierNode)) {}
437
438 fn for_each_delegate_mut<'b>(&'b mut self, _visitor: &mut dyn FnMut(&'b mut dyn ModifierNode)) {
440 }
441}
442
443pub trait LayoutModifierNode: ModifierNode {
449 fn measure(
471 &self,
472 _context: &mut dyn ModifierNodeContext,
473 measurable: &dyn Measurable,
474 constraints: Constraints,
475 ) -> cranpose_ui_layout::LayoutModifierMeasureResult {
476 let placeable = measurable.measure(constraints);
477 cranpose_ui_layout::LayoutModifierMeasureResult::with_size(Size {
478 width: placeable.width(),
479 height: placeable.height(),
480 })
481 }
482
483 fn min_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
485 0.0
486 }
487
488 fn max_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
490 0.0
491 }
492
493 fn min_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
495 0.0
496 }
497
498 fn max_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
500 0.0
501 }
502}
503
504pub trait DrawModifierNode: ModifierNode {
512 fn draw(&self, _draw_scope: &mut dyn DrawScope) {}
521
522 fn create_draw_closure(&self) -> Option<NodeDrawClosure> {
533 None
534 }
535
536 fn create_behind_draw_closure(&self) -> Option<NodeDrawClosure> {
541 None
542 }
543}
544
545pub type NodeDrawClosure = Rc<dyn Fn(&mut cranpose_ui_graphics::DrawScopeDefault)>;
550
551pub trait PointerInputNode: ModifierNode {
557 fn on_pointer_event(
560 &mut self,
561 _context: &mut dyn ModifierNodeContext,
562 _event: &PointerEvent,
563 ) -> bool {
564 false
565 }
566
567 fn hit_test(&self, _x: f32, _y: f32) -> bool {
570 true
571 }
572
573 fn pointer_input_handler(&self) -> Option<Rc<dyn Fn(PointerEvent)>> {
575 None
576 }
577
578 fn layout_size_sink(&self) -> Option<Rc<Cell<Size>>> {
591 None
592 }
593}
594
595pub trait SemanticsNode: ModifierNode {
601 fn merge_semantics(&self, _config: &mut SemanticsConfiguration) {}
603}
604
605#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
610pub enum FocusState {
611 Active,
613 ActiveParent,
615 Captured,
619 #[default]
622 Inactive,
623}
624
625impl FocusState {
626 pub fn is_focused(self) -> bool {
628 matches!(self, FocusState::Active | FocusState::Captured)
629 }
630
631 pub fn has_focus(self) -> bool {
633 matches!(
634 self,
635 FocusState::Active | FocusState::ActiveParent | FocusState::Captured
636 )
637 }
638
639 pub fn is_captured(self) -> bool {
641 matches!(self, FocusState::Captured)
642 }
643}
644
645pub trait FocusNode: ModifierNode {
650 fn focus_state(&self) -> FocusState;
652
653 fn on_focus_changed(&mut self, _context: &mut dyn ModifierNodeContext, _state: FocusState) {}
655}
656
657#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
668pub enum SemanticsWidgetRole {
669 Button,
670 Checkbox,
671 Switch,
672 RadioButton,
673 Tab,
674 Image,
675 DropdownList,
678 ValuePicker,
681 Header,
686 Dialog,
690}
691
692#[derive(Clone, Copy, Debug, PartialEq)]
700pub struct ProgressBarRangeInfo {
701 pub current: f32,
702 pub start: f32,
703 pub end: f32,
704 pub steps: u32,
707}
708
709impl ProgressBarRangeInfo {
710 pub fn new(current: f32, start: f32, end: f32, steps: u32) -> Self {
711 Self {
712 current,
713 start,
714 end,
715 steps,
716 }
717 }
718
719 pub fn fraction(&self) -> f32 {
721 let span = self.end - self.start;
722 if span.abs() < f32::EPSILON {
723 return 0.0;
724 }
725 ((self.current - self.start) / span).clamp(0.0, 1.0)
726 }
727
728 pub fn step(&self) -> f32 {
731 let span = self.end - self.start;
732 if self.steps == 0 {
733 span / 10.0
734 } else {
735 span / (self.steps as f32 + 1.0)
736 }
737 }
738}
739
740#[derive(Clone, Copy, Debug, PartialEq, Eq)]
745pub struct CollectionInfo {
746 pub rows: usize,
747 pub columns: usize,
748}
749
750#[derive(Clone, Copy, Debug, PartialEq)]
756pub struct ScrollAxisRange {
757 pub value: f32,
758 pub max_value: f32,
759 pub reverse: bool,
760}
761
762impl ScrollAxisRange {
763 pub fn new(value: f32, max_value: f32, reverse: bool) -> Self {
764 Self {
765 value,
766 max_value,
767 reverse,
768 }
769 }
770
771 pub fn can_scroll_forward(&self) -> bool {
772 self.value < self.max_value
773 }
774
775 pub fn can_scroll_backward(&self) -> bool {
776 self.value > 0.0
777 }
778}
779
780#[derive(Clone)]
786pub struct SemanticsScrollBy {
787 handler: Rc<dyn Fn(f32, f32) -> bool>,
788}
789
790impl SemanticsScrollBy {
791 pub fn new(handler: impl Fn(f32, f32) -> bool + 'static) -> Self {
792 Self {
793 handler: Rc::new(handler),
794 }
795 }
796
797 pub fn invoke(&self, dx: f32, dy: f32) -> bool {
798 (self.handler)(dx, dy)
799 }
800}
801
802impl fmt::Debug for SemanticsScrollBy {
803 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
804 f.debug_struct("SemanticsScrollBy").finish_non_exhaustive()
805 }
806}
807
808impl PartialEq for SemanticsScrollBy {
811 fn eq(&self, _other: &Self) -> bool {
812 true
813 }
814}
815
816impl Eq for SemanticsScrollBy {}
817
818#[derive(Clone)]
824pub struct SemanticsScrollToIndex {
825 handler: Rc<dyn Fn(usize) -> bool>,
826}
827
828impl SemanticsScrollToIndex {
829 pub fn new(handler: impl Fn(usize) -> bool + 'static) -> Self {
830 Self {
831 handler: Rc::new(handler),
832 }
833 }
834
835 pub fn invoke(&self, index: usize) -> bool {
836 (self.handler)(index)
837 }
838}
839
840impl fmt::Debug for SemanticsScrollToIndex {
841 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
842 f.debug_struct("SemanticsScrollToIndex")
843 .finish_non_exhaustive()
844 }
845}
846
847impl PartialEq for SemanticsScrollToIndex {
850 fn eq(&self, _other: &Self) -> bool {
851 true
852 }
853}
854
855impl Eq for SemanticsScrollToIndex {}
856
857#[derive(Clone)]
863pub struct SemanticsSetProgress {
864 handler: Rc<dyn Fn(f32) -> bool>,
865}
866
867impl SemanticsSetProgress {
868 pub fn new(handler: impl Fn(f32) -> bool + 'static) -> Self {
869 Self {
870 handler: Rc::new(handler),
871 }
872 }
873
874 pub fn invoke(&self, value: f32) -> bool {
875 (self.handler)(value)
876 }
877}
878
879impl fmt::Debug for SemanticsSetProgress {
880 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
881 f.debug_struct("SemanticsSetProgress")
882 .finish_non_exhaustive()
883 }
884}
885
886#[derive(Clone)]
890pub struct SemanticsSetText(Rc<dyn Fn(&str) -> bool>);
891
892impl SemanticsSetText {
893 pub fn new(handler: impl Fn(&str) -> bool + 'static) -> Self {
894 Self(Rc::new(handler))
895 }
896
897 pub fn invoke(&self, text: &str) -> bool {
898 (self.0)(text)
899 }
900}
901
902impl fmt::Debug for SemanticsSetText {
903 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
904 f.write_str("SemanticsSetText")
905 }
906}
907
908#[derive(Clone)]
911pub struct SemanticsExpand(Rc<dyn Fn() -> bool>);
912
913impl SemanticsExpand {
914 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
915 Self(Rc::new(handler))
916 }
917
918 pub fn invoke(&self) -> bool {
919 (self.0)()
920 }
921}
922
923impl fmt::Debug for SemanticsExpand {
924 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
925 f.write_str("SemanticsExpand")
926 }
927}
928
929#[derive(Clone)]
933pub struct SemanticsLongClick(Rc<dyn Fn() -> bool>);
934
935impl SemanticsLongClick {
936 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
937 Self(Rc::new(handler))
938 }
939
940 pub fn invoke(&self) -> bool {
941 (self.0)()
942 }
943}
944
945impl fmt::Debug for SemanticsLongClick {
946 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
947 f.write_str("SemanticsLongClick")
948 }
949}
950
951impl PartialEq for SemanticsLongClick {
952 fn eq(&self, _other: &Self) -> bool {
953 true
954 }
955}
956
957impl PartialEq for SemanticsExpand {
958 fn eq(&self, _other: &Self) -> bool {
959 true
960 }
961}
962
963#[derive(Clone)]
967pub struct SemanticsDismiss(Rc<dyn Fn() -> bool>);
968
969impl SemanticsDismiss {
970 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
971 Self(Rc::new(handler))
972 }
973
974 pub fn invoke(&self) -> bool {
975 (self.0)()
976 }
977}
978
979impl fmt::Debug for SemanticsDismiss {
980 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
981 f.write_str("SemanticsDismiss")
982 }
983}
984
985impl PartialEq for SemanticsDismiss {
986 fn eq(&self, _other: &Self) -> bool {
987 true
988 }
989}
990
991impl PartialEq for SemanticsSetText {
992 fn eq(&self, _other: &Self) -> bool {
993 true
994 }
995}
996
997impl PartialEq for SemanticsSetProgress {
1002 fn eq(&self, _other: &Self) -> bool {
1003 true
1004 }
1005}
1006
1007impl Eq for SemanticsSetProgress {}
1008
1009#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
1016pub enum LiveRegionMode {
1017 Polite,
1019 Assertive,
1022}
1023
1024#[derive(Clone)]
1031pub struct SemanticsCustomAction {
1032 pub label: String,
1034 handler: Rc<dyn Fn()>,
1035}
1036
1037impl SemanticsCustomAction {
1038 pub fn new(label: impl Into<String>, handler: impl Fn() + 'static) -> Self {
1039 Self {
1040 label: label.into(),
1041 handler: Rc::new(handler),
1042 }
1043 }
1044
1045 pub fn invoke(&self) {
1046 (self.handler)();
1047 }
1048}
1049
1050impl fmt::Debug for SemanticsCustomAction {
1051 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1052 f.debug_struct("SemanticsCustomAction")
1053 .field("label", &self.label)
1054 .finish_non_exhaustive()
1055 }
1056}
1057
1058impl PartialEq for SemanticsCustomAction {
1068 fn eq(&self, other: &Self) -> bool {
1069 self.label == other.label
1070 }
1071}
1072
1073impl Eq for SemanticsCustomAction {}
1074
1075#[derive(Clone, Debug, PartialEq)]
1090pub struct CanvasSemanticsNode {
1091 pub key: u64,
1098 pub bounds: cranpose_ui_graphics::Rect,
1100 pub label: String,
1101 pub role: Option<SemanticsWidgetRole>,
1102 pub state_description: Option<String>,
1106 pub on_click_label: Option<String>,
1109 pub clickable: bool,
1110 pub selected: Option<bool>,
1112 pub toggled: Option<bool>,
1114 pub enabled: bool,
1115 pub custom_actions: Vec<SemanticsCustomAction>,
1116}
1117
1118impl Default for CanvasSemanticsNode {
1119 fn default() -> Self {
1120 Self {
1121 key: 0,
1122 bounds: cranpose_ui_graphics::Rect {
1123 x: 0.0,
1124 y: 0.0,
1125 width: 0.0,
1126 height: 0.0,
1127 },
1128 label: String::new(),
1129 role: None,
1130 state_description: None,
1131 on_click_label: None,
1132 clickable: false,
1133 selected: None,
1134 toggled: None,
1135 enabled: true,
1136 custom_actions: Vec::new(),
1137 }
1138 }
1139}
1140
1141impl CanvasSemanticsNode {
1142 pub fn control(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1144 Self {
1145 key,
1146 bounds,
1147 label: label.into(),
1148 clickable: true,
1149 ..Self::default()
1150 }
1151 }
1152
1153 pub fn text(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1155 Self {
1156 key,
1157 bounds,
1158 label: label.into(),
1159 ..Self::default()
1160 }
1161 }
1162
1163 pub fn with_role(mut self, role: SemanticsWidgetRole) -> Self {
1164 self.role = Some(role);
1165 self
1166 }
1167
1168 pub fn with_state_description(mut self, state: impl Into<String>) -> Self {
1169 self.state_description = Some(state.into());
1170 self
1171 }
1172
1173 pub fn with_click_label(mut self, label: impl Into<String>) -> Self {
1174 self.on_click_label = Some(label.into());
1175 self.clickable = true;
1176 self
1177 }
1178
1179 pub fn with_selected(mut self, selected: bool) -> Self {
1180 self.selected = Some(selected);
1181 self
1182 }
1183
1184 pub fn with_toggled(mut self, toggled: bool) -> Self {
1185 self.toggled = Some(toggled);
1186 self
1187 }
1188
1189 pub fn with_enabled(mut self, enabled: bool) -> Self {
1190 self.enabled = enabled;
1191 self
1192 }
1193
1194 pub fn with_custom_action(mut self, action: SemanticsCustomAction) -> Self {
1195 self.custom_actions.push(action);
1196 self
1197 }
1198}
1199
1200#[derive(Clone, Debug, PartialEq)]
1202pub struct SemanticsConfiguration {
1203 pub content_description: Option<String>,
1204 pub state_description: Option<String>,
1206 pub on_click_label: Option<String>,
1208 pub on_long_click: Option<SemanticsLongClick>,
1211 pub on_long_click_label: Option<String>,
1214 pub role: Option<SemanticsWidgetRole>,
1216 pub selected: Option<bool>,
1217 pub toggled: Option<bool>,
1218 pub enabled: bool,
1219 pub is_clickable: bool,
1220 pub is_editable_text: bool,
1221 pub text: Option<String>,
1224 pub text_selection: Option<crate::text::TextRange>,
1225 pub custom_actions: Vec<SemanticsCustomAction>,
1226 pub canvas_children: Vec<CanvasSemanticsNode>,
1229 pub is_modal: bool,
1232 pub hidden: bool,
1236 pub merge_descendants: bool,
1240 pub selectable_group: bool,
1244 pub pane_title: Option<String>,
1247 pub error: Option<String>,
1250 pub password: bool,
1253 pub traversal_index: f32,
1257 pub live_region: Option<LiveRegionMode>,
1260 pub progress: Option<ProgressBarRangeInfo>,
1263 pub set_progress: Option<SemanticsSetProgress>,
1266 pub set_text: Option<SemanticsSetText>,
1269 pub expand: Option<SemanticsExpand>,
1272 pub dismiss: Option<SemanticsDismiss>,
1276 pub collapse: Option<SemanticsExpand>,
1279 pub vertical_scroll: Option<ScrollAxisRange>,
1282 pub horizontal_scroll: Option<ScrollAxisRange>,
1285 pub scroll_by: Option<SemanticsScrollBy>,
1288 pub scroll_to_index: Option<SemanticsScrollToIndex>,
1292 pub collection: Option<CollectionInfo>,
1294}
1295
1296impl Default for SemanticsConfiguration {
1297 fn default() -> Self {
1298 Self {
1299 content_description: None,
1300 state_description: None,
1301 on_click_label: None,
1302 on_long_click: None,
1303 on_long_click_label: None,
1304 role: None,
1305 selected: None,
1306 toggled: None,
1307 enabled: true,
1308 is_clickable: false,
1309 is_editable_text: false,
1310 text: None,
1311 text_selection: None,
1312 custom_actions: Vec::new(),
1313 canvas_children: Vec::new(),
1314 is_modal: false,
1315 hidden: false,
1316 merge_descendants: false,
1317 selectable_group: false,
1318 pane_title: None,
1319 error: None,
1320 password: false,
1321 traversal_index: 0.0,
1322 live_region: None,
1323 progress: None,
1324 set_progress: None,
1325 set_text: None,
1326 expand: None,
1327 dismiss: None,
1328 collapse: None,
1329 vertical_scroll: None,
1330 horizontal_scroll: None,
1331 scroll_by: None,
1332 scroll_to_index: None,
1333 collection: None,
1334 }
1335 }
1336}
1337
1338pub type SemanticsSpec = SemanticsConfiguration;
1347
1348impl SemanticsConfiguration {
1349 pub fn new() -> Self {
1352 Self::default()
1353 }
1354
1355 pub fn content_description(mut self, name: impl Into<String>) -> Self {
1358 self.content_description = Some(name.into());
1359 self
1360 }
1361
1362 pub fn state_description(mut self, state: impl Into<String>) -> Self {
1365 self.state_description = Some(state.into());
1366 self
1367 }
1368
1369 pub fn clickable(mut self) -> Self {
1371 self.is_clickable = true;
1372 self
1373 }
1374
1375 pub fn on_long_click(
1379 mut self,
1380 label: impl Into<String>,
1381 action: impl Fn() -> bool + 'static,
1382 ) -> Self {
1383 self.on_long_click_label = Some(label.into());
1384 self.on_long_click = Some(SemanticsLongClick::new(action));
1385 self
1386 }
1387
1388 pub fn toggled(mut self, toggled: bool) -> Self {
1390 self.toggled = Some(toggled);
1391 self
1392 }
1393
1394 pub fn selected(mut self, selected: bool) -> Self {
1397 self.selected = Some(selected);
1398 self
1399 }
1400
1401 pub fn role(mut self, role: SemanticsWidgetRole) -> Self {
1403 self.role = Some(role);
1404 self
1405 }
1406
1407 pub fn heading(self) -> Self {
1410 self.role(SemanticsWidgetRole::Header)
1411 }
1412
1413 pub fn error(mut self, message: impl Into<String>) -> Self {
1415 self.error = Some(message.into());
1416 self
1417 }
1418
1419 pub fn password(mut self) -> Self {
1421 self.password = true;
1422 self
1423 }
1424
1425 pub fn pane_title(mut self, title: impl Into<String>) -> Self {
1428 self.pane_title = Some(title.into());
1429 self
1430 }
1431
1432 pub fn traversal_index(mut self, index: f32) -> Self {
1435 self.traversal_index = index;
1436 self
1437 }
1438
1439 pub fn hidden(mut self) -> Self {
1442 self.hidden = true;
1443 self
1444 }
1445
1446 pub fn merge_descendants(mut self) -> Self {
1449 self.merge_descendants = true;
1450 self
1451 }
1452
1453 pub fn selectable_group(mut self) -> Self {
1456 self.selectable_group = true;
1457 self
1458 }
1459
1460 pub fn live_region(mut self, mode: LiveRegionMode) -> Self {
1463 self.live_region = Some(mode);
1464 self
1465 }
1466 pub fn merge(&mut self, other: &SemanticsConfiguration) {
1467 if let Some(description) = &other.content_description {
1468 self.content_description = Some(description.clone());
1469 }
1470 if let Some(state) = &other.state_description {
1471 self.state_description = Some(state.clone());
1472 }
1473 if let Some(label) = &other.on_click_label {
1474 self.on_click_label = Some(label.clone());
1475 }
1476 if let Some(label) = &other.on_long_click_label {
1477 self.on_long_click_label = Some(label.clone());
1478 }
1479 if let Some(role) = other.role {
1480 self.role = Some(role);
1481 }
1482 if let Some(selected) = other.selected {
1483 self.selected = Some(selected);
1484 }
1485 if let Some(toggled) = other.toggled {
1486 self.toggled = Some(toggled);
1487 }
1488 self.enabled &= other.enabled;
1489 self.is_clickable |= other.is_clickable;
1490 self.is_editable_text |= other.is_editable_text;
1491 if let Some(text) = &other.text {
1492 self.text = Some(text.clone());
1493 }
1494 self.is_modal |= other.is_modal;
1495 self.hidden |= other.hidden;
1496 self.merge_descendants |= other.merge_descendants;
1497 self.selectable_group |= other.selectable_group;
1498 self.password |= other.password;
1499 if other.traversal_index != 0.0 {
1500 self.traversal_index = other.traversal_index;
1501 }
1502 if let Some(live_region) = other.live_region {
1503 self.live_region = Some(live_region);
1504 }
1505 self.merge_words(other);
1506 self.merge_actions(other);
1507 self.merge_ranges(other);
1508 }
1509
1510 fn merge_words(&mut self, other: &SemanticsConfiguration) {
1513 if let Some(title) = &other.pane_title {
1514 self.pane_title = Some(title.clone());
1515 }
1516 if let Some(error) = &other.error {
1517 self.error = Some(error.clone());
1518 }
1519 }
1520
1521 fn merge_actions(&mut self, other: &SemanticsConfiguration) {
1524 self.custom_actions
1525 .extend(other.custom_actions.iter().cloned());
1526 self.canvas_children
1527 .extend(other.canvas_children.iter().cloned());
1528 if let Some(set_progress) = &other.set_progress {
1529 self.set_progress = Some(set_progress.clone());
1530 }
1531 if let Some(set_text) = &other.set_text {
1532 self.set_text = Some(set_text.clone());
1533 }
1534 if let Some(expand) = &other.expand {
1535 self.expand = Some(expand.clone());
1536 }
1537 if let Some(collapse) = &other.collapse {
1538 self.collapse = Some(collapse.clone());
1539 }
1540 if let Some(dismiss) = &other.dismiss {
1541 self.dismiss = Some(dismiss.clone());
1542 }
1543 if let Some(long_click) = &other.on_long_click {
1544 self.on_long_click = Some(long_click.clone());
1545 }
1546 if let Some(scroll_by) = &other.scroll_by {
1547 self.scroll_by = Some(scroll_by.clone());
1548 }
1549 if let Some(scroll_to_index) = &other.scroll_to_index {
1550 self.scroll_to_index = Some(scroll_to_index.clone());
1551 }
1552 }
1553
1554 fn merge_ranges(&mut self, other: &SemanticsConfiguration) {
1557 if let Some(selection) = other.text_selection {
1558 self.text_selection = Some(selection);
1559 }
1560 if let Some(progress) = other.progress {
1561 self.progress = Some(progress);
1562 }
1563 if let Some(range) = other.vertical_scroll {
1564 self.vertical_scroll = Some(range);
1565 }
1566 if let Some(range) = other.horizontal_scroll {
1567 self.horizontal_scroll = Some(range);
1568 }
1569 if let Some(collection) = other.collection {
1570 self.collection = Some(collection);
1571 }
1572 }
1573
1574 pub fn is_activatable(&self) -> bool {
1577 self.is_clickable || self.on_click_label.is_some()
1578 }
1579}
1580
1581impl fmt::Debug for dyn ModifierNode {
1582 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1583 f.debug_struct("ModifierNode").finish_non_exhaustive()
1584 }
1585}
1586
1587impl dyn ModifierNode {
1588 pub fn as_any(&self) -> &dyn Any {
1589 self
1590 }
1591
1592 pub fn as_any_mut(&mut self) -> &mut dyn Any {
1593 self
1594 }
1595}
1596
1597pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
1600 type Node: ModifierNode;
1601
1602 fn create(&self) -> Self::Node;
1604
1605 fn update(&self, node: &mut Self::Node);
1607
1608 fn key(&self) -> Option<u64> {
1610 None
1611 }
1612
1613 fn inspector_name(&self) -> &'static str {
1615 type_name::<Self>()
1616 }
1617
1618 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
1620
1621 fn capabilities(&self) -> NodeCapabilities {
1624 NodeCapabilities::default()
1625 }
1626
1627 fn always_update(&self) -> bool {
1633 false
1634 }
1635
1636 fn auto_invalidate_on_update(&self) -> bool {
1639 true
1640 }
1641
1642 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1649 None
1650 }
1651}
1652
1653#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1655pub struct NodeCapabilities(u32);
1656
1657impl NodeCapabilities {
1658 pub const NONE: Self = Self(0);
1660 pub const LAYOUT: Self = Self(1 << 0);
1662 pub const DRAW: Self = Self(1 << 1);
1664 pub const POINTER_INPUT: Self = Self(1 << 2);
1666 pub const SEMANTICS: Self = Self(1 << 3);
1668 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1670 pub const FOCUS: Self = Self(1 << 5);
1672
1673 pub const fn empty() -> Self {
1675 Self::NONE
1676 }
1677
1678 pub const fn contains(self, other: Self) -> bool {
1680 (self.0 & other.0) == other.0
1681 }
1682
1683 pub const fn intersects(self, other: Self) -> bool {
1685 (self.0 & other.0) != 0
1686 }
1687
1688 pub fn insert(&mut self, other: Self) {
1690 self.0 |= other.0;
1691 }
1692
1693 pub const fn bits(self) -> u32 {
1695 self.0
1696 }
1697
1698 pub const fn is_empty(self) -> bool {
1700 self.0 == 0
1701 }
1702
1703 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1705 match kind {
1706 InvalidationKind::Layout => Self::LAYOUT,
1707 InvalidationKind::Draw => Self::DRAW,
1708 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1709 InvalidationKind::Semantics => Self::SEMANTICS,
1710 InvalidationKind::Focus => Self::FOCUS,
1711 }
1712 }
1713}
1714
1715impl Default for NodeCapabilities {
1716 fn default() -> Self {
1717 Self::NONE
1718 }
1719}
1720
1721impl fmt::Debug for NodeCapabilities {
1722 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1723 f.debug_struct("NodeCapabilities")
1724 .field("layout", &self.contains(Self::LAYOUT))
1725 .field("draw", &self.contains(Self::DRAW))
1726 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1727 .field("semantics", &self.contains(Self::SEMANTICS))
1728 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1729 .field("focus", &self.contains(Self::FOCUS))
1730 .finish()
1731 }
1732}
1733
1734impl BitOr for NodeCapabilities {
1735 type Output = Self;
1736
1737 fn bitor(self, rhs: Self) -> Self::Output {
1738 Self(self.0 | rhs.0)
1739 }
1740}
1741
1742impl BitOrAssign for NodeCapabilities {
1743 fn bitor_assign(&mut self, rhs: Self) {
1744 self.0 |= rhs.0;
1745 }
1746}
1747
1748#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1750pub struct ModifierInvalidation {
1751 kind: InvalidationKind,
1752 capabilities: NodeCapabilities,
1753}
1754
1755impl ModifierInvalidation {
1756 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1758 Self { kind, capabilities }
1759 }
1760
1761 pub const fn kind(self) -> InvalidationKind {
1763 self.kind
1764 }
1765
1766 pub const fn capabilities(self) -> NodeCapabilities {
1768 self.capabilities
1769 }
1770}
1771
1772pub trait AnyModifierElement: fmt::Debug {
1774 fn node_type(&self) -> TypeId;
1775
1776 fn element_type(&self) -> TypeId;
1777
1778 fn create_node(&self) -> Box<dyn ModifierNode>;
1779
1780 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
1781
1782 fn update_node(&self, node: &mut dyn ModifierNode);
1783
1784 fn key(&self) -> Option<u64>;
1785
1786 fn capabilities(&self) -> NodeCapabilities {
1787 NodeCapabilities::default()
1788 }
1789
1790 fn hash_code(&self) -> u64;
1791
1792 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
1793
1794 fn inspector_name(&self) -> &'static str;
1795
1796 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
1797
1798 fn requires_update(&self) -> bool;
1799
1800 fn auto_invalidates_on_update(&self) -> bool;
1801
1802 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
1803
1804 fn as_any(&self) -> &dyn Any;
1805}
1806
1807struct TypedModifierElement<E: ModifierNodeElement> {
1808 element: E,
1809 cached_hash: u64,
1810}
1811
1812impl<E: ModifierNodeElement> TypedModifierElement<E> {
1813 fn new(element: E) -> Self {
1814 let mut hasher = default::new();
1815 element.hash(&mut hasher);
1816 Self {
1817 element,
1818 cached_hash: hasher.finish(),
1819 }
1820 }
1821}
1822
1823impl<E> fmt::Debug for TypedModifierElement<E>
1824where
1825 E: ModifierNodeElement,
1826{
1827 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1828 f.debug_struct("TypedModifierElement")
1829 .field("type", &type_name::<E>())
1830 .finish()
1831 }
1832}
1833
1834impl<E> AnyModifierElement for TypedModifierElement<E>
1835where
1836 E: ModifierNodeElement,
1837{
1838 fn node_type(&self) -> TypeId {
1839 TypeId::of::<E::Node>()
1840 }
1841
1842 fn element_type(&self) -> TypeId {
1843 TypeId::of::<E>()
1844 }
1845
1846 fn create_node(&self) -> Box<dyn ModifierNode> {
1847 Box::new(self.element.create())
1848 }
1849
1850 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
1851 node.as_any().is::<E::Node>()
1852 }
1853
1854 fn update_node(&self, node: &mut dyn ModifierNode) {
1855 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
1856 self.element.update(typed);
1857 }
1858 }
1859
1860 fn key(&self) -> Option<u64> {
1861 self.element.key()
1862 }
1863
1864 fn capabilities(&self) -> NodeCapabilities {
1865 self.element.capabilities()
1866 }
1867
1868 fn hash_code(&self) -> u64 {
1869 self.cached_hash
1870 }
1871
1872 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
1873 other
1874 .as_any()
1875 .downcast_ref::<Self>()
1876 .map(|typed| typed.element == self.element)
1877 .unwrap_or(false)
1878 }
1879
1880 fn inspector_name(&self) -> &'static str {
1881 self.element.inspector_name()
1882 }
1883
1884 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
1885 self.element.inspector_properties(visitor);
1886 }
1887
1888 fn requires_update(&self) -> bool {
1889 self.element.always_update()
1890 }
1891
1892 fn auto_invalidates_on_update(&self) -> bool {
1893 self.element.auto_invalidate_on_update()
1894 }
1895
1896 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1897 self.element.update_invalidation_kind()
1898 }
1899
1900 fn as_any(&self) -> &dyn Any {
1901 self
1902 }
1903}
1904
1905fn request_update_auto_invalidations(
1906 element: &dyn AnyModifierElement,
1907 context: &mut dyn ModifierNodeContext,
1908 capabilities: NodeCapabilities,
1909) {
1910 if let Some(kind) = element.update_invalidation_kind() {
1911 let capabilities = NodeCapabilities::for_invalidation(kind);
1912 context.push_active_capabilities(capabilities);
1913 context.invalidate(kind);
1914 context.pop_active_capabilities();
1915 } else if element.auto_invalidates_on_update() {
1916 request_auto_invalidations(context, capabilities);
1917 }
1918}
1919
1920pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
1923 Rc::new(TypedModifierElement::new(element))
1924}
1925
1926pub type DynModifierElement = Rc<dyn AnyModifierElement>;
1928
1929#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1930enum TraversalDirection {
1931 Forward,
1932 Backward,
1933}
1934
1935pub struct ModifierChainIter<'a> {
1940 chain: &'a ModifierNodeChain,
1941 cursor: usize,
1942 remaining: usize,
1943 direction: TraversalDirection,
1944}
1945
1946impl<'a> ModifierChainIter<'a> {
1947 fn forward(chain: &'a ModifierNodeChain) -> Self {
1948 Self {
1949 chain,
1950 cursor: 0,
1951 remaining: chain.ordered_nodes.len(),
1952 direction: TraversalDirection::Forward,
1953 }
1954 }
1955
1956 fn backward(chain: &'a ModifierNodeChain) -> Self {
1957 let len = chain.ordered_nodes.len();
1958 Self {
1959 chain,
1960 cursor: len.wrapping_sub(1),
1961 remaining: len,
1962 direction: TraversalDirection::Backward,
1963 }
1964 }
1965}
1966
1967impl<'a> Iterator for ModifierChainIter<'a> {
1968 type Item = ModifierChainNodeRef<'a>;
1969
1970 #[inline]
1971 fn next(&mut self) -> Option<Self::Item> {
1972 if self.remaining == 0 {
1973 return None;
1974 }
1975 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
1976 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
1977 self.remaining -= 1;
1978 match self.direction {
1979 TraversalDirection::Forward => self.cursor += 1,
1980 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
1981 }
1982 Some(node_ref)
1983 }
1984
1985 #[inline]
1986 fn size_hint(&self) -> (usize, Option<usize>) {
1987 (self.remaining, Some(self.remaining))
1988 }
1989}
1990
1991impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
1992impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
1993
1994#[derive(Debug)]
1995struct ModifierNodeEntry {
1996 element_type: TypeId,
1997 node_type: TypeId,
1998 key: Option<u64>,
1999 hash_code: u64,
2000 element: DynModifierElement,
2001 node: Rc<RefCell<Box<dyn ModifierNode>>>,
2002 capabilities: NodeCapabilities,
2003}
2004
2005impl ModifierNodeEntry {
2006 fn new(
2007 element_type: TypeId,
2008 node_type: TypeId,
2009 key: Option<u64>,
2010 element: DynModifierElement,
2011 node: Box<dyn ModifierNode>,
2012 hash_code: u64,
2013 capabilities: NodeCapabilities,
2014 ) -> Self {
2015 let node_rc = Rc::new(RefCell::new(node));
2016 let entry = Self {
2017 element_type,
2018 node_type,
2019 key,
2020 hash_code,
2021 element,
2022 node: Rc::clone(&node_rc),
2023 capabilities,
2024 };
2025 entry
2026 .node
2027 .borrow()
2028 .node_state()
2029 .set_capabilities(entry.capabilities);
2030 entry
2031 }
2032}
2033
2034fn visit_node_tree_mut(
2035 node: &mut dyn ModifierNode,
2036 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
2037) {
2038 visitor(node);
2039 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
2040}
2041
2042fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
2043 let mut current = 0usize;
2044 let mut result: Option<&dyn ModifierNode> = None;
2045 node.for_each_delegate(&mut |child| {
2046 if result.is_none() && current == target {
2047 result = Some(child);
2048 }
2049 current += 1;
2050 });
2051 result
2052}
2053
2054fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
2055 let mut current = 0usize;
2056 let mut result: Option<&mut dyn ModifierNode> = None;
2057 node.for_each_delegate_mut(&mut |child| {
2058 if result.is_none() && current == target {
2059 result = Some(child);
2060 }
2061 current += 1;
2062 });
2063 result
2064}
2065
2066fn with_node_context<F, R>(
2067 node: &mut dyn ModifierNode,
2068 context: &mut dyn ModifierNodeContext,
2069 f: F,
2070) -> R
2071where
2072 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
2073{
2074 context.push_active_capabilities(node.node_state().capabilities());
2075 let result = f(node, context);
2076 context.pop_active_capabilities();
2077 result
2078}
2079
2080fn request_auto_invalidations(
2081 context: &mut dyn ModifierNodeContext,
2082 capabilities: NodeCapabilities,
2083) {
2084 if capabilities.is_empty() {
2085 return;
2086 }
2087
2088 context.push_active_capabilities(capabilities);
2089
2090 if capabilities.contains(NodeCapabilities::LAYOUT) {
2091 context.invalidate(InvalidationKind::Layout);
2092 }
2093 if capabilities.contains(NodeCapabilities::DRAW) {
2094 context.invalidate(InvalidationKind::Draw);
2095 }
2096 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
2097 context.invalidate(InvalidationKind::PointerInput);
2098 }
2099 if capabilities.contains(NodeCapabilities::SEMANTICS) {
2100 context.invalidate(InvalidationKind::Semantics);
2101 }
2102 if capabilities.contains(NodeCapabilities::FOCUS) {
2103 context.invalidate(InvalidationKind::Focus);
2104 }
2105
2106 context.pop_active_capabilities();
2107}
2108
2109fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
2117 visit_node_tree_mut(node, &mut |n| {
2118 if !n.node_state().is_attached() {
2119 n.node_state().set_attached(true);
2120 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
2121 }
2122 });
2123}
2124
2125fn reset_node_tree(node: &mut dyn ModifierNode) {
2126 visit_node_tree_mut(node, &mut |n| n.on_reset());
2127}
2128
2129fn detach_node_tree(node: &mut dyn ModifierNode) {
2130 visit_node_tree_mut(node, &mut |n| {
2131 if n.node_state().is_attached() {
2132 n.on_detach();
2133 n.node_state().set_attached(false);
2134 }
2135 n.node_state().set_parent_link(None);
2136 n.node_state().set_child_link(None);
2137 n.node_state()
2138 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2139 });
2140}
2141
2142pub struct ModifierNodeChain {
2149 entries: Vec<ModifierNodeEntry>,
2150 aggregated_capabilities: NodeCapabilities,
2151 head_aggregate_child_capabilities: NodeCapabilities,
2152 head_sentinel: Box<SentinelNode>,
2153 tail_sentinel: Box<SentinelNode>,
2154 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2155 scratch_old_used: Vec<bool>,
2156 scratch_match_order: Vec<Option<usize>>,
2157 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
2158 scratch_elements: Vec<DynModifierElement>,
2159}
2160
2161struct SentinelNode {
2162 state: NodeState,
2163}
2164
2165impl SentinelNode {
2166 fn new() -> Self {
2167 Self {
2168 state: NodeState::sentinel(),
2169 }
2170 }
2171}
2172
2173impl DelegatableNode for SentinelNode {
2174 fn node_state(&self) -> &NodeState {
2175 &self.state
2176 }
2177}
2178
2179impl ModifierNode for SentinelNode {}
2180
2181#[derive(Clone)]
2182pub struct ModifierChainNodeRef<'a> {
2183 chain: &'a ModifierNodeChain,
2184 link: NodeLink,
2185 cached_capabilities: Option<NodeCapabilities>,
2186 cached_aggregate_child: Option<NodeCapabilities>,
2187}
2188
2189impl Default for ModifierNodeChain {
2190 fn default() -> Self {
2191 Self::new()
2192 }
2193}
2194
2195struct EntryIndex {
2200 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2201 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2202 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
2203}
2204
2205struct EntryMatchQuery<'a> {
2206 element_type: TypeId,
2207 node_type: TypeId,
2208 key: Option<u64>,
2209 hash_code: u64,
2210 element: &'a DynModifierElement,
2211}
2212
2213impl EntryIndex {
2214 fn build(entries: &[ModifierNodeEntry]) -> Self {
2215 let mut keyed = HashMap::default();
2216 let mut hashed = HashMap::default();
2217 let mut typed = HashMap::default();
2218
2219 for (i, entry) in entries.iter().enumerate() {
2220 if let Some(key_value) = entry.key {
2221 keyed
2222 .entry((entry.element_type, entry.node_type, key_value))
2223 .or_insert_with(Vec::new)
2224 .push(i);
2225 } else {
2226 hashed
2227 .entry((entry.element_type, entry.node_type, entry.hash_code))
2228 .or_insert_with(Vec::new)
2229 .push(i);
2230 typed
2231 .entry((entry.element_type, entry.node_type))
2232 .or_insert_with(Vec::new)
2233 .push(i);
2234 }
2235 }
2236
2237 Self {
2238 keyed,
2239 hashed,
2240 typed,
2241 }
2242 }
2243
2244 fn find_match(
2245 &self,
2246 entries: &[ModifierNodeEntry],
2247 used: &[bool],
2248 query: EntryMatchQuery<'_>,
2249 ) -> Option<usize> {
2250 if let Some(key_value) = query.key {
2251 if let Some(candidates) =
2252 self.keyed
2253 .get(&(query.element_type, query.node_type, key_value))
2254 {
2255 for &i in candidates {
2256 if !used[i] {
2257 return Some(i);
2258 }
2259 }
2260 }
2261 } else {
2262 if let Some(candidates) =
2263 self.hashed
2264 .get(&(query.element_type, query.node_type, query.hash_code))
2265 {
2266 for &i in candidates {
2267 if !used[i]
2268 && entries[i]
2269 .element
2270 .as_ref()
2271 .equals_element(query.element.as_ref())
2272 {
2273 return Some(i);
2274 }
2275 }
2276 }
2277
2278 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
2279 for &i in candidates {
2280 if !used[i] {
2281 return Some(i);
2282 }
2283 }
2284 }
2285 }
2286
2287 None
2288 }
2289}
2290
2291impl ModifierNodeChain {
2292 pub fn new() -> Self {
2293 let mut chain = Self {
2294 entries: Vec::new(),
2295 aggregated_capabilities: NodeCapabilities::empty(),
2296 head_aggregate_child_capabilities: NodeCapabilities::empty(),
2297 head_sentinel: Box::new(SentinelNode::new()),
2298 tail_sentinel: Box::new(SentinelNode::new()),
2299 ordered_nodes: Vec::new(),
2300 scratch_old_used: Vec::new(),
2301 scratch_match_order: Vec::new(),
2302 scratch_final_slots: Vec::new(),
2303 scratch_elements: Vec::new(),
2304 };
2305 chain.sync_chain_links();
2306 chain
2307 }
2308
2309 pub fn detach_nodes(&mut self) {
2311 for entry in &self.entries {
2312 detach_node_tree(&mut **entry.node.borrow_mut());
2313 }
2314 }
2315
2316 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
2318 for entry in &self.entries {
2319 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2320 }
2321 }
2322
2323 pub fn repair_chain(&mut self) {
2326 self.sync_chain_links();
2327 }
2328
2329 pub fn update_from_slice(
2335 &mut self,
2336 elements: &[DynModifierElement],
2337 context: &mut dyn ModifierNodeContext,
2338 ) {
2339 self.update_from_ref_iter(elements.iter(), context);
2340 }
2341
2342 pub fn update_from_ref_iter<'a, I>(
2347 &mut self,
2348 elements: I,
2349 context: &mut dyn ModifierNodeContext,
2350 ) where
2351 I: Iterator<Item = &'a DynModifierElement>,
2352 {
2353 let old_len = self.entries.len();
2354 let mut fast_path_failed_at: Option<usize> = None;
2355 let mut elements_count = 0;
2356
2357 self.scratch_elements.clear();
2358
2359 for (idx, element) in elements.enumerate() {
2360 elements_count = idx + 1;
2361
2362 if fast_path_failed_at.is_none() && idx < old_len {
2363 let entry = &mut self.entries[idx];
2364 let same_type = entry.element_type == element.element_type();
2365 let same_node_type = entry.node_type == element.node_type();
2366 let same_key = entry.key == element.key();
2367 let same_hash = entry.hash_code == element.hash_code();
2368
2369 let positional_update = element.requires_update();
2370 if same_type && same_node_type && same_key && (same_hash || positional_update) {
2371 let can_update_node = {
2372 let node_borrow = entry.node.borrow();
2373 element.can_update_node(&**node_borrow)
2374 };
2375 if !can_update_node {
2376 fast_path_failed_at = Some(idx);
2377 self.scratch_elements.push(element.clone());
2378 continue;
2379 }
2380
2381 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2382 let capabilities = element.capabilities();
2383
2384 {
2385 let node_borrow = entry.node.borrow();
2386 if !node_borrow.node_state().is_attached() {
2387 drop(node_borrow);
2388 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2389 }
2390 }
2391
2392 let needs_update = !same_element || element.requires_update();
2393 if needs_update {
2394 element.update_node(&mut **entry.node.borrow_mut());
2395 entry.element = element.clone();
2396 entry.hash_code = element.hash_code();
2397 request_update_auto_invalidations(element.as_ref(), context, capabilities);
2398 }
2399
2400 entry.capabilities = capabilities;
2401 entry
2402 .node
2403 .borrow()
2404 .node_state()
2405 .set_capabilities(capabilities);
2406 continue;
2407 }
2408 fast_path_failed_at = Some(idx);
2409 }
2410
2411 self.scratch_elements.push(element.clone());
2412 }
2413
2414 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
2415 if elements_count < self.entries.len() {
2416 for entry in self.entries.drain(elements_count..) {
2417 request_auto_invalidations(context, entry.capabilities);
2418 detach_node_tree(&mut **entry.node.borrow_mut());
2419 }
2420 }
2421 self.sync_chain_links();
2422 return;
2423 }
2424
2425 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
2426
2427 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
2428 let processed_entries_len = self.entries.len();
2429 let old_len = old_entries.len();
2430
2431 self.scratch_old_used.clear();
2432 self.scratch_old_used.resize(old_len, false);
2433
2434 self.scratch_match_order.clear();
2435 self.scratch_match_order.resize(old_len, None);
2436
2437 let index = EntryIndex::build(&old_entries);
2438
2439 let new_elements_count = self.scratch_elements.len();
2440 self.scratch_final_slots.clear();
2441 self.scratch_final_slots.reserve(new_elements_count);
2442
2443 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
2444 self.scratch_final_slots.push(None);
2445 let element_type = element.element_type();
2446 let node_type = element.node_type();
2447 let key = element.key();
2448 let hash_code = element.hash_code();
2449 let capabilities = element.capabilities();
2450
2451 let matched_idx = index.find_match(
2452 &old_entries,
2453 &self.scratch_old_used,
2454 EntryMatchQuery {
2455 element_type,
2456 node_type,
2457 key,
2458 hash_code,
2459 element: &element,
2460 },
2461 );
2462
2463 if let Some(idx) = matched_idx {
2464 let entry = &mut old_entries[idx];
2465 let can_update_node = {
2466 let node_borrow = entry.node.borrow();
2467 element.can_update_node(&**node_borrow)
2468 };
2469 if !can_update_node {
2470 let replacement = ModifierNodeEntry::new(
2471 element_type,
2472 node_type,
2473 key,
2474 element.clone(),
2475 element.create_node(),
2476 hash_code,
2477 capabilities,
2478 );
2479 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
2480 element.update_node(&mut **replacement.node.borrow_mut());
2481 request_auto_invalidations(context, capabilities);
2482 self.scratch_final_slots[new_pos] = Some(replacement);
2483 continue;
2484 }
2485
2486 self.scratch_old_used[idx] = true;
2487 self.scratch_match_order[idx] = Some(new_pos);
2488 let moved = idx != new_pos;
2489
2490 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2491
2492 {
2493 let node_borrow = entry.node.borrow();
2494 if !node_borrow.node_state().is_attached() {
2495 drop(node_borrow);
2496 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2497 }
2498 }
2499
2500 let needs_update = !same_element || element.requires_update();
2501 if needs_update {
2502 element.update_node(&mut **entry.node.borrow_mut());
2503 entry.element = element;
2504 entry.hash_code = hash_code;
2505 request_update_auto_invalidations(
2506 entry.element.as_ref(),
2507 context,
2508 capabilities,
2509 );
2510 }
2511 if moved {
2512 request_auto_invalidations(context, capabilities);
2513 }
2514
2515 entry.key = key;
2516 entry.element_type = element_type;
2517 entry.node_type = node_type;
2518 entry.capabilities = capabilities;
2519 entry
2520 .node
2521 .borrow()
2522 .node_state()
2523 .set_capabilities(capabilities);
2524 } else {
2525 let entry = ModifierNodeEntry::new(
2526 element_type,
2527 node_type,
2528 key,
2529 element.clone(),
2530 element.create_node(),
2531 hash_code,
2532 capabilities,
2533 );
2534 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2535 element.update_node(&mut **entry.node.borrow_mut());
2536 request_auto_invalidations(context, capabilities);
2537 self.scratch_final_slots[new_pos] = Some(entry);
2538 }
2539 }
2540
2541 for (i, entry) in old_entries.into_iter().enumerate() {
2542 if self.scratch_old_used[i] {
2543 if let Some(pos) = self.scratch_match_order[i] {
2544 self.scratch_final_slots[pos] = Some(entry);
2545 } else {
2546 request_auto_invalidations(context, entry.capabilities);
2547 detach_node_tree(&mut **entry.node.borrow_mut());
2548 }
2549 } else {
2550 request_auto_invalidations(context, entry.capabilities);
2551 detach_node_tree(&mut **entry.node.borrow_mut());
2552 }
2553 }
2554
2555 self.entries.reserve(self.scratch_final_slots.len());
2556 for slot in self.scratch_final_slots.drain(..) {
2557 if let Some(entry) = slot {
2558 self.entries.push(entry);
2559 } else {
2560 log::error!("modifier reconciliation produced an empty final slot");
2561 }
2562 }
2563
2564 debug_assert_eq!(
2565 self.entries.len(),
2566 processed_entries_len + new_elements_count
2567 );
2568 self.sync_chain_links();
2569 }
2570
2571 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2575 where
2576 I: IntoIterator<Item = DynModifierElement>,
2577 {
2578 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2579 self.update_from_slice(&collected, context);
2580 }
2581
2582 pub fn reset(&mut self) {
2585 for entry in &mut self.entries {
2586 reset_node_tree(&mut **entry.node.borrow_mut());
2587 }
2588 }
2589
2590 pub fn detach_all(&mut self) {
2592 for entry in std::mem::take(&mut self.entries) {
2593 detach_node_tree(&mut **entry.node.borrow_mut());
2594 {
2595 let node_borrow = entry.node.borrow();
2596 let state = node_borrow.node_state();
2597 state.set_capabilities(NodeCapabilities::empty());
2598 }
2599 }
2600 self.aggregated_capabilities = NodeCapabilities::empty();
2601 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2602 self.ordered_nodes.clear();
2603 self.sync_chain_links();
2604 }
2605
2606 pub fn len(&self) -> usize {
2607 self.entries.len()
2608 }
2609
2610 pub fn is_empty(&self) -> bool {
2611 self.entries.is_empty()
2612 }
2613
2614 pub fn capabilities(&self) -> NodeCapabilities {
2616 self.aggregated_capabilities
2617 }
2618
2619 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2621 self.aggregated_capabilities.contains(capability)
2622 }
2623
2624 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2626 self.make_node_ref(NodeLink::Head)
2627 }
2628
2629 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2631 self.make_node_ref(NodeLink::Tail)
2632 }
2633
2634 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2636 ModifierChainIter::forward(self)
2637 }
2638
2639 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2641 ModifierChainIter::backward(self)
2642 }
2643
2644 pub fn for_each_forward<F>(&self, mut f: F)
2646 where
2647 F: FnMut(ModifierChainNodeRef<'_>),
2648 {
2649 for node in self.head_to_tail() {
2650 f(node);
2651 }
2652 }
2653
2654 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2656 where
2657 F: FnMut(ModifierChainNodeRef<'_>),
2658 {
2659 if mask.is_empty() {
2660 self.for_each_forward(f);
2661 return;
2662 }
2663
2664 if !self.head().aggregate_child_capabilities().intersects(mask) {
2665 return;
2666 }
2667
2668 for node in self.head_to_tail() {
2669 if node.kind_set().intersects(mask) {
2670 f(node);
2671 }
2672 }
2673 }
2674
2675 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2677 where
2678 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2679 {
2680 self.for_each_forward_matching(mask, |node_ref| {
2681 node_ref.with_node(|node| f(node_ref.clone(), node));
2682 });
2683 }
2684
2685 pub fn for_each_backward<F>(&self, mut f: F)
2687 where
2688 F: FnMut(ModifierChainNodeRef<'_>),
2689 {
2690 for node in self.tail_to_head() {
2691 f(node);
2692 }
2693 }
2694
2695 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2697 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2698 node as *const dyn ModifierNode as *const ()
2699 }
2700
2701 let target = node_data_ptr(node);
2702 for (index, entry) in self.entries.iter().enumerate() {
2703 if node_data_ptr(&**entry.node.borrow()) == target {
2704 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2705 }
2706 }
2707
2708 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2709 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2710 return None;
2711 }
2712 let matches_target = match link {
2713 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2714 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2715 NodeLink::Entry(path) => {
2716 let node_borrow = self.entries[path.entry()].node.borrow();
2717 node_data_ptr(&**node_borrow) == target
2718 }
2719 };
2720 if matches_target {
2721 Some(self.make_node_ref(*link))
2722 } else {
2723 None
2724 }
2725 })
2726 }
2727
2728 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2731 self.entries.get(index).and_then(|entry| {
2732 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2733 boxed_node.as_any().downcast_ref::<N>()
2734 })
2735 .ok()
2736 })
2737 }
2738
2739 pub fn node_mut<N: ModifierNode + 'static>(
2742 &self,
2743 index: usize,
2744 ) -> Option<std::cell::RefMut<'_, N>> {
2745 self.entries.get(index).and_then(|entry| {
2746 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2747 boxed_node.as_any_mut().downcast_mut::<N>()
2748 })
2749 .ok()
2750 })
2751 }
2752
2753 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2756 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
2757 }
2758
2759 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
2761 self.aggregated_capabilities
2762 .contains(NodeCapabilities::for_invalidation(kind))
2763 }
2764
2765 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
2767 where
2768 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
2769 {
2770 for index in 0..self.ordered_nodes.len() {
2771 let (link, cached_caps, _agg) = self.ordered_nodes[index];
2772 match link {
2773 NodeLink::Head => {
2774 f(self.head_sentinel.as_mut(), cached_caps);
2775 }
2776 NodeLink::Tail => {
2777 f(self.tail_sentinel.as_mut(), cached_caps);
2778 }
2779 NodeLink::Entry(path) => {
2780 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
2781 if path.delegates().is_empty() {
2782 f(&mut **node_borrow, cached_caps);
2783 } else {
2784 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
2785 for &delegate_index in path.delegates() {
2786 if let Some(delegate) =
2787 nth_delegate_mut(current, delegate_index as usize)
2788 {
2789 current = delegate;
2790 } else {
2791 return;
2792 }
2793 }
2794 f(current, cached_caps);
2795 }
2796 }
2797 }
2798 }
2799 }
2800
2801 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2802 ModifierChainNodeRef {
2803 chain: self,
2804 link,
2805 cached_capabilities: None,
2806 cached_aggregate_child: None,
2807 }
2808 }
2809
2810 fn make_node_ref_with_caps(
2811 &self,
2812 link: NodeLink,
2813 caps: NodeCapabilities,
2814 aggregate_child: NodeCapabilities,
2815 ) -> ModifierChainNodeRef<'_> {
2816 ModifierChainNodeRef {
2817 chain: self,
2818 link,
2819 cached_capabilities: Some(caps),
2820 cached_aggregate_child: Some(aggregate_child),
2821 }
2822 }
2823
2824 fn sync_chain_links(&mut self) {
2825 self.rebuild_ordered_nodes();
2826
2827 self.head_sentinel.node_state().set_parent_link(None);
2828 self.tail_sentinel.node_state().set_child_link(None);
2829
2830 if self.ordered_nodes.is_empty() {
2831 self.head_sentinel
2832 .node_state()
2833 .set_child_link(Some(NodeLink::Tail));
2834 self.tail_sentinel
2835 .node_state()
2836 .set_parent_link(Some(NodeLink::Head));
2837 self.aggregated_capabilities = NodeCapabilities::empty();
2838 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2839 self.head_sentinel
2840 .node_state()
2841 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2842 self.tail_sentinel
2843 .node_state()
2844 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2845 return;
2846 }
2847
2848 let mut previous = NodeLink::Head;
2849 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
2850 match &previous {
2851 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
2852 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
2853 NodeLink::Entry(path) => {
2854 let node_borrow = self.entries[path.entry()].node.borrow();
2855 if path.delegates().is_empty() {
2856 node_borrow.node_state().set_child_link(Some(link));
2857 } else {
2858 let mut current: &dyn ModifierNode = &**node_borrow;
2859 for &delegate_index in path.delegates() {
2860 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2861 current = delegate;
2862 }
2863 }
2864 current.node_state().set_child_link(Some(link));
2865 }
2866 }
2867 }
2868 match &link {
2869 NodeLink::Head => self
2870 .head_sentinel
2871 .node_state()
2872 .set_parent_link(Some(previous)),
2873 NodeLink::Tail => self
2874 .tail_sentinel
2875 .node_state()
2876 .set_parent_link(Some(previous)),
2877 NodeLink::Entry(path) => {
2878 let node_borrow = self.entries[path.entry()].node.borrow();
2879 if path.delegates().is_empty() {
2880 node_borrow.node_state().set_parent_link(Some(previous));
2881 } else {
2882 let mut current: &dyn ModifierNode = &**node_borrow;
2883 for &delegate_index in path.delegates() {
2884 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2885 current = delegate;
2886 }
2887 }
2888 current.node_state().set_parent_link(Some(previous));
2889 }
2890 }
2891 }
2892 previous = link;
2893 }
2894
2895 match &previous {
2896 NodeLink::Head => self
2897 .head_sentinel
2898 .node_state()
2899 .set_child_link(Some(NodeLink::Tail)),
2900 NodeLink::Tail => self
2901 .tail_sentinel
2902 .node_state()
2903 .set_child_link(Some(NodeLink::Tail)),
2904 NodeLink::Entry(path) => {
2905 let node_borrow = self.entries[path.entry()].node.borrow();
2906 if path.delegates().is_empty() {
2907 node_borrow
2908 .node_state()
2909 .set_child_link(Some(NodeLink::Tail));
2910 } else {
2911 let mut current: &dyn ModifierNode = &**node_borrow;
2912 for &delegate_index in path.delegates() {
2913 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2914 current = delegate;
2915 }
2916 }
2917 current.node_state().set_child_link(Some(NodeLink::Tail));
2918 }
2919 }
2920 }
2921 self.tail_sentinel
2922 .node_state()
2923 .set_parent_link(Some(previous));
2924 self.tail_sentinel.node_state().set_child_link(None);
2925
2926 let mut aggregate = NodeCapabilities::empty();
2927 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
2928 aggregate |= *cached_caps;
2929 *cached_aggregate = aggregate;
2930 match link {
2931 NodeLink::Head => {
2932 self.head_sentinel
2933 .node_state()
2934 .set_aggregate_child_capabilities(aggregate);
2935 }
2936 NodeLink::Tail => {
2937 self.tail_sentinel
2938 .node_state()
2939 .set_aggregate_child_capabilities(aggregate);
2940 }
2941 NodeLink::Entry(path) => {
2942 let node_borrow = self.entries[path.entry()].node.borrow();
2943 let state = if path.delegates().is_empty() {
2944 node_borrow.node_state()
2945 } else {
2946 let mut current: &dyn ModifierNode = &**node_borrow;
2947 for &delegate_index in path.delegates() {
2948 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2949 current = delegate;
2950 }
2951 }
2952 current.node_state()
2953 };
2954 state.set_aggregate_child_capabilities(aggregate);
2955 }
2956 }
2957 }
2958
2959 self.aggregated_capabilities = aggregate;
2960 self.head_aggregate_child_capabilities = aggregate;
2961 self.head_sentinel
2962 .node_state()
2963 .set_aggregate_child_capabilities(aggregate);
2964 self.tail_sentinel
2965 .node_state()
2966 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2967 }
2968
2969 fn rebuild_ordered_nodes(&mut self) {
2970 self.ordered_nodes.clear();
2971 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
2972 for (index, entry) in self.entries.iter().enumerate() {
2973 let node_borrow = entry.node.borrow();
2974 Self::enumerate_link_order(
2975 &**node_borrow,
2976 index,
2977 &mut path_buf,
2978 0,
2979 &mut self.ordered_nodes,
2980 );
2981 }
2982 }
2983
2984 fn enumerate_link_order(
2985 node: &dyn ModifierNode,
2986 entry: usize,
2987 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
2988 path_len: usize,
2989 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2990 ) {
2991 let caps = node.node_state().capabilities();
2992 out.push((
2993 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
2994 caps,
2995 NodeCapabilities::empty(),
2996 ));
2997 let mut delegate_index = 0usize;
2998 node.for_each_delegate(&mut |child| {
2999 if path_len < MAX_DELEGATE_DEPTH {
3000 path_buf[path_len] = delegate_index;
3001 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
3002 }
3003 delegate_index += 1;
3004 });
3005 }
3006}
3007
3008impl<'a> ModifierChainNodeRef<'a> {
3009 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
3010 match &self.link {
3011 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
3012 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
3013 NodeLink::Entry(path) => {
3014 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3015 if path.delegates().is_empty() {
3016 f(node_borrow.node_state())
3017 } else {
3018 let mut current: &dyn ModifierNode = &**node_borrow;
3019 for &delegate_index in path.delegates() {
3020 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
3021 current = delegate;
3022 } else {
3023 return f(node_borrow.node_state());
3024 }
3025 }
3026 f(current.node_state())
3027 }
3028 }
3029 }
3030 }
3031
3032 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
3035 match &self.link {
3036 NodeLink::Head => None,
3037 NodeLink::Tail => None,
3038 NodeLink::Entry(path) => {
3039 let node_borrow = self.chain.entries[path.entry()].node.borrow();
3040 if path.delegates().is_empty() {
3041 Some(f(&**node_borrow))
3042 } else {
3043 let mut current: &dyn ModifierNode = &**node_borrow;
3044 for &delegate_index in path.delegates() {
3045 current = nth_delegate(current, delegate_index as usize)?;
3046 }
3047 Some(f(current))
3048 }
3049 }
3050 }
3051 }
3052
3053 #[inline]
3055 pub fn parent(&self) -> Option<Self> {
3056 self.with_state(|state| state.parent_link())
3057 .map(|link| self.chain.make_node_ref(link))
3058 }
3059
3060 #[inline]
3062 pub fn child(&self) -> Option<Self> {
3063 self.with_state(|state| state.child_link())
3064 .map(|link| self.chain.make_node_ref(link))
3065 }
3066
3067 #[inline]
3069 pub fn kind_set(&self) -> NodeCapabilities {
3070 if let Some(caps) = self.cached_capabilities {
3071 return caps;
3072 }
3073 match &self.link {
3074 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
3075 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
3076 }
3077 }
3078
3079 pub fn entry_index(&self) -> Option<usize> {
3081 match &self.link {
3082 NodeLink::Entry(path) => Some(path.entry()),
3083 _ => None,
3084 }
3085 }
3086
3087 pub fn delegate_depth(&self) -> usize {
3089 match &self.link {
3090 NodeLink::Entry(path) => path.delegates().len(),
3091 _ => 0,
3092 }
3093 }
3094
3095 #[inline]
3097 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
3098 if let Some(agg) = self.cached_aggregate_child {
3099 return agg;
3100 }
3101 if self.is_tail() {
3102 NodeCapabilities::empty()
3103 } else {
3104 self.with_state(|state| state.aggregate_child_capabilities())
3105 }
3106 }
3107
3108 pub fn is_head(&self) -> bool {
3110 matches!(self.link, NodeLink::Head)
3111 }
3112
3113 pub fn is_tail(&self) -> bool {
3115 matches!(self.link, NodeLink::Tail)
3116 }
3117
3118 pub fn is_sentinel(&self) -> bool {
3120 matches!(self.link, NodeLink::Head | NodeLink::Tail)
3121 }
3122
3123 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
3125 !mask.is_empty() && self.kind_set().intersects(mask)
3126 }
3127
3128 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
3130 where
3131 F: FnMut(ModifierChainNodeRef<'a>),
3132 {
3133 let mut current = if include_self {
3134 Some(self)
3135 } else {
3136 self.child()
3137 };
3138 while let Some(node) = current {
3139 if node.is_tail() {
3140 break;
3141 }
3142 if !node.is_sentinel() {
3143 f(node.clone());
3144 }
3145 current = node.child();
3146 }
3147 }
3148
3149 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3151 where
3152 F: FnMut(ModifierChainNodeRef<'a>),
3153 {
3154 if mask.is_empty() {
3155 self.visit_descendants(include_self, f);
3156 return;
3157 }
3158
3159 if !self.aggregate_child_capabilities().intersects(mask) {
3160 return;
3161 }
3162
3163 self.visit_descendants(include_self, |node| {
3164 if node.kind_set().intersects(mask) {
3165 f(node);
3166 }
3167 });
3168 }
3169
3170 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
3172 where
3173 F: FnMut(ModifierChainNodeRef<'a>),
3174 {
3175 let mut current = if include_self {
3176 Some(self)
3177 } else {
3178 self.parent()
3179 };
3180 while let Some(node) = current {
3181 if node.is_head() {
3182 break;
3183 }
3184 f(node.clone());
3185 current = node.parent();
3186 }
3187 }
3188
3189 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3191 where
3192 F: FnMut(ModifierChainNodeRef<'a>),
3193 {
3194 if mask.is_empty() {
3195 self.visit_ancestors(include_self, f);
3196 return;
3197 }
3198
3199 self.visit_ancestors(include_self, |node| {
3200 if node.kind_set().intersects(mask) {
3201 f(node);
3202 }
3203 });
3204 }
3205}
3206
3207#[cfg(test)]
3208#[path = "tests/modifier_tests.rs"]
3209mod tests;