event_handler/
lib.rs

1//! # Event Handling
2//!
3//! An .NET `event`, `EventHandler` and `EventArgs` inspired event handling system.
4//!
5//! ## Examples
6//!
7//! The following example constructs an [`Event`] and two handles to it.
8//! It invokes the event through one of the handles (de-registering it), then on the event itself.
9//!
10//! ```
11//! use event_handler::prelude::*;
12//! use std::sync::{Arc, Mutex};
13//!
14//! // The values we want to mutate.
15//! // These need to be Send such that the handle functions can update them.
16//! let value = Arc::new(Mutex::new(0));
17//! let value2 = Arc::new(Mutex::new(0));
18//!
19//! // Create an event handler.
20//! let event = Event::new();
21//!
22//! // Create a closure to mutate the value.
23//! let update_first_value = {
24//!     let first_value = value.clone();
25//!     move |amount| *first_value.lock().unwrap() = amount
26//! };
27//!
28//! // Create a closure to mutate the other value.
29//! let update_second_value = {
30//!     let second_value = value2.clone();
31//!     move |amount| *second_value.lock().unwrap() = amount * 2
32//! };
33//!
34//! // Register the function to the event.
35//! let handle = event.add_fn(update_first_value).unwrap();
36//! let _handle = event.add_fn(update_second_value).unwrap();
37//!
38//! // Two handlers are now registered.
39//! assert_eq!(event.len(), 2);
40//!
41//! // Invoke the event on the handle.
42//! // Since we move the handle, this will de-register the handler when the scope is left.
43//! assert!(std::thread::spawn(move || { handle.invoke(41) })
44//!     .join()
45//!     .is_ok());
46//! assert_eq!(event.len(), 1);
47//! assert_eq!(*value.lock().unwrap(), 41);
48//! assert_eq!(*value2.lock().unwrap(), 41 * 2);
49//!
50//! // Invoke the event on the event itself.
51//! event.invoke(42);
52//! assert_eq!(*value.lock().unwrap(), 41);         // previous value
53//! assert_eq!(*value2.lock().unwrap(), 42 * 2);    // updated value
54//! ```
55//!
56//! If the [`Event`] is dropped, calls to [`EventHandle::invoke`] will return an error.
57//!
58//! ```
59//! # use event_handler::prelude::*;
60//! # use std::sync::{Arc, Mutex};
61//! let event = Event::new();
62//!
63//! // Register the function to the event.
64//! let value = Arc::new(Mutex::new(0));
65//! let handle = event.add_fn({
66//!         let value = value.clone();
67//!         move |amount| *value.lock().unwrap() = amount
68//! }).unwrap();
69//!
70//! // Register another function.
71//! let value2 = Arc::new(Mutex::new(0));
72//! let late_handle = event.add_fn({
73//!         let value = value2.clone();
74//!         move |amount| *value.lock().unwrap() = amount * 2
75//! }).unwrap();
76//!
77//! // Invoke the event on the handler itself.
78//! // This will move the event, dropping it afterwards.
79//! assert!(std::thread::spawn(move || {
80//!     event.invoke(42);
81//! })
82//! .join()
83//! .is_ok());
84//! assert_eq!(*value.lock().unwrap(), 42);
85//! assert_eq!(*value2.lock().unwrap(), 42 * 2);
86//!
87//! // This event invocation will fail because the event is already dropped.
88//! assert_eq!(
89//!     std::thread::spawn(move || { late_handle.invoke(41) })
90//!         .join()
91//!         .unwrap(),
92//!     Err(EventInvocationError::EventDropped)
93//! );
94//! ```
95
96#![allow(unsafe_code)]
97#![forbid(unused_must_use)]
98
99use std::cell::Cell;
100use std::collections::BTreeMap;
101use std::error::Error;
102use std::fmt::{Display, Formatter};
103use std::hash::{Hash, Hasher};
104use std::ops::{Deref, DerefMut};
105use std::sync::{Arc, RwLock, Weak};
106
107pub mod prelude {
108    pub use crate::{Event, EventHandle, EventInvocationError, Invoke};
109}
110
111/// Alias for trivial function pointers.
112pub type FnEventHandlerDelegate<TEventArgs> = fn(TEventArgs) -> ();
113
114/// An event registration.
115pub struct Event<TEventArgs = ()> {
116    handlers: Arc<MapLocked<TEventArgs>>,
117}
118
119unsafe impl<TEventArgs: Send + Sync> Sync for Event<TEventArgs> {}
120
121/// A concrete type of a handler.
122enum HandlerType<TEventArgs> {
123    BoxedFn(Box<dyn Fn(TEventArgs) + Send>),
124    BoxedFnOnce(Cell<Option<Box<dyn FnOnce(TEventArgs) + Send>>>),
125    Function(FnEventHandlerDelegate<TEventArgs>),
126}
127
128unsafe impl<TEventArgs: Send + Sync> Sync for HandlerType<TEventArgs> {}
129
130/// Helper type declaration for a locked [`MapInner`].
131struct MapLocked<TEventArgs>(RwLock<MapInner<TEventArgs>>);
132
133/// The actual storage type.
134type MapInner<TEventArgs> = BTreeMap<HandleKey, HandlerType<TEventArgs>>;
135
136/// A handle to a registration.
137/// When the handle is dropped, the registration is revoked.
138#[must_use = "This handle must be held alive for as long as the event should be used."]
139pub struct EventHandle<TEventArgs> {
140    /// The key in the map.
141    key: HandleKey,
142    /// Pointer to the map that (possibly) contains the key.
143    pointer: Weak<MapLocked<TEventArgs>>,
144}
145
146/// A key entry for a handler.
147#[derive(Debug, PartialOrd, Ord, PartialEq, Eq, Copy, Clone)]
148enum HandleKey {
149    PtrOfBox(usize),
150    FunctionPointer(usize),
151}
152
153/// Hashing for [`HandleKey`] instances.
154impl Hash for HandleKey {
155    fn hash<H: Hasher>(&self, state: &mut H) {
156        match self {
157            HandleKey::PtrOfBox(ptr) => {
158                let address = ptr as *const usize as usize;
159                address.hash(state)
160            }
161            HandleKey::FunctionPointer(ptr) => {
162                let address = ptr as *const usize as usize;
163                address.hash(state)
164            }
165        }
166    }
167}
168
169impl<TEventArgs> EventHandle<TEventArgs> {
170    /// Initializes a new `Handle` from a successful registration.
171    fn new(key: HandleKey, pointer: &Arc<MapLocked<TEventArgs>>) -> Self {
172        Self {
173            key,
174            pointer: Arc::downgrade(pointer),
175        }
176    }
177
178    /// Determines whether the registration is still valid.
179    pub fn is_valid(&self) -> bool {
180        self.pointer.strong_count() > 0
181    }
182
183    /// Invokes the event with the specified arguments.
184    ///
185    /// ## Arguments
186    /// * `args` - The event arguments to pass.
187    pub fn invoke(&self, args: TEventArgs) -> Result<(), EventInvocationError>
188    where
189        TEventArgs: Clone,
190    {
191        if let Some(ptr) = self.pointer.upgrade() {
192            ptr.invoke(args);
193            Ok(())
194        } else {
195            Err(EventInvocationError::EventDropped)
196        }
197    }
198}
199
200#[derive(Debug, PartialEq)]
201pub enum EventInvocationError {
202    /// The event was dropped.
203    EventDropped,
204}
205
206impl Display for EventInvocationError {
207    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
208        match self {
209            EventInvocationError::EventDropped => write!(
210                f,
211                "Event could not be invoked because it was already dropped"
212            ),
213        }
214    }
215}
216
217impl Error for EventInvocationError {}
218
219impl<TEventArgs> Drop for EventHandle<TEventArgs> {
220    fn drop(&mut self) {
221        if let Some(lock) = self.pointer.upgrade() {
222            let mut handlers = lock.write().unwrap();
223            handlers.remove(&self.key);
224        }
225    }
226}
227
228impl<TEventArgs> Event<TEventArgs> {
229    pub fn new() -> Self
230    where
231        TEventArgs: Clone,
232    {
233        Self {
234            handlers: Arc::new(MapLocked::new(MapInner::new())),
235        }
236    }
237
238    pub fn add_fn<T>(&self, handler: T) -> Result<EventHandle<TEventArgs>, String>
239    where
240        T: Fn(TEventArgs) -> () + Send + 'static,
241    {
242        let handler = Box::new(handler);
243        let key = HandleKey::PtrOfBox((&*handler as *const _) as usize);
244        let mut handlers = self.handlers.write().unwrap();
245        let entry = HandlerType::BoxedFn(handler);
246        match handlers.insert(key, entry) {
247            None => Ok(EventHandle::new(key, &self.handlers)),
248            Some(_) => Err(String::from("The handler was already registered")),
249        }
250    }
251
252    pub fn add_fnonce<T>(&self, handler: T) -> Result<EventHandle<TEventArgs>, String>
253    where
254        T: FnOnce(TEventArgs) -> () + Send + 'static,
255    {
256        let handler = Box::new(handler);
257        let key = HandleKey::PtrOfBox((&*handler as *const _) as usize);
258        let mut handlers = self.handlers.write().unwrap();
259        let entry = HandlerType::BoxedFnOnce(Cell::new(Some(handler)));
260        match handlers.insert(key, entry) {
261            None => Ok(EventHandle::new(key, &self.handlers)),
262            Some(_) => Err(String::from("The handler was already registered")),
263        }
264    }
265
266    pub fn add_ptr(
267        &self,
268        handler: FnEventHandlerDelegate<TEventArgs>,
269    ) -> Result<EventHandle<TEventArgs>, String> {
270        let key = HandleKey::FunctionPointer((&handler as *const _) as usize);
271        let mut handlers = self.handlers.write().unwrap();
272        let entry = HandlerType::Function(handler);
273        match handlers.insert(key, entry) {
274            None => Ok(EventHandle::new(key, &self.handlers)),
275            Some(_) => Err(String::from("The handler was already registered")),
276        }
277    }
278
279    /// Returns the number of currently registered handlers.
280    pub fn len(&self) -> usize {
281        self.handlers.read().unwrap().len()
282    }
283
284    /// Invokes the event.
285    ///
286    /// ## Arguments
287    /// * `args` - The event arguments.
288    pub fn invoke(&self, args: TEventArgs)
289    where
290        TEventArgs: Clone,
291    {
292        self.handlers.invoke(args)
293    }
294}
295
296impl Default for Event {
297    fn default() -> Self {
298        Self::new()
299    }
300}
301
302impl<TEventArgs> MapLocked<TEventArgs>
303where
304    TEventArgs: Clone,
305{
306    const fn new(inner: MapInner<TEventArgs>) -> Self {
307        Self(RwLock::new(inner))
308    }
309
310    fn invoke(&self, args: TEventArgs) {
311        let mut unregister_list = Vec::new();
312
313        {
314            let handlers = self.read().unwrap();
315            for (key, entry) in handlers.iter() {
316                let args = args.clone();
317                match &entry {
318                    HandlerType::Function(fun) => fun(args),
319                    HandlerType::BoxedFn(fun) => fun(args),
320                    HandlerType::BoxedFnOnce(cell) => {
321                        let fun = cell.replace(None);
322                        if fun.is_some() {
323                            (fun.unwrap())(args);
324                        }
325                        unregister_list.push(key.clone());
326                    }
327                }
328            }
329        }
330
331        // Clean up after any FnOnce type.
332        if !unregister_list.is_empty() {
333            let mut handlers = self.write().unwrap();
334            for key in unregister_list {
335                handlers.remove(&key);
336            }
337        }
338    }
339}
340
341impl<TEventArgs> Deref for MapLocked<TEventArgs> {
342    type Target = RwLock<MapInner<TEventArgs>>;
343
344    fn deref(&self) -> &Self::Target {
345        &self.0
346    }
347}
348
349impl<TEventArgs> DerefMut for MapLocked<TEventArgs> {
350    fn deref_mut(&mut self) -> &mut Self::Target {
351        &mut self.0
352    }
353}
354
355/// Provides the `invoke` function for an event.
356pub trait Invoke<TEventArgs>
357where
358    TEventArgs: Clone,
359{
360    fn invoke(&self, args: TEventArgs);
361}
362
363impl<TEventArgs> Invoke<TEventArgs> for Event<TEventArgs>
364where
365    TEventArgs: Clone,
366{
367    fn invoke(&self, args: TEventArgs) {
368        self.invoke(args)
369    }
370}
371
372impl<TEventArgs> Invoke<TEventArgs> for EventHandle<TEventArgs>
373where
374    TEventArgs: Clone,
375{
376    fn invoke(&self, args: TEventArgs) {
377        self.invoke(args).ok();
378    }
379}
380
381#[cfg(test)]
382mod tests {
383    use super::*;
384
385    fn dummy(_args: ()) {
386        println!("Dummy called.");
387    }
388
389    #[test]
390    fn new_handler_has_no_registrations() {
391        let handler = Event::<()>::new();
392        assert_eq!(handler.len(), 0);
393    }
394
395    #[test]
396    #[allow(unused_variables)]
397    fn can_add_fn() {
398        let handler = Event::<()>::new();
399        let handle = handler.add_fn(dummy).unwrap();
400        assert_eq!(handler.len(), 1);
401        handler.invoke(());
402    }
403
404    #[test]
405    #[allow(unused_variables)]
406    fn can_add_fnonce() {
407        let handler = Event::new();
408        let handle = handler.add_fnonce(dummy).unwrap();
409        assert_eq!(handler.len(), 1);
410        handler.invoke(());
411        assert_eq!(handler.len(), 0);
412    }
413
414    #[test]
415    #[allow(unused_variables)]
416    fn can_add_function_pointer() {
417        let handler = Event::<()>::new();
418        let handle = handler.add_ptr(dummy).unwrap();
419        assert_eq!(handler.len(), 1);
420        handler.invoke(());
421    }
422
423    #[test]
424    #[allow(unused_variables)]
425    fn cannot_register_same_function_twice() {
426        let handler = Event::new();
427        let handle = handler.add_ptr(dummy).unwrap();
428        assert!(handler.add_ptr(dummy).is_err());
429    }
430
431    #[test]
432    fn can_remove_handlers() {
433        let handler = Event::new();
434        let handle = handler.add_fn(dummy).unwrap();
435        assert_eq!(handler.len(), 1);
436        drop(handle);
437        assert_eq!(handler.len(), 0);
438    }
439
440    #[test]
441    fn handler_is_sync() {
442        let handler: Event = Event::new();
443        let _sync: Box<dyn Sync> = Box::new(handler);
444    }
445}