Events

To facilitate intra and interlayer communication a deferred bus like event system is provided.

Any user can subscribe to an event by using a channel. Every layer of type T will be broadcaasted to every subscribed sender. The event can thereafter be read by iterating the receiving half.

By default, std::mpsc::channel, flume, and crossbeam-channel (feature = "crossbeam-channel") implement the EventSender trait.

The events will not be cleared between different frames but rather consumed when iterated. This allows layers which execute occasionally to not miss any events.

Any 'static Send + Sync + Clone type can be used as an event. However, if cloning is expensive, consider wrapping the event in an Arc or referring to it by other means as the event will be cloned for every subscribed sender.

Example

#![allow(unused)]
fn main() {
fn events() {
    #[derive(Debug, Clone, PartialEq, Eq)]
    pub struct MyEvent(String);
    #[derive(Debug, Clone, PartialEq, Eq)]
    pub struct OtherEvent(String);

    // Normally, events will be supplied by App
    let mut events = Events::new();
    let my_events = events.subscribe::<MyEvent>();

    let other_events = events.subscribe::<OtherEvent>();

    // Send some events
    events.send(MyEvent(String::from("Hello, World!")));

    // Receive events
    for event in my_events.try_iter() {
        let other = OtherEvent(event.0.to_uppercase());
        events.send(other)
    }

    assert!(other_events
        .try_iter()
        .map(|val| val.0)
}

Intercepting

Sometimes it is necessary to intercept events, either absorbing them or re-emitting them. This can be accomplished in two main ways.

Events of a certain type can be sent and consumed, to then be resent using a different type. The final consumers should then subscribe to the latter type.

Sometimes however, it is not possible to re-emit events; either because of already existing architecture, or that the intercepting component may not always be present and thus requiring a mockup intercepter that simply re-emits.

For these use cases, the use of the intercept API is necessary.

#![allow(unused)]
fn main() {
fn intercept_events() {
    #[derive(Debug, Clone, PartialEq, Eq)]
    pub struct MyEvent(String);

    // Normally, events will be supplied by App
    let mut events = Events::new();
    let (tx, my_events) = flume::unbounded();
    events.intercept::<MyEvent, _>(tx).unwrap();

    let other_events = events.subscribe::<MyEvent>();

    // Send some events
    events.send(MyEvent(String::from("Hello, World!")));

    // Receive events
    for event in my_events.try_iter() {
        let other = MyEvent(event.0.to_uppercase());
        events.intercepted_send(other)
    }

    assert!(other_events
        .try_iter()
        .map(|val| val.0)
}