tram/
lib.rs

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