euv_core/reactive/hook/impl.rs
1use crate::*;
2
3/// Implementation of hook context lifecycle and hook index management.
4impl HookContext {
5 /// Creates a new `HookContext` from an existing raw pointer.
6 ///
7 /// # Arguments
8 ///
9 /// - `*mut HookContextInner` - A raw pointer to the heap-allocated hook context inner state.
10 ///
11 /// # Returns
12 ///
13 /// - `Self` - A hook context handle wrapping the given pointer.
14 pub fn from_inner(inner: *mut HookContextInner) -> Self {
15 HookContext { inner }
16 }
17
18 /// Returns a mutable reference to the inner hook context state.
19 ///
20 /// # Safety
21 ///
22 /// The caller must ensure no other references to the inner state exist.
23 /// In single-threaded WASM this is always safe.
24 #[allow(clippy::mut_from_ref)]
25 fn get_inner_mut(&self) -> &mut HookContextInner {
26 unsafe { &mut *self.inner }
27 }
28
29 /// Returns the current hook index.
30 ///
31 /// # Returns
32 ///
33 /// - `usize` - The current hook index.
34 pub fn get_hook_index(&self) -> usize {
35 self.get_inner_mut().get_hook_index()
36 }
37
38 /// Sets the hook index.
39 ///
40 /// # Arguments
41 ///
42 /// - `usize` - The new hook index value.
43 pub fn set_hook_index(&mut self, index: usize) {
44 self.get_inner_mut().set_hook_index(index);
45 }
46
47 /// Returns a reference to the hooks storage.
48 ///
49 /// # Returns
50 ///
51 /// - `&Vec<Box<dyn Any>>` - A reference to the hooks storage.
52 pub fn get_hooks(&self) -> &Vec<Box<dyn Any>> {
53 self.get_inner_mut().get_hooks()
54 }
55
56 /// Returns a mutable reference to the hooks storage.
57 ///
58 /// # Returns
59 ///
60 /// - `&mut Vec<Box<dyn Any>>` - A mutable reference to the hooks storage.
61 pub fn get_mut_hooks(&mut self) -> &mut Vec<Box<dyn Any>> {
62 self.get_inner_mut().get_mut_hooks()
63 }
64
65 /// Returns a mutable reference to the cleanup closures storage.
66 ///
67 /// # Returns
68 ///
69 /// - `&mut Vec<Box<dyn FnOnce()>>` - A mutable reference to the cleanup closures storage.
70 pub fn get_mut_cleanups(&mut self) -> &mut Vec<Box<dyn FnOnce()>> {
71 self.get_inner_mut().get_mut_cleanups()
72 }
73
74 /// Resets the hook index for a new render cycle.
75 ///
76 /// Sets the hook index back to `0` so that subsequent hook calls
77 /// re-associate with their stored state by call order.
78 pub fn reset_hook_index(&mut self) {
79 self.set_hook_index(0_usize);
80 }
81
82 /// Notifies the hook context that a match arm is being entered.
83 /// Toggles the `arm_changed` flag; if it differs from the previous value,
84 /// the hooks array is cleared to prevent signal leakage between arms.
85 ///
86 /// # Arguments
87 ///
88 /// - `bool` - The new arm changed state.
89 pub fn set_arm_changed(&mut self, changed: bool) {
90 let inner: &mut HookContextInner = self.get_inner_mut();
91 if inner.get_arm_changed() != changed {
92 let cleanups: Vec<Box<dyn FnOnce()>> = std::mem::take(inner.get_mut_cleanups());
93 for cleanup in cleanups {
94 cleanup();
95 }
96 inner.get_mut_hooks().clear();
97 inner.set_arm_changed(changed);
98 }
99 self.reset_hook_index();
100 }
101}
102
103/// Clones the hook context, sharing the same inner state.
104impl Clone for HookContext {
105 /// Returns a bitwise copy of this hook context.
106 fn clone(&self) -> Self {
107 *self
108 }
109}
110
111/// Copies the hook context, sharing the same inner state.
112///
113/// A `HookContext` is just a raw pointer; copying it is a trivial bitwise copy.
114impl Copy for HookContext {}
115
116/// Provides a default empty hook context.
117impl Default for HookContext {
118 /// Returns a default `HookContext` by allocating a new empty inner via `Box::leak`.
119 fn default() -> Self {
120 let boxed: Box<HookContextInner> = Box::default();
121 HookContext::from_inner(Box::leak(boxed) as *mut HookContextInner)
122 }
123}
124
125/// Implementation of HookContextInner construction.
126impl HookContextInner {
127 /// Creates a new empty hook context inner.
128 ///
129 /// # Returns
130 ///
131 /// - `Self` - A new hook context inner with empty hooks and cleanups.
132 pub const fn new() -> Self {
133 HookContextInner {
134 hooks: Vec::new(),
135 arm_changed: false,
136 hook_index: 0_usize,
137 cleanups: Vec::new(),
138 }
139 }
140}
141
142/// Provides a default empty hook context inner.
143impl Default for HookContextInner {
144 /// Returns a default `HookContextInner` by delegating to `HookContextInner::new`.
145 fn default() -> Self {
146 Self::new()
147 }
148}
149
150/// SAFETY: `HookContextCell` is only used in single-threaded WASM contexts.
151/// Concurrent access from multiple threads would be undefined behavior.
152unsafe impl Sync for HookContextCell {}