134 lines
3.5 KiB
Rust
Raw Normal View History

extern crate toml;
extern crate crossbeam;
extern crate discord;
2017-02-16 02:00:38 -06:00
extern crate rand;
2017-02-19 04:49:06 -06:00
extern crate pvn;
use std::collections::BTreeMap;
use toml::Table;
2017-02-16 01:05:33 -06:00
mod modules;
use modules::Module;
use modules::loader::{ModuleLoader, ModuleLoaderError};
mod event;
use event::Event;
2017-02-16 00:16:48 -06:00
use std::sync::Arc;
use std::sync::mpsc;
use std::sync::mpsc::Sender;
2017-02-16 02:00:38 -06:00
mod helpers;
2017-02-17 02:38:15 -06:00
#[macro_use]
extern crate log;
pub struct Tenquestionmarks {
2017-02-16 01:05:33 -06:00
modules: BTreeMap<String, Box<Module>>
}
impl Tenquestionmarks {
2017-02-16 01:05:33 -06:00
pub fn with_modules (modules: BTreeMap<String, Box<Module>>) -> Tenquestionmarks {
let tqm = Tenquestionmarks {
2017-02-16 01:05:33 -06:00
modules: modules
};
2017-02-16 01:05:33 -06:00
for (key, module) in &tqm.modules {
module.register(&tqm);
}
tqm
}
2017-02-16 01:05:33 -06:00
pub fn from_configuration (configuration: Table) -> Result<Tenquestionmarks, ModuleLoaderError> {
let loader = ModuleLoader::new();
let modules = loader.load_from_configuration(configuration)?;
Result::Ok(Tenquestionmarks::with_modules(modules))
}
pub fn run (&self) {
crossbeam::scope(|scope| {
// Our event channel.
2017-02-16 01:05:33 -06:00
// Modules push events to tenquestionmarks using this channel.
let (ref sender, ref receiver) = mpsc::channel();
2017-02-16 01:05:33 -06:00
// Module event consumer threads.
// tenquestionmarks propagates all events to each Module through these
// channels.
let senders: Vec<Sender<Arc<Event>>> = self.modules.values().map(|module| {
let (sender, receiver) = mpsc::channel();
2017-02-16 01:05:33 -06:00
scope.spawn(move || module.consume_events(receiver));
sender
}).collect();
2017-02-16 01:05:33 -06:00
// Module event producer threads.
// Each Module will produce events which tenquestionmarks will push
// into all other Modules.
for module in self.modules.values() {
let module_sender = sender.clone();
scope.spawn(move || module.produce_events(module_sender));
}
// tenquestionmarks main event loop.
2017-02-16 01:05:33 -06:00
// tenquestionmarks receives events produced by Modules and pushes them
// into all other Modules
loop {
match receiver.recv() {
Ok(event) => {
for sender in &senders {
2017-02-17 02:38:15 -06:00
match sender.send(event.clone()) {
Err(err) => debug!("Failed to dispatch event to module: {:?}", err),
Ok(_) => {}
}
}
},
2017-02-17 02:38:15 -06:00
Err(err) => { error!("Failed to receive event in main event loop: {:?}", err); }
}
}
});
}
}
pub struct Message {
content: String,
author: User,
channel: Option<Channel>
}
impl Message {
fn reply (&self, message: &str) {
match self.channel {
Some(ref channel) => channel.send(message),
None => self.author.send(message)
}
}
}
pub struct Channel {
name: String,
description: String,
topic: String,
sender: Box<MessageSender>
}
impl Channel {
pub fn send (&self, message: &str) {
self.sender.send_message(message);
}
}
pub struct User {
name: String,
sender: Box<MessageSender>
}
impl User {
pub fn send (&self, message: &str) {
self.sender.send_message(message);
}
}
pub trait MessageSender : Sync + Send {
fn send_message (&self, message: &str) {}
}