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