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}; use {Channel, User};
#[derive(Clone)]
pub enum Event { pub enum Event {
Message { sender: User, channel: Option<Channel>, content: String }, Message { sender: User, channel: Option<Channel>, content: String },
Join { channel: Channel }, Join { channel: Channel },

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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