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 SemanticsSetProgress {
825 handler: Rc<dyn Fn(f32) -> bool>,
826}
827
828impl SemanticsSetProgress {
829 pub fn new(handler: impl Fn(f32) -> bool + 'static) -> Self {
830 Self {
831 handler: Rc::new(handler),
832 }
833 }
834
835 pub fn invoke(&self, value: f32) -> bool {
836 (self.handler)(value)
837 }
838}
839
840impl fmt::Debug for SemanticsSetProgress {
841 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
842 f.debug_struct("SemanticsSetProgress")
843 .finish_non_exhaustive()
844 }
845}
846
847#[derive(Clone)]
851pub struct SemanticsSetText(Rc<dyn Fn(&str) -> bool>);
852
853impl SemanticsSetText {
854 pub fn new(handler: impl Fn(&str) -> bool + 'static) -> Self {
855 Self(Rc::new(handler))
856 }
857
858 pub fn invoke(&self, text: &str) -> bool {
859 (self.0)(text)
860 }
861}
862
863impl fmt::Debug for SemanticsSetText {
864 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
865 f.write_str("SemanticsSetText")
866 }
867}
868
869#[derive(Clone)]
872pub struct SemanticsExpand(Rc<dyn Fn() -> bool>);
873
874impl SemanticsExpand {
875 pub fn new(handler: impl Fn() -> bool + 'static) -> Self {
876 Self(Rc::new(handler))
877 }
878
879 pub fn invoke(&self) -> bool {
880 (self.0)()
881 }
882}
883
884impl fmt::Debug for SemanticsExpand {
885 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
886 f.write_str("SemanticsExpand")
887 }
888}
889
890impl PartialEq for SemanticsExpand {
891 fn eq(&self, _other: &Self) -> bool {
892 true
893 }
894}
895
896impl PartialEq for SemanticsSetText {
897 fn eq(&self, _other: &Self) -> bool {
898 true
899 }
900}
901
902impl PartialEq for SemanticsSetProgress {
907 fn eq(&self, _other: &Self) -> bool {
908 true
909 }
910}
911
912impl Eq for SemanticsSetProgress {}
913
914#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
921pub enum LiveRegionMode {
922 Polite,
924 Assertive,
927}
928
929#[derive(Clone)]
936pub struct SemanticsCustomAction {
937 pub label: String,
939 handler: Rc<dyn Fn()>,
940}
941
942impl SemanticsCustomAction {
943 pub fn new(label: impl Into<String>, handler: impl Fn() + 'static) -> Self {
944 Self {
945 label: label.into(),
946 handler: Rc::new(handler),
947 }
948 }
949
950 pub fn invoke(&self) {
951 (self.handler)();
952 }
953}
954
955impl fmt::Debug for SemanticsCustomAction {
956 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
957 f.debug_struct("SemanticsCustomAction")
958 .field("label", &self.label)
959 .finish_non_exhaustive()
960 }
961}
962
963impl PartialEq for SemanticsCustomAction {
973 fn eq(&self, other: &Self) -> bool {
974 self.label == other.label
975 }
976}
977
978impl Eq for SemanticsCustomAction {}
979
980#[derive(Clone, Debug, PartialEq)]
995pub struct CanvasSemanticsNode {
996 pub key: u64,
1003 pub bounds: cranpose_ui_graphics::Rect,
1005 pub label: String,
1006 pub role: Option<SemanticsWidgetRole>,
1007 pub state_description: Option<String>,
1011 pub on_click_label: Option<String>,
1014 pub clickable: bool,
1015 pub selected: Option<bool>,
1017 pub toggled: Option<bool>,
1019 pub enabled: bool,
1020 pub custom_actions: Vec<SemanticsCustomAction>,
1021}
1022
1023impl Default for CanvasSemanticsNode {
1024 fn default() -> Self {
1025 Self {
1026 key: 0,
1027 bounds: cranpose_ui_graphics::Rect {
1028 x: 0.0,
1029 y: 0.0,
1030 width: 0.0,
1031 height: 0.0,
1032 },
1033 label: String::new(),
1034 role: None,
1035 state_description: None,
1036 on_click_label: None,
1037 clickable: false,
1038 selected: None,
1039 toggled: None,
1040 enabled: true,
1041 custom_actions: Vec::new(),
1042 }
1043 }
1044}
1045
1046impl CanvasSemanticsNode {
1047 pub fn control(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1049 Self {
1050 key,
1051 bounds,
1052 label: label.into(),
1053 clickable: true,
1054 ..Self::default()
1055 }
1056 }
1057
1058 pub fn text(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
1060 Self {
1061 key,
1062 bounds,
1063 label: label.into(),
1064 ..Self::default()
1065 }
1066 }
1067
1068 pub fn with_role(mut self, role: SemanticsWidgetRole) -> Self {
1069 self.role = Some(role);
1070 self
1071 }
1072
1073 pub fn with_state_description(mut self, state: impl Into<String>) -> Self {
1074 self.state_description = Some(state.into());
1075 self
1076 }
1077
1078 pub fn with_click_label(mut self, label: impl Into<String>) -> Self {
1079 self.on_click_label = Some(label.into());
1080 self.clickable = true;
1081 self
1082 }
1083
1084 pub fn with_selected(mut self, selected: bool) -> Self {
1085 self.selected = Some(selected);
1086 self
1087 }
1088
1089 pub fn with_toggled(mut self, toggled: bool) -> Self {
1090 self.toggled = Some(toggled);
1091 self
1092 }
1093
1094 pub fn with_enabled(mut self, enabled: bool) -> Self {
1095 self.enabled = enabled;
1096 self
1097 }
1098
1099 pub fn with_custom_action(mut self, action: SemanticsCustomAction) -> Self {
1100 self.custom_actions.push(action);
1101 self
1102 }
1103}
1104
1105#[derive(Clone, Debug, PartialEq)]
1107pub struct SemanticsConfiguration {
1108 pub content_description: Option<String>,
1109 pub state_description: Option<String>,
1111 pub on_click_label: Option<String>,
1113 pub role: Option<SemanticsWidgetRole>,
1115 pub selected: Option<bool>,
1116 pub toggled: Option<bool>,
1117 pub enabled: bool,
1118 pub is_clickable: bool,
1119 pub is_editable_text: bool,
1120 pub text: Option<String>,
1123 pub text_selection: Option<crate::text::TextRange>,
1124 pub custom_actions: Vec<SemanticsCustomAction>,
1125 pub canvas_children: Vec<CanvasSemanticsNode>,
1128 pub is_modal: bool,
1131 pub hidden: bool,
1135 pub merge_descendants: bool,
1139 pub selectable_group: bool,
1143 pub pane_title: Option<String>,
1146 pub error: Option<String>,
1149 pub password: bool,
1152 pub traversal_index: f32,
1156 pub live_region: Option<LiveRegionMode>,
1159 pub progress: Option<ProgressBarRangeInfo>,
1162 pub set_progress: Option<SemanticsSetProgress>,
1165 pub set_text: Option<SemanticsSetText>,
1168 pub expand: Option<SemanticsExpand>,
1171 pub collapse: Option<SemanticsExpand>,
1174 pub vertical_scroll: Option<ScrollAxisRange>,
1177 pub horizontal_scroll: Option<ScrollAxisRange>,
1180 pub scroll_by: Option<SemanticsScrollBy>,
1183 pub collection: Option<CollectionInfo>,
1185}
1186
1187impl Default for SemanticsConfiguration {
1188 fn default() -> Self {
1189 Self {
1190 content_description: None,
1191 state_description: None,
1192 on_click_label: None,
1193 role: None,
1194 selected: None,
1195 toggled: None,
1196 enabled: true,
1197 is_clickable: false,
1198 is_editable_text: false,
1199 text: None,
1200 text_selection: None,
1201 custom_actions: Vec::new(),
1202 canvas_children: Vec::new(),
1203 is_modal: false,
1204 hidden: false,
1205 merge_descendants: false,
1206 selectable_group: false,
1207 pane_title: None,
1208 error: None,
1209 password: false,
1210 traversal_index: 0.0,
1211 live_region: None,
1212 progress: None,
1213 set_progress: None,
1214 set_text: None,
1215 expand: None,
1216 collapse: None,
1217 vertical_scroll: None,
1218 horizontal_scroll: None,
1219 scroll_by: None,
1220 collection: None,
1221 }
1222 }
1223}
1224
1225pub type SemanticsSpec = SemanticsConfiguration;
1234
1235impl SemanticsConfiguration {
1236 pub fn new() -> Self {
1239 Self::default()
1240 }
1241
1242 pub fn content_description(mut self, name: impl Into<String>) -> Self {
1245 self.content_description = Some(name.into());
1246 self
1247 }
1248
1249 pub fn state_description(mut self, state: impl Into<String>) -> Self {
1252 self.state_description = Some(state.into());
1253 self
1254 }
1255
1256 pub fn clickable(mut self) -> Self {
1258 self.is_clickable = true;
1259 self
1260 }
1261
1262 pub fn toggled(mut self, toggled: bool) -> Self {
1264 self.toggled = Some(toggled);
1265 self
1266 }
1267
1268 pub fn selected(mut self, selected: bool) -> Self {
1271 self.selected = Some(selected);
1272 self
1273 }
1274
1275 pub fn role(mut self, role: SemanticsWidgetRole) -> Self {
1277 self.role = Some(role);
1278 self
1279 }
1280
1281 pub fn heading(self) -> Self {
1284 self.role(SemanticsWidgetRole::Header)
1285 }
1286
1287 pub fn error(mut self, message: impl Into<String>) -> Self {
1289 self.error = Some(message.into());
1290 self
1291 }
1292
1293 pub fn password(mut self) -> Self {
1295 self.password = true;
1296 self
1297 }
1298
1299 pub fn pane_title(mut self, title: impl Into<String>) -> Self {
1302 self.pane_title = Some(title.into());
1303 self
1304 }
1305
1306 pub fn traversal_index(mut self, index: f32) -> Self {
1309 self.traversal_index = index;
1310 self
1311 }
1312
1313 pub fn hidden(mut self) -> Self {
1316 self.hidden = true;
1317 self
1318 }
1319
1320 pub fn merge_descendants(mut self) -> Self {
1323 self.merge_descendants = true;
1324 self
1325 }
1326
1327 pub fn selectable_group(mut self) -> Self {
1330 self.selectable_group = true;
1331 self
1332 }
1333
1334 pub fn live_region(mut self, mode: LiveRegionMode) -> Self {
1337 self.live_region = Some(mode);
1338 self
1339 }
1340 pub fn merge(&mut self, other: &SemanticsConfiguration) {
1341 if let Some(description) = &other.content_description {
1342 self.content_description = Some(description.clone());
1343 }
1344 if let Some(state) = &other.state_description {
1345 self.state_description = Some(state.clone());
1346 }
1347 if let Some(label) = &other.on_click_label {
1348 self.on_click_label = Some(label.clone());
1349 }
1350 if let Some(role) = other.role {
1351 self.role = Some(role);
1352 }
1353 if let Some(selected) = other.selected {
1354 self.selected = Some(selected);
1355 }
1356 if let Some(toggled) = other.toggled {
1357 self.toggled = Some(toggled);
1358 }
1359 self.enabled &= other.enabled;
1360 self.is_clickable |= other.is_clickable;
1361 self.is_editable_text |= other.is_editable_text;
1362 if let Some(text) = &other.text {
1363 self.text = Some(text.clone());
1364 }
1365 self.is_modal |= other.is_modal;
1366 self.hidden |= other.hidden;
1367 self.merge_descendants |= other.merge_descendants;
1368 self.selectable_group |= other.selectable_group;
1369 self.password |= other.password;
1370 if other.traversal_index != 0.0 {
1371 self.traversal_index = other.traversal_index;
1372 }
1373 if let Some(live_region) = other.live_region {
1374 self.live_region = Some(live_region);
1375 }
1376 self.merge_words(other);
1377 self.merge_actions(other);
1378 self.merge_ranges(other);
1379 }
1380
1381 fn merge_words(&mut self, other: &SemanticsConfiguration) {
1384 if let Some(title) = &other.pane_title {
1385 self.pane_title = Some(title.clone());
1386 }
1387 if let Some(error) = &other.error {
1388 self.error = Some(error.clone());
1389 }
1390 }
1391
1392 fn merge_actions(&mut self, other: &SemanticsConfiguration) {
1395 self.custom_actions
1396 .extend(other.custom_actions.iter().cloned());
1397 self.canvas_children
1398 .extend(other.canvas_children.iter().cloned());
1399 if let Some(set_progress) = &other.set_progress {
1400 self.set_progress = Some(set_progress.clone());
1401 }
1402 if let Some(set_text) = &other.set_text {
1403 self.set_text = Some(set_text.clone());
1404 }
1405 if let Some(expand) = &other.expand {
1406 self.expand = Some(expand.clone());
1407 }
1408 if let Some(collapse) = &other.collapse {
1409 self.collapse = Some(collapse.clone());
1410 }
1411 if let Some(scroll_by) = &other.scroll_by {
1412 self.scroll_by = Some(scroll_by.clone());
1413 }
1414 }
1415
1416 fn merge_ranges(&mut self, other: &SemanticsConfiguration) {
1419 if let Some(selection) = other.text_selection {
1420 self.text_selection = Some(selection);
1421 }
1422 if let Some(progress) = other.progress {
1423 self.progress = Some(progress);
1424 }
1425 if let Some(range) = other.vertical_scroll {
1426 self.vertical_scroll = Some(range);
1427 }
1428 if let Some(range) = other.horizontal_scroll {
1429 self.horizontal_scroll = Some(range);
1430 }
1431 if let Some(collection) = other.collection {
1432 self.collection = Some(collection);
1433 }
1434 }
1435
1436 pub fn is_activatable(&self) -> bool {
1439 self.is_clickable || self.on_click_label.is_some()
1440 }
1441}
1442
1443impl fmt::Debug for dyn ModifierNode {
1444 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1445 f.debug_struct("ModifierNode").finish_non_exhaustive()
1446 }
1447}
1448
1449impl dyn ModifierNode {
1450 pub fn as_any(&self) -> &dyn Any {
1451 self
1452 }
1453
1454 pub fn as_any_mut(&mut self) -> &mut dyn Any {
1455 self
1456 }
1457}
1458
1459pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
1462 type Node: ModifierNode;
1463
1464 fn create(&self) -> Self::Node;
1466
1467 fn update(&self, node: &mut Self::Node);
1469
1470 fn key(&self) -> Option<u64> {
1472 None
1473 }
1474
1475 fn inspector_name(&self) -> &'static str {
1477 type_name::<Self>()
1478 }
1479
1480 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
1482
1483 fn capabilities(&self) -> NodeCapabilities {
1486 NodeCapabilities::default()
1487 }
1488
1489 fn always_update(&self) -> bool {
1495 false
1496 }
1497
1498 fn auto_invalidate_on_update(&self) -> bool {
1501 true
1502 }
1503
1504 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1511 None
1512 }
1513}
1514
1515#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1517pub struct NodeCapabilities(u32);
1518
1519impl NodeCapabilities {
1520 pub const NONE: Self = Self(0);
1522 pub const LAYOUT: Self = Self(1 << 0);
1524 pub const DRAW: Self = Self(1 << 1);
1526 pub const POINTER_INPUT: Self = Self(1 << 2);
1528 pub const SEMANTICS: Self = Self(1 << 3);
1530 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1532 pub const FOCUS: Self = Self(1 << 5);
1534
1535 pub const fn empty() -> Self {
1537 Self::NONE
1538 }
1539
1540 pub const fn contains(self, other: Self) -> bool {
1542 (self.0 & other.0) == other.0
1543 }
1544
1545 pub const fn intersects(self, other: Self) -> bool {
1547 (self.0 & other.0) != 0
1548 }
1549
1550 pub fn insert(&mut self, other: Self) {
1552 self.0 |= other.0;
1553 }
1554
1555 pub const fn bits(self) -> u32 {
1557 self.0
1558 }
1559
1560 pub const fn is_empty(self) -> bool {
1562 self.0 == 0
1563 }
1564
1565 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1567 match kind {
1568 InvalidationKind::Layout => Self::LAYOUT,
1569 InvalidationKind::Draw => Self::DRAW,
1570 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1571 InvalidationKind::Semantics => Self::SEMANTICS,
1572 InvalidationKind::Focus => Self::FOCUS,
1573 }
1574 }
1575}
1576
1577impl Default for NodeCapabilities {
1578 fn default() -> Self {
1579 Self::NONE
1580 }
1581}
1582
1583impl fmt::Debug for NodeCapabilities {
1584 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1585 f.debug_struct("NodeCapabilities")
1586 .field("layout", &self.contains(Self::LAYOUT))
1587 .field("draw", &self.contains(Self::DRAW))
1588 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1589 .field("semantics", &self.contains(Self::SEMANTICS))
1590 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1591 .field("focus", &self.contains(Self::FOCUS))
1592 .finish()
1593 }
1594}
1595
1596impl BitOr for NodeCapabilities {
1597 type Output = Self;
1598
1599 fn bitor(self, rhs: Self) -> Self::Output {
1600 Self(self.0 | rhs.0)
1601 }
1602}
1603
1604impl BitOrAssign for NodeCapabilities {
1605 fn bitor_assign(&mut self, rhs: Self) {
1606 self.0 |= rhs.0;
1607 }
1608}
1609
1610#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1612pub struct ModifierInvalidation {
1613 kind: InvalidationKind,
1614 capabilities: NodeCapabilities,
1615}
1616
1617impl ModifierInvalidation {
1618 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1620 Self { kind, capabilities }
1621 }
1622
1623 pub const fn kind(self) -> InvalidationKind {
1625 self.kind
1626 }
1627
1628 pub const fn capabilities(self) -> NodeCapabilities {
1630 self.capabilities
1631 }
1632}
1633
1634pub trait AnyModifierElement: fmt::Debug {
1636 fn node_type(&self) -> TypeId;
1637
1638 fn element_type(&self) -> TypeId;
1639
1640 fn create_node(&self) -> Box<dyn ModifierNode>;
1641
1642 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
1643
1644 fn update_node(&self, node: &mut dyn ModifierNode);
1645
1646 fn key(&self) -> Option<u64>;
1647
1648 fn capabilities(&self) -> NodeCapabilities {
1649 NodeCapabilities::default()
1650 }
1651
1652 fn hash_code(&self) -> u64;
1653
1654 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
1655
1656 fn inspector_name(&self) -> &'static str;
1657
1658 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
1659
1660 fn requires_update(&self) -> bool;
1661
1662 fn auto_invalidates_on_update(&self) -> bool;
1663
1664 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
1665
1666 fn as_any(&self) -> &dyn Any;
1667}
1668
1669struct TypedModifierElement<E: ModifierNodeElement> {
1670 element: E,
1671 cached_hash: u64,
1672}
1673
1674impl<E: ModifierNodeElement> TypedModifierElement<E> {
1675 fn new(element: E) -> Self {
1676 let mut hasher = default::new();
1677 element.hash(&mut hasher);
1678 Self {
1679 element,
1680 cached_hash: hasher.finish(),
1681 }
1682 }
1683}
1684
1685impl<E> fmt::Debug for TypedModifierElement<E>
1686where
1687 E: ModifierNodeElement,
1688{
1689 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1690 f.debug_struct("TypedModifierElement")
1691 .field("type", &type_name::<E>())
1692 .finish()
1693 }
1694}
1695
1696impl<E> AnyModifierElement for TypedModifierElement<E>
1697where
1698 E: ModifierNodeElement,
1699{
1700 fn node_type(&self) -> TypeId {
1701 TypeId::of::<E::Node>()
1702 }
1703
1704 fn element_type(&self) -> TypeId {
1705 TypeId::of::<E>()
1706 }
1707
1708 fn create_node(&self) -> Box<dyn ModifierNode> {
1709 Box::new(self.element.create())
1710 }
1711
1712 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
1713 node.as_any().is::<E::Node>()
1714 }
1715
1716 fn update_node(&self, node: &mut dyn ModifierNode) {
1717 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
1718 self.element.update(typed);
1719 }
1720 }
1721
1722 fn key(&self) -> Option<u64> {
1723 self.element.key()
1724 }
1725
1726 fn capabilities(&self) -> NodeCapabilities {
1727 self.element.capabilities()
1728 }
1729
1730 fn hash_code(&self) -> u64 {
1731 self.cached_hash
1732 }
1733
1734 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
1735 other
1736 .as_any()
1737 .downcast_ref::<Self>()
1738 .map(|typed| typed.element == self.element)
1739 .unwrap_or(false)
1740 }
1741
1742 fn inspector_name(&self) -> &'static str {
1743 self.element.inspector_name()
1744 }
1745
1746 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
1747 self.element.inspector_properties(visitor);
1748 }
1749
1750 fn requires_update(&self) -> bool {
1751 self.element.always_update()
1752 }
1753
1754 fn auto_invalidates_on_update(&self) -> bool {
1755 self.element.auto_invalidate_on_update()
1756 }
1757
1758 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1759 self.element.update_invalidation_kind()
1760 }
1761
1762 fn as_any(&self) -> &dyn Any {
1763 self
1764 }
1765}
1766
1767fn request_update_auto_invalidations(
1768 element: &dyn AnyModifierElement,
1769 context: &mut dyn ModifierNodeContext,
1770 capabilities: NodeCapabilities,
1771) {
1772 if let Some(kind) = element.update_invalidation_kind() {
1773 let capabilities = NodeCapabilities::for_invalidation(kind);
1774 context.push_active_capabilities(capabilities);
1775 context.invalidate(kind);
1776 context.pop_active_capabilities();
1777 } else if element.auto_invalidates_on_update() {
1778 request_auto_invalidations(context, capabilities);
1779 }
1780}
1781
1782pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
1785 Rc::new(TypedModifierElement::new(element))
1786}
1787
1788pub type DynModifierElement = Rc<dyn AnyModifierElement>;
1790
1791#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1792enum TraversalDirection {
1793 Forward,
1794 Backward,
1795}
1796
1797pub struct ModifierChainIter<'a> {
1802 chain: &'a ModifierNodeChain,
1803 cursor: usize,
1804 remaining: usize,
1805 direction: TraversalDirection,
1806}
1807
1808impl<'a> ModifierChainIter<'a> {
1809 fn forward(chain: &'a ModifierNodeChain) -> Self {
1810 Self {
1811 chain,
1812 cursor: 0,
1813 remaining: chain.ordered_nodes.len(),
1814 direction: TraversalDirection::Forward,
1815 }
1816 }
1817
1818 fn backward(chain: &'a ModifierNodeChain) -> Self {
1819 let len = chain.ordered_nodes.len();
1820 Self {
1821 chain,
1822 cursor: len.wrapping_sub(1),
1823 remaining: len,
1824 direction: TraversalDirection::Backward,
1825 }
1826 }
1827}
1828
1829impl<'a> Iterator for ModifierChainIter<'a> {
1830 type Item = ModifierChainNodeRef<'a>;
1831
1832 #[inline]
1833 fn next(&mut self) -> Option<Self::Item> {
1834 if self.remaining == 0 {
1835 return None;
1836 }
1837 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
1838 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
1839 self.remaining -= 1;
1840 match self.direction {
1841 TraversalDirection::Forward => self.cursor += 1,
1842 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
1843 }
1844 Some(node_ref)
1845 }
1846
1847 #[inline]
1848 fn size_hint(&self) -> (usize, Option<usize>) {
1849 (self.remaining, Some(self.remaining))
1850 }
1851}
1852
1853impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
1854impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
1855
1856#[derive(Debug)]
1857struct ModifierNodeEntry {
1858 element_type: TypeId,
1859 node_type: TypeId,
1860 key: Option<u64>,
1861 hash_code: u64,
1862 element: DynModifierElement,
1863 node: Rc<RefCell<Box<dyn ModifierNode>>>,
1864 capabilities: NodeCapabilities,
1865}
1866
1867impl ModifierNodeEntry {
1868 fn new(
1869 element_type: TypeId,
1870 node_type: TypeId,
1871 key: Option<u64>,
1872 element: DynModifierElement,
1873 node: Box<dyn ModifierNode>,
1874 hash_code: u64,
1875 capabilities: NodeCapabilities,
1876 ) -> Self {
1877 let node_rc = Rc::new(RefCell::new(node));
1878 let entry = Self {
1879 element_type,
1880 node_type,
1881 key,
1882 hash_code,
1883 element,
1884 node: Rc::clone(&node_rc),
1885 capabilities,
1886 };
1887 entry
1888 .node
1889 .borrow()
1890 .node_state()
1891 .set_capabilities(entry.capabilities);
1892 entry
1893 }
1894}
1895
1896fn visit_node_tree_mut(
1897 node: &mut dyn ModifierNode,
1898 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
1899) {
1900 visitor(node);
1901 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
1902}
1903
1904fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
1905 let mut current = 0usize;
1906 let mut result: Option<&dyn ModifierNode> = None;
1907 node.for_each_delegate(&mut |child| {
1908 if result.is_none() && current == target {
1909 result = Some(child);
1910 }
1911 current += 1;
1912 });
1913 result
1914}
1915
1916fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
1917 let mut current = 0usize;
1918 let mut result: Option<&mut dyn ModifierNode> = None;
1919 node.for_each_delegate_mut(&mut |child| {
1920 if result.is_none() && current == target {
1921 result = Some(child);
1922 }
1923 current += 1;
1924 });
1925 result
1926}
1927
1928fn with_node_context<F, R>(
1929 node: &mut dyn ModifierNode,
1930 context: &mut dyn ModifierNodeContext,
1931 f: F,
1932) -> R
1933where
1934 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
1935{
1936 context.push_active_capabilities(node.node_state().capabilities());
1937 let result = f(node, context);
1938 context.pop_active_capabilities();
1939 result
1940}
1941
1942fn request_auto_invalidations(
1943 context: &mut dyn ModifierNodeContext,
1944 capabilities: NodeCapabilities,
1945) {
1946 if capabilities.is_empty() {
1947 return;
1948 }
1949
1950 context.push_active_capabilities(capabilities);
1951
1952 if capabilities.contains(NodeCapabilities::LAYOUT) {
1953 context.invalidate(InvalidationKind::Layout);
1954 }
1955 if capabilities.contains(NodeCapabilities::DRAW) {
1956 context.invalidate(InvalidationKind::Draw);
1957 }
1958 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
1959 context.invalidate(InvalidationKind::PointerInput);
1960 }
1961 if capabilities.contains(NodeCapabilities::SEMANTICS) {
1962 context.invalidate(InvalidationKind::Semantics);
1963 }
1964 if capabilities.contains(NodeCapabilities::FOCUS) {
1965 context.invalidate(InvalidationKind::Focus);
1966 }
1967
1968 context.pop_active_capabilities();
1969}
1970
1971fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
1979 visit_node_tree_mut(node, &mut |n| {
1980 if !n.node_state().is_attached() {
1981 n.node_state().set_attached(true);
1982 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
1983 }
1984 });
1985}
1986
1987fn reset_node_tree(node: &mut dyn ModifierNode) {
1988 visit_node_tree_mut(node, &mut |n| n.on_reset());
1989}
1990
1991fn detach_node_tree(node: &mut dyn ModifierNode) {
1992 visit_node_tree_mut(node, &mut |n| {
1993 if n.node_state().is_attached() {
1994 n.on_detach();
1995 n.node_state().set_attached(false);
1996 }
1997 n.node_state().set_parent_link(None);
1998 n.node_state().set_child_link(None);
1999 n.node_state()
2000 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2001 });
2002}
2003
2004pub struct ModifierNodeChain {
2011 entries: Vec<ModifierNodeEntry>,
2012 aggregated_capabilities: NodeCapabilities,
2013 head_aggregate_child_capabilities: NodeCapabilities,
2014 head_sentinel: Box<SentinelNode>,
2015 tail_sentinel: Box<SentinelNode>,
2016 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2017 scratch_old_used: Vec<bool>,
2018 scratch_match_order: Vec<Option<usize>>,
2019 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
2020 scratch_elements: Vec<DynModifierElement>,
2021}
2022
2023struct SentinelNode {
2024 state: NodeState,
2025}
2026
2027impl SentinelNode {
2028 fn new() -> Self {
2029 Self {
2030 state: NodeState::sentinel(),
2031 }
2032 }
2033}
2034
2035impl DelegatableNode for SentinelNode {
2036 fn node_state(&self) -> &NodeState {
2037 &self.state
2038 }
2039}
2040
2041impl ModifierNode for SentinelNode {}
2042
2043#[derive(Clone)]
2044pub struct ModifierChainNodeRef<'a> {
2045 chain: &'a ModifierNodeChain,
2046 link: NodeLink,
2047 cached_capabilities: Option<NodeCapabilities>,
2048 cached_aggregate_child: Option<NodeCapabilities>,
2049}
2050
2051impl Default for ModifierNodeChain {
2052 fn default() -> Self {
2053 Self::new()
2054 }
2055}
2056
2057struct EntryIndex {
2062 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2063 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
2064 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
2065}
2066
2067struct EntryMatchQuery<'a> {
2068 element_type: TypeId,
2069 node_type: TypeId,
2070 key: Option<u64>,
2071 hash_code: u64,
2072 element: &'a DynModifierElement,
2073}
2074
2075impl EntryIndex {
2076 fn build(entries: &[ModifierNodeEntry]) -> Self {
2077 let mut keyed = HashMap::default();
2078 let mut hashed = HashMap::default();
2079 let mut typed = HashMap::default();
2080
2081 for (i, entry) in entries.iter().enumerate() {
2082 if let Some(key_value) = entry.key {
2083 keyed
2084 .entry((entry.element_type, entry.node_type, key_value))
2085 .or_insert_with(Vec::new)
2086 .push(i);
2087 } else {
2088 hashed
2089 .entry((entry.element_type, entry.node_type, entry.hash_code))
2090 .or_insert_with(Vec::new)
2091 .push(i);
2092 typed
2093 .entry((entry.element_type, entry.node_type))
2094 .or_insert_with(Vec::new)
2095 .push(i);
2096 }
2097 }
2098
2099 Self {
2100 keyed,
2101 hashed,
2102 typed,
2103 }
2104 }
2105
2106 fn find_match(
2107 &self,
2108 entries: &[ModifierNodeEntry],
2109 used: &[bool],
2110 query: EntryMatchQuery<'_>,
2111 ) -> Option<usize> {
2112 if let Some(key_value) = query.key {
2113 if let Some(candidates) =
2114 self.keyed
2115 .get(&(query.element_type, query.node_type, key_value))
2116 {
2117 for &i in candidates {
2118 if !used[i] {
2119 return Some(i);
2120 }
2121 }
2122 }
2123 } else {
2124 if let Some(candidates) =
2125 self.hashed
2126 .get(&(query.element_type, query.node_type, query.hash_code))
2127 {
2128 for &i in candidates {
2129 if !used[i]
2130 && entries[i]
2131 .element
2132 .as_ref()
2133 .equals_element(query.element.as_ref())
2134 {
2135 return Some(i);
2136 }
2137 }
2138 }
2139
2140 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
2141 for &i in candidates {
2142 if !used[i] {
2143 return Some(i);
2144 }
2145 }
2146 }
2147 }
2148
2149 None
2150 }
2151}
2152
2153impl ModifierNodeChain {
2154 pub fn new() -> Self {
2155 let mut chain = Self {
2156 entries: Vec::new(),
2157 aggregated_capabilities: NodeCapabilities::empty(),
2158 head_aggregate_child_capabilities: NodeCapabilities::empty(),
2159 head_sentinel: Box::new(SentinelNode::new()),
2160 tail_sentinel: Box::new(SentinelNode::new()),
2161 ordered_nodes: Vec::new(),
2162 scratch_old_used: Vec::new(),
2163 scratch_match_order: Vec::new(),
2164 scratch_final_slots: Vec::new(),
2165 scratch_elements: Vec::new(),
2166 };
2167 chain.sync_chain_links();
2168 chain
2169 }
2170
2171 pub fn detach_nodes(&mut self) {
2173 for entry in &self.entries {
2174 detach_node_tree(&mut **entry.node.borrow_mut());
2175 }
2176 }
2177
2178 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
2180 for entry in &self.entries {
2181 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2182 }
2183 }
2184
2185 pub fn repair_chain(&mut self) {
2188 self.sync_chain_links();
2189 }
2190
2191 pub fn update_from_slice(
2197 &mut self,
2198 elements: &[DynModifierElement],
2199 context: &mut dyn ModifierNodeContext,
2200 ) {
2201 self.update_from_ref_iter(elements.iter(), context);
2202 }
2203
2204 pub fn update_from_ref_iter<'a, I>(
2209 &mut self,
2210 elements: I,
2211 context: &mut dyn ModifierNodeContext,
2212 ) where
2213 I: Iterator<Item = &'a DynModifierElement>,
2214 {
2215 let old_len = self.entries.len();
2216 let mut fast_path_failed_at: Option<usize> = None;
2217 let mut elements_count = 0;
2218
2219 self.scratch_elements.clear();
2220
2221 for (idx, element) in elements.enumerate() {
2222 elements_count = idx + 1;
2223
2224 if fast_path_failed_at.is_none() && idx < old_len {
2225 let entry = &mut self.entries[idx];
2226 let same_type = entry.element_type == element.element_type();
2227 let same_node_type = entry.node_type == element.node_type();
2228 let same_key = entry.key == element.key();
2229 let same_hash = entry.hash_code == element.hash_code();
2230
2231 let positional_update = element.requires_update();
2232 if same_type && same_node_type && same_key && (same_hash || positional_update) {
2233 let can_update_node = {
2234 let node_borrow = entry.node.borrow();
2235 element.can_update_node(&**node_borrow)
2236 };
2237 if !can_update_node {
2238 fast_path_failed_at = Some(idx);
2239 self.scratch_elements.push(element.clone());
2240 continue;
2241 }
2242
2243 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2244 let capabilities = element.capabilities();
2245
2246 {
2247 let node_borrow = entry.node.borrow();
2248 if !node_borrow.node_state().is_attached() {
2249 drop(node_borrow);
2250 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2251 }
2252 }
2253
2254 let needs_update = !same_element || element.requires_update();
2255 if needs_update {
2256 element.update_node(&mut **entry.node.borrow_mut());
2257 entry.element = element.clone();
2258 entry.hash_code = element.hash_code();
2259 request_update_auto_invalidations(element.as_ref(), context, capabilities);
2260 }
2261
2262 entry.capabilities = capabilities;
2263 entry
2264 .node
2265 .borrow()
2266 .node_state()
2267 .set_capabilities(capabilities);
2268 continue;
2269 }
2270 fast_path_failed_at = Some(idx);
2271 }
2272
2273 self.scratch_elements.push(element.clone());
2274 }
2275
2276 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
2277 if elements_count < self.entries.len() {
2278 for entry in self.entries.drain(elements_count..) {
2279 request_auto_invalidations(context, entry.capabilities);
2280 detach_node_tree(&mut **entry.node.borrow_mut());
2281 }
2282 }
2283 self.sync_chain_links();
2284 return;
2285 }
2286
2287 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
2288
2289 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
2290 let processed_entries_len = self.entries.len();
2291 let old_len = old_entries.len();
2292
2293 self.scratch_old_used.clear();
2294 self.scratch_old_used.resize(old_len, false);
2295
2296 self.scratch_match_order.clear();
2297 self.scratch_match_order.resize(old_len, None);
2298
2299 let index = EntryIndex::build(&old_entries);
2300
2301 let new_elements_count = self.scratch_elements.len();
2302 self.scratch_final_slots.clear();
2303 self.scratch_final_slots.reserve(new_elements_count);
2304
2305 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
2306 self.scratch_final_slots.push(None);
2307 let element_type = element.element_type();
2308 let node_type = element.node_type();
2309 let key = element.key();
2310 let hash_code = element.hash_code();
2311 let capabilities = element.capabilities();
2312
2313 let matched_idx = index.find_match(
2314 &old_entries,
2315 &self.scratch_old_used,
2316 EntryMatchQuery {
2317 element_type,
2318 node_type,
2319 key,
2320 hash_code,
2321 element: &element,
2322 },
2323 );
2324
2325 if let Some(idx) = matched_idx {
2326 let entry = &mut old_entries[idx];
2327 let can_update_node = {
2328 let node_borrow = entry.node.borrow();
2329 element.can_update_node(&**node_borrow)
2330 };
2331 if !can_update_node {
2332 let replacement = ModifierNodeEntry::new(
2333 element_type,
2334 node_type,
2335 key,
2336 element.clone(),
2337 element.create_node(),
2338 hash_code,
2339 capabilities,
2340 );
2341 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
2342 element.update_node(&mut **replacement.node.borrow_mut());
2343 request_auto_invalidations(context, capabilities);
2344 self.scratch_final_slots[new_pos] = Some(replacement);
2345 continue;
2346 }
2347
2348 self.scratch_old_used[idx] = true;
2349 self.scratch_match_order[idx] = Some(new_pos);
2350 let moved = idx != new_pos;
2351
2352 let same_element = entry.element.as_ref().equals_element(element.as_ref());
2353
2354 {
2355 let node_borrow = entry.node.borrow();
2356 if !node_borrow.node_state().is_attached() {
2357 drop(node_borrow);
2358 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2359 }
2360 }
2361
2362 let needs_update = !same_element || element.requires_update();
2363 if needs_update {
2364 element.update_node(&mut **entry.node.borrow_mut());
2365 entry.element = element;
2366 entry.hash_code = hash_code;
2367 request_update_auto_invalidations(
2368 entry.element.as_ref(),
2369 context,
2370 capabilities,
2371 );
2372 }
2373 if moved {
2374 request_auto_invalidations(context, capabilities);
2375 }
2376
2377 entry.key = key;
2378 entry.element_type = element_type;
2379 entry.node_type = node_type;
2380 entry.capabilities = capabilities;
2381 entry
2382 .node
2383 .borrow()
2384 .node_state()
2385 .set_capabilities(capabilities);
2386 } else {
2387 let entry = ModifierNodeEntry::new(
2388 element_type,
2389 node_type,
2390 key,
2391 element.clone(),
2392 element.create_node(),
2393 hash_code,
2394 capabilities,
2395 );
2396 attach_node_tree(&mut **entry.node.borrow_mut(), context);
2397 element.update_node(&mut **entry.node.borrow_mut());
2398 request_auto_invalidations(context, capabilities);
2399 self.scratch_final_slots[new_pos] = Some(entry);
2400 }
2401 }
2402
2403 for (i, entry) in old_entries.into_iter().enumerate() {
2404 if self.scratch_old_used[i] {
2405 if let Some(pos) = self.scratch_match_order[i] {
2406 self.scratch_final_slots[pos] = Some(entry);
2407 } else {
2408 request_auto_invalidations(context, entry.capabilities);
2409 detach_node_tree(&mut **entry.node.borrow_mut());
2410 }
2411 } else {
2412 request_auto_invalidations(context, entry.capabilities);
2413 detach_node_tree(&mut **entry.node.borrow_mut());
2414 }
2415 }
2416
2417 self.entries.reserve(self.scratch_final_slots.len());
2418 for slot in self.scratch_final_slots.drain(..) {
2419 if let Some(entry) = slot {
2420 self.entries.push(entry);
2421 } else {
2422 log::error!("modifier reconciliation produced an empty final slot");
2423 }
2424 }
2425
2426 debug_assert_eq!(
2427 self.entries.len(),
2428 processed_entries_len + new_elements_count
2429 );
2430 self.sync_chain_links();
2431 }
2432
2433 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2437 where
2438 I: IntoIterator<Item = DynModifierElement>,
2439 {
2440 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2441 self.update_from_slice(&collected, context);
2442 }
2443
2444 pub fn reset(&mut self) {
2447 for entry in &mut self.entries {
2448 reset_node_tree(&mut **entry.node.borrow_mut());
2449 }
2450 }
2451
2452 pub fn detach_all(&mut self) {
2454 for entry in std::mem::take(&mut self.entries) {
2455 detach_node_tree(&mut **entry.node.borrow_mut());
2456 {
2457 let node_borrow = entry.node.borrow();
2458 let state = node_borrow.node_state();
2459 state.set_capabilities(NodeCapabilities::empty());
2460 }
2461 }
2462 self.aggregated_capabilities = NodeCapabilities::empty();
2463 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2464 self.ordered_nodes.clear();
2465 self.sync_chain_links();
2466 }
2467
2468 pub fn len(&self) -> usize {
2469 self.entries.len()
2470 }
2471
2472 pub fn is_empty(&self) -> bool {
2473 self.entries.is_empty()
2474 }
2475
2476 pub fn capabilities(&self) -> NodeCapabilities {
2478 self.aggregated_capabilities
2479 }
2480
2481 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2483 self.aggregated_capabilities.contains(capability)
2484 }
2485
2486 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2488 self.make_node_ref(NodeLink::Head)
2489 }
2490
2491 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2493 self.make_node_ref(NodeLink::Tail)
2494 }
2495
2496 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2498 ModifierChainIter::forward(self)
2499 }
2500
2501 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2503 ModifierChainIter::backward(self)
2504 }
2505
2506 pub fn for_each_forward<F>(&self, mut f: F)
2508 where
2509 F: FnMut(ModifierChainNodeRef<'_>),
2510 {
2511 for node in self.head_to_tail() {
2512 f(node);
2513 }
2514 }
2515
2516 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2518 where
2519 F: FnMut(ModifierChainNodeRef<'_>),
2520 {
2521 if mask.is_empty() {
2522 self.for_each_forward(f);
2523 return;
2524 }
2525
2526 if !self.head().aggregate_child_capabilities().intersects(mask) {
2527 return;
2528 }
2529
2530 for node in self.head_to_tail() {
2531 if node.kind_set().intersects(mask) {
2532 f(node);
2533 }
2534 }
2535 }
2536
2537 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2539 where
2540 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2541 {
2542 self.for_each_forward_matching(mask, |node_ref| {
2543 node_ref.with_node(|node| f(node_ref.clone(), node));
2544 });
2545 }
2546
2547 pub fn for_each_backward<F>(&self, mut f: F)
2549 where
2550 F: FnMut(ModifierChainNodeRef<'_>),
2551 {
2552 for node in self.tail_to_head() {
2553 f(node);
2554 }
2555 }
2556
2557 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2559 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2560 node as *const dyn ModifierNode as *const ()
2561 }
2562
2563 let target = node_data_ptr(node);
2564 for (index, entry) in self.entries.iter().enumerate() {
2565 if node_data_ptr(&**entry.node.borrow()) == target {
2566 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2567 }
2568 }
2569
2570 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2571 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2572 return None;
2573 }
2574 let matches_target = match link {
2575 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2576 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2577 NodeLink::Entry(path) => {
2578 let node_borrow = self.entries[path.entry()].node.borrow();
2579 node_data_ptr(&**node_borrow) == target
2580 }
2581 };
2582 if matches_target {
2583 Some(self.make_node_ref(*link))
2584 } else {
2585 None
2586 }
2587 })
2588 }
2589
2590 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2593 self.entries.get(index).and_then(|entry| {
2594 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2595 boxed_node.as_any().downcast_ref::<N>()
2596 })
2597 .ok()
2598 })
2599 }
2600
2601 pub fn node_mut<N: ModifierNode + 'static>(
2604 &self,
2605 index: usize,
2606 ) -> Option<std::cell::RefMut<'_, N>> {
2607 self.entries.get(index).and_then(|entry| {
2608 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2609 boxed_node.as_any_mut().downcast_mut::<N>()
2610 })
2611 .ok()
2612 })
2613 }
2614
2615 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2618 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
2619 }
2620
2621 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
2623 self.aggregated_capabilities
2624 .contains(NodeCapabilities::for_invalidation(kind))
2625 }
2626
2627 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
2629 where
2630 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
2631 {
2632 for index in 0..self.ordered_nodes.len() {
2633 let (link, cached_caps, _agg) = self.ordered_nodes[index];
2634 match link {
2635 NodeLink::Head => {
2636 f(self.head_sentinel.as_mut(), cached_caps);
2637 }
2638 NodeLink::Tail => {
2639 f(self.tail_sentinel.as_mut(), cached_caps);
2640 }
2641 NodeLink::Entry(path) => {
2642 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
2643 if path.delegates().is_empty() {
2644 f(&mut **node_borrow, cached_caps);
2645 } else {
2646 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
2647 for &delegate_index in path.delegates() {
2648 if let Some(delegate) =
2649 nth_delegate_mut(current, delegate_index as usize)
2650 {
2651 current = delegate;
2652 } else {
2653 return;
2654 }
2655 }
2656 f(current, cached_caps);
2657 }
2658 }
2659 }
2660 }
2661 }
2662
2663 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2664 ModifierChainNodeRef {
2665 chain: self,
2666 link,
2667 cached_capabilities: None,
2668 cached_aggregate_child: None,
2669 }
2670 }
2671
2672 fn make_node_ref_with_caps(
2673 &self,
2674 link: NodeLink,
2675 caps: NodeCapabilities,
2676 aggregate_child: NodeCapabilities,
2677 ) -> ModifierChainNodeRef<'_> {
2678 ModifierChainNodeRef {
2679 chain: self,
2680 link,
2681 cached_capabilities: Some(caps),
2682 cached_aggregate_child: Some(aggregate_child),
2683 }
2684 }
2685
2686 fn sync_chain_links(&mut self) {
2687 self.rebuild_ordered_nodes();
2688
2689 self.head_sentinel.node_state().set_parent_link(None);
2690 self.tail_sentinel.node_state().set_child_link(None);
2691
2692 if self.ordered_nodes.is_empty() {
2693 self.head_sentinel
2694 .node_state()
2695 .set_child_link(Some(NodeLink::Tail));
2696 self.tail_sentinel
2697 .node_state()
2698 .set_parent_link(Some(NodeLink::Head));
2699 self.aggregated_capabilities = NodeCapabilities::empty();
2700 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2701 self.head_sentinel
2702 .node_state()
2703 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2704 self.tail_sentinel
2705 .node_state()
2706 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2707 return;
2708 }
2709
2710 let mut previous = NodeLink::Head;
2711 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
2712 match &previous {
2713 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
2714 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
2715 NodeLink::Entry(path) => {
2716 let node_borrow = self.entries[path.entry()].node.borrow();
2717 if path.delegates().is_empty() {
2718 node_borrow.node_state().set_child_link(Some(link));
2719 } else {
2720 let mut current: &dyn ModifierNode = &**node_borrow;
2721 for &delegate_index in path.delegates() {
2722 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2723 current = delegate;
2724 }
2725 }
2726 current.node_state().set_child_link(Some(link));
2727 }
2728 }
2729 }
2730 match &link {
2731 NodeLink::Head => self
2732 .head_sentinel
2733 .node_state()
2734 .set_parent_link(Some(previous)),
2735 NodeLink::Tail => self
2736 .tail_sentinel
2737 .node_state()
2738 .set_parent_link(Some(previous)),
2739 NodeLink::Entry(path) => {
2740 let node_borrow = self.entries[path.entry()].node.borrow();
2741 if path.delegates().is_empty() {
2742 node_borrow.node_state().set_parent_link(Some(previous));
2743 } else {
2744 let mut current: &dyn ModifierNode = &**node_borrow;
2745 for &delegate_index in path.delegates() {
2746 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2747 current = delegate;
2748 }
2749 }
2750 current.node_state().set_parent_link(Some(previous));
2751 }
2752 }
2753 }
2754 previous = link;
2755 }
2756
2757 match &previous {
2758 NodeLink::Head => self
2759 .head_sentinel
2760 .node_state()
2761 .set_child_link(Some(NodeLink::Tail)),
2762 NodeLink::Tail => self
2763 .tail_sentinel
2764 .node_state()
2765 .set_child_link(Some(NodeLink::Tail)),
2766 NodeLink::Entry(path) => {
2767 let node_borrow = self.entries[path.entry()].node.borrow();
2768 if path.delegates().is_empty() {
2769 node_borrow
2770 .node_state()
2771 .set_child_link(Some(NodeLink::Tail));
2772 } else {
2773 let mut current: &dyn ModifierNode = &**node_borrow;
2774 for &delegate_index in path.delegates() {
2775 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2776 current = delegate;
2777 }
2778 }
2779 current.node_state().set_child_link(Some(NodeLink::Tail));
2780 }
2781 }
2782 }
2783 self.tail_sentinel
2784 .node_state()
2785 .set_parent_link(Some(previous));
2786 self.tail_sentinel.node_state().set_child_link(None);
2787
2788 let mut aggregate = NodeCapabilities::empty();
2789 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
2790 aggregate |= *cached_caps;
2791 *cached_aggregate = aggregate;
2792 match link {
2793 NodeLink::Head => {
2794 self.head_sentinel
2795 .node_state()
2796 .set_aggregate_child_capabilities(aggregate);
2797 }
2798 NodeLink::Tail => {
2799 self.tail_sentinel
2800 .node_state()
2801 .set_aggregate_child_capabilities(aggregate);
2802 }
2803 NodeLink::Entry(path) => {
2804 let node_borrow = self.entries[path.entry()].node.borrow();
2805 let state = if path.delegates().is_empty() {
2806 node_borrow.node_state()
2807 } else {
2808 let mut current: &dyn ModifierNode = &**node_borrow;
2809 for &delegate_index in path.delegates() {
2810 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2811 current = delegate;
2812 }
2813 }
2814 current.node_state()
2815 };
2816 state.set_aggregate_child_capabilities(aggregate);
2817 }
2818 }
2819 }
2820
2821 self.aggregated_capabilities = aggregate;
2822 self.head_aggregate_child_capabilities = aggregate;
2823 self.head_sentinel
2824 .node_state()
2825 .set_aggregate_child_capabilities(aggregate);
2826 self.tail_sentinel
2827 .node_state()
2828 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2829 }
2830
2831 fn rebuild_ordered_nodes(&mut self) {
2832 self.ordered_nodes.clear();
2833 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
2834 for (index, entry) in self.entries.iter().enumerate() {
2835 let node_borrow = entry.node.borrow();
2836 Self::enumerate_link_order(
2837 &**node_borrow,
2838 index,
2839 &mut path_buf,
2840 0,
2841 &mut self.ordered_nodes,
2842 );
2843 }
2844 }
2845
2846 fn enumerate_link_order(
2847 node: &dyn ModifierNode,
2848 entry: usize,
2849 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
2850 path_len: usize,
2851 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2852 ) {
2853 let caps = node.node_state().capabilities();
2854 out.push((
2855 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
2856 caps,
2857 NodeCapabilities::empty(),
2858 ));
2859 let mut delegate_index = 0usize;
2860 node.for_each_delegate(&mut |child| {
2861 if path_len < MAX_DELEGATE_DEPTH {
2862 path_buf[path_len] = delegate_index;
2863 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
2864 }
2865 delegate_index += 1;
2866 });
2867 }
2868}
2869
2870impl<'a> ModifierChainNodeRef<'a> {
2871 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
2872 match &self.link {
2873 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
2874 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
2875 NodeLink::Entry(path) => {
2876 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2877 if path.delegates().is_empty() {
2878 f(node_borrow.node_state())
2879 } else {
2880 let mut current: &dyn ModifierNode = &**node_borrow;
2881 for &delegate_index in path.delegates() {
2882 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2883 current = delegate;
2884 } else {
2885 return f(node_borrow.node_state());
2886 }
2887 }
2888 f(current.node_state())
2889 }
2890 }
2891 }
2892 }
2893
2894 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
2897 match &self.link {
2898 NodeLink::Head => None,
2899 NodeLink::Tail => None,
2900 NodeLink::Entry(path) => {
2901 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2902 if path.delegates().is_empty() {
2903 Some(f(&**node_borrow))
2904 } else {
2905 let mut current: &dyn ModifierNode = &**node_borrow;
2906 for &delegate_index in path.delegates() {
2907 current = nth_delegate(current, delegate_index as usize)?;
2908 }
2909 Some(f(current))
2910 }
2911 }
2912 }
2913 }
2914
2915 #[inline]
2917 pub fn parent(&self) -> Option<Self> {
2918 self.with_state(|state| state.parent_link())
2919 .map(|link| self.chain.make_node_ref(link))
2920 }
2921
2922 #[inline]
2924 pub fn child(&self) -> Option<Self> {
2925 self.with_state(|state| state.child_link())
2926 .map(|link| self.chain.make_node_ref(link))
2927 }
2928
2929 #[inline]
2931 pub fn kind_set(&self) -> NodeCapabilities {
2932 if let Some(caps) = self.cached_capabilities {
2933 return caps;
2934 }
2935 match &self.link {
2936 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
2937 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
2938 }
2939 }
2940
2941 pub fn entry_index(&self) -> Option<usize> {
2943 match &self.link {
2944 NodeLink::Entry(path) => Some(path.entry()),
2945 _ => None,
2946 }
2947 }
2948
2949 pub fn delegate_depth(&self) -> usize {
2951 match &self.link {
2952 NodeLink::Entry(path) => path.delegates().len(),
2953 _ => 0,
2954 }
2955 }
2956
2957 #[inline]
2959 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
2960 if let Some(agg) = self.cached_aggregate_child {
2961 return agg;
2962 }
2963 if self.is_tail() {
2964 NodeCapabilities::empty()
2965 } else {
2966 self.with_state(|state| state.aggregate_child_capabilities())
2967 }
2968 }
2969
2970 pub fn is_head(&self) -> bool {
2972 matches!(self.link, NodeLink::Head)
2973 }
2974
2975 pub fn is_tail(&self) -> bool {
2977 matches!(self.link, NodeLink::Tail)
2978 }
2979
2980 pub fn is_sentinel(&self) -> bool {
2982 matches!(self.link, NodeLink::Head | NodeLink::Tail)
2983 }
2984
2985 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
2987 !mask.is_empty() && self.kind_set().intersects(mask)
2988 }
2989
2990 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
2992 where
2993 F: FnMut(ModifierChainNodeRef<'a>),
2994 {
2995 let mut current = if include_self {
2996 Some(self)
2997 } else {
2998 self.child()
2999 };
3000 while let Some(node) = current {
3001 if node.is_tail() {
3002 break;
3003 }
3004 if !node.is_sentinel() {
3005 f(node.clone());
3006 }
3007 current = node.child();
3008 }
3009 }
3010
3011 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3013 where
3014 F: FnMut(ModifierChainNodeRef<'a>),
3015 {
3016 if mask.is_empty() {
3017 self.visit_descendants(include_self, f);
3018 return;
3019 }
3020
3021 if !self.aggregate_child_capabilities().intersects(mask) {
3022 return;
3023 }
3024
3025 self.visit_descendants(include_self, |node| {
3026 if node.kind_set().intersects(mask) {
3027 f(node);
3028 }
3029 });
3030 }
3031
3032 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
3034 where
3035 F: FnMut(ModifierChainNodeRef<'a>),
3036 {
3037 let mut current = if include_self {
3038 Some(self)
3039 } else {
3040 self.parent()
3041 };
3042 while let Some(node) = current {
3043 if node.is_head() {
3044 break;
3045 }
3046 f(node.clone());
3047 current = node.parent();
3048 }
3049 }
3050
3051 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
3053 where
3054 F: FnMut(ModifierChainNodeRef<'a>),
3055 {
3056 if mask.is_empty() {
3057 self.visit_ancestors(include_self, f);
3058 return;
3059 }
3060
3061 self.visit_ancestors(include_self, |node| {
3062 if node.kind_set().intersects(mask) {
3063 f(node);
3064 }
3065 });
3066 }
3067}
3068
3069#[cfg(test)]
3070#[path = "tests/modifier_tests.rs"]
3071mod tests;