Skip to main content

euv_core/event/handler/
impl.rs

1use crate::*;
2
3/// Implementation of `From` trait for converting `usize` address into `&'static mut NativeEventCallbackInner`.
4impl From<usize> for &'static mut NativeEventCallbackInner {
5    /// Converts a memory address into a mutable reference to `NativeEventCallbackInner`.
6    ///
7    /// # Arguments
8    ///
9    /// - `usize` - The memory address of the `NativeEventCallbackInner` instance.
10    ///
11    /// # Returns
12    ///
13    /// - `&'static mut NativeEventCallbackInner` - A mutable reference to the `NativeEventCallbackInner` at the given address.
14    ///
15    /// # Safety
16    ///
17    /// - The address is guaranteed to be a valid `NativeEventCallbackInner` instance
18    ///   that was previously converted from a reference and is managed by the runtime.
19    #[inline(always)]
20    fn from(address: usize) -> Self {
21        unsafe { &mut *(address as *mut NativeEventCallbackInner) }
22    }
23}
24
25/// Implementation of `From` trait for converting `usize` address into `&'static NativeEventCallbackInner`.
26impl From<usize> for &'static NativeEventCallbackInner {
27    /// Converts a memory address into a reference to `NativeEventCallbackInner`.
28    ///
29    /// # Arguments
30    ///
31    /// - `usize` - The memory address of the `NativeEventCallbackInner` instance.
32    ///
33    /// # Returns
34    ///
35    /// - `&'static NativeEventCallbackInner` - A reference to the `NativeEventCallbackInner` at the given address.
36    ///
37    /// # Safety
38    ///
39    /// - The address is guaranteed to be a valid `NativeEventCallbackInner` instance
40    ///   that was previously converted from a reference and is managed by the runtime.
41    #[inline(always)]
42    fn from(address: usize) -> Self {
43        unsafe { &*(address as *const NativeEventCallbackInner) }
44    }
45}
46
47/// Implementation of `From` trait for converting `&NativeEventHandler` into `usize` address.
48impl From<&NativeEventHandler> for usize {
49    /// Converts a reference to `NativeEventHandler` into its callback pointer address.
50    ///
51    /// # Arguments
52    ///
53    /// - `&NativeEventHandler` - The reference to the event handler.
54    ///
55    /// # Returns
56    ///
57    /// - `usize` - The memory address of the callback pointer.
58    #[inline(always)]
59    fn from(handler: &NativeEventHandler) -> Self {
60        handler.callback as usize
61    }
62}
63
64/// Implementation of event handler construction, cloning, and invocation.
65impl NativeEventHandler {
66    /// Creates a new event handler from an `NativeEventName` enum and callback.
67    ///
68    /// # Arguments
69    ///
70    /// - `NativeEventName` - The event name enum variant.
71    /// - `FnMut(Event) + 'static` - The callback to invoke when the event fires.
72    ///
73    /// # Returns
74    ///
75    /// - `Self` - A new event handler.
76    pub fn new<F>(event_name: NativeEventName, callback: F) -> Self
77    where
78        F: FnMut(Event) + 'static,
79    {
80        let inner: Box<NativeEventCallbackInner> = Box::new(NativeEventCallbackInner {
81            callback: Box::new(callback),
82        });
83        NativeEventHandler {
84            event_name: event_name.as_str().into_owned(),
85            callback: Box::leak(inner) as *mut NativeEventCallbackInner,
86        }
87    }
88
89    /// Returns a mutable reference to the inner callback closure state by going
90    /// through `usize` intermediate conversion.
91    ///
92    /// # Returns
93    ///
94    /// - `&'static mut NativeEventCallbackInner` - A mutable reference to the inner callback state.
95    pub(crate) fn leak_mut(&self) -> &'static mut NativeEventCallbackInner {
96        let address: usize = self.into();
97        address.into()
98    }
99
100    /// Invokes the underlying callback with the given event.
101    ///
102    /// # Arguments
103    ///
104    /// - `Event` - The event to pass to the callback.
105    pub fn handle(&self, event: Event) {
106        let inner: &mut NativeEventCallbackInner = self.leak_mut();
107        (inner.callback)(event);
108    }
109}