[−][src]Crate revent
Synchronous event system.
What is an event system
An event system is a set of signals connected to a bunch of objects. When a signal is emitted, the objects subscribing to said signal will have their handlers invoked to perform some useful processing.
Synchronous?
Revent is synchonous, meaning that calling emit
will immediately call all subscribers. This
also means that subscribers can return complex types with lifetimes referring to themselves.
Example
use revent::{shared, Topic}; // Create a trait for your event handler. trait A { // Here is one "event". We call this on all handlers (implementors of A). fn a(&mut self); } // Create a struct implementing A. struct X; impl A for X { fn a(&mut self) { println!("Hello world"); } } // Create a new topic channel. let mut topic: Topic<dyn A> = Topic::new(); // Insert a new object of X. topic.insert(shared(X)); // Iterate over all objects and call the event function. topic.emit(|x| { x.a(); }); // Remove all subscribers to this topic. topic.remove(|_| true);
Nested emitting
To allow for nested emitting we simply provide a &mut Topic<_>
to an event handler. The next
example shows this and its possible downside.
Mutable borrowing
It's possible to put a single object in two or more Topics. If one topic is able to emit into another topic then we may get a double-mutable borrow.
The following code panics because of 2 mutable borrows.
use revent::{shared, Topic}; trait A { fn a(&mut self, b: &mut Topic<dyn B>); } trait B { fn b(&mut self); } struct X; impl A for X { fn a(&mut self, b: &mut Topic<dyn B>) { b.emit(|x| { x.b(); }); } } impl B for X { fn b(&mut self) { } } let mut a: Topic<dyn A> = Topic::new(); let mut b: Topic<dyn B> = Topic::new(); let x = shared(X); a.insert(x.clone()); b.insert(x.clone()); a.emit(|x| { x.a(&mut b); });
To avoid this, design all your event handler types to never emit into a handler they subscribe
to.
In the above case we have X
subscribe to B
while also emitting into a Topic<dyn B>
. For
larger systems it is highly advised to ensure all your event handlers never emit into a topic
they also subscribe to.
Structs
Topic | A topic to which objects can subscribe. |
Functions
shared | Wrapper for |