1use std::collections::HashMap;
2use std::sync::Arc;
3use std::sync::Mutex;
4
5type Callback<T> = dyn Fn(&T) + Send + Sync + 'static;
6
7#[derive(Default)]
8struct EventInner<T> {
9 callbacks: Mutex<HashMap<usize, Arc<Callback<T>>>>,
10 next_id: Mutex<usize>,
11}
12
13#[derive(Clone, Default)]
17pub struct Event<T> {
18 inner: Arc<EventInner<T>>,
19}
20
21impl<T> Event<T> {
22 pub fn new() -> Self {
24 Self {
25 inner: Arc::new(EventInner {
26 callbacks: Mutex::new(HashMap::new()),
27 next_id: Mutex::new(0),
28 }),
29 }
30 }
31
32 pub fn connect<F>(&self, callback: F) -> usize
37 where
38 F: Fn(&T) + Send + Sync + 'static,
39 {
40 let callback_id = {
41 let mut next_id = self.inner.next_id.lock().unwrap();
42 let id = *next_id;
43 *next_id += 1;
44 id
45 };
46
47 self.inner
48 .callbacks
49 .lock()
50 .unwrap()
51 .insert(callback_id, Arc::new(callback));
52
53 callback_id
54 }
55
56 pub fn emit(&self, value: &T) {
60 let callbacks = {
61 let map = self.inner.callbacks.lock().unwrap();
62 map.values().cloned().collect::<Vec<_>>()
63 };
64
65 for callback in callbacks {
66 callback(value)
67 }
68 }
69
70 pub fn disconnect(&self, handle: usize) {
72 self.inner.callbacks.lock().unwrap().remove(&handle);
73 }
74}
75
76#[cfg(test)]
77mod tests {
78 use super::*;
79
80 #[test]
81 fn test_emit() {
82 let event = Event::new();
83 let received = Arc::new(Mutex::new(None));
84
85 let received_clone = Arc::clone(&received);
86
87 event.connect(move |value: &i32| {
88 *received_clone.lock().unwrap() = Some(*value);
89 });
90
91 event.emit(&67);
92
93 assert_eq!(*received.lock().unwrap(), Some(67));
94 }
95}