send/receive Arc<Event> instead of Event so we don't have to clone objects all over the place. This might also enable us to be a bit more flexible with what we send with Events, and might simplify things elsewhere.

This commit is contained in:
Adrian Malacoda
2017-02-19 02:55:30 -06:00
parent 1a69349557
commit 84d2921f8f
7 changed files with 35 additions and 32 deletions

View File

@@ -1,6 +1,5 @@
use {Channel, User};
#[derive(Clone)]
pub enum Event {
Message { sender: User, channel: Option<Channel>, content: String },
Join { channel: Channel },

View File

@@ -54,7 +54,7 @@ impl Tenquestionmarks {
// Module event consumer threads.
// tenquestionmarks propagates all events to each Module through these
// channels.
let senders: Vec<Sender<Event>> = self.modules.values().map(|module| {
let senders: Vec<Sender<Arc<Event>>> = self.modules.values().map(|module| {
let (sender, receiver) = mpsc::channel();
scope.spawn(move || module.consume_events(receiver));
sender
@@ -88,12 +88,11 @@ impl Tenquestionmarks {
}
}
#[derive(Clone)]
pub struct Channel {
name: String,
description: String,
topic: String,
sender: Arc<MessageSender>
sender: Box<MessageSender>
}
impl Channel {
@@ -102,10 +101,9 @@ impl Channel {
}
}
#[derive(Clone)]
pub struct User {
name: String,
sender: Arc<MessageSender>
sender: Box<MessageSender>
}
impl User {

View File

@@ -54,7 +54,7 @@ impl MessageSender for DiscordMessageSender {
}
impl Module for DiscordModule {
fn produce_events<'a>(&'a self, sender: Sender<event::Event>) {
fn produce_events<'a>(&'a self, sender: Sender<Arc<event::Event>>) {
let discord = Arc::new(Discord::from_bot_token(&self.token[..]).expect("Discord module: Login failed"));
let (mut connection, _) = discord.connect().expect("Discord module: Connection failed");
@@ -66,7 +66,7 @@ impl Module for DiscordModule {
Ok(Event::MessageCreate(message)) => {
let author = User {
name: message.author.name.clone(),
sender: Arc::new(DiscordMessageSender {
sender: Box::new(DiscordMessageSender {
discord: discord.clone(),
channel_id: message.channel_id
})
@@ -76,13 +76,13 @@ impl Module for DiscordModule {
name: String::from("channel"),
description: String::from(""),
topic: String::from(""),
sender: Arc::new(DiscordMessageSender {
sender: Box::new(DiscordMessageSender {
discord: discord.clone(),
channel_id: message.channel_id
})
};
match sender.send(event::Event::Message { sender: author, content: message.content, channel: Option::Some(channel) }) {
match sender.send(Arc::new(event::Event::Message { sender: author, content: message.content, channel: Option::Some(channel) })) {
Err(err) => error!("Error sending message event: {:?}", err),
Ok(_) => {}
}

View File

@@ -1,6 +1,7 @@
use modules::Module;
use toml::Table;
use std::sync::Arc;
use std::sync::mpsc::Receiver;
use event::Event;
@@ -21,17 +22,17 @@ impl EchoModule {
}
impl Module for EchoModule {
fn consume_events (&self, receiver: Receiver<Event>) {
fn consume_events (&self, receiver: Receiver<Arc<Event>>) {
loop {
match receiver.recv() {
Ok(event) => {
match event {
Event::Message { content: message, channel, sender } => {
match *event {
Event::Message { content: ref message, ref channel, ref sender } => {
debug!("Received message... {:?}", message);
if message.starts_with(self.prefix.as_str()) {
let substring = &message[self.prefix.chars().count()..];
match channel {
Some(channel) => channel.send(substring),
match *channel {
Some(ref channel) => channel.send(substring),
None => sender.send(substring)
}
}

View File

@@ -9,10 +9,11 @@ pub mod loader;
use Tenquestionmarks;
use event::Event;
use std::sync::Arc;
use std::sync::mpsc::{Sender, Receiver};
pub trait Module : Sync {
fn register (&self, tenquestionmarks: &Tenquestionmarks) {}
fn consume_events (&self, receiver: Receiver<Event>) {}
fn produce_events<'a>(&'a self, sender: Sender<Event>) {}
fn consume_events (&self, receiver: Receiver<Arc<Event>>) {}
fn produce_events<'a>(&'a self, sender: Sender<Arc<Event>>) {}
}

View File

@@ -1,6 +1,7 @@
use modules::Module;
use toml::Table;
use std::sync::Arc;
use std::sync::mpsc::Receiver;
use event::Event;
@@ -33,20 +34,20 @@ impl RandomModule {
}
impl Module for RandomModule {
fn consume_events (&self, receiver: Receiver<Event>) {
fn consume_events (&self, receiver: Receiver<Arc<Event>>) {
let mut rng = rand::thread_rng();
loop {
match receiver.recv() {
Ok(event) => {
match event {
Event::Message { content: message, channel, sender } => {
match *event {
Event::Message { content: ref message, ref channel, ref sender } => {
debug!("Received message... {:?}", message);
if message.starts_with(self.prefix.as_str()) {
let response = &rand::sample(&mut rng, &self.responses, 1)[0][..];
match channel {
Some(channel) => channel.send(response),
match *channel {
Some(ref channel) => channel.send(response),
None => sender.send(response)
}
}

View File

@@ -30,20 +30,23 @@ impl StdinModule {
}
impl Module for StdinModule {
fn produce_events<'a>(&'a self, sender: Sender<Event>) {
let user = User {
name: String::from("Dave"),
sender: Arc::new(StdinMessageSender {
name: String::from("Dave")
})
};
fn produce_events<'a>(&'a self, sender: Sender<Arc<Event>>) {
loop {
let mut input = String::new();
match io::stdin().read_line(&mut input) {
Ok(n) => {
let message = Event::Message { sender: user.clone(), content: input, channel: None };
match sender.send(message) {
let message = Event::Message {
sender: User {
name: String::from("Dave"),
sender: Box::new(StdinMessageSender {
name: String::from("Dave")
})
},
content: input,
channel: None
};
match sender.send(Arc::new(message)) {
Err(err) => error!("Error sending message event: {:?}", err),
Ok(_) => {}
}