94 lines
2.5 KiB
Rust

extern crate toml;
extern crate crossbeam;
use std::collections::BTreeMap;
use toml::Table;
mod plugins;
use plugins::Plugin;
use plugins::loader::{PluginLoader, PluginLoaderError};
mod event;
use event::Event;
use std::sync::mpsc;
use std::sync::mpsc::{Sender, Receiver};
pub struct Tenquestionmarks {
plugins: BTreeMap<String, Box<Plugin>>
}
impl Tenquestionmarks {
pub fn with_plugins (plugins: BTreeMap<String, Box<Plugin>>) -> Tenquestionmarks {
let tqm = Tenquestionmarks {
plugins: plugins
};
for (key, plugin) in &tqm.plugins {
plugin.register(&tqm);
}
tqm
}
pub fn from_configuration (configuration: Table) -> Result<Tenquestionmarks, PluginLoaderError> {
let loader = PluginLoader::new();
let plugins = loader.load_from_configuration(configuration)?;
Result::Ok(Tenquestionmarks::with_plugins(plugins))
}
pub fn run (&self) {
crossbeam::scope(|scope| {
// Our event channel.
// Plugins push events to tenquestionmarks using this channel.
let (ref sender, ref receiver) = mpsc::channel();
// Plugin event channels.
// tenquestionmarks propagates all events to each plugin through these
// channels.
let senders: Vec<Sender<Event>> = self.plugins.values().map(|plugin| {
let (sender, receiver) = mpsc::channel();
scope.spawn(move || {
loop {
match receiver.recv() {
Ok(event) => { plugin.on_event(event) }
Err(error) => { println!("{:?}", error); }
}
}
});
sender
}).collect();
// Plugin main threads.
for plugin in self.plugins.values() {
let plugin_sender = sender.clone();
scope.spawn(move || plugin.run(plugin_sender));
}
// tenquestionmarks main event loop.
loop {
match receiver.recv() {
Ok(event) => {
for sender in &senders {
sender.send(event.clone());
}
},
Err(_) => {}
}
}
});
}
}
#[derive(Debug, Clone)]
pub struct Channel {
name: String,
description: String,
topic: String
}
#[derive(Debug, Clone)]
pub struct User {
name: String
}