1use std::{
9 any::{Any, TypeId, type_name},
10 cell::{Cell, RefCell},
11 fmt,
12 hash::{Hash, Hasher},
13 ops::{BitOr, BitOrAssign},
14 rc::Rc,
15};
16
17use cranpose_core::{collections::map::HashMap, hash::default};
18pub use cranpose_ui_graphics::{DrawScope, Size};
19pub use cranpose_ui_layout::{Constraints, Measurable};
20
21use crate::nodes::input::types::PointerEvent;
22#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
27pub enum InvalidationKind {
28 Layout,
29 Draw,
30 PointerInput,
31 Semantics,
32 Focus,
33}
34
35pub trait ModifierNodeContext {
37 fn invalidate(&mut self, _kind: InvalidationKind) {}
39
40 fn request_update(&mut self) {}
43
44 fn node_id(&self) -> Option<cranpose_core::NodeId> {
47 None
48 }
49
50 fn push_active_capabilities(&mut self, _capabilities: NodeCapabilities) {}
52
53 fn pop_active_capabilities(&mut self) {}
55}
56
57#[derive(Default, Debug, Clone)]
66pub struct BasicModifierNodeContext {
67 invalidations: Vec<ModifierInvalidation>,
68 update_requested: bool,
69 active_capabilities: Vec<NodeCapabilities>,
70 node_id: Option<cranpose_core::NodeId>,
71}
72
73impl BasicModifierNodeContext {
74 pub fn new() -> Self {
76 Self::default()
77 }
78
79 pub fn invalidations(&self) -> &[ModifierInvalidation] {
83 &self.invalidations
84 }
85
86 pub fn clear_invalidations(&mut self) {
88 self.invalidations.clear();
89 }
90
91 pub fn take_invalidations(&mut self) -> Vec<ModifierInvalidation> {
93 std::mem::take(&mut self.invalidations)
94 }
95
96 pub fn update_requested(&self) -> bool {
99 self.update_requested
100 }
101
102 pub fn take_update_requested(&mut self) -> bool {
104 std::mem::take(&mut self.update_requested)
105 }
106
107 pub fn set_node_id(&mut self, id: Option<cranpose_core::NodeId>) {
109 self.node_id = id;
110 }
111
112 fn push_invalidation(&mut self, kind: InvalidationKind) {
113 let mut capabilities = self.current_capabilities();
114 capabilities.insert(NodeCapabilities::for_invalidation(kind));
115 if let Some(existing) = self
116 .invalidations
117 .iter_mut()
118 .find(|entry| entry.kind() == kind)
119 {
120 let updated = existing.capabilities() | capabilities;
121 *existing = ModifierInvalidation::new(kind, updated);
122 } else {
123 self.invalidations
124 .push(ModifierInvalidation::new(kind, capabilities));
125 }
126 }
127
128 fn current_capabilities(&self) -> NodeCapabilities {
129 self.active_capabilities
130 .last()
131 .copied()
132 .unwrap_or_else(NodeCapabilities::empty)
133 }
134}
135
136impl ModifierNodeContext for BasicModifierNodeContext {
137 fn invalidate(&mut self, kind: InvalidationKind) {
138 self.push_invalidation(kind);
139 }
140
141 fn request_update(&mut self) {
142 self.update_requested = true;
143 }
144
145 fn push_active_capabilities(&mut self, capabilities: NodeCapabilities) {
146 self.active_capabilities.push(capabilities);
147 }
148
149 fn pop_active_capabilities(&mut self) {
150 self.active_capabilities.pop();
151 }
152
153 fn node_id(&self) -> Option<cranpose_core::NodeId> {
154 self.node_id
155 }
156}
157
158const MAX_DELEGATE_DEPTH: usize = 3;
162
163#[derive(Copy, Clone, Debug, PartialEq, Eq)]
164pub(crate) struct NodePath {
165 entry: usize,
166 delegate_buf: [u8; MAX_DELEGATE_DEPTH],
167 delegate_len: u8,
168}
169
170impl NodePath {
171 #[inline]
172 fn root(entry: usize) -> Self {
173 Self {
174 entry,
175 delegate_buf: [0; MAX_DELEGATE_DEPTH],
176 delegate_len: 0,
177 }
178 }
179
180 #[inline]
181 fn from_slice(entry: usize, path: &[usize]) -> Self {
182 debug_assert!(
183 path.len() <= MAX_DELEGATE_DEPTH,
184 "delegate depth {} exceeds MAX_DELEGATE_DEPTH {}",
185 path.len(),
186 MAX_DELEGATE_DEPTH
187 );
188 debug_assert!(
189 path.iter().all(|&i| i <= u8::MAX as usize),
190 "delegate index exceeds u8 range"
191 );
192 let mut delegate_buf = [0u8; MAX_DELEGATE_DEPTH];
193 for (i, &v) in path.iter().enumerate().take(MAX_DELEGATE_DEPTH) {
194 delegate_buf[i] = v as u8;
195 }
196 Self {
197 entry,
198 delegate_buf,
199 delegate_len: path.len().min(MAX_DELEGATE_DEPTH) as u8,
200 }
201 }
202
203 #[inline]
204 fn entry(&self) -> usize {
205 self.entry
206 }
207
208 #[inline]
209 fn delegates(&self) -> &[u8] {
210 &self.delegate_buf[..self.delegate_len as usize]
211 }
212}
213
214#[derive(Copy, Clone, Debug, PartialEq, Eq)]
215pub(crate) enum NodeLink {
216 Head,
217 Tail,
218 Entry(NodePath),
219}
220
221#[derive(Debug)]
227pub struct NodeState {
228 aggregate_child_capabilities: Cell<NodeCapabilities>,
229 capabilities: Cell<NodeCapabilities>,
230 parent: RefCell<Option<NodeLink>>,
231 child: RefCell<Option<NodeLink>>,
232 attached: Cell<bool>,
233 is_sentinel: bool,
234}
235
236impl Default for NodeState {
237 fn default() -> Self {
238 Self::new()
239 }
240}
241
242impl NodeState {
243 pub const fn new() -> Self {
244 Self {
245 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
246 capabilities: Cell::new(NodeCapabilities::empty()),
247 parent: RefCell::new(None),
248 child: RefCell::new(None),
249 attached: Cell::new(false),
250 is_sentinel: false,
251 }
252 }
253
254 pub const fn sentinel() -> Self {
255 Self {
256 aggregate_child_capabilities: Cell::new(NodeCapabilities::empty()),
257 capabilities: Cell::new(NodeCapabilities::empty()),
258 parent: RefCell::new(None),
259 child: RefCell::new(None),
260 attached: Cell::new(true),
261 is_sentinel: true,
262 }
263 }
264
265 pub fn set_capabilities(&self, capabilities: NodeCapabilities) {
266 self.capabilities.set(capabilities);
267 }
268
269 #[inline]
270 pub fn capabilities(&self) -> NodeCapabilities {
271 self.capabilities.get()
272 }
273
274 pub fn set_aggregate_child_capabilities(&self, capabilities: NodeCapabilities) {
275 self.aggregate_child_capabilities.set(capabilities);
276 }
277
278 #[inline]
279 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
280 self.aggregate_child_capabilities.get()
281 }
282
283 pub(crate) fn set_parent_link(&self, parent: Option<NodeLink>) {
284 *self.parent.borrow_mut() = parent;
285 }
286
287 #[inline]
288 pub(crate) fn parent_link(&self) -> Option<NodeLink> {
289 *self.parent.borrow()
290 }
291
292 pub(crate) fn set_child_link(&self, child: Option<NodeLink>) {
293 *self.child.borrow_mut() = child;
294 }
295
296 #[inline]
297 pub(crate) fn child_link(&self) -> Option<NodeLink> {
298 *self.child.borrow()
299 }
300
301 pub fn set_attached(&self, attached: bool) {
302 self.attached.set(attached);
303 }
304
305 pub fn is_attached(&self) -> bool {
306 self.attached.get()
307 }
308
309 pub fn is_sentinel(&self) -> bool {
310 self.is_sentinel
311 }
312}
313
314pub trait DelegatableNode {
316 fn node_state(&self) -> &NodeState;
317 fn aggregate_child_capabilities(&self) -> NodeCapabilities {
318 self.node_state().aggregate_child_capabilities()
319 }
320}
321
322pub trait ModifierNode: Any + DelegatableNode {
380 fn on_attach(&mut self, _context: &mut dyn ModifierNodeContext) {}
381
382 fn on_detach(&mut self) {}
383
384 fn on_reset(&mut self) {}
385
386 fn as_draw_node(&self) -> Option<&dyn DrawModifierNode> {
388 None
389 }
390
391 fn as_draw_node_mut(&mut self) -> Option<&mut dyn DrawModifierNode> {
393 None
394 }
395
396 fn as_pointer_input_node(&self) -> Option<&dyn PointerInputNode> {
398 None
399 }
400
401 fn as_pointer_input_node_mut(&mut self) -> Option<&mut dyn PointerInputNode> {
403 None
404 }
405
406 fn as_semantics_node(&self) -> Option<&dyn SemanticsNode> {
408 None
409 }
410
411 fn as_semantics_node_mut(&mut self) -> Option<&mut dyn SemanticsNode> {
413 None
414 }
415
416 fn as_focus_node(&self) -> Option<&dyn FocusNode> {
418 None
419 }
420
421 fn as_focus_node_mut(&mut self) -> Option<&mut dyn FocusNode> {
423 None
424 }
425
426 fn as_layout_node(&self) -> Option<&dyn LayoutModifierNode> {
428 None
429 }
430
431 fn as_layout_node_mut(&mut self) -> Option<&mut dyn LayoutModifierNode> {
433 None
434 }
435
436 fn for_each_delegate<'b>(&'b self, _visitor: &mut dyn FnMut(&'b dyn ModifierNode)) {}
438
439 fn for_each_delegate_mut<'b>(&'b mut self, _visitor: &mut dyn FnMut(&'b mut dyn ModifierNode)) {
441 }
442}
443
444pub trait LayoutModifierNode: ModifierNode {
450 fn measure(
472 &self,
473 _context: &mut dyn ModifierNodeContext,
474 measurable: &dyn Measurable,
475 constraints: Constraints,
476 ) -> cranpose_ui_layout::LayoutModifierMeasureResult {
477 let placeable = measurable.measure(constraints);
479 cranpose_ui_layout::LayoutModifierMeasureResult::with_size(Size {
480 width: placeable.width(),
481 height: placeable.height(),
482 })
483 }
484
485 fn min_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
487 0.0
488 }
489
490 fn max_intrinsic_width(&self, _measurable: &dyn Measurable, _height: f32) -> f32 {
492 0.0
493 }
494
495 fn min_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
497 0.0
498 }
499
500 fn max_intrinsic_height(&self, _measurable: &dyn Measurable, _width: f32) -> f32 {
502 0.0
503 }
504}
505
506pub trait DrawModifierNode: ModifierNode {
514 fn draw(&self, _draw_scope: &mut dyn DrawScope) {
523 }
525
526 fn create_draw_closure(&self) -> Option<NodeDrawClosure> {
537 None
538 }
539
540 fn create_behind_draw_closure(&self) -> Option<NodeDrawClosure> {
545 None
546 }
547}
548
549pub type NodeDrawClosure = Rc<dyn Fn(&mut cranpose_ui_graphics::DrawScopeDefault)>;
554
555pub trait PointerInputNode: ModifierNode {
561 fn on_pointer_event(
564 &mut self,
565 _context: &mut dyn ModifierNodeContext,
566 _event: &PointerEvent,
567 ) -> bool {
568 false
569 }
570
571 fn hit_test(&self, _x: f32, _y: f32) -> bool {
574 true
575 }
576
577 fn pointer_input_handler(&self) -> Option<Rc<dyn Fn(PointerEvent)>> {
579 None
580 }
581
582 fn layout_size_sink(&self) -> Option<Rc<Cell<Size>>> {
595 None
596 }
597}
598
599pub trait SemanticsNode: ModifierNode {
605 fn merge_semantics(&self, _config: &mut SemanticsConfiguration) {
607 }
609}
610
611#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
616pub enum FocusState {
617 Active,
619 ActiveParent,
621 Captured,
625 #[default]
628 Inactive,
629}
630
631impl FocusState {
632 pub fn is_focused(self) -> bool {
634 matches!(self, FocusState::Active | FocusState::Captured)
635 }
636
637 pub fn has_focus(self) -> bool {
639 matches!(
640 self,
641 FocusState::Active | FocusState::ActiveParent | FocusState::Captured
642 )
643 }
644
645 pub fn is_captured(self) -> bool {
647 matches!(self, FocusState::Captured)
648 }
649}
650
651pub trait FocusNode: ModifierNode {
656 fn focus_state(&self) -> FocusState;
658
659 fn on_focus_changed(&mut self, _context: &mut dyn ModifierNodeContext, _state: FocusState) {
661 }
663}
664
665#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
676pub enum SemanticsWidgetRole {
677 Button,
678 Checkbox,
679 Switch,
680 RadioButton,
681 Tab,
682 Image,
683 Header,
688 Dialog,
692}
693
694#[derive(Clone)]
701pub struct SemanticsCustomAction {
702 pub label: String,
704 handler: Rc<dyn Fn()>,
705}
706
707impl SemanticsCustomAction {
708 pub fn new(label: impl Into<String>, handler: impl Fn() + 'static) -> Self {
709 Self {
710 label: label.into(),
711 handler: Rc::new(handler),
712 }
713 }
714
715 pub fn invoke(&self) {
716 (self.handler)();
717 }
718}
719
720impl fmt::Debug for SemanticsCustomAction {
721 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
722 f.debug_struct("SemanticsCustomAction")
723 .field("label", &self.label)
724 .finish_non_exhaustive()
725 }
726}
727
728impl PartialEq for SemanticsCustomAction {
738 fn eq(&self, other: &Self) -> bool {
739 self.label == other.label
740 }
741}
742
743impl Eq for SemanticsCustomAction {}
744
745#[derive(Clone, Debug, PartialEq)]
760pub struct CanvasSemanticsNode {
761 pub key: u64,
768 pub bounds: cranpose_ui_graphics::Rect,
770 pub label: String,
771 pub role: Option<SemanticsWidgetRole>,
772 pub state_description: Option<String>,
776 pub on_click_label: Option<String>,
779 pub clickable: bool,
780 pub selected: Option<bool>,
782 pub toggled: Option<bool>,
784 pub enabled: bool,
785 pub custom_actions: Vec<SemanticsCustomAction>,
786}
787
788impl Default for CanvasSemanticsNode {
789 fn default() -> Self {
790 Self {
791 key: 0,
792 bounds: cranpose_ui_graphics::Rect {
793 x: 0.0,
794 y: 0.0,
795 width: 0.0,
796 height: 0.0,
797 },
798 label: String::new(),
799 role: None,
800 state_description: None,
801 on_click_label: None,
802 clickable: false,
803 selected: None,
804 toggled: None,
805 enabled: true,
809 custom_actions: Vec::new(),
810 }
811 }
812}
813
814impl CanvasSemanticsNode {
815 pub fn control(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
817 Self {
818 key,
819 bounds,
820 label: label.into(),
821 clickable: true,
822 ..Self::default()
823 }
824 }
825
826 pub fn text(key: u64, bounds: cranpose_ui_graphics::Rect, label: impl Into<String>) -> Self {
828 Self {
829 key,
830 bounds,
831 label: label.into(),
832 ..Self::default()
833 }
834 }
835
836 pub fn with_role(mut self, role: SemanticsWidgetRole) -> Self {
837 self.role = Some(role);
838 self
839 }
840
841 pub fn with_state_description(mut self, state: impl Into<String>) -> Self {
842 self.state_description = Some(state.into());
843 self
844 }
845
846 pub fn with_click_label(mut self, label: impl Into<String>) -> Self {
847 self.on_click_label = Some(label.into());
848 self.clickable = true;
849 self
850 }
851
852 pub fn with_selected(mut self, selected: bool) -> Self {
853 self.selected = Some(selected);
854 self
855 }
856
857 pub fn with_toggled(mut self, toggled: bool) -> Self {
858 self.toggled = Some(toggled);
859 self
860 }
861
862 pub fn with_enabled(mut self, enabled: bool) -> Self {
863 self.enabled = enabled;
864 self
865 }
866
867 pub fn with_custom_action(mut self, action: SemanticsCustomAction) -> Self {
868 self.custom_actions.push(action);
869 self
870 }
871}
872
873#[derive(Clone, Debug, PartialEq)]
875pub struct SemanticsConfiguration {
876 pub content_description: Option<String>,
877 pub state_description: Option<String>,
879 pub on_click_label: Option<String>,
881 pub role: Option<SemanticsWidgetRole>,
883 pub selected: Option<bool>,
884 pub toggled: Option<bool>,
885 pub enabled: bool,
886 pub is_clickable: bool,
887 pub is_editable_text: bool,
888 pub text_selection: Option<crate::text::TextRange>,
889 pub custom_actions: Vec<SemanticsCustomAction>,
890 pub canvas_children: Vec<CanvasSemanticsNode>,
893 pub is_modal: bool,
896}
897
898impl Default for SemanticsConfiguration {
899 fn default() -> Self {
900 Self {
901 content_description: None,
902 state_description: None,
903 on_click_label: None,
904 role: None,
905 selected: None,
906 toggled: None,
907 enabled: true,
908 is_clickable: false,
909 is_editable_text: false,
910 text_selection: None,
911 custom_actions: Vec::new(),
912 canvas_children: Vec::new(),
913 is_modal: false,
914 }
915 }
916}
917
918impl SemanticsConfiguration {
919 pub fn merge(&mut self, other: &SemanticsConfiguration) {
920 if let Some(description) = &other.content_description {
921 self.content_description = Some(description.clone());
922 }
923 if let Some(state) = &other.state_description {
924 self.state_description = Some(state.clone());
925 }
926 if let Some(label) = &other.on_click_label {
927 self.on_click_label = Some(label.clone());
928 }
929 if let Some(role) = other.role {
930 self.role = Some(role);
931 }
932 if let Some(selected) = other.selected {
933 self.selected = Some(selected);
934 }
935 if let Some(toggled) = other.toggled {
936 self.toggled = Some(toggled);
937 }
938 self.enabled &= other.enabled;
941 self.is_clickable |= other.is_clickable;
942 self.is_editable_text |= other.is_editable_text;
943 if let Some(selection) = other.text_selection {
944 self.text_selection = Some(selection);
945 }
946 self.custom_actions
947 .extend(other.custom_actions.iter().cloned());
948 self.canvas_children
949 .extend(other.canvas_children.iter().cloned());
950 self.is_modal |= other.is_modal;
951 }
952
953 pub fn is_activatable(&self) -> bool {
956 self.is_clickable || self.on_click_label.is_some()
957 }
958}
959
960impl fmt::Debug for dyn ModifierNode {
961 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
962 f.debug_struct("ModifierNode").finish_non_exhaustive()
963 }
964}
965
966impl dyn ModifierNode {
967 pub fn as_any(&self) -> &dyn Any {
968 self
969 }
970
971 pub fn as_any_mut(&mut self) -> &mut dyn Any {
972 self
973 }
974}
975
976pub trait ModifierNodeElement: fmt::Debug + Hash + PartialEq + 'static {
979 type Node: ModifierNode;
980
981 fn create(&self) -> Self::Node;
983
984 fn update(&self, node: &mut Self::Node);
986
987 fn key(&self) -> Option<u64> {
989 None
990 }
991
992 fn inspector_name(&self) -> &'static str {
994 type_name::<Self>()
995 }
996
997 fn inspector_properties(&self, _inspector: &mut dyn FnMut(&'static str, String)) {}
999
1000 fn capabilities(&self) -> NodeCapabilities {
1003 NodeCapabilities::default()
1004 }
1005
1006 fn always_update(&self) -> bool {
1012 false
1013 }
1014
1015 fn auto_invalidate_on_update(&self) -> bool {
1018 true
1019 }
1020
1021 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1028 None
1029 }
1030}
1031
1032#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1034pub struct NodeCapabilities(u32);
1035
1036impl NodeCapabilities {
1037 pub const NONE: Self = Self(0);
1039 pub const LAYOUT: Self = Self(1 << 0);
1041 pub const DRAW: Self = Self(1 << 1);
1043 pub const POINTER_INPUT: Self = Self(1 << 2);
1045 pub const SEMANTICS: Self = Self(1 << 3);
1047 pub const MODIFIER_LOCALS: Self = Self(1 << 4);
1049 pub const FOCUS: Self = Self(1 << 5);
1051
1052 pub const fn empty() -> Self {
1054 Self::NONE
1055 }
1056
1057 pub const fn contains(self, other: Self) -> bool {
1059 (self.0 & other.0) == other.0
1060 }
1061
1062 pub const fn intersects(self, other: Self) -> bool {
1064 (self.0 & other.0) != 0
1065 }
1066
1067 pub fn insert(&mut self, other: Self) {
1069 self.0 |= other.0;
1070 }
1071
1072 pub const fn bits(self) -> u32 {
1074 self.0
1075 }
1076
1077 pub const fn is_empty(self) -> bool {
1079 self.0 == 0
1080 }
1081
1082 pub const fn for_invalidation(kind: InvalidationKind) -> Self {
1084 match kind {
1085 InvalidationKind::Layout => Self::LAYOUT,
1086 InvalidationKind::Draw => Self::DRAW,
1087 InvalidationKind::PointerInput => Self::POINTER_INPUT,
1088 InvalidationKind::Semantics => Self::SEMANTICS,
1089 InvalidationKind::Focus => Self::FOCUS,
1090 }
1091 }
1092}
1093
1094impl Default for NodeCapabilities {
1095 fn default() -> Self {
1096 Self::NONE
1097 }
1098}
1099
1100impl fmt::Debug for NodeCapabilities {
1101 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1102 f.debug_struct("NodeCapabilities")
1103 .field("layout", &self.contains(Self::LAYOUT))
1104 .field("draw", &self.contains(Self::DRAW))
1105 .field("pointer_input", &self.contains(Self::POINTER_INPUT))
1106 .field("semantics", &self.contains(Self::SEMANTICS))
1107 .field("modifier_locals", &self.contains(Self::MODIFIER_LOCALS))
1108 .field("focus", &self.contains(Self::FOCUS))
1109 .finish()
1110 }
1111}
1112
1113impl BitOr for NodeCapabilities {
1114 type Output = Self;
1115
1116 fn bitor(self, rhs: Self) -> Self::Output {
1117 Self(self.0 | rhs.0)
1118 }
1119}
1120
1121impl BitOrAssign for NodeCapabilities {
1122 fn bitor_assign(&mut self, rhs: Self) {
1123 self.0 |= rhs.0;
1124 }
1125}
1126
1127#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1129pub struct ModifierInvalidation {
1130 kind: InvalidationKind,
1131 capabilities: NodeCapabilities,
1132}
1133
1134impl ModifierInvalidation {
1135 pub const fn new(kind: InvalidationKind, capabilities: NodeCapabilities) -> Self {
1137 Self { kind, capabilities }
1138 }
1139
1140 pub const fn kind(self) -> InvalidationKind {
1142 self.kind
1143 }
1144
1145 pub const fn capabilities(self) -> NodeCapabilities {
1147 self.capabilities
1148 }
1149}
1150
1151pub trait AnyModifierElement: fmt::Debug {
1153 fn node_type(&self) -> TypeId;
1154
1155 fn element_type(&self) -> TypeId;
1156
1157 fn create_node(&self) -> Box<dyn ModifierNode>;
1158
1159 fn can_update_node(&self, node: &dyn ModifierNode) -> bool;
1160
1161 fn update_node(&self, node: &mut dyn ModifierNode);
1162
1163 fn key(&self) -> Option<u64>;
1164
1165 fn capabilities(&self) -> NodeCapabilities {
1166 NodeCapabilities::default()
1167 }
1168
1169 fn hash_code(&self) -> u64;
1170
1171 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool;
1172
1173 fn inspector_name(&self) -> &'static str;
1174
1175 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String));
1176
1177 fn requires_update(&self) -> bool;
1178
1179 fn auto_invalidates_on_update(&self) -> bool;
1180
1181 fn update_invalidation_kind(&self) -> Option<InvalidationKind>;
1182
1183 fn as_any(&self) -> &dyn Any;
1184}
1185
1186struct TypedModifierElement<E: ModifierNodeElement> {
1187 element: E,
1188 cached_hash: u64,
1189}
1190
1191impl<E: ModifierNodeElement> TypedModifierElement<E> {
1192 fn new(element: E) -> Self {
1193 let mut hasher = default::new();
1194 element.hash(&mut hasher);
1195 Self {
1196 element,
1197 cached_hash: hasher.finish(),
1198 }
1199 }
1200}
1201
1202impl<E> fmt::Debug for TypedModifierElement<E>
1203where
1204 E: ModifierNodeElement,
1205{
1206 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1207 f.debug_struct("TypedModifierElement")
1208 .field("type", &type_name::<E>())
1209 .finish()
1210 }
1211}
1212
1213impl<E> AnyModifierElement for TypedModifierElement<E>
1214where
1215 E: ModifierNodeElement,
1216{
1217 fn node_type(&self) -> TypeId {
1218 TypeId::of::<E::Node>()
1219 }
1220
1221 fn element_type(&self) -> TypeId {
1222 TypeId::of::<E>()
1223 }
1224
1225 fn create_node(&self) -> Box<dyn ModifierNode> {
1226 Box::new(self.element.create())
1227 }
1228
1229 fn can_update_node(&self, node: &dyn ModifierNode) -> bool {
1230 node.as_any().is::<E::Node>()
1231 }
1232
1233 fn update_node(&self, node: &mut dyn ModifierNode) {
1234 if let Some(typed) = node.as_any_mut().downcast_mut::<E::Node>() {
1235 self.element.update(typed);
1236 }
1237 }
1238
1239 fn key(&self) -> Option<u64> {
1240 self.element.key()
1241 }
1242
1243 fn capabilities(&self) -> NodeCapabilities {
1244 self.element.capabilities()
1245 }
1246
1247 fn hash_code(&self) -> u64 {
1248 self.cached_hash
1249 }
1250
1251 fn equals_element(&self, other: &dyn AnyModifierElement) -> bool {
1252 other
1253 .as_any()
1254 .downcast_ref::<Self>()
1255 .map(|typed| typed.element == self.element)
1256 .unwrap_or(false)
1257 }
1258
1259 fn inspector_name(&self) -> &'static str {
1260 self.element.inspector_name()
1261 }
1262
1263 fn record_inspector_properties(&self, visitor: &mut dyn FnMut(&'static str, String)) {
1264 self.element.inspector_properties(visitor);
1265 }
1266
1267 fn requires_update(&self) -> bool {
1268 self.element.always_update()
1269 }
1270
1271 fn auto_invalidates_on_update(&self) -> bool {
1272 self.element.auto_invalidate_on_update()
1273 }
1274
1275 fn update_invalidation_kind(&self) -> Option<InvalidationKind> {
1276 self.element.update_invalidation_kind()
1277 }
1278
1279 fn as_any(&self) -> &dyn Any {
1280 self
1281 }
1282}
1283
1284fn request_update_auto_invalidations(
1285 element: &dyn AnyModifierElement,
1286 context: &mut dyn ModifierNodeContext,
1287 capabilities: NodeCapabilities,
1288) {
1289 if let Some(kind) = element.update_invalidation_kind() {
1290 let capabilities = NodeCapabilities::for_invalidation(kind);
1291 context.push_active_capabilities(capabilities);
1292 context.invalidate(kind);
1293 context.pop_active_capabilities();
1294 } else if element.auto_invalidates_on_update() {
1295 request_auto_invalidations(context, capabilities);
1296 }
1297}
1298
1299pub fn modifier_element<E: ModifierNodeElement>(element: E) -> DynModifierElement {
1302 Rc::new(TypedModifierElement::new(element))
1303}
1304
1305pub type DynModifierElement = Rc<dyn AnyModifierElement>;
1307
1308#[derive(Clone, Copy, Debug, PartialEq, Eq)]
1309enum TraversalDirection {
1310 Forward,
1311 Backward,
1312}
1313
1314pub struct ModifierChainIter<'a> {
1319 chain: &'a ModifierNodeChain,
1320 cursor: usize,
1323 remaining: usize,
1325 direction: TraversalDirection,
1326}
1327
1328impl<'a> ModifierChainIter<'a> {
1329 fn forward(chain: &'a ModifierNodeChain) -> Self {
1330 Self {
1331 chain,
1332 cursor: 0,
1333 remaining: chain.ordered_nodes.len(),
1334 direction: TraversalDirection::Forward,
1335 }
1336 }
1337
1338 fn backward(chain: &'a ModifierNodeChain) -> Self {
1339 let len = chain.ordered_nodes.len();
1340 Self {
1341 chain,
1342 cursor: len.wrapping_sub(1),
1343 remaining: len,
1344 direction: TraversalDirection::Backward,
1345 }
1346 }
1347}
1348
1349impl<'a> Iterator for ModifierChainIter<'a> {
1350 type Item = ModifierChainNodeRef<'a>;
1351
1352 #[inline]
1353 fn next(&mut self) -> Option<Self::Item> {
1354 if self.remaining == 0 {
1355 return None;
1356 }
1357 let (link, caps, agg) = self.chain.ordered_nodes[self.cursor];
1358 let node_ref = self.chain.make_node_ref_with_caps(link, caps, agg);
1359 self.remaining -= 1;
1360 match self.direction {
1361 TraversalDirection::Forward => self.cursor += 1,
1362 TraversalDirection::Backward => self.cursor = self.cursor.wrapping_sub(1),
1363 }
1364 Some(node_ref)
1365 }
1366
1367 #[inline]
1368 fn size_hint(&self) -> (usize, Option<usize>) {
1369 (self.remaining, Some(self.remaining))
1370 }
1371}
1372
1373impl<'a> ExactSizeIterator for ModifierChainIter<'a> {}
1374impl<'a> std::iter::FusedIterator for ModifierChainIter<'a> {}
1375
1376#[derive(Debug)]
1377struct ModifierNodeEntry {
1378 element_type: TypeId,
1379 node_type: TypeId,
1380 key: Option<u64>,
1381 hash_code: u64,
1382 element: DynModifierElement,
1383 node: Rc<RefCell<Box<dyn ModifierNode>>>,
1384 capabilities: NodeCapabilities,
1385}
1386
1387impl ModifierNodeEntry {
1388 fn new(
1389 element_type: TypeId,
1390 node_type: TypeId,
1391 key: Option<u64>,
1392 element: DynModifierElement,
1393 node: Box<dyn ModifierNode>,
1394 hash_code: u64,
1395 capabilities: NodeCapabilities,
1396 ) -> Self {
1397 let node_rc = Rc::new(RefCell::new(node));
1399 let entry = Self {
1400 element_type,
1401 node_type,
1402 key,
1403 hash_code,
1404 element,
1405 node: Rc::clone(&node_rc),
1406 capabilities,
1407 };
1408 entry
1409 .node
1410 .borrow()
1411 .node_state()
1412 .set_capabilities(entry.capabilities);
1413 entry
1414 }
1415}
1416
1417fn visit_node_tree_mut(
1418 node: &mut dyn ModifierNode,
1419 visitor: &mut dyn FnMut(&mut dyn ModifierNode),
1420) {
1421 visitor(node);
1422 node.for_each_delegate_mut(&mut |child| visit_node_tree_mut(child, visitor));
1423}
1424
1425fn nth_delegate(node: &dyn ModifierNode, target: usize) -> Option<&dyn ModifierNode> {
1426 let mut current = 0usize;
1427 let mut result: Option<&dyn ModifierNode> = None;
1428 node.for_each_delegate(&mut |child| {
1429 if result.is_none() && current == target {
1430 result = Some(child);
1431 }
1432 current += 1;
1433 });
1434 result
1435}
1436
1437fn nth_delegate_mut(node: &mut dyn ModifierNode, target: usize) -> Option<&mut dyn ModifierNode> {
1438 let mut current = 0usize;
1439 let mut result: Option<&mut dyn ModifierNode> = None;
1440 node.for_each_delegate_mut(&mut |child| {
1441 if result.is_none() && current == target {
1442 result = Some(child);
1443 }
1444 current += 1;
1445 });
1446 result
1447}
1448
1449fn with_node_context<F, R>(
1450 node: &mut dyn ModifierNode,
1451 context: &mut dyn ModifierNodeContext,
1452 f: F,
1453) -> R
1454where
1455 F: FnOnce(&mut dyn ModifierNode, &mut dyn ModifierNodeContext) -> R,
1456{
1457 context.push_active_capabilities(node.node_state().capabilities());
1458 let result = f(node, context);
1459 context.pop_active_capabilities();
1460 result
1461}
1462
1463fn request_auto_invalidations(
1464 context: &mut dyn ModifierNodeContext,
1465 capabilities: NodeCapabilities,
1466) {
1467 if capabilities.is_empty() {
1468 return;
1469 }
1470
1471 context.push_active_capabilities(capabilities);
1472
1473 if capabilities.contains(NodeCapabilities::LAYOUT) {
1474 context.invalidate(InvalidationKind::Layout);
1475 }
1476 if capabilities.contains(NodeCapabilities::DRAW) {
1477 context.invalidate(InvalidationKind::Draw);
1478 }
1479 if capabilities.contains(NodeCapabilities::POINTER_INPUT) {
1480 context.invalidate(InvalidationKind::PointerInput);
1481 }
1482 if capabilities.contains(NodeCapabilities::SEMANTICS) {
1483 context.invalidate(InvalidationKind::Semantics);
1484 }
1485 if capabilities.contains(NodeCapabilities::FOCUS) {
1486 context.invalidate(InvalidationKind::Focus);
1487 }
1488
1489 context.pop_active_capabilities();
1490}
1491
1492fn attach_node_tree(node: &mut dyn ModifierNode, context: &mut dyn ModifierNodeContext) {
1500 visit_node_tree_mut(node, &mut |n| {
1501 if !n.node_state().is_attached() {
1502 n.node_state().set_attached(true);
1503 with_node_context(n, context, |node, ctx| node.on_attach(ctx));
1504 }
1505 });
1506}
1507
1508fn reset_node_tree(node: &mut dyn ModifierNode) {
1509 visit_node_tree_mut(node, &mut |n| n.on_reset());
1510}
1511
1512fn detach_node_tree(node: &mut dyn ModifierNode) {
1513 visit_node_tree_mut(node, &mut |n| {
1514 if n.node_state().is_attached() {
1515 n.on_detach();
1516 n.node_state().set_attached(false);
1517 }
1518 n.node_state().set_parent_link(None);
1519 n.node_state().set_child_link(None);
1520 n.node_state()
1521 .set_aggregate_child_capabilities(NodeCapabilities::empty());
1522 });
1523}
1524
1525pub struct ModifierNodeChain {
1532 entries: Vec<ModifierNodeEntry>,
1533 aggregated_capabilities: NodeCapabilities,
1534 head_aggregate_child_capabilities: NodeCapabilities,
1535 head_sentinel: Box<SentinelNode>,
1536 tail_sentinel: Box<SentinelNode>,
1537 ordered_nodes: Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
1539 scratch_old_used: Vec<bool>,
1541 scratch_match_order: Vec<Option<usize>>,
1542 scratch_final_slots: Vec<Option<ModifierNodeEntry>>,
1543 scratch_elements: Vec<DynModifierElement>,
1544}
1545
1546struct SentinelNode {
1547 state: NodeState,
1548}
1549
1550impl SentinelNode {
1551 fn new() -> Self {
1552 Self {
1553 state: NodeState::sentinel(),
1554 }
1555 }
1556}
1557
1558impl DelegatableNode for SentinelNode {
1559 fn node_state(&self) -> &NodeState {
1560 &self.state
1561 }
1562}
1563
1564impl ModifierNode for SentinelNode {}
1565
1566#[derive(Clone)]
1567pub struct ModifierChainNodeRef<'a> {
1568 chain: &'a ModifierNodeChain,
1569 link: NodeLink,
1570 cached_capabilities: Option<NodeCapabilities>,
1572 cached_aggregate_child: Option<NodeCapabilities>,
1574}
1575
1576impl Default for ModifierNodeChain {
1577 fn default() -> Self {
1578 Self::new()
1579 }
1580}
1581
1582struct EntryIndex {
1587 keyed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1589 hashed: HashMap<(TypeId, TypeId, u64), Vec<usize>>,
1591 typed: HashMap<(TypeId, TypeId), Vec<usize>>,
1593}
1594
1595struct EntryMatchQuery<'a> {
1596 element_type: TypeId,
1597 node_type: TypeId,
1598 key: Option<u64>,
1599 hash_code: u64,
1600 element: &'a DynModifierElement,
1601}
1602
1603impl EntryIndex {
1604 fn build(entries: &[ModifierNodeEntry]) -> Self {
1605 let mut keyed = HashMap::default();
1606 let mut hashed = HashMap::default();
1607 let mut typed = HashMap::default();
1608
1609 for (i, entry) in entries.iter().enumerate() {
1610 if let Some(key_value) = entry.key {
1611 keyed
1613 .entry((entry.element_type, entry.node_type, key_value))
1614 .or_insert_with(Vec::new)
1615 .push(i);
1616 } else {
1617 hashed
1619 .entry((entry.element_type, entry.node_type, entry.hash_code))
1620 .or_insert_with(Vec::new)
1621 .push(i);
1622 typed
1623 .entry((entry.element_type, entry.node_type))
1624 .or_insert_with(Vec::new)
1625 .push(i);
1626 }
1627 }
1628
1629 Self {
1630 keyed,
1631 hashed,
1632 typed,
1633 }
1634 }
1635
1636 fn find_match(
1643 &self,
1644 entries: &[ModifierNodeEntry],
1645 used: &[bool],
1646 query: EntryMatchQuery<'_>,
1647 ) -> Option<usize> {
1648 if let Some(key_value) = query.key {
1649 if let Some(candidates) =
1651 self.keyed
1652 .get(&(query.element_type, query.node_type, key_value))
1653 {
1654 for &i in candidates {
1655 if !used[i] {
1656 return Some(i);
1657 }
1658 }
1659 }
1660 } else {
1661 if let Some(candidates) =
1663 self.hashed
1664 .get(&(query.element_type, query.node_type, query.hash_code))
1665 {
1666 for &i in candidates {
1667 if !used[i]
1668 && entries[i]
1669 .element
1670 .as_ref()
1671 .equals_element(query.element.as_ref())
1672 {
1673 return Some(i);
1674 }
1675 }
1676 }
1677
1678 if let Some(candidates) = self.typed.get(&(query.element_type, query.node_type)) {
1680 for &i in candidates {
1681 if !used[i] {
1682 return Some(i);
1683 }
1684 }
1685 }
1686 }
1687
1688 None
1689 }
1690}
1691
1692impl ModifierNodeChain {
1693 pub fn new() -> Self {
1694 let mut chain = Self {
1695 entries: Vec::new(),
1696 aggregated_capabilities: NodeCapabilities::empty(),
1697 head_aggregate_child_capabilities: NodeCapabilities::empty(),
1698 head_sentinel: Box::new(SentinelNode::new()),
1699 tail_sentinel: Box::new(SentinelNode::new()),
1700 ordered_nodes: Vec::new(),
1701 scratch_old_used: Vec::new(),
1702 scratch_match_order: Vec::new(),
1703 scratch_final_slots: Vec::new(),
1704 scratch_elements: Vec::new(),
1705 };
1706 chain.sync_chain_links();
1707 chain
1708 }
1709
1710 pub fn detach_nodes(&mut self) {
1712 for entry in &self.entries {
1713 detach_node_tree(&mut **entry.node.borrow_mut());
1714 }
1715 }
1716
1717 pub fn attach_nodes(&mut self, context: &mut dyn ModifierNodeContext) {
1719 for entry in &self.entries {
1720 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1721 }
1722 }
1723
1724 pub fn repair_chain(&mut self) {
1727 self.sync_chain_links();
1728 }
1729
1730 pub fn update_from_slice(
1736 &mut self,
1737 elements: &[DynModifierElement],
1738 context: &mut dyn ModifierNodeContext,
1739 ) {
1740 self.update_from_ref_iter(elements.iter(), context);
1741 }
1742
1743 pub fn update_from_ref_iter<'a, I>(
1748 &mut self,
1749 elements: I,
1750 context: &mut dyn ModifierNodeContext,
1751 ) where
1752 I: Iterator<Item = &'a DynModifierElement>,
1753 {
1754 let old_len = self.entries.len();
1758 let mut fast_path_failed_at: Option<usize> = None;
1759 let mut elements_count = 0;
1760
1761 self.scratch_elements.clear();
1763
1764 for (idx, element) in elements.enumerate() {
1765 elements_count = idx + 1;
1766
1767 if fast_path_failed_at.is_none() && idx < old_len {
1768 let entry = &mut self.entries[idx];
1769 let same_type = entry.element_type == element.element_type();
1770 let same_node_type = entry.node_type == element.node_type();
1771 let same_key = entry.key == element.key();
1772 let same_hash = entry.hash_code == element.hash_code();
1773
1774 let positional_update = element.requires_update();
1777 if same_type && same_node_type && same_key && (same_hash || positional_update) {
1778 let can_update_node = {
1779 let node_borrow = entry.node.borrow();
1780 element.can_update_node(&**node_borrow)
1781 };
1782 if !can_update_node {
1783 fast_path_failed_at = Some(idx);
1784 self.scratch_elements.push(element.clone());
1785 continue;
1786 }
1787
1788 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1790 let capabilities = element.capabilities();
1791
1792 {
1794 let node_borrow = entry.node.borrow();
1795 if !node_borrow.node_state().is_attached() {
1796 drop(node_borrow);
1797 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1798 }
1799 }
1800
1801 let needs_update = !same_element || element.requires_update();
1803 if needs_update {
1804 element.update_node(&mut **entry.node.borrow_mut());
1805 entry.element = element.clone();
1806 entry.hash_code = element.hash_code();
1807 request_update_auto_invalidations(element.as_ref(), context, capabilities);
1808 }
1809
1810 entry.capabilities = capabilities;
1812 entry
1813 .node
1814 .borrow()
1815 .node_state()
1816 .set_capabilities(capabilities);
1817 continue;
1818 }
1819 fast_path_failed_at = Some(idx);
1821 }
1822
1823 self.scratch_elements.push(element.clone());
1825 }
1826
1827 if fast_path_failed_at.is_none() && self.scratch_elements.is_empty() {
1832 if elements_count < self.entries.len() {
1834 for entry in self.entries.drain(elements_count..) {
1835 request_auto_invalidations(context, entry.capabilities);
1836 detach_node_tree(&mut **entry.node.borrow_mut());
1837 }
1838 }
1839 self.sync_chain_links();
1840 return;
1841 }
1842
1843 let fail_idx = fast_path_failed_at.unwrap_or(old_len);
1846
1847 let mut old_entries: Vec<ModifierNodeEntry> = self.entries.drain(fail_idx..).collect();
1849 let processed_entries_len = self.entries.len();
1850 let old_len = old_entries.len();
1851
1852 self.scratch_old_used.clear();
1854 self.scratch_old_used.resize(old_len, false);
1855
1856 self.scratch_match_order.clear();
1857 self.scratch_match_order.resize(old_len, None);
1858
1859 let index = EntryIndex::build(&old_entries);
1861
1862 let new_elements_count = self.scratch_elements.len();
1863 self.scratch_final_slots.clear();
1864 self.scratch_final_slots.reserve(new_elements_count);
1865
1866 for (new_pos, element) in self.scratch_elements.drain(..).enumerate() {
1868 self.scratch_final_slots.push(None);
1869 let element_type = element.element_type();
1870 let node_type = element.node_type();
1871 let key = element.key();
1872 let hash_code = element.hash_code();
1873 let capabilities = element.capabilities();
1874
1875 let matched_idx = index.find_match(
1877 &old_entries,
1878 &self.scratch_old_used,
1879 EntryMatchQuery {
1880 element_type,
1881 node_type,
1882 key,
1883 hash_code,
1884 element: &element,
1885 },
1886 );
1887
1888 if let Some(idx) = matched_idx {
1889 let entry = &mut old_entries[idx];
1891 let can_update_node = {
1892 let node_borrow = entry.node.borrow();
1893 element.can_update_node(&**node_borrow)
1894 };
1895 if !can_update_node {
1896 let replacement = ModifierNodeEntry::new(
1897 element_type,
1898 node_type,
1899 key,
1900 element.clone(),
1901 element.create_node(),
1902 hash_code,
1903 capabilities,
1904 );
1905 attach_node_tree(&mut **replacement.node.borrow_mut(), context);
1906 element.update_node(&mut **replacement.node.borrow_mut());
1907 request_auto_invalidations(context, capabilities);
1908 self.scratch_final_slots[new_pos] = Some(replacement);
1909 continue;
1910 }
1911
1912 self.scratch_old_used[idx] = true;
1913 self.scratch_match_order[idx] = Some(new_pos);
1914 let moved = idx != new_pos;
1915
1916 let same_element = entry.element.as_ref().equals_element(element.as_ref());
1918
1919 {
1921 let node_borrow = entry.node.borrow();
1922 if !node_borrow.node_state().is_attached() {
1923 drop(node_borrow);
1924 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1925 }
1926 }
1927
1928 let needs_update = !same_element || element.requires_update();
1930 if needs_update {
1931 element.update_node(&mut **entry.node.borrow_mut());
1932 entry.element = element;
1933 entry.hash_code = hash_code;
1934 request_update_auto_invalidations(
1935 entry.element.as_ref(),
1936 context,
1937 capabilities,
1938 );
1939 }
1940 if moved {
1941 request_auto_invalidations(context, capabilities);
1942 }
1943
1944 entry.key = key;
1946 entry.element_type = element_type;
1947 entry.node_type = node_type;
1948 entry.capabilities = capabilities;
1949 entry
1950 .node
1951 .borrow()
1952 .node_state()
1953 .set_capabilities(capabilities);
1954 } else {
1955 let entry = ModifierNodeEntry::new(
1957 element_type,
1958 node_type,
1959 key,
1960 element.clone(),
1961 element.create_node(),
1962 hash_code,
1963 capabilities,
1964 );
1965 attach_node_tree(&mut **entry.node.borrow_mut(), context);
1966 element.update_node(&mut **entry.node.borrow_mut());
1967 request_auto_invalidations(context, capabilities);
1968 self.scratch_final_slots[new_pos] = Some(entry);
1969 }
1970 }
1971
1972 for (i, entry) in old_entries.into_iter().enumerate() {
1974 if self.scratch_old_used[i] {
1975 if let Some(pos) = self.scratch_match_order[i] {
1976 self.scratch_final_slots[pos] = Some(entry);
1977 } else {
1978 request_auto_invalidations(context, entry.capabilities);
1979 detach_node_tree(&mut **entry.node.borrow_mut());
1980 }
1981 } else {
1982 request_auto_invalidations(context, entry.capabilities);
1983 detach_node_tree(&mut **entry.node.borrow_mut());
1984 }
1985 }
1986
1987 self.entries.reserve(self.scratch_final_slots.len());
1989 for slot in self.scratch_final_slots.drain(..) {
1990 if let Some(entry) = slot {
1991 self.entries.push(entry);
1992 } else {
1993 log::error!("modifier reconciliation produced an empty final slot");
1994 }
1995 }
1996
1997 debug_assert_eq!(
1998 self.entries.len(),
1999 processed_entries_len + new_elements_count
2000 );
2001 self.sync_chain_links();
2002 }
2003
2004 pub fn update<I>(&mut self, elements: I, context: &mut dyn ModifierNodeContext)
2008 where
2009 I: IntoIterator<Item = DynModifierElement>,
2010 {
2011 let collected: Vec<DynModifierElement> = elements.into_iter().collect();
2012 self.update_from_slice(&collected, context);
2013 }
2014
2015 pub fn reset(&mut self) {
2018 for entry in &mut self.entries {
2019 reset_node_tree(&mut **entry.node.borrow_mut());
2020 }
2021 }
2022
2023 pub fn detach_all(&mut self) {
2025 for entry in std::mem::take(&mut self.entries) {
2026 detach_node_tree(&mut **entry.node.borrow_mut());
2027 {
2028 let node_borrow = entry.node.borrow();
2029 let state = node_borrow.node_state();
2030 state.set_capabilities(NodeCapabilities::empty());
2031 }
2032 }
2033 self.aggregated_capabilities = NodeCapabilities::empty();
2034 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2035 self.ordered_nodes.clear();
2036 self.sync_chain_links();
2037 }
2038
2039 pub fn len(&self) -> usize {
2040 self.entries.len()
2041 }
2042
2043 pub fn is_empty(&self) -> bool {
2044 self.entries.is_empty()
2045 }
2046
2047 pub fn capabilities(&self) -> NodeCapabilities {
2049 self.aggregated_capabilities
2050 }
2051
2052 pub fn has_capability(&self, capability: NodeCapabilities) -> bool {
2054 self.aggregated_capabilities.contains(capability)
2055 }
2056
2057 pub fn head(&self) -> ModifierChainNodeRef<'_> {
2059 self.make_node_ref(NodeLink::Head)
2060 }
2061
2062 pub fn tail(&self) -> ModifierChainNodeRef<'_> {
2064 self.make_node_ref(NodeLink::Tail)
2065 }
2066
2067 pub fn head_to_tail(&self) -> ModifierChainIter<'_> {
2069 ModifierChainIter::forward(self)
2070 }
2071
2072 pub fn tail_to_head(&self) -> ModifierChainIter<'_> {
2074 ModifierChainIter::backward(self)
2075 }
2076
2077 pub fn for_each_forward<F>(&self, mut f: F)
2079 where
2080 F: FnMut(ModifierChainNodeRef<'_>),
2081 {
2082 for node in self.head_to_tail() {
2083 f(node);
2084 }
2085 }
2086
2087 pub fn for_each_forward_matching<F>(&self, mask: NodeCapabilities, mut f: F)
2089 where
2090 F: FnMut(ModifierChainNodeRef<'_>),
2091 {
2092 if mask.is_empty() {
2093 self.for_each_forward(f);
2094 return;
2095 }
2096
2097 if !self.head().aggregate_child_capabilities().intersects(mask) {
2098 return;
2099 }
2100
2101 for node in self.head_to_tail() {
2102 if node.kind_set().intersects(mask) {
2103 f(node);
2104 }
2105 }
2106 }
2107
2108 pub fn for_each_node_with_capability<F>(&self, mask: NodeCapabilities, mut f: F)
2110 where
2111 F: FnMut(ModifierChainNodeRef<'_>, &dyn ModifierNode),
2112 {
2113 self.for_each_forward_matching(mask, |node_ref| {
2114 node_ref.with_node(|node| f(node_ref.clone(), node));
2115 });
2116 }
2117
2118 pub fn for_each_backward<F>(&self, mut f: F)
2120 where
2121 F: FnMut(ModifierChainNodeRef<'_>),
2122 {
2123 for node in self.tail_to_head() {
2124 f(node);
2125 }
2126 }
2127
2128 pub fn find_node_ref(&self, node: &dyn ModifierNode) -> Option<ModifierChainNodeRef<'_>> {
2130 fn node_data_ptr(node: &dyn ModifierNode) -> *const () {
2131 node as *const dyn ModifierNode as *const ()
2132 }
2133
2134 let target = node_data_ptr(node);
2135 for (index, entry) in self.entries.iter().enumerate() {
2136 if node_data_ptr(&**entry.node.borrow()) == target {
2137 return Some(self.make_node_ref(NodeLink::Entry(NodePath::root(index))));
2138 }
2139 }
2140
2141 self.ordered_nodes.iter().find_map(|(link, _caps, _agg)| {
2142 if matches!(link, NodeLink::Entry(path) if path.delegates().is_empty()) {
2143 return None;
2144 }
2145 let matches_target = match link {
2146 NodeLink::Head => node_data_ptr(self.head_sentinel.as_ref()) == target,
2147 NodeLink::Tail => node_data_ptr(self.tail_sentinel.as_ref()) == target,
2148 NodeLink::Entry(path) => {
2149 let node_borrow = self.entries[path.entry()].node.borrow();
2150 node_data_ptr(&**node_borrow) == target
2151 }
2152 };
2153 if matches_target {
2154 Some(self.make_node_ref(*link))
2155 } else {
2156 None
2157 }
2158 })
2159 }
2160
2161 pub fn node<N: ModifierNode + 'static>(&self, index: usize) -> Option<std::cell::Ref<'_, N>> {
2164 self.entries.get(index).and_then(|entry| {
2165 std::cell::Ref::filter_map(entry.node.borrow(), |boxed_node| {
2166 boxed_node.as_any().downcast_ref::<N>()
2167 })
2168 .ok()
2169 })
2170 }
2171
2172 pub fn node_mut<N: ModifierNode + 'static>(
2175 &self,
2176 index: usize,
2177 ) -> Option<std::cell::RefMut<'_, N>> {
2178 self.entries.get(index).and_then(|entry| {
2179 std::cell::RefMut::filter_map(entry.node.borrow_mut(), |boxed_node| {
2180 boxed_node.as_any_mut().downcast_mut::<N>()
2181 })
2182 .ok()
2183 })
2184 }
2185
2186 pub fn get_node_rc(&self, index: usize) -> Option<Rc<RefCell<Box<dyn ModifierNode>>>> {
2189 self.entries.get(index).map(|entry| Rc::clone(&entry.node))
2190 }
2191
2192 pub fn has_nodes_for_invalidation(&self, kind: InvalidationKind) -> bool {
2194 self.aggregated_capabilities
2195 .contains(NodeCapabilities::for_invalidation(kind))
2196 }
2197
2198 pub fn visit_nodes_mut<F>(&mut self, mut f: F)
2200 where
2201 F: FnMut(&mut dyn ModifierNode, NodeCapabilities),
2202 {
2203 for index in 0..self.ordered_nodes.len() {
2204 let (link, cached_caps, _agg) = self.ordered_nodes[index];
2205 match link {
2206 NodeLink::Head => {
2207 f(self.head_sentinel.as_mut(), cached_caps);
2208 }
2209 NodeLink::Tail => {
2210 f(self.tail_sentinel.as_mut(), cached_caps);
2211 }
2212 NodeLink::Entry(path) => {
2213 let mut node_borrow = self.entries[path.entry()].node.borrow_mut();
2214 if path.delegates().is_empty() {
2215 f(&mut **node_borrow, cached_caps);
2216 } else {
2217 let mut current: &mut dyn ModifierNode = &mut **node_borrow;
2218 for &delegate_index in path.delegates() {
2219 if let Some(delegate) =
2220 nth_delegate_mut(current, delegate_index as usize)
2221 {
2222 current = delegate;
2223 } else {
2224 return; }
2226 }
2227 f(current, cached_caps);
2228 }
2229 }
2230 }
2231 }
2232 }
2233
2234 fn make_node_ref(&self, link: NodeLink) -> ModifierChainNodeRef<'_> {
2235 ModifierChainNodeRef {
2236 chain: self,
2237 link,
2238 cached_capabilities: None,
2239 cached_aggregate_child: None,
2240 }
2241 }
2242
2243 fn make_node_ref_with_caps(
2244 &self,
2245 link: NodeLink,
2246 caps: NodeCapabilities,
2247 aggregate_child: NodeCapabilities,
2248 ) -> ModifierChainNodeRef<'_> {
2249 ModifierChainNodeRef {
2250 chain: self,
2251 link,
2252 cached_capabilities: Some(caps),
2253 cached_aggregate_child: Some(aggregate_child),
2254 }
2255 }
2256
2257 fn sync_chain_links(&mut self) {
2258 self.rebuild_ordered_nodes();
2259
2260 self.head_sentinel.node_state().set_parent_link(None);
2261 self.tail_sentinel.node_state().set_child_link(None);
2262
2263 if self.ordered_nodes.is_empty() {
2264 self.head_sentinel
2265 .node_state()
2266 .set_child_link(Some(NodeLink::Tail));
2267 self.tail_sentinel
2268 .node_state()
2269 .set_parent_link(Some(NodeLink::Head));
2270 self.aggregated_capabilities = NodeCapabilities::empty();
2271 self.head_aggregate_child_capabilities = NodeCapabilities::empty();
2272 self.head_sentinel
2273 .node_state()
2274 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2275 self.tail_sentinel
2276 .node_state()
2277 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2278 return;
2279 }
2280
2281 let mut previous = NodeLink::Head;
2282 for (link, _caps, _agg) in self.ordered_nodes.iter().copied() {
2283 match &previous {
2285 NodeLink::Head => self.head_sentinel.node_state().set_child_link(Some(link)),
2286 NodeLink::Tail => self.tail_sentinel.node_state().set_child_link(Some(link)),
2287 NodeLink::Entry(path) => {
2288 let node_borrow = self.entries[path.entry()].node.borrow();
2289 if path.delegates().is_empty() {
2291 node_borrow.node_state().set_child_link(Some(link));
2292 } else {
2293 let mut current: &dyn ModifierNode = &**node_borrow;
2294 for &delegate_index in path.delegates() {
2295 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2296 current = delegate;
2297 }
2298 }
2299 current.node_state().set_child_link(Some(link));
2300 }
2301 }
2302 }
2303 match &link {
2305 NodeLink::Head => self
2306 .head_sentinel
2307 .node_state()
2308 .set_parent_link(Some(previous)),
2309 NodeLink::Tail => self
2310 .tail_sentinel
2311 .node_state()
2312 .set_parent_link(Some(previous)),
2313 NodeLink::Entry(path) => {
2314 let node_borrow = self.entries[path.entry()].node.borrow();
2315 if path.delegates().is_empty() {
2317 node_borrow.node_state().set_parent_link(Some(previous));
2318 } else {
2319 let mut current: &dyn ModifierNode = &**node_borrow;
2320 for &delegate_index in path.delegates() {
2321 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2322 current = delegate;
2323 }
2324 }
2325 current.node_state().set_parent_link(Some(previous));
2326 }
2327 }
2328 }
2329 previous = link;
2330 }
2331
2332 match &previous {
2334 NodeLink::Head => self
2335 .head_sentinel
2336 .node_state()
2337 .set_child_link(Some(NodeLink::Tail)),
2338 NodeLink::Tail => self
2339 .tail_sentinel
2340 .node_state()
2341 .set_child_link(Some(NodeLink::Tail)),
2342 NodeLink::Entry(path) => {
2343 let node_borrow = self.entries[path.entry()].node.borrow();
2344 if path.delegates().is_empty() {
2346 node_borrow
2347 .node_state()
2348 .set_child_link(Some(NodeLink::Tail));
2349 } else {
2350 let mut current: &dyn ModifierNode = &**node_borrow;
2351 for &delegate_index in path.delegates() {
2352 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2353 current = delegate;
2354 }
2355 }
2356 current.node_state().set_child_link(Some(NodeLink::Tail));
2357 }
2358 }
2359 }
2360 self.tail_sentinel
2361 .node_state()
2362 .set_parent_link(Some(previous));
2363 self.tail_sentinel.node_state().set_child_link(None);
2364
2365 let mut aggregate = NodeCapabilities::empty();
2366 for (link, cached_caps, cached_aggregate) in self.ordered_nodes.iter_mut().rev() {
2367 aggregate |= *cached_caps;
2368 *cached_aggregate = aggregate;
2369 match link {
2371 NodeLink::Head => {
2372 self.head_sentinel
2373 .node_state()
2374 .set_aggregate_child_capabilities(aggregate);
2375 }
2376 NodeLink::Tail => {
2377 self.tail_sentinel
2378 .node_state()
2379 .set_aggregate_child_capabilities(aggregate);
2380 }
2381 NodeLink::Entry(path) => {
2382 let node_borrow = self.entries[path.entry()].node.borrow();
2383 let state = if path.delegates().is_empty() {
2384 node_borrow.node_state()
2385 } else {
2386 let mut current: &dyn ModifierNode = &**node_borrow;
2387 for &delegate_index in path.delegates() {
2388 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2389 current = delegate;
2390 }
2391 }
2392 current.node_state()
2393 };
2394 state.set_aggregate_child_capabilities(aggregate);
2395 }
2396 }
2397 }
2398
2399 self.aggregated_capabilities = aggregate;
2400 self.head_aggregate_child_capabilities = aggregate;
2401 self.head_sentinel
2402 .node_state()
2403 .set_aggregate_child_capabilities(aggregate);
2404 self.tail_sentinel
2405 .node_state()
2406 .set_aggregate_child_capabilities(NodeCapabilities::empty());
2407 }
2408
2409 fn rebuild_ordered_nodes(&mut self) {
2410 self.ordered_nodes.clear();
2411 let mut path_buf = [0usize; MAX_DELEGATE_DEPTH];
2412 for (index, entry) in self.entries.iter().enumerate() {
2413 let node_borrow = entry.node.borrow();
2414 Self::enumerate_link_order(
2415 &**node_borrow,
2416 index,
2417 &mut path_buf,
2418 0,
2419 &mut self.ordered_nodes,
2420 );
2421 }
2422 }
2423
2424 fn enumerate_link_order(
2425 node: &dyn ModifierNode,
2426 entry: usize,
2427 path_buf: &mut [usize; MAX_DELEGATE_DEPTH],
2428 path_len: usize,
2429 out: &mut Vec<(NodeLink, NodeCapabilities, NodeCapabilities)>,
2430 ) {
2431 let caps = node.node_state().capabilities();
2432 out.push((
2433 NodeLink::Entry(NodePath::from_slice(entry, &path_buf[..path_len])),
2434 caps,
2435 NodeCapabilities::empty(),
2436 ));
2437 let mut delegate_index = 0usize;
2438 node.for_each_delegate(&mut |child| {
2439 if path_len < MAX_DELEGATE_DEPTH {
2440 path_buf[path_len] = delegate_index;
2441 Self::enumerate_link_order(child, entry, path_buf, path_len + 1, out);
2442 }
2443 delegate_index += 1;
2444 });
2445 }
2446}
2447
2448impl<'a> ModifierChainNodeRef<'a> {
2449 fn with_state<R>(&self, f: impl FnOnce(&NodeState) -> R) -> R {
2452 match &self.link {
2453 NodeLink::Head => f(self.chain.head_sentinel.node_state()),
2454 NodeLink::Tail => f(self.chain.tail_sentinel.node_state()),
2455 NodeLink::Entry(path) => {
2456 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2457 if path.delegates().is_empty() {
2459 f(node_borrow.node_state())
2460 } else {
2461 let mut current: &dyn ModifierNode = &**node_borrow;
2463 for &delegate_index in path.delegates() {
2464 if let Some(delegate) = nth_delegate(current, delegate_index as usize) {
2465 current = delegate;
2466 } else {
2467 return f(node_borrow.node_state());
2469 }
2470 }
2471 f(current.node_state())
2472 }
2473 }
2474 }
2475 }
2476
2477 pub fn with_node<R>(&self, f: impl FnOnce(&dyn ModifierNode) -> R) -> Option<R> {
2480 match &self.link {
2481 NodeLink::Head => None, NodeLink::Tail => None, NodeLink::Entry(path) => {
2484 let node_borrow = self.chain.entries[path.entry()].node.borrow();
2485 if path.delegates().is_empty() {
2487 Some(f(&**node_borrow))
2488 } else {
2489 let mut current: &dyn ModifierNode = &**node_borrow;
2491 for &delegate_index in path.delegates() {
2492 current = nth_delegate(current, delegate_index as usize)?;
2494 }
2495 Some(f(current))
2496 }
2497 }
2498 }
2499 }
2500
2501 #[inline]
2503 pub fn parent(&self) -> Option<Self> {
2504 self.with_state(|state| state.parent_link())
2505 .map(|link| self.chain.make_node_ref(link))
2506 }
2507
2508 #[inline]
2510 pub fn child(&self) -> Option<Self> {
2511 self.with_state(|state| state.child_link())
2512 .map(|link| self.chain.make_node_ref(link))
2513 }
2514
2515 #[inline]
2517 pub fn kind_set(&self) -> NodeCapabilities {
2518 if let Some(caps) = self.cached_capabilities {
2519 return caps;
2520 }
2521 match &self.link {
2522 NodeLink::Head | NodeLink::Tail => NodeCapabilities::empty(),
2523 NodeLink::Entry(_) => self.with_state(|state| state.capabilities()),
2524 }
2525 }
2526
2527 pub fn entry_index(&self) -> Option<usize> {
2529 match &self.link {
2530 NodeLink::Entry(path) => Some(path.entry()),
2531 _ => None,
2532 }
2533 }
2534
2535 pub fn delegate_depth(&self) -> usize {
2537 match &self.link {
2538 NodeLink::Entry(path) => path.delegates().len(),
2539 _ => 0,
2540 }
2541 }
2542
2543 #[inline]
2545 pub fn aggregate_child_capabilities(&self) -> NodeCapabilities {
2546 if let Some(agg) = self.cached_aggregate_child {
2547 return agg;
2548 }
2549 if self.is_tail() {
2550 NodeCapabilities::empty()
2551 } else {
2552 self.with_state(|state| state.aggregate_child_capabilities())
2553 }
2554 }
2555
2556 pub fn is_head(&self) -> bool {
2558 matches!(self.link, NodeLink::Head)
2559 }
2560
2561 pub fn is_tail(&self) -> bool {
2563 matches!(self.link, NodeLink::Tail)
2564 }
2565
2566 pub fn is_sentinel(&self) -> bool {
2568 matches!(self.link, NodeLink::Head | NodeLink::Tail)
2569 }
2570
2571 pub fn has_capability(&self, mask: NodeCapabilities) -> bool {
2573 !mask.is_empty() && self.kind_set().intersects(mask)
2574 }
2575
2576 pub fn visit_descendants<F>(self, include_self: bool, mut f: F)
2578 where
2579 F: FnMut(ModifierChainNodeRef<'a>),
2580 {
2581 let mut current = if include_self {
2582 Some(self)
2583 } else {
2584 self.child()
2585 };
2586 while let Some(node) = current {
2587 if node.is_tail() {
2588 break;
2589 }
2590 if !node.is_sentinel() {
2591 f(node.clone());
2592 }
2593 current = node.child();
2594 }
2595 }
2596
2597 pub fn visit_descendants_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2599 where
2600 F: FnMut(ModifierChainNodeRef<'a>),
2601 {
2602 if mask.is_empty() {
2603 self.visit_descendants(include_self, f);
2604 return;
2605 }
2606
2607 if !self.aggregate_child_capabilities().intersects(mask) {
2608 return;
2609 }
2610
2611 self.visit_descendants(include_self, |node| {
2612 if node.kind_set().intersects(mask) {
2613 f(node);
2614 }
2615 });
2616 }
2617
2618 pub fn visit_ancestors<F>(self, include_self: bool, mut f: F)
2620 where
2621 F: FnMut(ModifierChainNodeRef<'a>),
2622 {
2623 let mut current = if include_self {
2624 Some(self)
2625 } else {
2626 self.parent()
2627 };
2628 while let Some(node) = current {
2629 if node.is_head() {
2630 break;
2631 }
2632 f(node.clone());
2633 current = node.parent();
2634 }
2635 }
2636
2637 pub fn visit_ancestors_matching<F>(self, include_self: bool, mask: NodeCapabilities, mut f: F)
2639 where
2640 F: FnMut(ModifierChainNodeRef<'a>),
2641 {
2642 if mask.is_empty() {
2643 self.visit_ancestors(include_self, f);
2644 return;
2645 }
2646
2647 self.visit_ancestors(include_self, |node| {
2648 if node.kind_set().intersects(mask) {
2649 f(node);
2650 }
2651 });
2652 }
2653}
2654
2655#[cfg(test)]
2656#[path = "tests/modifier_tests.rs"]
2657mod tests;