Code Monkey home page Code Monkey logo

simple-event-bus's People

Contributors

dimitri-br avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

wimvelzeboer

simple-event-bus's Issues

Multiple events of different payloads

Hi @dimitri-br
I like the simplicity of this event bus, I tried to add a feature to but got stranded. That probably because I am quite new to Rust.

My idea was to add the ability to have different events with any type of payload, so that you could do something like this:

fn main() {
  let mut event_bus = EventBus::new();

  // Add each subscriber to the event bus, two for the "foo" and one for the "bar" event
  event_bus.subscribe_listener("foo".to_string(), FooOneSubscriber::new("Foo Subscriber 1".to_string()));
  event_bus.subscribe_listener("foo".to_string(), FooTwoSubscriber::new("Foo Subscriber 2".to_string()));
  event_bus.subscribe_listener("bar".to_string(), BarSubscriber::new("Foo Subscriber 1".to_string()));

  // publish two events, one for each.
  event_bus.publish("foo".to_string(), Event::new("hello".to_string()));  // takes a String as payload/message
  event_bus.publish("bar".to_string(), Event::new(42)); // takes a Number/u32 as payload/message

  // Run through each event
  event_bus.run();
}

The event name (foo/bar) is always a String but it should be able to take any kind of payload/message, e.g. String, u32, Struct/Trait
I started with changing the event of EventBus into a HashMap, but got into a conflict where I could only payloads of either a String or u32, not both. And got lost while trying to refactor everything into a Trait.

Any pointers that you can give me are very welcome!

This is the changed event_bus:

#![allow(dead_code)]

use std::collections::HashMap;
use super::Event;
use super::Subscriber;

pub struct EventBus<T> {
    /// A vec of events that have been published to the event bus.
    events: HashMap<String, Vec<Box<Event<T>>>>,
    /// A vec of all subscribers that are linked to the event bus.
    subscribers: HashMap<String, Vec<Box<dyn Subscriber<Input = T>>>>,
}

impl<T> EventBus<T> {

    pub fn new() -> EventBus<T> {
        EventBus {
            events: HashMap::new(),
            subscribers: HashMap::new(),
        }
    }

    pub fn publish(&mut self, event_name: String, message: Event<T>) {
        if self.events.contains_key(&event_name) {
            self.events.get_mut(&event_name).unwrap()
                .push(Box::new(message));
        } else {
            self.events.insert(event_name, vec![Box::new(message)]);
        }
    }

    pub fn subscribe_listener<R: Subscriber<Input = T> + 'static>(&mut self, event_name:String, listener: R) {
        if self.subscribers.contains_key(&event_name) {
            self.subscribers.get_mut(&event_name).unwrap()
                .push(Box::new(listener));
        } else {
            self.subscribers.insert(event_name, vec![Box::new(listener)]);
        }
    }

    pub fn run(&mut self) {
        for (event, messages) in self.events.drain() {
            if self.subscribers.contains_key(&event) {
                for listener in self.subscribers.get_mut(&event).unwrap().iter_mut() {
                    for message in &messages {
                        listener.on_event(message);
                    }
                }
            } else {
                println!("No event subscribers for '{}'", event);
            }
        }
    }
...
}

// Default
impl<T> Default for EventBus<T> {
...
}

And this is the Example to test it

use simple_event_bus::{Event, EventBus, Subscriber};

struct ExampleSubscriber {
    pub name: String,
}

impl ExampleSubscriber {
    pub fn new(name: String) -> ExampleSubscriber {
        ExampleSubscriber { name }
    }
}

impl Subscriber for ExampleSubscriber {
    type Input = String;

    fn on_event(&mut self, event: &Event<Self::Input>) {
        println!("{} received message: {}", self.name, event.get_data());
    }
}

struct NumberSubscriber {
    pub name: String,
}

impl NumberSubscriber {
    pub fn new(name: String) -> NumberSubscriber {
        NumberSubscriber { name }
    }
}

impl Subscriber for NumberSubscriber {
    type Input = u32;

    fn on_event(&mut self, event: &Event<Self::Input>) {
        println!("{} received message: {}", self.name, event.get_data());
    }
}


fn main() {
    let mut event_bus = EventBus::new();

    // We have to manually create and add each subscriber to the event bus.
    // event_bus.subscribe_listener("bar".to_string(), ExampleSubscriber::new("Subscriber 1".to_string()));
    // event_bus.subscribe_listener("bar".to_string(), ExampleSubscriber::new("Subscriber 2".to_string()));
    event_bus.subscribe_listener("foo".to_string(), NumberSubscriber::new("Number Subscriber".to_string()));

    // We can manually define an event and publish it to the event bus.
    // event_bus.publish(Event::new("hello".to_string()));
    let number: u32 = 32;
    event_bus.publish("foo".to_string(), Event::new(number));
    // event_bus.publish("bar".to_string(), Event::new("hello".to_string()));


    // Runs through each event, and calls each listener's on_event method.
    event_bus.run();
}

It works, but I can't use both ExampleSubscriber and NumberSubscriber at the same time...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.