1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
//! A simple event bus that can be cloned and shared across threads.
//!
//! ## Emit inside `on` blocks
//!
//! To re-emit events inside `on` closures do not clone the original bus, use the bus
//! reference provided to the closure instead.
//!
//! ## Example
//!
//! ```rust
//! use tram::{prelude::*, unsync::EventBus};
//! use std::{rc::Rc, cell::RefCell};
//!
//! #[derive(PartialEq, Eq, Hash)]
//! enum EventType {
//! Start,
//! Stop,
//! }
//!
//! #[derive(Debug, PartialEq)]
//! enum Status {
//! Stopped,
//! Started,
//! }
//!
//! let bus: EventBus<EventType, ()> = EventBus::unbound();
//!
//! let status = Rc::new(RefCell::new(Status::Stopped));
//! let status_closure = Rc::clone(&status);
//! let status_closure_2 = Rc::clone(&status);
//!
//! bus.on(EventType::Start, move |_bus, _| {
//! *status_closure.borrow_mut() = Status::Started;
//! })
//! .expect("Failed to register listener");
//!
//! bus.on(EventType::Stop, move |_bus, _| {
//! *status_closure_2.borrow_mut() = Status::Stopped;
//! })
//! .expect("Failed to register listener");
//!
//! bus.emit(EventType::Start).expect("Failed to emit");
//!
//! assert_eq!(*status.borrow(), Status::Started);
//! assert_eq!(bus.event_count(), 1);
//!
//! bus.emit(EventType::Stop).expect("Failed to emit");
//!
//! assert_eq!(*status.borrow(), Status::Stopped);
//! assert_eq!(bus.event_count(), 2);
//! ```
//!
//! ## Using it in threads
//!
//! ```
//! use tram::{prelude::*, sync::EventBus};
//! use std::sync::{Arc, Mutex};
//!
//! #[derive(PartialEq, Eq, Hash)]
//! enum EventType {
//! Start,
//! Stop,
//! }
//!
//! #[derive(Debug, PartialEq)]
//! enum Status {
//! Stopped,
//! Started,
//! }
//!
//! let bus: EventBus<EventType, ()> = EventBus::unbound();
//! let bus_clone = bus.clone();
//!
//! let status = Arc::new(Mutex::new(Status::Stopped));
//! let final_status = Arc::clone(&status);
//!
//! bus.on(EventType::Start, move |_bus, _| {
//! let mut status_lock = status.lock().expect("Could not lock status");
//! *status_lock = Status::Started;
//! }).expect("Could not register listener");
//!
//! let t2 = std::thread::spawn(move || {
//! bus_clone.emit(EventType::Start).expect("Could not emit start event");
//! });
//!
//! t2.join().unwrap();
//!
//! let final_status_lock = final_status.lock().expect("Could not lock final status");
//! assert_eq!(*final_status_lock, Status::Started)
//! ```
//!
//! ## Passing data to events
//!
//! ```rust
//! use tram::{prelude::*, unsync::EventBus};
//! use std::{rc::Rc, cell::RefCell};
//!
//! #[derive(PartialEq, Eq, Hash)]
//! enum EventType {
//! Start,
//! Stop,
//! }
//!
//! #[derive(Debug, PartialEq)]
//! enum Status {
//! Stopped,
//! Started,
//! }
//!
//! let bus: EventBus<EventType, u8> = EventBus::unbound();
//! let status: Rc<RefCell<Option<u8>>> = Rc::new(RefCell::new(None));
//! let status_closure = Rc::clone(&status);
//!
//! bus.on(EventType::Start, move |_bus, startup_data| {
//! *status_closure.borrow_mut() = Some(*startup_data.unwrap());
//! })
//! .unwrap();
//!
//! bus.emit_with_value(EventType::Start, Some(&123)).expect("Failed to emit");
//!
//! assert_eq!(*status.borrow(), Some(123));
//! assert_eq!(bus.event_count(), 1);
//! ```