[][src]Struct maidsafe_utilities::event_sender::EventSender

pub struct EventSender<Category, EventSubset> { /* fields omitted */ }

This structure is coded to achieve event-subsetting. Receivers in Rust are blocking. One cannot listen to multiple receivers at the same time except by using try_recv which again is bad for the same reasons spin-lock based on some sleep is bad (wasting cycles, 50% efficient on an average etc.).

Consider a module that listens to signals from various other modules. Different modules want to talk to this one. So one solution is make a common event set and all senders (registered in all the interested modules) send events from the same set. This is bad for maintenance. Wrong modules might use events not expected to originate from them since it is just one huge event-set. Thus there is a need of event-subsetting and distribute this module-wise so we prevent modules from using wrong events, completely by design and code-mechanics.

We also don't want to spawn threads listening to different receivers (which could force shared ownership and is anyway silly otherwise too). This is what EventSender helps to salvage. A simple mechanism that does what a skip-list in linked list does. It brings forth a concept of an Umbrella event-category and an event subset. The creator of EventSender hard-codes the category for different observers. Each category only links to a particular event-subset and type information of this is put into EventSender too during its construction. Thus when distributed, the modules cannot cheat (do the wrong thing) by trying to fire an event they are not permitted to. Also a single thread listens to many receivers. All problems solved.

#Examples

    #[derive(Debug, Clone)]
    enum EventCategory {
        Network,
        UserInterface,
    }

    #[derive(Debug)]
    enum NetworkEvent {
        Connected,
        Disconnected,
    }

    #[derive(Debug)]
    enum UiEvent {
        CreateDirectory,
        Terminate,
    }

    let (ui_event_tx, ui_event_rx) = std::sync::mpsc::channel();
    let (category_tx, category_rx) = std::sync::mpsc::channel();
    let (network_event_tx, network_event_rx) = std::sync::mpsc::channel();

    let ui_event_sender = maidsafe_utilities::event_sender
                                            ::EventSender::<EventCategory, UiEvent>
                                            ::new(ui_event_tx,
                                                  EventCategory::UserInterface,
                                                  category_tx.clone());

    let nw_event_sender = maidsafe_utilities::event_sender
                                            ::EventSender::<EventCategory, NetworkEvent>
                                            ::new(network_event_tx,
                                                  EventCategory::Network,
                                                  category_tx);

    let _joiner = maidsafe_utilities::thread::named("EventListenerThread", move || {
        for it in category_rx.iter() {
            match it {
                EventCategory::Network => {
                    if let Ok(network_event) = network_event_rx.try_recv() {
                        match network_event {
                            NetworkEvent::Connected    => { /* Do Something */ },
                            NetworkEvent::Disconnected => { /* Do Something */ },
                        }
                    }
                },
                EventCategory::UserInterface => {
                    if let Ok(ui_event) = ui_event_rx.try_recv() {
                        match ui_event {
                            UiEvent::Terminate       => break,
                            UiEvent::CreateDirectory => { /* Do Something */ },
                        }
                    }
                }
            }
        }
    });

    assert!(nw_event_sender.send(NetworkEvent::Connected).is_ok());
    assert!(ui_event_sender.send(UiEvent::CreateDirectory).is_ok());
    assert!(ui_event_sender.send(UiEvent::Terminate).is_ok());

Implementations

impl<Category: Debug + Clone, EventSubset: Debug> EventSender<Category, EventSubset>[src]

pub fn new(
    event_tx: Sender<EventSubset>,
    event_category: Category,
    event_category_tx: Sender<Category>
) -> EventSender<Category, EventSubset>
[src]

Create a new instance of EventSender. Category type, category value and EventSubset type are baked into EventSender to disallow user code from misusing it.

pub fn send(
    &self,
    event: EventSubset
) -> Result<(), EventSenderError<Category, EventSubset>>
[src]

Fire an allowed event/signal to the observer.

Trait Implementations

impl<Category: Debug + Clone, EventSubset: Debug> Clone for EventSender<Category, EventSubset>[src]

impl<Category: Debug, EventSubset: Debug> Debug for EventSender<Category, EventSubset>[src]

Auto Trait Implementations

impl<Category, EventSubset> !RefUnwindSafe for EventSender<Category, EventSubset>

impl<Category, EventSubset> Send for EventSender<Category, EventSubset> where
    Category: Send,
    EventSubset: Send

impl<Category, EventSubset> !Sync for EventSender<Category, EventSubset>

impl<Category, EventSubset> Unpin for EventSender<Category, EventSubset> where
    Category: Unpin

impl<Category, EventSubset> !UnwindSafe for EventSender<Category, EventSubset>

Blanket Implementations

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> CloneAny for T where
    T: Clone + Any

impl<T> DebugAny for T where
    T: Any + Debug

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> UnsafeAny for T where
    T: Any