event_emitter_rs/
lib.rs

1/*! 
2[![](http://meritbadge.herokuapp.com/event-emitter-rs)](https://crates.io/crates/event-emitter-rs)
3
4A simple EventEmitter implementation.
5
6Allows you to subscribe to events with callbacks and also fire those events.
7Events are in the form of (strings, value) and callbacks are in the form of closures that take in a value parameter.
8
9# Getting Started
10
11```
12use event_emitter_rs::EventEmitter;
13let mut event_emitter = EventEmitter::new();
14
15// This will print <"Hello world!"> whenever the <"Say Hello"> event is emitted
16event_emitter.on("Say Hello", |value: ()| println!("Hello world!"));
17event_emitter.emit("Say Hello", ()); 
18// >> "Hello world!"
19```
20
21# Basic Usage
22
23We can emit and listen to values of any type so long as they implement the serde Serialize and Deserialize traits.
24A single EventEmitter instance can have listeners to values of multiple types.
25
26```
27use event_emitter_rs::EventEmitter;
28use serde::{Deserialize, Serialize};
29let mut event_emitter = EventEmitter::new();
30
31event_emitter.on("Add three", |number: f32| println!("{}", number + 3.0));
32event_emitter.emit("Add three", 5.0 as f32); 
33event_emitter.emit("Add three", 4.0 as f32);
34// >> "8.0"
35// >> "7.0"
36
37// Using a more advanced value type such as a struct by implementing the serde traits
38#[derive(Serialize, Deserialize)]
39struct Date {
40    month: String,
41    day: String,   
42}
43
44event_emitter.on("LOG_DATE", |date: Date| {
45    println!("Month: {} - Day: {}", date.month, date.day)
46});
47event_emitter.emit("LOG_DATE", Date { 
48    month: "January".to_string(), 
49    day: "Tuesday".to_string() 
50}); 
51// >> "Month: January - Day: Tuesday"
52```
53
54Removing listeners is also easy
55
56```
57use event_emitter_rs::EventEmitter;
58let mut event_emitter = EventEmitter::new();
59
60let listener_id = event_emitter.on("Hello", |_: ()| println!("Hello World"));
61match event_emitter.remove_listener(&listener_id) {
62    Some(listener_id) => print!("Removed event listener!"),
63    None => print!("No event listener of that id exists")
64}
65```
66# Creating a Global EventEmitter
67
68It's likely that you'll want to have a single EventEmitter instance that can be shared accross files;
69
70After all, one of the main points of using an EventEmitter is to avoid passing down a value through several nested functions/types and having a global subscription service.
71
72```
73// global_event_emitter.rs
74use std::sync::Mutex;
75use crate::EventEmitter;
76
77// Use lazy_static! because the size of EventEmitter is not known at compile time
78lazy_static! {
79    // Export the emitter with `pub` keyword
80    pub static ref EVENT_EMITTER: Mutex<EventEmitter> = Mutex::new(EventEmitter::new());
81}
82```
83
84Then we can import this instance into multiple files.
85
86```
87// main.rs
88#[macro_use]
89extern crate lazy_static;
90
91mod global_event_emitter;
92use global_event_emitter::EVENT_EMITTER;
93
94fn main() {
95    // We need to maintain a lock through the mutex so we can avoid data races
96    EVENT_EMITTER.lock().unwrap().on("Hello", |_: ()| println!("hello there!"));
97    EVENT_EMITTER.lock().unwrap().emit("Hello", ());
98}
99```
100
101And in another file we can now listen to the <"Hello"> event in main.rs by adding a listener to the global event emitter.
102
103```
104// some_random_file.rs
105use crate::global_event_emitter::EVENT_EMITTER;
106
107fn random_function() {
108    // When the <"Hello"> event is emitted in main.rs then print <"Random stuff!">
109    EVENT_EMITTER.lock().unwrap().on("Hello", |_: ()| println!("Random stuff!"));
110}
111```
112*/
113
114//#[cfg(test)]
115mod tests;
116
117use std::collections::HashMap;
118use std::thread;
119use std::sync::Arc;
120use serde::{Deserialize, Serialize};
121
122#[macro_use]
123extern crate lazy_static;
124
125use bincode;
126
127use uuid::Uuid;
128
129pub struct Listener {
130    callback: Arc<dyn Fn(Vec<u8>) + Sync + Send + 'static>,
131    limit: Option<u64>,
132    id: String,
133}
134
135#[derive(Default)]
136pub struct EventEmitter {
137    pub listeners: HashMap<String, Vec<Listener>>
138}
139
140impl EventEmitter {
141    // Potentially may want to add features here in the future so keep it like this
142    pub fn new() -> Self {
143        Self {
144            ..Self::default()
145        }
146    }
147
148    /// Adds an event listener with a callback that will get called whenever the given event is emitted.
149    /// Returns the id of the newly added listener.
150    ///
151    /// # Example
152    ///
153    /// ```
154    /// use event_emitter_rs::EventEmitter;
155    /// let mut event_emitter = EventEmitter::new();
156    ///
157    /// // This will print <"Hello world!"> whenever the <"Some event"> event is emitted
158    /// // The type of the `value` parameter for the closure MUST be specified and, if you plan to use the `value`, the `value` type 
159    /// // MUST also match the type that is being emitted (here we just use a throwaway `()` type since we don't care about using the `value`)
160    /// event_emitter.on("Some event", |value: ()| println!("Hello world!"));
161    /// ```
162    pub fn on<F, T>(&mut self, event: &str, callback: F) -> String
163        where 
164            for<'de> T: Deserialize<'de>,
165            F: Fn(T) + 'static + Sync + Send 
166    {
167        let id = self.on_limited(event, None, callback);
168        return id;
169    }
170
171    /// Emits an event of the given parameters and executes each callback that is listening to that event asynchronously by spawning a new thread for each callback.
172    ///
173    /// # Example
174    ///
175    /// ```
176    /// use event_emitter_rs::EventEmitter;
177    /// let mut event_emitter = EventEmitter::new();
178    ///
179    /// // Emits the <"Some event"> event and a value <"Hello programmer">
180    /// // The value can be of any type as long as it implements the serde Serialize trait
181    /// event_emitter.emit("Some event", "Hello programmer!");
182    /// ```
183    pub fn emit<T>(&mut self, event: &str, value: T) -> Vec<thread::JoinHandle<()>>
184        where T: Serialize
185    {
186        let mut callback_handlers: Vec<thread::JoinHandle<()>> = Vec::new();
187
188        if let Some(listeners) = self.listeners.get_mut(event) {
189            let bytes: Vec<u8> = bincode::serialize(&value).unwrap();
190            
191            let mut listeners_to_remove: Vec<usize> = Vec::new();
192            for (index, listener) in listeners.iter_mut().enumerate() {
193                let cloned_bytes = bytes.clone();
194                let callback = Arc::clone(&listener.callback);
195
196                match listener.limit {
197                    None => { 
198                        callback_handlers.push(thread::spawn(move || { 
199                            callback(cloned_bytes);
200                        })); 
201                    },
202                    Some(limit) => {
203                        if limit != 0 {
204                            callback_handlers.push(thread::spawn(move || {
205                                callback(cloned_bytes);
206                            }));
207                            listener.limit = Some(limit - 1);
208                        } else {
209                            listeners_to_remove.push(index);
210                        }
211                    }
212                }
213            }
214
215            // Reverse here so we don't mess up the ordering of the vector
216            for index in listeners_to_remove.into_iter().rev() {
217                listeners.remove(index);
218            }
219        }
220
221        return callback_handlers;
222    }
223
224    /// Removes an event listener with the given id
225    ///
226    /// # Example
227    ///
228    /// ```
229    /// use event_emitter_rs::EventEmitter;
230    /// let mut event_emitter = EventEmitter::new();
231    /// let listener_id = event_emitter.on("Some event", |value: ()| println!("Hello world!"));
232    ///
233    /// // Removes the listener that we just added
234    /// event_emitter.remove_listener(&listener_id);
235    /// ```
236    pub fn remove_listener(&mut self, id_to_delete: &str) -> Option<String> {
237        for (_, event_listeners) in self.listeners.iter_mut() {
238            if let Some(index) = event_listeners.iter().position(|listener| listener.id == id_to_delete) {
239                event_listeners.remove(index);
240                return Some(id_to_delete.to_string());
241            } 
242        }
243
244        return None;
245    }
246
247    /// Adds an event listener that will only execute the listener x amount of times - Then the listener will be deleted.
248    /// Returns the id of the newly added listener.
249    ///
250    /// # Example
251    ///
252    /// ```
253    /// use event_emitter_rs::EventEmitter;
254    /// let mut event_emitter = EventEmitter::new();
255    ///
256    /// // Listener will be executed 3 times. After the third time, the listener will be deleted.
257    /// event_emitter.on_limited("Some event", Some(3), |value: ()| println!("Hello world!"));
258    /// event_emitter.emit("Some event", ()); // 1 >> "Hello world!"
259    /// event_emitter.emit("Some event", ()); // 2 >> "Hello world!"
260    /// event_emitter.emit("Some event", ()); // 3 >> "Hello world!"
261    /// event_emitter.emit("Some event", ()); // 4 >> <Nothing happens here because listener was deleted after the 3rd call>
262    /// ```
263    pub fn on_limited<F, T>(&mut self, event: &str, limit: Option<u64>, callback: F) -> String
264        where 
265            for<'de> T: Deserialize<'de>,
266            F: Fn(T) + 'static + Sync + Send 
267    {
268        let id = Uuid::new_v4().to_string();
269        let parsed_callback = move |bytes: Vec<u8>| {
270            let value: T = bincode::deserialize(&bytes).unwrap();
271            callback(value);
272        };
273
274        let listener = Listener {
275            id: id.clone(),
276            limit,
277            callback: Arc::new(parsed_callback),
278        };
279
280        match self.listeners.get_mut(event) {
281            Some(callbacks) => { callbacks.push(listener); },
282            None => { self.listeners.insert(event.to_string(), vec![listener]); }
283        }
284
285        return id;
286    }
287
288    /// Adds an event listener that will only execute the callback once - Then the listener will be deleted.
289    /// Returns the id of the newly added listener.
290    ///
291    /// # Example
292    ///
293    /// ```
294    /// use event_emitter_rs::EventEmitter;
295    /// let mut event_emitter = EventEmitter::new();
296    ///
297    /// event_emitter.once("Some event", |value: ()| println!("Hello world!"));
298    /// event_emitter.emit("Some event", ()); // First event is emitted and the listener's callback is called once
299    /// // >> "Hello world!"
300    ///
301    /// event_emitter.emit("Some event", ());
302    /// // >> <Nothing happens here since listener was deleted>
303    /// ```
304    pub fn once<F, T>(&mut self, event: &str, callback: F) -> String
305        where 
306            for<'de> T: Deserialize<'de>,
307            F: Fn(T) + 'static + Sync + Send 
308    {
309        let id = self.on_limited(event, Some(1), callback);
310        return id;
311    }
312
313    /// NOT IMPLEMENTED!
314    /// Emits an event of the given parameters in a synchronous fashion.
315    /// Instead of executing each callback in a newly spawned thread, it will execute each callback in the order that they were inserted.
316    ///
317    /// # Example
318    ///
319    /// ```
320    /// use event_emitter_rs::EventEmitter;
321    /// let mut event_emitter = EventEmitter::new();
322    ///
323    /// event_emitter.on("Some event", |value: ()| println!("1")); // Guaranteed to be executed first
324    /// event_emitter.on("Some event", |value: ()| println!("2")); // Will not execute this until the first callback has finished executing
325    /// event_emitter.on("Some event", |value: ()| println!("3")); // Will not execute this until the second callback has finished executing
326    ///
327    /// // Emits the <"Some event"> event and a value <"Hello programmer">
328    /// // The value can be of any type
329    /// event_emitter.sync_emit("Some event", "Hello programmer!");
330    /// ```
331    pub fn sync_emit<T>(&self, event: &str, value: T) 
332        where T: Serialize
333    {
334    }
335}