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 Dialog,
693}
694
695#[derive(Clone)]
702pub struct SemanticsCustomAction {
703 pub label: String,
705 handler: Rc<dyn Fn()>,
706}
707
708impl SemanticsCustomAction {
709 pub fn new(label: impl Into<String>, handler: impl Fn() + 'static) -> Self {
710 Self {
711 label: label.into(),
712 handler: Rc::new(handler),
713 }
714 }
715
716 pub fn invoke(&self) {
717 (self.handler)();
718 }
719}
720
721impl fmt::Debug for SemanticsCustomAction {
722 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
723 f.debug_struct("SemanticsCustomAction")
724 .field("label", &self.label)
725 .finish_non_exhaustive()
726 }
727}
728
729impl PartialEq for SemanticsCustomAction {
739 fn eq(&self, other: &Self) -> bool {
740 self.label == other.label
741 }
742}
743
744impl Eq for SemanticsCustomAction {}
745
746#[derive(Clone, Debug, PartialEq)]
761pub struct CanvasSemanticsNode {
762 pub key: u64,
769 pub bounds: cranpose_ui_graphics::Rect,
771 pub label: String,
772 pub role: Option<SemanticsWidgetRole>,
773 pub state_description: Option<String>,
777 pub on_click_label: Option<String>,
780 pub clickable: bool,
781 pub selected: Option<bool>,
783 pub toggled: Option<bool>,
785 pub enabled: bool,
786 pub custom_actions: Vec<SemanticsCustomAction>,
787}
788
789impl Default for CanvasSemanticsNode {
790 fn default() -> Self {
791 Self {
792 key: 0,
793 bounds: cranpose_ui_graphics::Rect {
794 x: 0.0,
795 y: 0.0,
796 width: 0.0,
797 height: 0.0,
798 },
799 label: String::new(),
800 role: None,
801 state_description: None,
802 on_click_label: None,
803 clickable: false,
804 selected: None,
805 toggled: None,
806 enabled: true,
810 custom_actions: Vec::new(),
811 }
812 }
813}
814
815impl CanvasSemanticsNode {
816 pub fn control(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
818 Self {
819 key,
820 bounds,
821 label: label.into(),
822 clickable: true,
823 ..Self::default()
824 }
825 }
826
827 pub fn text(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
829 Self {
830 key,
831 bounds,
832 label: label.into(),
833 ..Self::default()
834 }
835 }
836
837 pub fn with_role(mut self, role: SemanticsWidgetRole) -> Self {
838 self.role = Some(role);
839 self
840 }
841
842 pub fn with_state_description(mut self, state: impl Into<String>) -> Self {
843 self.state_description = Some(state.into());
844 self
845 }
846
847 pub fn with_click_label(mut self, label: impl Into<String>) -> Self {
848 self.on_click_label = Some(label.into());
849 self.clickable = true;
850 self
851 }
852
853 pub fn with_selected(mut self, selected: bool) -> Self {
854 self.selected = Some(selected);
855 self
856 }
857
858 pub fn with_toggled(mut self, toggled: bool) -> Self {
859 self.toggled = Some(toggled);
860 self
861 }
862
863 pub fn with_enabled(mut self, enabled: bool) -> Self {
864 self.enabled = enabled;
865 self
866 }
867
868 pub fn with_custom_action(mut self, action: SemanticsCustomAction) -> Self {
869 self.custom_actions.push(action);
870 self
871 }
872}
873
874#[derive(Clone, Debug, PartialEq)]
876pub struct SemanticsConfiguration {
877 pub content_description: Option<String>,
878 pub state_description: Option<String>,
880 pub on_click_label: Option<String>,
882 pub role: Option<SemanticsWidgetRole>,
884 pub selected: Option<bool>,
885 pub toggled: Option<bool>,
886 pub enabled: bool,
887 pub is_clickable: bool,
888 pub is_editable_text: bool,
889 pub text_selection: Option<crate::text::TextRange>,
890 pub custom_actions: Vec<SemanticsCustomAction>,
891 pub canvas_children: Vec<CanvasSemanticsNode>,
894 pub is_modal: bool,
897}
898
899impl Default for SemanticsConfiguration {
900 fn default() -> Self {
901 Self {
902 content_description: None,
903 state_description: None,
904 on_click_label: None,
905 role: None,
906 selected: None,
907 toggled: None,
908 enabled: true,
909 is_clickable: false,
910 is_editable_text: false,
911 text_selection: None,
912 custom_actions: Vec::new(),
913 canvas_children: Vec::new(),
914 is_modal: false,
915 }
916 }
917}
918
919impl SemanticsConfiguration {
920 pub fn merge(&mut self, other: &SemanticsConfiguration) {
921 if let Some(description) = &other.content_description {
922 self.content_description = Some(description.clone());
923 }
924 if let Some(state) = &other.state_description {
925 self.state_description = Some(state.clone());
926 }
927 if let Some(label) = &other.on_click_label {
928 self.on_click_label = Some(label.clone());
929 }
930 if let Some(role) = other.role {
931 self.role = Some(role);
932 }
933 if let Some(selected) = other.selected {
934 self.selected = Some(selected);
935 }
936 if let Some(toggled) = other.toggled {
937 self.toggled = Some(toggled);
938 }
939 self.enabled &= other.enabled;
942 self.is_clickable |= other.is_clickable;
943 self.is_editable_text |= other.is_editable_text;
944 if let Some(selection) = other.text_selection {
945 self.text_selection = Some(selection);
946 }
947 self.custom_actions
948 .extend(other.custom_actions.iter().cloned());
949 self.canvas_children
950 .extend(other.canvas_children.iter().cloned());
951 self.is_modal |= other.is_modal;
952 }
953
954 pub fn is_activatable(&self) -> bool {
957 self.is_clickable || self.on_click_label.is_some()
958 }
959}
960
961impl fmt::Debug for dyn ModifierNode {
962 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
963 f.debug_struct("ModifierNode").finish_non_exhaustive()
964 }
965}
966
967impl dyn ModifierNode {
968 pub fn as_any(&self) -> &dyn Any {
969 self
970 }
971
972 pub fn as_any_mut(&mut self) -> &mut dyn Any {
973 self
974 }
975}
976
977pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
980 type Node: ModifierNode;
981
982 fn create(&self) -> Self::Node;
984
985 fn update(&self, node: &mut Self::Node);
987
988 fn key(&self) -> Option<u64> {
990 None
991 }
992
993 fn inspector_name(&self) -> &'static str {
995 type_name::<Self>()
996 }
997
998 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
1000
1001 fn capabilities(&self) -> NodeCapabilities {
1004 NodeCapabilities::default()
1005 }
1006
1007 fn always_update(&self) -> bool {
1013 false
1014 }
1015
1016 fn auto_invalidate_on_update(&self) -> bool {
1019 true
1020 }
1021
1022 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1029 None
1030 }
1031}
1032
1033#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1035pub struct NodeCapabilities(u32);
1036
1037impl NodeCapabilities {
1038 pub const NONE: Self = Self(0);
1040 pub const LAYOUT: Self = Self(1 << 0);
1042 pub const DRAW: Self = Self(1 << 1);
1044 pub const POINTER_INPUT: Self = Self(1 << 2);
1046 pub const SEMANTICS: Self = Self(1 << 3);
1048 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1050 pub const FOCUS: Self = Self(1 << 5);
1052
1053 pub const fn empty() -> Self {
1055 Self::NONE
1056 }
1057
1058 pub const fn contains(self, other: Self) -> bool {
1060 (self.0 & other.0) == other.0
1061 }
1062
1063 pub const fn intersects(self, other: Self) -> bool {
1065 (self.0 & other.0) != 0
1066 }
1067
1068 pub fn insert(&mut self, other: Self) {
1070 self.0 |= other.0;
1071 }
1072
1073 pub const fn bits(self) -> u32 {
1075 self.0
1076 }
1077
1078 pub const fn is_empty(self) -> bool {
1080 self.0 == 0
1081 }
1082
1083 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1085 match kind {
1086 InvalidationKind::Layout => Self::LAYOUT,
1087 InvalidationKind::Draw => Self::DRAW,
1088 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1089 InvalidationKind::Semantics => Self::SEMANTICS,
1090 InvalidationKind::Focus => Self::FOCUS,
1091 }
1092 }
1093}
1094
1095impl Default for NodeCapabilities {
1096 fn default() -> Self {
1097 Self::NONE
1098 }
1099}
1100
1101impl fmt::Debug for NodeCapabilities {
1102 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1103 f.debug_struct("NodeCapabilities")
1104 .field("layout", &self.contains(Self::LAYOUT))
1105 .field("draw", &self.contains(Self::DRAW))
1106 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1107 .field("semantics", &self.contains(Self::SEMANTICS))
1108 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1109 .field("focus", &self.contains(Self::FOCUS))
1110 .finish()
1111 }
1112}
1113
1114impl BitOr for NodeCapabilities {
1115 type Output = Self;
1116
1117 fn bitor(self, rhs: Self) -> Self::Output {
1118 Self(self.0 | rhs.0)
1119 }
1120}
1121
1122impl BitOrAssign for NodeCapabilities {
1123 fn bitor_assign(&mut self, rhs: Self) {
1124 self.0 |= rhs.0;
1125 }
1126}
1127
1128#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1130pub struct ModifierInvalidation {
1131 kind: InvalidationKind,
1132 capabilities: NodeCapabilities,
1133}
1134
1135impl ModifierInvalidation {
1136 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1138 Self { kind, capabilities }
1139 }
1140
1141 pub const fn kind(self) -> InvalidationKind {
1143 self.kind
1144 }
1145
1146 pub const fn capabilities(self) -> NodeCapabilities {
1148 self.capabilities
1149 }
1150}
1151
1152pub trait AnyModifierElement: fmt::Debug {
1154 fn node_type(&self) -> TypeId;
1155
1156 fn element_type(&self) -> TypeId;
1157
1158 fn create_node(&self) -> Box<dyn ModifierNode>;
1159
1160 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
1161
1162 fn update_node(&self, node: &mut dyn ModifierNode);
1163
1164 fn key(&self) -> Option<u64>;
1165
1166 fn capabilities(&self) -> NodeCapabilities {
1167 NodeCapabilities::default()
1168 }
1169
1170 fn hash_code(&self) -> u64;
1171
1172 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
1173
1174 fn inspector_name(&self) -> &'static str;
1175
1176 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
1177
1178 fn requires_update(&self) -> bool;
1179
1180 fn auto_invalidates_on_update(&self) -> bool;
1181
1182 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
1183
1184 fn as_any(&self) -> &dyn Any;
1185}
1186
1187struct TypedModifierElement<E: ModifierNodeElement> {
1188 element: E,
1189 cached_hash: u64,
1190}
1191
1192impl<E: ModifierNodeElement> TypedModifierElement<E> {
1193 fn new(element: E) -> Self {
1194 let mut hasher = default::new();
1195 element.hash(&mut hasher);
1196 Self {
1197 element,
1198 cached_hash: hasher.finish(),
1199 }
1200 }
1201}
1202
1203impl<E> fmt::Debug for TypedModifierElement<E>
1204where
1205 E: ModifierNodeElement,
1206{
1207 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1208 f.debug_struct("TypedModifierElement")
1209 .field("type", &type_name::<E>())
1210 .finish()
1211 }
1212}
1213
1214impl<E> AnyModifierElement for TypedModifierElement<E>
1215where
1216 E: ModifierNodeElement,
1217{
1218 fn node_type(&self) -> TypeId {
1219 TypeId::of::<E::Node>()
1220 }
1221
1222 fn element_type(&self) -> TypeId {
1223 TypeId::of::<E>()
1224 }
1225
1226 fn create_node(&self) -> Box<dyn ModifierNode> {
1227 Box::new(self.element.create())
1228 }
1229
1230 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
1231 node.as_any().is::<E::Node>()
1232 }
1233
1234 fn update_node(&self, node: &mut dyn ModifierNode) {
1235 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
1236 self.element.update(typed);
1237 }
1238 }
1239
1240 fn key(&self) -> Option<u64> {
1241 self.element.key()
1242 }
1243
1244 fn capabilities(&self) -> NodeCapabilities {
1245 self.element.capabilities()
1246 }
1247
1248 fn hash_code(&self) -> u64 {
1249 self.cached_hash
1250 }
1251
1252 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
1253 other
1254 .as_any()
1255 .downcast_ref::<Self>()
1256 .map(|typed| typed.element == self.element)
1257 .unwrap_or(false)
1258 }
1259
1260 fn inspector_name(&self) -> &'static str {
1261 self.element.inspector_name()
1262 }
1263
1264 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
1265 self.element.inspector_properties(visitor);
1266 }
1267
1268 fn requires_update(&self) -> bool {
1269 self.element.always_update()
1270 }
1271
1272 fn auto_invalidates_on_update(&self) -> bool {
1273 self.element.auto_invalidate_on_update()
1274 }
1275
1276 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1277 self.element.update_invalidation_kind()
1278 }
1279
1280 fn as_any(&self) -> &dyn Any {
1281 self
1282 }
1283}
1284
1285fn request_update_auto_invalidations(
1286 element: &dyn AnyModifierElement,
1287 context: &mut dyn ModifierNodeContext,
1288 capabilities: NodeCapabilities,
1289) {
1290 if let Some(kind) = element.update_invalidation_kind() {
1291 let capabilities = NodeCapabilities::for_invalidation(kind);
1292 context.push_active_capabilities(capabilities);
1293 context.invalidate(kind);
1294 context.pop_active_capabilities();
1295 } else if element.auto_invalidates_on_update() {
1296 request_auto_invalidations(context, capabilities);
1297 }
1298}
1299
1300pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
1303 Rc::new(TypedModifierElement::new(element))
1304}
1305
1306pub type DynModifierElement = Rc<dyn AnyModifierElement>;
1308
1309#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1310enum TraversalDirection {
1311 Forward,
1312 Backward,
1313}
1314
1315pub struct ModifierChainIter<'a> {
1320 chain: &'a ModifierNodeChain,
1321 cursor: usize,
1324 remaining: usize,
1326 direction: TraversalDirection,
1327}
1328
1329impl<'a> ModifierChainIter<'a> {
1330 fn forward(chain: &'a ModifierNodeChain) -> Self {
1331 Self {
1332 chain,
1333 cursor: 0,
1334 remaining: chain.ordered_nodes.len(),
1335 direction: TraversalDirection::Forward,
1336 }
1337 }
1338
1339 fn backward(chain: &'a ModifierNodeChain) -> Self {
1340 let len = chain.ordered_nodes.len();
1341 Self {
1342 chain,
1343 cursor: len.wrapping_sub(1),
1344 remaining: len,
1345 direction: TraversalDirection::Backward,
1346 }
1347 }
1348}
1349
1350impl<'a> Iterator for ModifierChainIter<'a> {
1351 type Item = ModifierChainNodeRef<'a>;
1352
1353 #[inline]
1354 fn next(&mut self) -> Option<Self::Item> {
1355 if self.remaining == 0 {
1356 return None;
1357 }
1358 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
1359 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
1360 self.remaining -= 1;
1361 match self.direction {
1362 TraversalDirection::Forward => self.cursor += 1,
1363 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
1364 }
1365 Some(node_ref)
1366 }
1367
1368 #[inline]
1369 fn size_hint(&self) -> (usize, Option<usize>) {
1370 (self.remaining, Some(self.remaining))
1371 }
1372}
1373
1374impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
1375impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
1376
1377#[derive(Debug)]
1378struct ModifierNodeEntry {
1379 element_type: TypeId,
1380 node_type: TypeId,
1381 key: Option<u64>,
1382 hash_code: u64,
1383 element: DynModifierElement,
1384 node: Rc<RefCell<Box<dyn ModifierNode>>>,
1385 capabilities: NodeCapabilities,
1386}
1387
1388impl ModifierNodeEntry {
1389 fn new(
1390 element_type: TypeId,
1391 node_type: TypeId,
1392 key: Option<u64>,
1393 element: DynModifierElement,
1394 node: Box<dyn ModifierNode>,
1395 hash_code: u64,
1396 capabilities: NodeCapabilities,
1397 ) -> Self {
1398 let node_rc = Rc::new(RefCell::new(node));
1400 let entry = Self {
1401 element_type,
1402 node_type,
1403 key,
1404 hash_code,
1405 element,
1406 node: Rc::clone(&node_rc),
1407 capabilities,
1408 };
1409 entry
1410 .node
1411 .borrow()
1412 .node_state()
1413 .set_capabilities(entry.capabilities);
1414 entry
1415 }
1416}
1417
1418fn visit_node_tree_mut(
1419 node: &mut dyn ModifierNode,
1420 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
1421) {
1422 visitor(node);
1423 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
1424}
1425
1426fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
1427 let mut current = 0usize;
1428 let mut result: Option<&dyn ModifierNode> = None;
1429 node.for_each_delegate(&mut |child| {
1430 if result.is_none() && current == target {
1431 result = Some(child);
1432 }
1433 current += 1;
1434 });
1435 result
1436}
1437
1438fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
1439 let mut current = 0usize;
1440 let mut result: Option<&mut dyn ModifierNode> = None;
1441 node.for_each_delegate_mut(&mut |child| {
1442 if result.is_none() && current == target {
1443 result = Some(child);
1444 }
1445 current += 1;
1446 });
1447 result
1448}
1449
1450fn with_node_context<F, R>(
1451 node: &mut dyn ModifierNode,
1452 context: &mut dyn ModifierNodeContext,
1453 f: F,
1454) -> R
1455where
1456 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
1457{
1458 context.push_active_capabilities(node.node_state().capabilities());
1459 let result = f(node, context);
1460 context.pop_active_capabilities();
1461 result
1462}
1463
1464fn request_auto_invalidations(
1465 context: &mut dyn ModifierNodeContext,
1466 capabilities: NodeCapabilities,
1467) {
1468 if capabilities.is_empty() {
1469 return;
1470 }
1471
1472 context.push_active_capabilities(capabilities);
1473
1474 if capabilities.contains(NodeCapabilities::LAYOUT) {
1475 context.invalidate(InvalidationKind::Layout);
1476 }
1477 if capabilities.contains(NodeCapabilities::DRAW) {
1478 context.invalidate(InvalidationKind::Draw);
1479 }
1480 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
1481 context.invalidate(InvalidationKind::PointerInput);
1482 }
1483 if capabilities.contains(NodeCapabilities::SEMANTICS) {
1484 context.invalidate(InvalidationKind::Semantics);
1485 }
1486 if capabilities.contains(NodeCapabilities::FOCUS) {
1487 context.invalidate(InvalidationKind::Focus);
1488 }
1489
1490 context.pop_active_capabilities();
1491}
1492
1493fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
1501 visit_node_tree_mut(node, &mut |n| {
1502 if !n.node_state().is_attached() {
1503 n.node_state().set_attached(true);
1504 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
1505 }
1506 });
1507}
1508
1509fn reset_node_tree(node: &mut dyn ModifierNode) {
1510 visit_node_tree_mut(node, &mut |n| n.on_reset());
1511}
1512
1513fn detach_node_tree(node: &mut dyn ModifierNode) {
1514 visit_node_tree_mut(node, &mut |n| {
1515 if n.node_state().is_attached() {
1516 n.on_detach();
1517 n.node_state().set_attached(false);
1518 }
1519 n.node_state().set_parent_link(None);
1520 n.node_state().set_child_link(None);
1521 n.node_state()
1522 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1523 });
1524}
1525
1526pub struct ModifierNodeChain {
1533 entries: Vec<ModifierNodeEntry>,
1534 aggregated_capabilities: NodeCapabilities,
1535 head_aggregate_child_capabilities: NodeCapabilities,
1536 head_sentinel: Box<SentinelNode>,
1537 tail_sentinel: Box<SentinelNode>,
1538 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
1540 scratch_old_used: Vec<bool>,
1542 scratch_match_order: Vec<Option<usize>>,
1543 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
1544 scratch_elements: Vec<DynModifierElement>,
1545}
1546
1547struct SentinelNode {
1548 state: NodeState,
1549}
1550
1551impl SentinelNode {
1552 fn new() -> Self {
1553 Self {
1554 state: NodeState::sentinel(),
1555 }
1556 }
1557}
1558
1559impl DelegatableNode for SentinelNode {
1560 fn node_state(&self) -> &NodeState {
1561 &self.state
1562 }
1563}
1564
1565impl ModifierNode for SentinelNode {}
1566
1567#[derive(Clone)]
1568pub struct ModifierChainNodeRef<'a> {
1569 chain: &'a ModifierNodeChain,
1570 link: NodeLink,
1571 cached_capabilities: Option<NodeCapabilities>,
1573 cached_aggregate_child: Option<NodeCapabilities>,
1575}
1576
1577impl Default for ModifierNodeChain {
1578 fn default() -> Self {
1579 Self::new()
1580 }
1581}
1582
1583struct EntryIndex {
1588 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1590 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1592 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
1594}
1595
1596struct EntryMatchQuery<'a> {
1597 element_type: TypeId,
1598 node_type: TypeId,
1599 key: Option<u64>,
1600 hash_code: u64,
1601 element: &'a DynModifierElement,
1602}
1603
1604impl EntryIndex {
1605 fn build(entries: &[ModifierNodeEntry]) -> Self {
1606 let mut keyed = HashMap::default();
1607 let mut hashed = HashMap::default();
1608 let mut typed = HashMap::default();
1609
1610 for (i, entry) in entries.iter().enumerate() {
1611 if let Some(key_value) = entry.key {
1612 keyed
1614 .entry((entry.element_type, entry.node_type, key_value))
1615 .or_insert_with(Vec::new)
1616 .push(i);
1617 } else {
1618 hashed
1620 .entry((entry.element_type, entry.node_type, entry.hash_code))
1621 .or_insert_with(Vec::new)
1622 .push(i);
1623 typed
1624 .entry((entry.element_type, entry.node_type))
1625 .or_insert_with(Vec::new)
1626 .push(i);
1627 }
1628 }
1629
1630 Self {
1631 keyed,
1632 hashed,
1633 typed,
1634 }
1635 }
1636
1637 fn find_match(
1644 &self,
1645 entries: &[ModifierNodeEntry],
1646 used: &[bool],
1647 query: EntryMatchQuery<'_>,
1648 ) -> Option<usize> {
1649 if let Some(key_value) = query.key {
1650 if let Some(candidates) =
1652 self.keyed
1653 .get(&(query.element_type, query.node_type, key_value))
1654 {
1655 for &i in candidates {
1656 if !used[i] {
1657 return Some(i);
1658 }
1659 }
1660 }
1661 } else {
1662 if let Some(candidates) =
1664 self.hashed
1665 .get(&(query.element_type, query.node_type, query.hash_code))
1666 {
1667 for &i in candidates {
1668 if !used[i]
1669 && entries[i]
1670 .element
1671 .as_ref()
1672 .equals_element(query.element.as_ref())
1673 {
1674 return Some(i);
1675 }
1676 }
1677 }
1678
1679 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
1681 for &i in candidates {
1682 if !used[i] {
1683 return Some(i);
1684 }
1685 }
1686 }
1687 }
1688
1689 None
1690 }
1691}
1692
1693impl ModifierNodeChain {
1694 pub fn new() -> Self {
1695 let mut chain = Self {
1696 entries: Vec::new(),
1697 aggregated_capabilities: NodeCapabilities::empty(),
1698 head_aggregate_child_capabilities: NodeCapabilities::empty(),
1699 head_sentinel: Box::new(SentinelNode::new()),
1700 tail_sentinel: Box::new(SentinelNode::new()),
1701 ordered_nodes: Vec::new(),
1702 scratch_old_used: Vec::new(),
1703 scratch_match_order: Vec::new(),
1704 scratch_final_slots: Vec::new(),
1705 scratch_elements: Vec::new(),
1706 };
1707 chain.sync_chain_links();
1708 chain
1709 }
1710
1711 pub fn detach_nodes(&mut self) {
1713 for entry in &self.entries {
1714 detach_node_tree(&mut **entry.node.borrow_mut());
1715 }
1716 }
1717
1718 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
1720 for entry in &self.entries {
1721 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1722 }
1723 }
1724
1725 pub fn repair_chain(&mut self) {
1728 self.sync_chain_links();
1729 }
1730
1731 pub fn update_from_slice(
1737 &mut self,
1738 elements: &[DynModifierElement],
1739 context: &mut dyn ModifierNodeContext,
1740 ) {
1741 self.update_from_ref_iter(elements.iter(), context);
1742 }
1743
1744 pub fn update_from_ref_iter<'a, I>(
1749 &mut self,
1750 elements: I,
1751 context: &mut dyn ModifierNodeContext,
1752 ) where
1753 I: Iterator<Item = &'a DynModifierElement>,
1754 {
1755 let old_len = self.entries.len();
1759 let mut fast_path_failed_at: Option<usize> = None;
1760 let mut elements_count = 0;
1761
1762 self.scratch_elements.clear();
1764
1765 for (idx, element) in elements.enumerate() {
1766 elements_count = idx + 1;
1767
1768 if fast_path_failed_at.is_none() && idx < old_len {
1769 let entry = &mut self.entries[idx];
1770 let same_type = entry.element_type == element.element_type();
1771 let same_node_type = entry.node_type == element.node_type();
1772 let same_key = entry.key == element.key();
1773 let same_hash = entry.hash_code == element.hash_code();
1774
1775 let positional_update = element.requires_update();
1778 if same_type && same_node_type && same_key && (same_hash || positional_update) {
1779 let can_update_node = {
1780 let node_borrow = entry.node.borrow();
1781 element.can_update_node(&**node_borrow)
1782 };
1783 if !can_update_node {
1784 fast_path_failed_at = Some(idx);
1785 self.scratch_elements.push(element.clone());
1786 continue;
1787 }
1788
1789 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1791 let capabilities = element.capabilities();
1792
1793 {
1795 let node_borrow = entry.node.borrow();
1796 if !node_borrow.node_state().is_attached() {
1797 drop(node_borrow);
1798 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1799 }
1800 }
1801
1802 let needs_update = !same_element || element.requires_update();
1804 if needs_update {
1805 element.update_node(&mut **entry.node.borrow_mut());
1806 entry.element = element.clone();
1807 entry.hash_code = element.hash_code();
1808 request_update_auto_invalidations(element.as_ref(), context, capabilities);
1809 }
1810
1811 entry.capabilities = capabilities;
1813 entry
1814 .node
1815 .borrow()
1816 .node_state()
1817 .set_capabilities(capabilities);
1818 continue;
1819 }
1820 fast_path_failed_at = Some(idx);
1822 }
1823
1824 self.scratch_elements.push(element.clone());
1826 }
1827
1828 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
1833 if elements_count < self.entries.len() {
1835 for entry in self.entries.drain(elements_count..) {
1836 request_auto_invalidations(context, entry.capabilities);
1837 detach_node_tree(&mut **entry.node.borrow_mut());
1838 }
1839 }
1840 self.sync_chain_links();
1841 return;
1842 }
1843
1844 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
1847
1848 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
1850 let processed_entries_len = self.entries.len();
1851 let old_len = old_entries.len();
1852
1853 self.scratch_old_used.clear();
1855 self.scratch_old_used.resize(old_len, false);
1856
1857 self.scratch_match_order.clear();
1858 self.scratch_match_order.resize(old_len, None);
1859
1860 let index = EntryIndex::build(&old_entries);
1862
1863 let new_elements_count = self.scratch_elements.len();
1864 self.scratch_final_slots.clear();
1865 self.scratch_final_slots.reserve(new_elements_count);
1866
1867 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
1869 self.scratch_final_slots.push(None);
1870 let element_type = element.element_type();
1871 let node_type = element.node_type();
1872 let key = element.key();
1873 let hash_code = element.hash_code();
1874 let capabilities = element.capabilities();
1875
1876 let matched_idx = index.find_match(
1878 &old_entries,
1879 &self.scratch_old_used,
1880 EntryMatchQuery {
1881 element_type,
1882 node_type,
1883 key,
1884 hash_code,
1885 element: &element,
1886 },
1887 );
1888
1889 if let Some(idx) = matched_idx {
1890 let entry = &mut old_entries[idx];
1892 let can_update_node = {
1893 let node_borrow = entry.node.borrow();
1894 element.can_update_node(&**node_borrow)
1895 };
1896 if !can_update_node {
1897 let replacement = ModifierNodeEntry::new(
1898 element_type,
1899 node_type,
1900 key,
1901 element.clone(),
1902 element.create_node(),
1903 hash_code,
1904 capabilities,
1905 );
1906 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
1907 element.update_node(&mut **replacement.node.borrow_mut());
1908 request_auto_invalidations(context, capabilities);
1909 self.scratch_final_slots[new_pos] = Some(replacement);
1910 continue;
1911 }
1912
1913 self.scratch_old_used[idx] = true;
1914 self.scratch_match_order[idx] = Some(new_pos);
1915 let moved = idx != new_pos;
1916
1917 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1919
1920 {
1922 let node_borrow = entry.node.borrow();
1923 if !node_borrow.node_state().is_attached() {
1924 drop(node_borrow);
1925 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1926 }
1927 }
1928
1929 let needs_update = !same_element || element.requires_update();
1931 if needs_update {
1932 element.update_node(&mut **entry.node.borrow_mut());
1933 entry.element = element;
1934 entry.hash_code = hash_code;
1935 request_update_auto_invalidations(
1936 entry.element.as_ref(),
1937 context,
1938 capabilities,
1939 );
1940 }
1941 if moved {
1942 request_auto_invalidations(context, capabilities);
1943 }
1944
1945 entry.key = key;
1947 entry.element_type = element_type;
1948 entry.node_type = node_type;
1949 entry.capabilities = capabilities;
1950 entry
1951 .node
1952 .borrow()
1953 .node_state()
1954 .set_capabilities(capabilities);
1955 } else {
1956 let entry = ModifierNodeEntry::new(
1958 element_type,
1959 node_type,
1960 key,
1961 element.clone(),
1962 element.create_node(),
1963 hash_code,
1964 capabilities,
1965 );
1966 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1967 element.update_node(&mut **entry.node.borrow_mut());
1968 request_auto_invalidations(context, capabilities);
1969 self.scratch_final_slots[new_pos] = Some(entry);
1970 }
1971 }
1972
1973 for (i, entry) in old_entries.into_iter().enumerate() {
1975 if self.scratch_old_used[i] {
1976 if let Some(pos) = self.scratch_match_order[i] {
1977 self.scratch_final_slots[pos] = Some(entry);
1978 } else {
1979 request_auto_invalidations(context, entry.capabilities);
1980 detach_node_tree(&mut **entry.node.borrow_mut());
1981 }
1982 } else {
1983 request_auto_invalidations(context, entry.capabilities);
1984 detach_node_tree(&mut **entry.node.borrow_mut());
1985 }
1986 }
1987
1988 self.entries.reserve(self.scratch_final_slots.len());
1990 for slot in self.scratch_final_slots.drain(..) {
1991 if let Some(entry) = slot {
1992 self.entries.push(entry);
1993 } else {
1994 log::error!("modifier reconciliation produced an empty final slot");
1995 }
1996 }
1997
1998 debug_assert_eq!(
1999 self.entries.len(),
2000 processed_entries_len + new_elements_count
2001 );
2002 self.sync_chain_links();
2003 }
2004
2005 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2009 where
2010 I: IntoIterator<Item = DynModifierElement>,
2011 {
2012 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2013 self.update_from_slice(&collected, context);
2014 }
2015
2016 pub fn reset(&mut self) {
2019 for entry in &mut self.entries {
2020 reset_node_tree(&mut **entry.node.borrow_mut());
2021 }
2022 }
2023
2024 pub fn detach_all(&mut self) {
2026 for entry in std::mem::take(&mut self.entries) {
2027 detach_node_tree(&mut **entry.node.borrow_mut());
2028 {
2029 let node_borrow = entry.node.borrow();
2030 let state = node_borrow.node_state();
2031 state.set_capabilities(NodeCapabilities::empty());
2032 }
2033 }
2034 self.aggregated_capabilities = NodeCapabilities::empty();
2035 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2036 self.ordered_nodes.clear();
2037 self.sync_chain_links();
2038 }
2039
2040 pub fn len(&self) -> usize {
2041 self.entries.len()
2042 }
2043
2044 pub fn is_empty(&self) -> bool {
2045 self.entries.is_empty()
2046 }
2047
2048 pub fn capabilities(&self) -> NodeCapabilities {
2050 self.aggregated_capabilities
2051 }
2052
2053 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2055 self.aggregated_capabilities.contains(capability)
2056 }
2057
2058 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2060 self.make_node_ref(NodeLink::Head)
2061 }
2062
2063 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2065 self.make_node_ref(NodeLink::Tail)
2066 }
2067
2068 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2070 ModifierChainIter::forward(self)
2071 }
2072
2073 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2075 ModifierChainIter::backward(self)
2076 }
2077
2078 pub fn for_each_forward<F>(&self, mut f: F)
2080 where
2081 F: FnMut(ModifierChainNodeRef<'_>),
2082 {
2083 for node in self.head_to_tail() {
2084 f(node);
2085 }
2086 }
2087
2088 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2090 where
2091 F: FnMut(ModifierChainNodeRef<'_>),
2092 {
2093 if mask.is_empty() {
2094 self.for_each_forward(f);
2095 return;
2096 }
2097
2098 if !self.head().aggregate_child_capabilities().intersects(mask) {
2099 return;
2100 }
2101
2102 for node in self.head_to_tail() {
2103 if node.kind_set().intersects(mask) {
2104 f(node);
2105 }
2106 }
2107 }
2108
2109 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2111 where
2112 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2113 {
2114 self.for_each_forward_matching(mask, |node_ref| {
2115 node_ref.with_node(|node| f(node_ref.clone(), node));
2116 });
2117 }
2118
2119 pub fn for_each_backward<F>(&self, mut f: F)
2121 where
2122 F: FnMut(ModifierChainNodeRef<'_>),
2123 {
2124 for node in self.tail_to_head() {
2125 f(node);
2126 }
2127 }
2128
2129 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2131 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2132 node as *const dyn ModifierNode as *const ()
2133 }
2134
2135 let target = node_data_ptr(node);
2136 for (index, entry) in self.entries.iter().enumerate() {
2137 if node_data_ptr(&**entry.node.borrow()) == target {
2138 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2139 }
2140 }
2141
2142 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2143 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2144 return None;
2145 }
2146 let matches_target = match link {
2147 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2148 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2149 NodeLink::Entry(path) => {
2150 let node_borrow = self.entries[path.entry()].node.borrow();
2151 node_data_ptr(&**node_borrow) == target
2152 }
2153 };
2154 if matches_target {
2155 Some(self.make_node_ref(*link))
2156 } else {
2157 None
2158 }
2159 })
2160 }
2161
2162 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2165 self.entries.get(index).and_then(|entry| {
2166 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2167 boxed_node.as_any().downcast_ref::<N>()
2168 })
2169 .ok()
2170 })
2171 }
2172
2173 pub fn node_mut<N: ModifierNode + 'static>(
2176 &self,
2177 index: usize,
2178 ) -> Option<std::cell::RefMut<'_, N>> {
2179 self.entries.get(index).and_then(|entry| {
2180 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2181 boxed_node.as_any_mut().downcast_mut::<N>()
2182 })
2183 .ok()
2184 })
2185 }
2186
2187 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2190 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
2191 }
2192
2193 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
2195 self.aggregated_capabilities
2196 .contains(NodeCapabilities::for_invalidation(kind))
2197 }
2198
2199 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
2201 where
2202 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
2203 {
2204 for index in 0..self.ordered_nodes.len() {
2205 let (link, cached_caps, _agg) = self.ordered_nodes[index];
2206 match link {
2207 NodeLink::Head => {
2208 f(self.head_sentinel.as_mut(), cached_caps);
2209 }
2210 NodeLink::Tail => {
2211 f(self.tail_sentinel.as_mut(), cached_caps);
2212 }
2213 NodeLink::Entry(path) => {
2214 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
2215 if path.delegates().is_empty() {
2216 f(&mut **node_borrow, cached_caps);
2217 } else {
2218 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
2219 for &delegate_index in path.delegates() {
2220 if let Some(delegate) =
2221 nth_delegate_mut(current, delegate_index as usize)
2222 {
2223 current = delegate;
2224 } else {
2225 return; }
2227 }
2228 f(current, cached_caps);
2229 }
2230 }
2231 }
2232 }
2233 }
2234
2235 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2236 ModifierChainNodeRef {
2237 chain: self,
2238 link,
2239 cached_capabilities: None,
2240 cached_aggregate_child: None,
2241 }
2242 }
2243
2244 fn make_node_ref_with_caps(
2245 &self,
2246 link: NodeLink,
2247 caps: NodeCapabilities,
2248 aggregate_child: NodeCapabilities,
2249 ) -> ModifierChainNodeRef<'_> {
2250 ModifierChainNodeRef {
2251 chain: self,
2252 link,
2253 cached_capabilities: Some(caps),
2254 cached_aggregate_child: Some(aggregate_child),
2255 }
2256 }
2257
2258 fn sync_chain_links(&mut self) {
2259 self.rebuild_ordered_nodes();
2260
2261 self.head_sentinel.node_state().set_parent_link(None);
2262 self.tail_sentinel.node_state().set_child_link(None);
2263
2264 if self.ordered_nodes.is_empty() {
2265 self.head_sentinel
2266 .node_state()
2267 .set_child_link(Some(NodeLink::Tail));
2268 self.tail_sentinel
2269 .node_state()
2270 .set_parent_link(Some(NodeLink::Head));
2271 self.aggregated_capabilities = NodeCapabilities::empty();
2272 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2273 self.head_sentinel
2274 .node_state()
2275 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2276 self.tail_sentinel
2277 .node_state()
2278 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2279 return;
2280 }
2281
2282 let mut previous = NodeLink::Head;
2283 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
2284 match &previous {
2286 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
2287 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
2288 NodeLink::Entry(path) => {
2289 let node_borrow = self.entries[path.entry()].node.borrow();
2290 if path.delegates().is_empty() {
2292 node_borrow.node_state().set_child_link(Some(link));
2293 } else {
2294 let mut current: &dyn ModifierNode = &**node_borrow;
2295 for &delegate_index in path.delegates() {
2296 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2297 current = delegate;
2298 }
2299 }
2300 current.node_state().set_child_link(Some(link));
2301 }
2302 }
2303 }
2304 match &link {
2306 NodeLink::Head => self
2307 .head_sentinel
2308 .node_state()
2309 .set_parent_link(Some(previous)),
2310 NodeLink::Tail => self
2311 .tail_sentinel
2312 .node_state()
2313 .set_parent_link(Some(previous)),
2314 NodeLink::Entry(path) => {
2315 let node_borrow = self.entries[path.entry()].node.borrow();
2316 if path.delegates().is_empty() {
2318 node_borrow.node_state().set_parent_link(Some(previous));
2319 } else {
2320 let mut current: &dyn ModifierNode = &**node_borrow;
2321 for &delegate_index in path.delegates() {
2322 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2323 current = delegate;
2324 }
2325 }
2326 current.node_state().set_parent_link(Some(previous));
2327 }
2328 }
2329 }
2330 previous = link;
2331 }
2332
2333 match &previous {
2335 NodeLink::Head => self
2336 .head_sentinel
2337 .node_state()
2338 .set_child_link(Some(NodeLink::Tail)),
2339 NodeLink::Tail => self
2340 .tail_sentinel
2341 .node_state()
2342 .set_child_link(Some(NodeLink::Tail)),
2343 NodeLink::Entry(path) => {
2344 let node_borrow = self.entries[path.entry()].node.borrow();
2345 if path.delegates().is_empty() {
2347 node_borrow
2348 .node_state()
2349 .set_child_link(Some(NodeLink::Tail));
2350 } else {
2351 let mut current: &dyn ModifierNode = &**node_borrow;
2352 for &delegate_index in path.delegates() {
2353 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2354 current = delegate;
2355 }
2356 }
2357 current.node_state().set_child_link(Some(NodeLink::Tail));
2358 }
2359 }
2360 }
2361 self.tail_sentinel
2362 .node_state()
2363 .set_parent_link(Some(previous));
2364 self.tail_sentinel.node_state().set_child_link(None);
2365
2366 let mut aggregate = NodeCapabilities::empty();
2367 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
2368 aggregate |= *cached_caps;
2369 *cached_aggregate = aggregate;
2370 match link {
2372 NodeLink::Head => {
2373 self.head_sentinel
2374 .node_state()
2375 .set_aggregate_child_capabilities(aggregate);
2376 }
2377 NodeLink::Tail => {
2378 self.tail_sentinel
2379 .node_state()
2380 .set_aggregate_child_capabilities(aggregate);
2381 }
2382 NodeLink::Entry(path) => {
2383 let node_borrow = self.entries[path.entry()].node.borrow();
2384 let state = if path.delegates().is_empty() {
2385 node_borrow.node_state()
2386 } else {
2387 let mut current: &dyn ModifierNode = &**node_borrow;
2388 for &delegate_index in path.delegates() {
2389 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2390 current = delegate;
2391 }
2392 }
2393 current.node_state()
2394 };
2395 state.set_aggregate_child_capabilities(aggregate);
2396 }
2397 }
2398 }
2399
2400 self.aggregated_capabilities = aggregate;
2401 self.head_aggregate_child_capabilities = aggregate;
2402 self.head_sentinel
2403 .node_state()
2404 .set_aggregate_child_capabilities(aggregate);
2405 self.tail_sentinel
2406 .node_state()
2407 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2408 }
2409
2410 fn rebuild_ordered_nodes(&mut self) {
2411 self.ordered_nodes.clear();
2412 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
2413 for (index, entry) in self.entries.iter().enumerate() {
2414 let node_borrow = entry.node.borrow();
2415 Self::enumerate_link_order(
2416 &**node_borrow,
2417 index,
2418 &mut path_buf,
2419 0,
2420 &mut self.ordered_nodes,
2421 );
2422 }
2423 }
2424
2425 fn enumerate_link_order(
2426 node: &dyn ModifierNode,
2427 entry: usize,
2428 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
2429 path_len: usize,
2430 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2431 ) {
2432 let caps = node.node_state().capabilities();
2433 out.push((
2434 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
2435 caps,
2436 NodeCapabilities::empty(),
2437 ));
2438 let mut delegate_index = 0usize;
2439 node.for_each_delegate(&mut |child| {
2440 if path_len < MAX_DELEGATE_DEPTH {
2441 path_buf[path_len] = delegate_index;
2442 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
2443 }
2444 delegate_index += 1;
2445 });
2446 }
2447}
2448
2449impl<'a> ModifierChainNodeRef<'a> {
2450 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
2453 match &self.link {
2454 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
2455 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
2456 NodeLink::Entry(path) => {
2457 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2458 if path.delegates().is_empty() {
2460 f(node_borrow.node_state())
2461 } else {
2462 let mut current: &dyn ModifierNode = &**node_borrow;
2464 for &delegate_index in path.delegates() {
2465 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2466 current = delegate;
2467 } else {
2468 return f(node_borrow.node_state());
2470 }
2471 }
2472 f(current.node_state())
2473 }
2474 }
2475 }
2476 }
2477
2478 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
2481 match &self.link {
2482 NodeLink::Head => None, NodeLink::Tail => None, NodeLink::Entry(path) => {
2485 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2486 if path.delegates().is_empty() {
2488 Some(f(&**node_borrow))
2489 } else {
2490 let mut current: &dyn ModifierNode = &**node_borrow;
2492 for &delegate_index in path.delegates() {
2493 current = nth_delegate(current, delegate_index as usize)?;
2495 }
2496 Some(f(current))
2497 }
2498 }
2499 }
2500 }
2501
2502 #[inline]
2504 pub fn parent(&self) -> Option<Self> {
2505 self.with_state(|state| state.parent_link())
2506 .map(|link| self.chain.make_node_ref(link))
2507 }
2508
2509 #[inline]
2511 pub fn child(&self) -> Option<Self> {
2512 self.with_state(|state| state.child_link())
2513 .map(|link| self.chain.make_node_ref(link))
2514 }
2515
2516 #[inline]
2518 pub fn kind_set(&self) -> NodeCapabilities {
2519 if let Some(caps) = self.cached_capabilities {
2520 return caps;
2521 }
2522 match &self.link {
2523 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
2524 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
2525 }
2526 }
2527
2528 pub fn entry_index(&self) -> Option<usize> {
2530 match &self.link {
2531 NodeLink::Entry(path) => Some(path.entry()),
2532 _ => None,
2533 }
2534 }
2535
2536 pub fn delegate_depth(&self) -> usize {
2538 match &self.link {
2539 NodeLink::Entry(path) => path.delegates().len(),
2540 _ => 0,
2541 }
2542 }
2543
2544 #[inline]
2546 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
2547 if let Some(agg) = self.cached_aggregate_child {
2548 return agg;
2549 }
2550 if self.is_tail() {
2551 NodeCapabilities::empty()
2552 } else {
2553 self.with_state(|state| state.aggregate_child_capabilities())
2554 }
2555 }
2556
2557 pub fn is_head(&self) -> bool {
2559 matches!(self.link, NodeLink::Head)
2560 }
2561
2562 pub fn is_tail(&self) -> bool {
2564 matches!(self.link, NodeLink::Tail)
2565 }
2566
2567 pub fn is_sentinel(&self) -> bool {
2569 matches!(self.link, NodeLink::Head | NodeLink::Tail)
2570 }
2571
2572 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
2574 !mask.is_empty() && self.kind_set().intersects(mask)
2575 }
2576
2577 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
2579 where
2580 F: FnMut(ModifierChainNodeRef<'a>),
2581 {
2582 let mut current = if include_self {
2583 Some(self)
2584 } else {
2585 self.child()
2586 };
2587 while let Some(node) = current {
2588 if node.is_tail() {
2589 break;
2590 }
2591 if !node.is_sentinel() {
2592 f(node.clone());
2593 }
2594 current = node.child();
2595 }
2596 }
2597
2598 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2600 where
2601 F: FnMut(ModifierChainNodeRef<'a>),
2602 {
2603 if mask.is_empty() {
2604 self.visit_descendants(include_self, f);
2605 return;
2606 }
2607
2608 if !self.aggregate_child_capabilities().intersects(mask) {
2609 return;
2610 }
2611
2612 self.visit_descendants(include_self, |node| {
2613 if node.kind_set().intersects(mask) {
2614 f(node);
2615 }
2616 });
2617 }
2618
2619 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
2621 where
2622 F: FnMut(ModifierChainNodeRef<'a>),
2623 {
2624 let mut current = if include_self {
2625 Some(self)
2626 } else {
2627 self.parent()
2628 };
2629 while let Some(node) = current {
2630 if node.is_head() {
2631 break;
2632 }
2633 f(node.clone());
2634 current = node.parent();
2635 }
2636 }
2637
2638 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2640 where
2641 F: FnMut(ModifierChainNodeRef<'a>),
2642 {
2643 if mask.is_empty() {
2644 self.visit_ancestors(include_self, f);
2645 return;
2646 }
2647
2648 self.visit_ancestors(include_self, |node| {
2649 if node.kind_set().intersects(mask) {
2650 f(node);
2651 }
2652 });
2653 }
2654}
2655
2656#[cfg(test)]
2657#[path = "tests/modifier_tests.rs"]
2658mod tests;