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