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> } impl Tenquestionmarks { pub fn with_plugins (plugins: BTreeMap>) -> Tenquestionmarks { let tqm = Tenquestionmarks { plugins: plugins }; for (key, plugin) in &tqm.plugins { plugin.register(&tqm); } tqm } pub fn from_configuration (configuration: Table) -> Result { 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 consumer threads. // tenquestionmarks propagates all events to each plugin through these // channels. let senders: Vec> = self.plugins.values().map(|plugin| { let (sender, receiver) = mpsc::channel(); scope.spawn(move || plugin.consume_events(receiver)); sender }).collect(); // Plugin event producer threads. // Each plugin will produce events which tenquestionmarks will push // into all other plugins. for plugin in self.plugins.values() { let plugin_sender = sender.clone(); scope.spawn(move || plugin.produce_events(plugin_sender)); } // tenquestionmarks main event loop. // tenquestionmarks receives events produced by plugins and pushes them // into all other plugins 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 }