1use std::any::{type_name, Any, TypeId};
9use std::cell::{Cell, RefCell};
10use std::fmt;
11use std::hash::{Hash, Hasher};
12use std::ops::{BitOr, BitOrAssign};
13use std::rc::Rc;
14
15use cranpose_core::collections::map::HashMap;
16use cranpose_core::hash::default;
17
18pub use cranpose_ui_graphics::DrawScope;
19pub use cranpose_ui_graphics::Size;
20pub use cranpose_ui_layout::{Constraints, Measurable};
21
22use crate::nodes::input::types::PointerEvent;
23#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
28pub enum InvalidationKind {
29 Layout,
30 Draw,
31 PointerInput,
32 Semantics,
33 Focus,
34}
35
36pub trait ModifierNodeContext {
38 fn invalidate(&mut self, _kind: InvalidationKind) {}
40
41 fn request_update(&mut self) {}
44
45 fn node_id(&self) -> Option<cranpose_core::NodeId> {
48 None
49 }
50
51 fn push_active_capabilities(&mut self, _capabilities: NodeCapabilities) {}
53
54 fn pop_active_capabilities(&mut self) {}
56}
57
58#[derive(Default, Debug, Clone)]
67pub struct BasicModifierNodeContext {
68 invalidations: Vec<ModifierInvalidation>,
69 update_requested: bool,
70 active_capabilities: Vec<NodeCapabilities>,
71 node_id: Option<cranpose_core::NodeId>,
72}
73
74impl BasicModifierNodeContext {
75 pub fn new() -> Self {
77 Self::default()
78 }
79
80 pub fn invalidations(&self) -> &[ModifierInvalidation] {
84 &self.invalidations
85 }
86
87 pub fn clear_invalidations(&mut self) {
89 self.invalidations.clear();
90 }
91
92 pub fn take_invalidations(&mut self) -> Vec<ModifierInvalidation> {
94 std::mem::take(&mut self.invalidations)
95 }
96
97 pub fn update_requested(&self) -> bool {
100 self.update_requested
101 }
102
103 pub fn take_update_requested(&mut self) -> bool {
105 std::mem::take(&mut self.update_requested)
106 }
107
108 pub fn set_node_id(&mut self, id: Option<cranpose_core::NodeId>) {
110 self.node_id = id;
111 }
112
113 fn push_invalidation(&mut self, kind: InvalidationKind) {
114 let mut capabilities = self.current_capabilities();
115 capabilities.insert(NodeCapabilities::for_invalidation(kind));
116 if let Some(existing) = self
117 .invalidations
118 .iter_mut()
119 .find(|entry| entry.kind() == kind)
120 {
121 let updated = existing.capabilities() | capabilities;
122 *existing = ModifierInvalidation::new(kind, updated);
123 } else {
124 self.invalidations
125 .push(ModifierInvalidation::new(kind, capabilities));
126 }
127 }
128
129 fn current_capabilities(&self) -> NodeCapabilities {
130 self.active_capabilities
131 .last()
132 .copied()
133 .unwrap_or_else(NodeCapabilities::empty)
134 }
135}
136
137impl ModifierNodeContext for BasicModifierNodeContext {
138 fn invalidate(&mut self, kind: InvalidationKind) {
139 self.push_invalidation(kind);
140 }
141
142 fn request_update(&mut self) {
143 self.update_requested = true;
144 }
145
146 fn push_active_capabilities(&mut self, capabilities: NodeCapabilities) {
147 self.active_capabilities.push(capabilities);
148 }
149
150 fn pop_active_capabilities(&mut self) {
151 self.active_capabilities.pop();
152 }
153
154 fn node_id(&self) -> Option<cranpose_core::NodeId> {
155 self.node_id
156 }
157}
158
159const MAX_DELEGATE_DEPTH: usize = 3;
163
164#[derive(Copy, Clone, Debug, PartialEq, Eq)]
165pub(crate) struct NodePath {
166 entry: usize,
167 delegate_buf: [u8; MAX_DELEGATE_DEPTH],
168 delegate_len: u8,
169}
170
171impl NodePath {
172 #[inline]
173 fn root(entry: usize) -> Self {
174 Self {
175 entry,
176 delegate_buf: [0; MAX_DELEGATE_DEPTH],
177 delegate_len: 0,
178 }
179 }
180
181 #[inline]
182 fn from_slice(entry: usize, path: &[usize]) -> Self {
183 debug_assert!(
184 path.len() <= MAX_DELEGATE_DEPTH,
185 "delegate depth {} exceeds MAX_DELEGATE_DEPTH {}",
186 path.len(),
187 MAX_DELEGATE_DEPTH
188 );
189 debug_assert!(
190 path.iter().all(|&i| i <= u8::MAX as usize),
191 "delegate index exceeds u8 range"
192 );
193 let mut delegate_buf = [0u8; MAX_DELEGATE_DEPTH];
194 for (i, &v) in path.iter().enumerate().take(MAX_DELEGATE_DEPTH) {
195 delegate_buf[i] = v as u8;
196 }
197 Self {
198 entry,
199 delegate_buf,
200 delegate_len: path.len().min(MAX_DELEGATE_DEPTH) as u8,
201 }
202 }
203
204 #[inline]
205 fn entry(&self) -> usize {
206 self.entry
207 }
208
209 #[inline]
210 fn delegates(&self) -> &[u8] {
211 &self.delegate_buf[..self.delegate_len as usize]
212 }
213}
214
215#[derive(Copy, Clone, Debug, PartialEq, Eq)]
216pub(crate) enum NodeLink {
217 Head,
218 Tail,
219 Entry(NodePath),
220}
221
222#[derive(Debug)]
228pub struct NodeState {
229 aggregate_child_capabilities: Cell<NodeCapabilities>,
230 capabilities: Cell<NodeCapabilities>,
231 parent: RefCell<Option<NodeLink>>,
232 child: RefCell<Option<NodeLink>>,
233 attached: Cell<bool>,
234 is_sentinel: bool,
235}
236
237impl Default for NodeState {
238 fn default() -> Self {
239 Self::new()
240 }
241}
242
243impl NodeState {
244 pub const fn new() -> Self {
245 Self {
246 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
247 capabilities: Cell::new(NodeCapabilities::empty()),
248 parent: RefCell::new(None),
249 child: RefCell::new(None),
250 attached: Cell::new(false),
251 is_sentinel: false,
252 }
253 }
254
255 pub const fn sentinel() -> Self {
256 Self {
257 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
258 capabilities: Cell::new(NodeCapabilities::empty()),
259 parent: RefCell::new(None),
260 child: RefCell::new(None),
261 attached: Cell::new(true),
262 is_sentinel: true,
263 }
264 }
265
266 pub fn set_capabilities(&self, capabilities: NodeCapabilities) {
267 self.capabilities.set(capabilities);
268 }
269
270 #[inline]
271 pub fn capabilities(&self) -> NodeCapabilities {
272 self.capabilities.get()
273 }
274
275 pub fn set_aggregate_child_capabilities(&self, capabilities: NodeCapabilities) {
276 self.aggregate_child_capabilities.set(capabilities);
277 }
278
279 #[inline]
280 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
281 self.aggregate_child_capabilities.get()
282 }
283
284 pub(crate) fn set_parent_link(&self, parent: Option<NodeLink>) {
285 *self.parent.borrow_mut() = parent;
286 }
287
288 #[inline]
289 pub(crate) fn parent_link(&self) -> Option<NodeLink> {
290 *self.parent.borrow()
291 }
292
293 pub(crate) fn set_child_link(&self, child: Option<NodeLink>) {
294 *self.child.borrow_mut() = child;
295 }
296
297 #[inline]
298 pub(crate) fn child_link(&self) -> Option<NodeLink> {
299 *self.child.borrow()
300 }
301
302 pub fn set_attached(&self, attached: bool) {
303 self.attached.set(attached);
304 }
305
306 pub fn is_attached(&self) -> bool {
307 self.attached.get()
308 }
309
310 pub fn is_sentinel(&self) -> bool {
311 self.is_sentinel
312 }
313}
314
315pub trait DelegatableNode {
317 fn node_state(&self) -> &NodeState;
318 fn aggregate_child_capabilities(&self) -> NodeCapabilities {
319 self.node_state().aggregate_child_capabilities()
320 }
321}
322
323pub trait ModifierNode: Any + DelegatableNode {
381 fn on_attach(&mut self, _context: &mut dyn ModifierNodeContext) {}
382
383 fn on_detach(&mut self) {}
384
385 fn on_reset(&mut self) {}
386
387 fn as_draw_node(&self) -> Option<&dyn DrawModifierNode> {
389 None
390 }
391
392 fn as_draw_node_mut(&mut self) -> Option<&mut dyn DrawModifierNode> {
394 None
395 }
396
397 fn as_pointer_input_node(&self) -> Option<&dyn PointerInputNode> {
399 None
400 }
401
402 fn as_pointer_input_node_mut(&mut self) -> Option<&mut dyn PointerInputNode> {
404 None
405 }
406
407 fn as_semantics_node(&self) -> Option<&dyn SemanticsNode> {
409 None
410 }
411
412 fn as_semantics_node_mut(&mut self) -> Option<&mut dyn SemanticsNode> {
414 None
415 }
416
417 fn as_focus_node(&self) -> Option<&dyn FocusNode> {
419 None
420 }
421
422 fn as_focus_node_mut(&mut self) -> Option<&mut dyn FocusNode> {
424 None
425 }
426
427 fn as_layout_node(&self) -> Option<&dyn LayoutModifierNode> {
429 None
430 }
431
432 fn as_layout_node_mut(&mut self) -> Option<&mut dyn LayoutModifierNode> {
434 None
435 }
436
437 fn for_each_delegate<'b>(&'b self, _visitor: &mut dyn FnMut(&'b dyn ModifierNode)) {}
439
440 fn for_each_delegate_mut<'b>(&'b mut self, _visitor: &mut dyn FnMut(&'b mut dyn ModifierNode)) {
442 }
443}
444
445pub trait LayoutModifierNode: ModifierNode {
451 fn measure(
473 &self,
474 _context: &mut dyn ModifierNodeContext,
475 measurable: &dyn Measurable,
476 constraints: Constraints,
477 ) -> cranpose_ui_layout::LayoutModifierMeasureResult {
478 let placeable = measurable.measure(constraints);
480 cranpose_ui_layout::LayoutModifierMeasureResult::with_size(Size {
481 width: placeable.width(),
482 height: placeable.height(),
483 })
484 }
485
486 fn min_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
488 0.0
489 }
490
491 fn max_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
493 0.0
494 }
495
496 fn min_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
498 0.0
499 }
500
501 fn max_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
503 0.0
504 }
505}
506
507pub trait DrawModifierNode: ModifierNode {
515 fn draw(&self, _draw_scope: &mut dyn DrawScope) {
524 }
526
527 fn create_draw_closure(&self) -> Option<NodeDrawClosure> {
538 None
539 }
540
541 fn create_behind_draw_closure(&self) -> Option<NodeDrawClosure> {
546 None
547 }
548}
549
550pub type NodeDrawClosure = Rc<dyn Fn(&mut cranpose_ui_graphics::DrawScopeDefault)>;
555
556pub trait PointerInputNode: ModifierNode {
562 fn on_pointer_event(
565 &mut self,
566 _context: &mut dyn ModifierNodeContext,
567 _event: &PointerEvent,
568 ) -> bool {
569 false
570 }
571
572 fn hit_test(&self, _x: f32, _y: f32) -> bool {
575 true
576 }
577
578 fn pointer_input_handler(&self) -> Option<Rc<dyn Fn(PointerEvent)>> {
580 None
581 }
582
583 fn layout_size_sink(&self) -> Option<Rc<Cell<Size>>> {
596 None
597 }
598}
599
600pub trait SemanticsNode: ModifierNode {
606 fn merge_semantics(&self, _config: &mut SemanticsConfiguration) {
608 }
610}
611
612#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
617pub enum FocusState {
618 Active,
620 ActiveParent,
622 Captured,
626 #[default]
629 Inactive,
630}
631
632impl FocusState {
633 pub fn is_focused(self) -> bool {
635 matches!(self, FocusState::Active | FocusState::Captured)
636 }
637
638 pub fn has_focus(self) -> bool {
640 matches!(
641 self,
642 FocusState::Active | FocusState::ActiveParent | FocusState::Captured
643 )
644 }
645
646 pub fn is_captured(self) -> bool {
648 matches!(self, FocusState::Captured)
649 }
650}
651
652pub trait FocusNode: ModifierNode {
657 fn focus_state(&self) -> FocusState;
659
660 fn on_focus_changed(&mut self, _context: &mut dyn ModifierNodeContext, _state: FocusState) {
662 }
664}
665
666#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
677pub enum SemanticsWidgetRole {
678 Button,
679 Checkbox,
680 Switch,
681 RadioButton,
682 Tab,
683 Image,
684 Header,
689}
690
691#[derive(Clone)]
698pub struct SemanticsCustomAction {
699 pub label: String,
701 handler: Rc<dyn Fn()>,
702}
703
704impl SemanticsCustomAction {
705 pub fn new(label: impl Into<String>, handler: impl Fn() + 'static) -> Self {
706 Self {
707 label: label.into(),
708 handler: Rc::new(handler),
709 }
710 }
711
712 pub fn invoke(&self) {
713 (self.handler)();
714 }
715}
716
717impl fmt::Debug for SemanticsCustomAction {
718 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
719 f.debug_struct("SemanticsCustomAction")
720 .field("label", &self.label)
721 .finish_non_exhaustive()
722 }
723}
724
725impl PartialEq for SemanticsCustomAction {
735 fn eq(&self, other: &Self) -> bool {
736 self.label == other.label
737 }
738}
739
740impl Eq for SemanticsCustomAction {}
741
742#[derive(Clone, Debug, PartialEq)]
757pub struct CanvasSemanticsNode {
758 pub key: u64,
765 pub bounds: cranpose_ui_graphics::Rect,
767 pub label: String,
768 pub role: Option<SemanticsWidgetRole>,
769 pub state_description: Option<String>,
773 pub on_click_label: Option<String>,
776 pub clickable: bool,
777 pub selected: Option<bool>,
779 pub toggled: Option<bool>,
781 pub enabled: bool,
782 pub custom_actions: Vec<SemanticsCustomAction>,
783}
784
785impl Default for CanvasSemanticsNode {
786 fn default() -> Self {
787 Self {
788 key: 0,
789 bounds: cranpose_ui_graphics::Rect {
790 x: 0.0,
791 y: 0.0,
792 width: 0.0,
793 height: 0.0,
794 },
795 label: String::new(),
796 role: None,
797 state_description: None,
798 on_click_label: None,
799 clickable: false,
800 selected: None,
801 toggled: None,
802 enabled: true,
806 custom_actions: Vec::new(),
807 }
808 }
809}
810
811impl CanvasSemanticsNode {
812 pub fn control(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
814 Self {
815 key,
816 bounds,
817 label: label.into(),
818 clickable: true,
819 ..Self::default()
820 }
821 }
822
823 pub fn text(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
825 Self {
826 key,
827 bounds,
828 label: label.into(),
829 ..Self::default()
830 }
831 }
832
833 pub fn with_role(mut self, role: SemanticsWidgetRole) -> Self {
834 self.role = Some(role);
835 self
836 }
837
838 pub fn with_state_description(mut self, state: impl Into<String>) -> Self {
839 self.state_description = Some(state.into());
840 self
841 }
842
843 pub fn with_click_label(mut self, label: impl Into<String>) -> Self {
844 self.on_click_label = Some(label.into());
845 self.clickable = true;
846 self
847 }
848
849 pub fn with_selected(mut self, selected: bool) -> Self {
850 self.selected = Some(selected);
851 self
852 }
853
854 pub fn with_toggled(mut self, toggled: bool) -> Self {
855 self.toggled = Some(toggled);
856 self
857 }
858
859 pub fn with_enabled(mut self, enabled: bool) -> Self {
860 self.enabled = enabled;
861 self
862 }
863
864 pub fn with_custom_action(mut self, action: SemanticsCustomAction) -> Self {
865 self.custom_actions.push(action);
866 self
867 }
868}
869
870#[derive(Clone, Debug, PartialEq)]
872pub struct SemanticsConfiguration {
873 pub content_description: Option<String>,
874 pub state_description: Option<String>,
876 pub on_click_label: Option<String>,
878 pub role: Option<SemanticsWidgetRole>,
880 pub selected: Option<bool>,
881 pub toggled: Option<bool>,
882 pub enabled: bool,
883 pub is_clickable: bool,
884 pub is_editable_text: bool,
885 pub text_selection: Option<crate::text::TextRange>,
886 pub custom_actions: Vec<SemanticsCustomAction>,
887 pub canvas_children: Vec<CanvasSemanticsNode>,
890}
891
892impl Default for SemanticsConfiguration {
893 fn default() -> Self {
894 Self {
895 content_description: None,
896 state_description: None,
897 on_click_label: None,
898 role: None,
899 selected: None,
900 toggled: None,
901 enabled: true,
902 is_clickable: false,
903 is_editable_text: false,
904 text_selection: None,
905 custom_actions: Vec::new(),
906 canvas_children: Vec::new(),
907 }
908 }
909}
910
911impl SemanticsConfiguration {
912 pub fn merge(&mut self, other: &SemanticsConfiguration) {
913 if let Some(description) = &other.content_description {
914 self.content_description = Some(description.clone());
915 }
916 if let Some(state) = &other.state_description {
917 self.state_description = Some(state.clone());
918 }
919 if let Some(label) = &other.on_click_label {
920 self.on_click_label = Some(label.clone());
921 }
922 if let Some(role) = other.role {
923 self.role = Some(role);
924 }
925 if let Some(selected) = other.selected {
926 self.selected = Some(selected);
927 }
928 if let Some(toggled) = other.toggled {
929 self.toggled = Some(toggled);
930 }
931 self.enabled &= other.enabled;
934 self.is_clickable |= other.is_clickable;
935 self.is_editable_text |= other.is_editable_text;
936 if let Some(selection) = other.text_selection {
937 self.text_selection = Some(selection);
938 }
939 self.custom_actions
940 .extend(other.custom_actions.iter().cloned());
941 self.canvas_children
942 .extend(other.canvas_children.iter().cloned());
943 }
944
945 pub fn is_activatable(&self) -> bool {
948 self.is_clickable || self.on_click_label.is_some()
949 }
950}
951
952impl fmt::Debug for dyn ModifierNode {
953 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
954 f.debug_struct("ModifierNode").finish_non_exhaustive()
955 }
956}
957
958impl dyn ModifierNode {
959 pub fn as_any(&self) -> &dyn Any {
960 self
961 }
962
963 pub fn as_any_mut(&mut self) -> &mut dyn Any {
964 self
965 }
966}
967
968pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
971 type Node: ModifierNode;
972
973 fn create(&self) -> Self::Node;
975
976 fn update(&self, node: &mut Self::Node);
978
979 fn key(&self) -> Option<u64> {
981 None
982 }
983
984 fn inspector_name(&self) -> &'static str {
986 type_name::<Self>()
987 }
988
989 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
991
992 fn capabilities(&self) -> NodeCapabilities {
995 NodeCapabilities::default()
996 }
997
998 fn always_update(&self) -> bool {
1004 false
1005 }
1006
1007 fn auto_invalidate_on_update(&self) -> bool {
1010 true
1011 }
1012
1013 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1020 None
1021 }
1022}
1023
1024#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1026pub struct NodeCapabilities(u32);
1027
1028impl NodeCapabilities {
1029 pub const NONE: Self = Self(0);
1031 pub const LAYOUT: Self = Self(1 << 0);
1033 pub const DRAW: Self = Self(1 << 1);
1035 pub const POINTER_INPUT: Self = Self(1 << 2);
1037 pub const SEMANTICS: Self = Self(1 << 3);
1039 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1041 pub const FOCUS: Self = Self(1 << 5);
1043
1044 pub const fn empty() -> Self {
1046 Self::NONE
1047 }
1048
1049 pub const fn contains(self, other: Self) -> bool {
1051 (self.0 & other.0) == other.0
1052 }
1053
1054 pub const fn intersects(self, other: Self) -> bool {
1056 (self.0 & other.0) != 0
1057 }
1058
1059 pub fn insert(&mut self, other: Self) {
1061 self.0 |= other.0;
1062 }
1063
1064 pub const fn bits(self) -> u32 {
1066 self.0
1067 }
1068
1069 pub const fn is_empty(self) -> bool {
1071 self.0 == 0
1072 }
1073
1074 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1076 match kind {
1077 InvalidationKind::Layout => Self::LAYOUT,
1078 InvalidationKind::Draw => Self::DRAW,
1079 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1080 InvalidationKind::Semantics => Self::SEMANTICS,
1081 InvalidationKind::Focus => Self::FOCUS,
1082 }
1083 }
1084}
1085
1086impl Default for NodeCapabilities {
1087 fn default() -> Self {
1088 Self::NONE
1089 }
1090}
1091
1092impl fmt::Debug for NodeCapabilities {
1093 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1094 f.debug_struct("NodeCapabilities")
1095 .field("layout", &self.contains(Self::LAYOUT))
1096 .field("draw", &self.contains(Self::DRAW))
1097 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1098 .field("semantics", &self.contains(Self::SEMANTICS))
1099 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1100 .field("focus", &self.contains(Self::FOCUS))
1101 .finish()
1102 }
1103}
1104
1105impl BitOr for NodeCapabilities {
1106 type Output = Self;
1107
1108 fn bitor(self, rhs: Self) -> Self::Output {
1109 Self(self.0 | rhs.0)
1110 }
1111}
1112
1113impl BitOrAssign for NodeCapabilities {
1114 fn bitor_assign(&mut self, rhs: Self) {
1115 self.0 |= rhs.0;
1116 }
1117}
1118
1119#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1121pub struct ModifierInvalidation {
1122 kind: InvalidationKind,
1123 capabilities: NodeCapabilities,
1124}
1125
1126impl ModifierInvalidation {
1127 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1129 Self { kind, capabilities }
1130 }
1131
1132 pub const fn kind(self) -> InvalidationKind {
1134 self.kind
1135 }
1136
1137 pub const fn capabilities(self) -> NodeCapabilities {
1139 self.capabilities
1140 }
1141}
1142
1143pub trait AnyModifierElement: fmt::Debug {
1145 fn node_type(&self) -> TypeId;
1146
1147 fn element_type(&self) -> TypeId;
1148
1149 fn create_node(&self) -> Box<dyn ModifierNode>;
1150
1151 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
1152
1153 fn update_node(&self, node: &mut dyn ModifierNode);
1154
1155 fn key(&self) -> Option<u64>;
1156
1157 fn capabilities(&self) -> NodeCapabilities {
1158 NodeCapabilities::default()
1159 }
1160
1161 fn hash_code(&self) -> u64;
1162
1163 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
1164
1165 fn inspector_name(&self) -> &'static str;
1166
1167 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
1168
1169 fn requires_update(&self) -> bool;
1170
1171 fn auto_invalidates_on_update(&self) -> bool;
1172
1173 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
1174
1175 fn as_any(&self) -> &dyn Any;
1176}
1177
1178struct TypedModifierElement<E: ModifierNodeElement> {
1179 element: E,
1180 cached_hash: u64,
1181}
1182
1183impl<E: ModifierNodeElement> TypedModifierElement<E> {
1184 fn new(element: E) -> Self {
1185 let mut hasher = default::new();
1186 element.hash(&mut hasher);
1187 Self {
1188 element,
1189 cached_hash: hasher.finish(),
1190 }
1191 }
1192}
1193
1194impl<E> fmt::Debug for TypedModifierElement<E>
1195where
1196 E: ModifierNodeElement,
1197{
1198 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1199 f.debug_struct("TypedModifierElement")
1200 .field("type", &type_name::<E>())
1201 .finish()
1202 }
1203}
1204
1205impl<E> AnyModifierElement for TypedModifierElement<E>
1206where
1207 E: ModifierNodeElement,
1208{
1209 fn node_type(&self) -> TypeId {
1210 TypeId::of::<E::Node>()
1211 }
1212
1213 fn element_type(&self) -> TypeId {
1214 TypeId::of::<E>()
1215 }
1216
1217 fn create_node(&self) -> Box<dyn ModifierNode> {
1218 Box::new(self.element.create())
1219 }
1220
1221 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
1222 node.as_any().is::<E::Node>()
1223 }
1224
1225 fn update_node(&self, node: &mut dyn ModifierNode) {
1226 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
1227 self.element.update(typed);
1228 }
1229 }
1230
1231 fn key(&self) -> Option<u64> {
1232 self.element.key()
1233 }
1234
1235 fn capabilities(&self) -> NodeCapabilities {
1236 self.element.capabilities()
1237 }
1238
1239 fn hash_code(&self) -> u64 {
1240 self.cached_hash
1241 }
1242
1243 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
1244 other
1245 .as_any()
1246 .downcast_ref::<Self>()
1247 .map(|typed| typed.element == self.element)
1248 .unwrap_or(false)
1249 }
1250
1251 fn inspector_name(&self) -> &'static str {
1252 self.element.inspector_name()
1253 }
1254
1255 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
1256 self.element.inspector_properties(visitor);
1257 }
1258
1259 fn requires_update(&self) -> bool {
1260 self.element.always_update()
1261 }
1262
1263 fn auto_invalidates_on_update(&self) -> bool {
1264 self.element.auto_invalidate_on_update()
1265 }
1266
1267 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1268 self.element.update_invalidation_kind()
1269 }
1270
1271 fn as_any(&self) -> &dyn Any {
1272 self
1273 }
1274}
1275
1276fn request_update_auto_invalidations(
1277 element: &dyn AnyModifierElement,
1278 context: &mut dyn ModifierNodeContext,
1279 capabilities: NodeCapabilities,
1280) {
1281 if let Some(kind) = element.update_invalidation_kind() {
1282 let capabilities = NodeCapabilities::for_invalidation(kind);
1283 context.push_active_capabilities(capabilities);
1284 context.invalidate(kind);
1285 context.pop_active_capabilities();
1286 } else if element.auto_invalidates_on_update() {
1287 request_auto_invalidations(context, capabilities);
1288 }
1289}
1290
1291pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
1294 Rc::new(TypedModifierElement::new(element))
1295}
1296
1297pub type DynModifierElement = Rc<dyn AnyModifierElement>;
1299
1300#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1301enum TraversalDirection {
1302 Forward,
1303 Backward,
1304}
1305
1306pub struct ModifierChainIter<'a> {
1311 chain: &'a ModifierNodeChain,
1312 cursor: usize,
1315 remaining: usize,
1317 direction: TraversalDirection,
1318}
1319
1320impl<'a> ModifierChainIter<'a> {
1321 fn forward(chain: &'a ModifierNodeChain) -> Self {
1322 Self {
1323 chain,
1324 cursor: 0,
1325 remaining: chain.ordered_nodes.len(),
1326 direction: TraversalDirection::Forward,
1327 }
1328 }
1329
1330 fn backward(chain: &'a ModifierNodeChain) -> Self {
1331 let len = chain.ordered_nodes.len();
1332 Self {
1333 chain,
1334 cursor: len.wrapping_sub(1),
1335 remaining: len,
1336 direction: TraversalDirection::Backward,
1337 }
1338 }
1339}
1340
1341impl<'a> Iterator for ModifierChainIter<'a> {
1342 type Item = ModifierChainNodeRef<'a>;
1343
1344 #[inline]
1345 fn next(&mut self) -> Option<Self::Item> {
1346 if self.remaining == 0 {
1347 return None;
1348 }
1349 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
1350 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
1351 self.remaining -= 1;
1352 match self.direction {
1353 TraversalDirection::Forward => self.cursor += 1,
1354 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
1355 }
1356 Some(node_ref)
1357 }
1358
1359 #[inline]
1360 fn size_hint(&self) -> (usize, Option<usize>) {
1361 (self.remaining, Some(self.remaining))
1362 }
1363}
1364
1365impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
1366impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
1367
1368#[derive(Debug)]
1369struct ModifierNodeEntry {
1370 element_type: TypeId,
1371 node_type: TypeId,
1372 key: Option<u64>,
1373 hash_code: u64,
1374 element: DynModifierElement,
1375 node: Rc<RefCell<Box<dyn ModifierNode>>>,
1376 capabilities: NodeCapabilities,
1377}
1378
1379impl ModifierNodeEntry {
1380 fn new(
1381 element_type: TypeId,
1382 node_type: TypeId,
1383 key: Option<u64>,
1384 element: DynModifierElement,
1385 node: Box<dyn ModifierNode>,
1386 hash_code: u64,
1387 capabilities: NodeCapabilities,
1388 ) -> Self {
1389 let node_rc = Rc::new(RefCell::new(node));
1391 let entry = Self {
1392 element_type,
1393 node_type,
1394 key,
1395 hash_code,
1396 element,
1397 node: Rc::clone(&node_rc),
1398 capabilities,
1399 };
1400 entry
1401 .node
1402 .borrow()
1403 .node_state()
1404 .set_capabilities(entry.capabilities);
1405 entry
1406 }
1407}
1408
1409fn visit_node_tree_mut(
1410 node: &mut dyn ModifierNode,
1411 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
1412) {
1413 visitor(node);
1414 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
1415}
1416
1417fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
1418 let mut current = 0usize;
1419 let mut result: Option<&dyn ModifierNode> = None;
1420 node.for_each_delegate(&mut |child| {
1421 if result.is_none() && current == target {
1422 result = Some(child);
1423 }
1424 current += 1;
1425 });
1426 result
1427}
1428
1429fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
1430 let mut current = 0usize;
1431 let mut result: Option<&mut dyn ModifierNode> = None;
1432 node.for_each_delegate_mut(&mut |child| {
1433 if result.is_none() && current == target {
1434 result = Some(child);
1435 }
1436 current += 1;
1437 });
1438 result
1439}
1440
1441fn with_node_context<F, R>(
1442 node: &mut dyn ModifierNode,
1443 context: &mut dyn ModifierNodeContext,
1444 f: F,
1445) -> R
1446where
1447 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
1448{
1449 context.push_active_capabilities(node.node_state().capabilities());
1450 let result = f(node, context);
1451 context.pop_active_capabilities();
1452 result
1453}
1454
1455fn request_auto_invalidations(
1456 context: &mut dyn ModifierNodeContext,
1457 capabilities: NodeCapabilities,
1458) {
1459 if capabilities.is_empty() {
1460 return;
1461 }
1462
1463 context.push_active_capabilities(capabilities);
1464
1465 if capabilities.contains(NodeCapabilities::LAYOUT) {
1466 context.invalidate(InvalidationKind::Layout);
1467 }
1468 if capabilities.contains(NodeCapabilities::DRAW) {
1469 context.invalidate(InvalidationKind::Draw);
1470 }
1471 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
1472 context.invalidate(InvalidationKind::PointerInput);
1473 }
1474 if capabilities.contains(NodeCapabilities::SEMANTICS) {
1475 context.invalidate(InvalidationKind::Semantics);
1476 }
1477 if capabilities.contains(NodeCapabilities::FOCUS) {
1478 context.invalidate(InvalidationKind::Focus);
1479 }
1480
1481 context.pop_active_capabilities();
1482}
1483
1484fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
1492 visit_node_tree_mut(node, &mut |n| {
1493 if !n.node_state().is_attached() {
1494 n.node_state().set_attached(true);
1495 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
1496 }
1497 });
1498}
1499
1500fn reset_node_tree(node: &mut dyn ModifierNode) {
1501 visit_node_tree_mut(node, &mut |n| n.on_reset());
1502}
1503
1504fn detach_node_tree(node: &mut dyn ModifierNode) {
1505 visit_node_tree_mut(node, &mut |n| {
1506 if n.node_state().is_attached() {
1507 n.on_detach();
1508 n.node_state().set_attached(false);
1509 }
1510 n.node_state().set_parent_link(None);
1511 n.node_state().set_child_link(None);
1512 n.node_state()
1513 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1514 });
1515}
1516
1517pub struct ModifierNodeChain {
1524 entries: Vec<ModifierNodeEntry>,
1525 aggregated_capabilities: NodeCapabilities,
1526 head_aggregate_child_capabilities: NodeCapabilities,
1527 head_sentinel: Box<SentinelNode>,
1528 tail_sentinel: Box<SentinelNode>,
1529 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
1531 scratch_old_used: Vec<bool>,
1533 scratch_match_order: Vec<Option<usize>>,
1534 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
1535 scratch_elements: Vec<DynModifierElement>,
1536}
1537
1538struct SentinelNode {
1539 state: NodeState,
1540}
1541
1542impl SentinelNode {
1543 fn new() -> Self {
1544 Self {
1545 state: NodeState::sentinel(),
1546 }
1547 }
1548}
1549
1550impl DelegatableNode for SentinelNode {
1551 fn node_state(&self) -> &NodeState {
1552 &self.state
1553 }
1554}
1555
1556impl ModifierNode for SentinelNode {}
1557
1558#[derive(Clone)]
1559pub struct ModifierChainNodeRef<'a> {
1560 chain: &'a ModifierNodeChain,
1561 link: NodeLink,
1562 cached_capabilities: Option<NodeCapabilities>,
1564 cached_aggregate_child: Option<NodeCapabilities>,
1566}
1567
1568impl Default for ModifierNodeChain {
1569 fn default() -> Self {
1570 Self::new()
1571 }
1572}
1573
1574struct EntryIndex {
1579 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1581 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1583 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
1585}
1586
1587struct EntryMatchQuery<'a> {
1588 element_type: TypeId,
1589 node_type: TypeId,
1590 key: Option<u64>,
1591 hash_code: u64,
1592 element: &'a DynModifierElement,
1593}
1594
1595impl EntryIndex {
1596 fn build(entries: &[ModifierNodeEntry]) -> Self {
1597 let mut keyed = HashMap::default();
1598 let mut hashed = HashMap::default();
1599 let mut typed = HashMap::default();
1600
1601 for (i, entry) in entries.iter().enumerate() {
1602 if let Some(key_value) = entry.key {
1603 keyed
1605 .entry((entry.element_type, entry.node_type, key_value))
1606 .or_insert_with(Vec::new)
1607 .push(i);
1608 } else {
1609 hashed
1611 .entry((entry.element_type, entry.node_type, entry.hash_code))
1612 .or_insert_with(Vec::new)
1613 .push(i);
1614 typed
1615 .entry((entry.element_type, entry.node_type))
1616 .or_insert_with(Vec::new)
1617 .push(i);
1618 }
1619 }
1620
1621 Self {
1622 keyed,
1623 hashed,
1624 typed,
1625 }
1626 }
1627
1628 fn find_match(
1635 &self,
1636 entries: &[ModifierNodeEntry],
1637 used: &[bool],
1638 query: EntryMatchQuery<'_>,
1639 ) -> Option<usize> {
1640 if let Some(key_value) = query.key {
1641 if let Some(candidates) =
1643 self.keyed
1644 .get(&(query.element_type, query.node_type, key_value))
1645 {
1646 for &i in candidates {
1647 if !used[i] {
1648 return Some(i);
1649 }
1650 }
1651 }
1652 } else {
1653 if let Some(candidates) =
1655 self.hashed
1656 .get(&(query.element_type, query.node_type, query.hash_code))
1657 {
1658 for &i in candidates {
1659 if !used[i]
1660 && entries[i]
1661 .element
1662 .as_ref()
1663 .equals_element(query.element.as_ref())
1664 {
1665 return Some(i);
1666 }
1667 }
1668 }
1669
1670 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
1672 for &i in candidates {
1673 if !used[i] {
1674 return Some(i);
1675 }
1676 }
1677 }
1678 }
1679
1680 None
1681 }
1682}
1683
1684impl ModifierNodeChain {
1685 pub fn new() -> Self {
1686 let mut chain = Self {
1687 entries: Vec::new(),
1688 aggregated_capabilities: NodeCapabilities::empty(),
1689 head_aggregate_child_capabilities: NodeCapabilities::empty(),
1690 head_sentinel: Box::new(SentinelNode::new()),
1691 tail_sentinel: Box::new(SentinelNode::new()),
1692 ordered_nodes: Vec::new(),
1693 scratch_old_used: Vec::new(),
1694 scratch_match_order: Vec::new(),
1695 scratch_final_slots: Vec::new(),
1696 scratch_elements: Vec::new(),
1697 };
1698 chain.sync_chain_links();
1699 chain
1700 }
1701
1702 pub fn detach_nodes(&mut self) {
1704 for entry in &self.entries {
1705 detach_node_tree(&mut **entry.node.borrow_mut());
1706 }
1707 }
1708
1709 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
1711 for entry in &self.entries {
1712 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1713 }
1714 }
1715
1716 pub fn repair_chain(&mut self) {
1719 self.sync_chain_links();
1720 }
1721
1722 pub fn update_from_slice(
1728 &mut self,
1729 elements: &[DynModifierElement],
1730 context: &mut dyn ModifierNodeContext,
1731 ) {
1732 self.update_from_ref_iter(elements.iter(), context);
1733 }
1734
1735 pub fn update_from_ref_iter<'a, I>(
1740 &mut self,
1741 elements: I,
1742 context: &mut dyn ModifierNodeContext,
1743 ) where
1744 I: Iterator<Item = &'a DynModifierElement>,
1745 {
1746 let old_len = self.entries.len();
1750 let mut fast_path_failed_at: Option<usize> = None;
1751 let mut elements_count = 0;
1752
1753 self.scratch_elements.clear();
1755
1756 for (idx, element) in elements.enumerate() {
1757 elements_count = idx + 1;
1758
1759 if fast_path_failed_at.is_none() && idx < old_len {
1760 let entry = &mut self.entries[idx];
1761 let same_type = entry.element_type == element.element_type();
1762 let same_node_type = entry.node_type == element.node_type();
1763 let same_key = entry.key == element.key();
1764 let same_hash = entry.hash_code == element.hash_code();
1765
1766 let positional_update = element.requires_update();
1769 if same_type && same_node_type && same_key && (same_hash || positional_update) {
1770 let can_update_node = {
1771 let node_borrow = entry.node.borrow();
1772 element.can_update_node(&**node_borrow)
1773 };
1774 if !can_update_node {
1775 fast_path_failed_at = Some(idx);
1776 self.scratch_elements.push(element.clone());
1777 continue;
1778 }
1779
1780 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1782 let capabilities = element.capabilities();
1783
1784 {
1786 let node_borrow = entry.node.borrow();
1787 if !node_borrow.node_state().is_attached() {
1788 drop(node_borrow);
1789 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1790 }
1791 }
1792
1793 let needs_update = !same_element || element.requires_update();
1795 if needs_update {
1796 element.update_node(&mut **entry.node.borrow_mut());
1797 entry.element = element.clone();
1798 entry.hash_code = element.hash_code();
1799 request_update_auto_invalidations(element.as_ref(), context, capabilities);
1800 }
1801
1802 entry.capabilities = capabilities;
1804 entry
1805 .node
1806 .borrow()
1807 .node_state()
1808 .set_capabilities(capabilities);
1809 continue;
1810 }
1811 fast_path_failed_at = Some(idx);
1813 }
1814
1815 self.scratch_elements.push(element.clone());
1817 }
1818
1819 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
1824 if elements_count < self.entries.len() {
1826 for entry in self.entries.drain(elements_count..) {
1827 request_auto_invalidations(context, entry.capabilities);
1828 detach_node_tree(&mut **entry.node.borrow_mut());
1829 }
1830 }
1831 self.sync_chain_links();
1832 return;
1833 }
1834
1835 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
1838
1839 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
1841 let processed_entries_len = self.entries.len();
1842 let old_len = old_entries.len();
1843
1844 self.scratch_old_used.clear();
1846 self.scratch_old_used.resize(old_len, false);
1847
1848 self.scratch_match_order.clear();
1849 self.scratch_match_order.resize(old_len, None);
1850
1851 let index = EntryIndex::build(&old_entries);
1853
1854 let new_elements_count = self.scratch_elements.len();
1855 self.scratch_final_slots.clear();
1856 self.scratch_final_slots.reserve(new_elements_count);
1857
1858 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
1860 self.scratch_final_slots.push(None);
1861 let element_type = element.element_type();
1862 let node_type = element.node_type();
1863 let key = element.key();
1864 let hash_code = element.hash_code();
1865 let capabilities = element.capabilities();
1866
1867 let matched_idx = index.find_match(
1869 &old_entries,
1870 &self.scratch_old_used,
1871 EntryMatchQuery {
1872 element_type,
1873 node_type,
1874 key,
1875 hash_code,
1876 element: &element,
1877 },
1878 );
1879
1880 if let Some(idx) = matched_idx {
1881 let entry = &mut old_entries[idx];
1883 let can_update_node = {
1884 let node_borrow = entry.node.borrow();
1885 element.can_update_node(&**node_borrow)
1886 };
1887 if !can_update_node {
1888 let replacement = ModifierNodeEntry::new(
1889 element_type,
1890 node_type,
1891 key,
1892 element.clone(),
1893 element.create_node(),
1894 hash_code,
1895 capabilities,
1896 );
1897 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
1898 element.update_node(&mut **replacement.node.borrow_mut());
1899 request_auto_invalidations(context, capabilities);
1900 self.scratch_final_slots[new_pos] = Some(replacement);
1901 continue;
1902 }
1903
1904 self.scratch_old_used[idx] = true;
1905 self.scratch_match_order[idx] = Some(new_pos);
1906 let moved = idx != new_pos;
1907
1908 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1910
1911 {
1913 let node_borrow = entry.node.borrow();
1914 if !node_borrow.node_state().is_attached() {
1915 drop(node_borrow);
1916 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1917 }
1918 }
1919
1920 let needs_update = !same_element || element.requires_update();
1922 if needs_update {
1923 element.update_node(&mut **entry.node.borrow_mut());
1924 entry.element = element;
1925 entry.hash_code = hash_code;
1926 request_update_auto_invalidations(
1927 entry.element.as_ref(),
1928 context,
1929 capabilities,
1930 );
1931 }
1932 if moved {
1933 request_auto_invalidations(context, capabilities);
1934 }
1935
1936 entry.key = key;
1938 entry.element_type = element_type;
1939 entry.node_type = node_type;
1940 entry.capabilities = capabilities;
1941 entry
1942 .node
1943 .borrow()
1944 .node_state()
1945 .set_capabilities(capabilities);
1946 } else {
1947 let entry = ModifierNodeEntry::new(
1949 element_type,
1950 node_type,
1951 key,
1952 element.clone(),
1953 element.create_node(),
1954 hash_code,
1955 capabilities,
1956 );
1957 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1958 element.update_node(&mut **entry.node.borrow_mut());
1959 request_auto_invalidations(context, capabilities);
1960 self.scratch_final_slots[new_pos] = Some(entry);
1961 }
1962 }
1963
1964 for (i, entry) in old_entries.into_iter().enumerate() {
1966 if self.scratch_old_used[i] {
1967 if let Some(pos) = self.scratch_match_order[i] {
1968 self.scratch_final_slots[pos] = Some(entry);
1969 } else {
1970 request_auto_invalidations(context, entry.capabilities);
1971 detach_node_tree(&mut **entry.node.borrow_mut());
1972 }
1973 } else {
1974 request_auto_invalidations(context, entry.capabilities);
1975 detach_node_tree(&mut **entry.node.borrow_mut());
1976 }
1977 }
1978
1979 self.entries.reserve(self.scratch_final_slots.len());
1981 for slot in self.scratch_final_slots.drain(..) {
1982 if let Some(entry) = slot {
1983 self.entries.push(entry);
1984 } else {
1985 log::error!("modifier reconciliation produced an empty final slot");
1986 }
1987 }
1988
1989 debug_assert_eq!(
1990 self.entries.len(),
1991 processed_entries_len + new_elements_count
1992 );
1993 self.sync_chain_links();
1994 }
1995
1996 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2000 where
2001 I: IntoIterator<Item = DynModifierElement>,
2002 {
2003 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2004 self.update_from_slice(&collected, context);
2005 }
2006
2007 pub fn reset(&mut self) {
2010 for entry in &mut self.entries {
2011 reset_node_tree(&mut **entry.node.borrow_mut());
2012 }
2013 }
2014
2015 pub fn detach_all(&mut self) {
2017 for entry in std::mem::take(&mut self.entries) {
2018 detach_node_tree(&mut **entry.node.borrow_mut());
2019 {
2020 let node_borrow = entry.node.borrow();
2021 let state = node_borrow.node_state();
2022 state.set_capabilities(NodeCapabilities::empty());
2023 }
2024 }
2025 self.aggregated_capabilities = NodeCapabilities::empty();
2026 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2027 self.ordered_nodes.clear();
2028 self.sync_chain_links();
2029 }
2030
2031 pub fn len(&self) -> usize {
2032 self.entries.len()
2033 }
2034
2035 pub fn is_empty(&self) -> bool {
2036 self.entries.is_empty()
2037 }
2038
2039 pub fn capabilities(&self) -> NodeCapabilities {
2041 self.aggregated_capabilities
2042 }
2043
2044 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2046 self.aggregated_capabilities.contains(capability)
2047 }
2048
2049 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2051 self.make_node_ref(NodeLink::Head)
2052 }
2053
2054 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2056 self.make_node_ref(NodeLink::Tail)
2057 }
2058
2059 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2061 ModifierChainIter::forward(self)
2062 }
2063
2064 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2066 ModifierChainIter::backward(self)
2067 }
2068
2069 pub fn for_each_forward<F>(&self, mut f: F)
2071 where
2072 F: FnMut(ModifierChainNodeRef<'_>),
2073 {
2074 for node in self.head_to_tail() {
2075 f(node);
2076 }
2077 }
2078
2079 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2081 where
2082 F: FnMut(ModifierChainNodeRef<'_>),
2083 {
2084 if mask.is_empty() {
2085 self.for_each_forward(f);
2086 return;
2087 }
2088
2089 if !self.head().aggregate_child_capabilities().intersects(mask) {
2090 return;
2091 }
2092
2093 for node in self.head_to_tail() {
2094 if node.kind_set().intersects(mask) {
2095 f(node);
2096 }
2097 }
2098 }
2099
2100 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2102 where
2103 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2104 {
2105 self.for_each_forward_matching(mask, |node_ref| {
2106 node_ref.with_node(|node| f(node_ref.clone(), node));
2107 });
2108 }
2109
2110 pub fn for_each_backward<F>(&self, mut f: F)
2112 where
2113 F: FnMut(ModifierChainNodeRef<'_>),
2114 {
2115 for node in self.tail_to_head() {
2116 f(node);
2117 }
2118 }
2119
2120 pub fn for_each_backward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2122 where
2123 F: FnMut(ModifierChainNodeRef<'_>),
2124 {
2125 if mask.is_empty() {
2126 self.for_each_backward(f);
2127 return;
2128 }
2129
2130 if !self.head().aggregate_child_capabilities().intersects(mask) {
2131 return;
2132 }
2133
2134 for node in self.tail_to_head() {
2135 if node.kind_set().intersects(mask) {
2136 f(node);
2137 }
2138 }
2139 }
2140
2141 pub fn node_ref_at(&self, index: usize) -> Option<ModifierChainNodeRef<'_>> {
2143 if index >= self.entries.len() {
2144 None
2145 } else {
2146 Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))))
2147 }
2148 }
2149
2150 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2152 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2153 node as *const dyn ModifierNode as *const ()
2154 }
2155
2156 let target = node_data_ptr(node);
2157 for (index, entry) in self.entries.iter().enumerate() {
2158 if node_data_ptr(&**entry.node.borrow()) == target {
2159 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2160 }
2161 }
2162
2163 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2164 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2165 return None;
2166 }
2167 let matches_target = match link {
2168 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2169 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2170 NodeLink::Entry(path) => {
2171 let node_borrow = self.entries[path.entry()].node.borrow();
2172 node_data_ptr(&**node_borrow) == target
2173 }
2174 };
2175 if matches_target {
2176 Some(self.make_node_ref(*link))
2177 } else {
2178 None
2179 }
2180 })
2181 }
2182
2183 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2186 self.entries.get(index).and_then(|entry| {
2187 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2188 boxed_node.as_any().downcast_ref::<N>()
2189 })
2190 .ok()
2191 })
2192 }
2193
2194 pub fn node_mut<N: ModifierNode + 'static>(
2197 &self,
2198 index: usize,
2199 ) -> Option<std::cell::RefMut<'_, N>> {
2200 self.entries.get(index).and_then(|entry| {
2201 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2202 boxed_node.as_any_mut().downcast_mut::<N>()
2203 })
2204 .ok()
2205 })
2206 }
2207
2208 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2211 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
2212 }
2213
2214 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
2216 self.aggregated_capabilities
2217 .contains(NodeCapabilities::for_invalidation(kind))
2218 }
2219
2220 pub fn visit_nodes<F>(&self, mut f: F)
2222 where
2223 F: FnMut(&dyn ModifierNode, NodeCapabilities),
2224 {
2225 for (link, cached_caps, _agg) in &self.ordered_nodes {
2226 match link {
2227 NodeLink::Head => {
2228 f(self.head_sentinel.as_ref(), *cached_caps);
2229 }
2230 NodeLink::Tail => {
2231 f(self.tail_sentinel.as_ref(), *cached_caps);
2232 }
2233 NodeLink::Entry(path) => {
2234 let node_borrow = self.entries[path.entry()].node.borrow();
2235 if path.delegates().is_empty() {
2236 f(&**node_borrow, *cached_caps);
2237 } else {
2238 let mut current: &dyn ModifierNode = &**node_borrow;
2239 for &delegate_index in path.delegates() {
2240 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2241 current = delegate;
2242 } else {
2243 return; }
2245 }
2246 f(current, *cached_caps);
2247 }
2248 }
2249 }
2250 }
2251 }
2252
2253 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
2255 where
2256 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
2257 {
2258 for index in 0..self.ordered_nodes.len() {
2259 let (link, cached_caps, _agg) = self.ordered_nodes[index];
2260 match link {
2261 NodeLink::Head => {
2262 f(self.head_sentinel.as_mut(), cached_caps);
2263 }
2264 NodeLink::Tail => {
2265 f(self.tail_sentinel.as_mut(), cached_caps);
2266 }
2267 NodeLink::Entry(path) => {
2268 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
2269 if path.delegates().is_empty() {
2270 f(&mut **node_borrow, cached_caps);
2271 } else {
2272 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
2273 for &delegate_index in path.delegates() {
2274 if let Some(delegate) =
2275 nth_delegate_mut(current, delegate_index as usize)
2276 {
2277 current = delegate;
2278 } else {
2279 return; }
2281 }
2282 f(current, cached_caps);
2283 }
2284 }
2285 }
2286 }
2287 }
2288
2289 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2290 ModifierChainNodeRef {
2291 chain: self,
2292 link,
2293 cached_capabilities: None,
2294 cached_aggregate_child: None,
2295 }
2296 }
2297
2298 fn make_node_ref_with_caps(
2299 &self,
2300 link: NodeLink,
2301 caps: NodeCapabilities,
2302 aggregate_child: NodeCapabilities,
2303 ) -> ModifierChainNodeRef<'_> {
2304 ModifierChainNodeRef {
2305 chain: self,
2306 link,
2307 cached_capabilities: Some(caps),
2308 cached_aggregate_child: Some(aggregate_child),
2309 }
2310 }
2311
2312 fn sync_chain_links(&mut self) {
2313 self.rebuild_ordered_nodes();
2314
2315 self.head_sentinel.node_state().set_parent_link(None);
2316 self.tail_sentinel.node_state().set_child_link(None);
2317
2318 if self.ordered_nodes.is_empty() {
2319 self.head_sentinel
2320 .node_state()
2321 .set_child_link(Some(NodeLink::Tail));
2322 self.tail_sentinel
2323 .node_state()
2324 .set_parent_link(Some(NodeLink::Head));
2325 self.aggregated_capabilities = NodeCapabilities::empty();
2326 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2327 self.head_sentinel
2328 .node_state()
2329 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2330 self.tail_sentinel
2331 .node_state()
2332 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2333 return;
2334 }
2335
2336 let mut previous = NodeLink::Head;
2337 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
2338 match &previous {
2340 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
2341 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
2342 NodeLink::Entry(path) => {
2343 let node_borrow = self.entries[path.entry()].node.borrow();
2344 if path.delegates().is_empty() {
2346 node_borrow.node_state().set_child_link(Some(link));
2347 } else {
2348 let mut current: &dyn ModifierNode = &**node_borrow;
2349 for &delegate_index in path.delegates() {
2350 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2351 current = delegate;
2352 }
2353 }
2354 current.node_state().set_child_link(Some(link));
2355 }
2356 }
2357 }
2358 match &link {
2360 NodeLink::Head => self
2361 .head_sentinel
2362 .node_state()
2363 .set_parent_link(Some(previous)),
2364 NodeLink::Tail => self
2365 .tail_sentinel
2366 .node_state()
2367 .set_parent_link(Some(previous)),
2368 NodeLink::Entry(path) => {
2369 let node_borrow = self.entries[path.entry()].node.borrow();
2370 if path.delegates().is_empty() {
2372 node_borrow.node_state().set_parent_link(Some(previous));
2373 } else {
2374 let mut current: &dyn ModifierNode = &**node_borrow;
2375 for &delegate_index in path.delegates() {
2376 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2377 current = delegate;
2378 }
2379 }
2380 current.node_state().set_parent_link(Some(previous));
2381 }
2382 }
2383 }
2384 previous = link;
2385 }
2386
2387 match &previous {
2389 NodeLink::Head => self
2390 .head_sentinel
2391 .node_state()
2392 .set_child_link(Some(NodeLink::Tail)),
2393 NodeLink::Tail => self
2394 .tail_sentinel
2395 .node_state()
2396 .set_child_link(Some(NodeLink::Tail)),
2397 NodeLink::Entry(path) => {
2398 let node_borrow = self.entries[path.entry()].node.borrow();
2399 if path.delegates().is_empty() {
2401 node_borrow
2402 .node_state()
2403 .set_child_link(Some(NodeLink::Tail));
2404 } else {
2405 let mut current: &dyn ModifierNode = &**node_borrow;
2406 for &delegate_index in path.delegates() {
2407 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2408 current = delegate;
2409 }
2410 }
2411 current.node_state().set_child_link(Some(NodeLink::Tail));
2412 }
2413 }
2414 }
2415 self.tail_sentinel
2416 .node_state()
2417 .set_parent_link(Some(previous));
2418 self.tail_sentinel.node_state().set_child_link(None);
2419
2420 let mut aggregate = NodeCapabilities::empty();
2421 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
2422 aggregate |= *cached_caps;
2423 *cached_aggregate = aggregate;
2424 match link {
2426 NodeLink::Head => {
2427 self.head_sentinel
2428 .node_state()
2429 .set_aggregate_child_capabilities(aggregate);
2430 }
2431 NodeLink::Tail => {
2432 self.tail_sentinel
2433 .node_state()
2434 .set_aggregate_child_capabilities(aggregate);
2435 }
2436 NodeLink::Entry(path) => {
2437 let node_borrow = self.entries[path.entry()].node.borrow();
2438 let state = if path.delegates().is_empty() {
2439 node_borrow.node_state()
2440 } else {
2441 let mut current: &dyn ModifierNode = &**node_borrow;
2442 for &delegate_index in path.delegates() {
2443 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2444 current = delegate;
2445 }
2446 }
2447 current.node_state()
2448 };
2449 state.set_aggregate_child_capabilities(aggregate);
2450 }
2451 }
2452 }
2453
2454 self.aggregated_capabilities = aggregate;
2455 self.head_aggregate_child_capabilities = aggregate;
2456 self.head_sentinel
2457 .node_state()
2458 .set_aggregate_child_capabilities(aggregate);
2459 self.tail_sentinel
2460 .node_state()
2461 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2462 }
2463
2464 fn rebuild_ordered_nodes(&mut self) {
2465 self.ordered_nodes.clear();
2466 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
2467 for (index, entry) in self.entries.iter().enumerate() {
2468 let node_borrow = entry.node.borrow();
2469 Self::enumerate_link_order(
2470 &**node_borrow,
2471 index,
2472 &mut path_buf,
2473 0,
2474 &mut self.ordered_nodes,
2475 );
2476 }
2477 }
2478
2479 fn enumerate_link_order(
2480 node: &dyn ModifierNode,
2481 entry: usize,
2482 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
2483 path_len: usize,
2484 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2485 ) {
2486 let caps = node.node_state().capabilities();
2487 out.push((
2488 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
2489 caps,
2490 NodeCapabilities::empty(),
2491 ));
2492 let mut delegate_index = 0usize;
2493 node.for_each_delegate(&mut |child| {
2494 if path_len < MAX_DELEGATE_DEPTH {
2495 path_buf[path_len] = delegate_index;
2496 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
2497 }
2498 delegate_index += 1;
2499 });
2500 }
2501}
2502
2503impl<'a> ModifierChainNodeRef<'a> {
2504 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
2507 match &self.link {
2508 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
2509 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
2510 NodeLink::Entry(path) => {
2511 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2512 if path.delegates().is_empty() {
2514 f(node_borrow.node_state())
2515 } else {
2516 let mut current: &dyn ModifierNode = &**node_borrow;
2518 for &delegate_index in path.delegates() {
2519 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2520 current = delegate;
2521 } else {
2522 return f(node_borrow.node_state());
2524 }
2525 }
2526 f(current.node_state())
2527 }
2528 }
2529 }
2530 }
2531
2532 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
2535 match &self.link {
2536 NodeLink::Head => None, NodeLink::Tail => None, NodeLink::Entry(path) => {
2539 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2540 if path.delegates().is_empty() {
2542 Some(f(&**node_borrow))
2543 } else {
2544 let mut current: &dyn ModifierNode = &**node_borrow;
2546 for &delegate_index in path.delegates() {
2547 current = nth_delegate(current, delegate_index as usize)?;
2549 }
2550 Some(f(current))
2551 }
2552 }
2553 }
2554 }
2555
2556 #[inline]
2558 pub fn parent(&self) -> Option<Self> {
2559 self.with_state(|state| state.parent_link())
2560 .map(|link| self.chain.make_node_ref(link))
2561 }
2562
2563 #[inline]
2565 pub fn child(&self) -> Option<Self> {
2566 self.with_state(|state| state.child_link())
2567 .map(|link| self.chain.make_node_ref(link))
2568 }
2569
2570 #[inline]
2572 pub fn kind_set(&self) -> NodeCapabilities {
2573 if let Some(caps) = self.cached_capabilities {
2574 return caps;
2575 }
2576 match &self.link {
2577 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
2578 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
2579 }
2580 }
2581
2582 pub fn entry_index(&self) -> Option<usize> {
2584 match &self.link {
2585 NodeLink::Entry(path) => Some(path.entry()),
2586 _ => None,
2587 }
2588 }
2589
2590 pub fn delegate_depth(&self) -> usize {
2592 match &self.link {
2593 NodeLink::Entry(path) => path.delegates().len(),
2594 _ => 0,
2595 }
2596 }
2597
2598 #[inline]
2600 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
2601 if let Some(agg) = self.cached_aggregate_child {
2602 return agg;
2603 }
2604 if self.is_tail() {
2605 NodeCapabilities::empty()
2606 } else {
2607 self.with_state(|state| state.aggregate_child_capabilities())
2608 }
2609 }
2610
2611 pub fn is_head(&self) -> bool {
2613 matches!(self.link, NodeLink::Head)
2614 }
2615
2616 pub fn is_tail(&self) -> bool {
2618 matches!(self.link, NodeLink::Tail)
2619 }
2620
2621 pub fn is_sentinel(&self) -> bool {
2623 matches!(self.link, NodeLink::Head | NodeLink::Tail)
2624 }
2625
2626 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
2628 !mask.is_empty() && self.kind_set().intersects(mask)
2629 }
2630
2631 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
2633 where
2634 F: FnMut(ModifierChainNodeRef<'a>),
2635 {
2636 let mut current = if include_self {
2637 Some(self)
2638 } else {
2639 self.child()
2640 };
2641 while let Some(node) = current {
2642 if node.is_tail() {
2643 break;
2644 }
2645 if !node.is_sentinel() {
2646 f(node.clone());
2647 }
2648 current = node.child();
2649 }
2650 }
2651
2652 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2654 where
2655 F: FnMut(ModifierChainNodeRef<'a>),
2656 {
2657 if mask.is_empty() {
2658 self.visit_descendants(include_self, f);
2659 return;
2660 }
2661
2662 if !self.aggregate_child_capabilities().intersects(mask) {
2663 return;
2664 }
2665
2666 self.visit_descendants(include_self, |node| {
2667 if node.kind_set().intersects(mask) {
2668 f(node);
2669 }
2670 });
2671 }
2672
2673 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
2675 where
2676 F: FnMut(ModifierChainNodeRef<'a>),
2677 {
2678 let mut current = if include_self {
2679 Some(self)
2680 } else {
2681 self.parent()
2682 };
2683 while let Some(node) = current {
2684 if node.is_head() {
2685 break;
2686 }
2687 f(node.clone());
2688 current = node.parent();
2689 }
2690 }
2691
2692 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2694 where
2695 F: FnMut(ModifierChainNodeRef<'a>),
2696 {
2697 if mask.is_empty() {
2698 self.visit_ancestors(include_self, f);
2699 return;
2700 }
2701
2702 self.visit_ancestors(include_self, |node| {
2703 if node.kind_set().intersects(mask) {
2704 f(node);
2705 }
2706 });
2707 }
2708
2709 pub fn find_parent_focus_target(&self) -> Option<ModifierChainNodeRef<'a>> {
2714 let mut result = None;
2715 self.clone()
2716 .visit_ancestors_matching(false, NodeCapabilities::FOCUS, |node| {
2717 if result.is_none() {
2718 result = Some(node);
2719 }
2720 });
2721 result
2722 }
2723
2724 pub fn find_first_focus_target(&self) -> Option<ModifierChainNodeRef<'a>> {
2729 let mut result = None;
2730 self.clone()
2731 .visit_descendants_matching(false, NodeCapabilities::FOCUS, |node| {
2732 if result.is_none() {
2733 result = Some(node);
2734 }
2735 });
2736 result
2737 }
2738
2739 pub fn has_focus_capability_in_ancestors(&self) -> bool {
2741 let mut found = false;
2742 self.clone()
2743 .visit_ancestors_matching(true, NodeCapabilities::FOCUS, |_| {
2744 found = true;
2745 });
2746 found
2747 }
2748}
2749
2750#[cfg(test)]
2751#[path = "tests/modifier_tests.rs"]
2752mod tests;