use crate::{
ActPlugin, ChannelOptions, Signal,
config::Config,
export::{Channel, Executor, Extender},
package,
scheduler::Runtime,
};
use std::sync::Arc;
#[derive(Clone)]
pub struct Engine {
config: Arc<Config>,
plugins: Vec<Arc<dyn ActPlugin>>,
runtime: Option<Arc<Runtime>>,
}
impl Default for Engine {
fn default() -> Self {
Self::new()
}
}
impl Engine {
pub fn new() -> Self {
Self {
config: Arc::new(Config::default()),
plugins: Vec::new(),
runtime: None,
}
}
pub fn config(&self) -> Arc<Config> {
self.config.clone()
}
pub fn with_config(mut self, config: &Config) -> Self {
self.config = Arc::new(config.clone());
self
}
pub fn add_plugin<T>(mut self, plugin: &T) -> Self
where
T: ActPlugin + Clone + 'static,
{
self.plugins.push(Arc::new(plugin.clone()));
self
}
pub fn set_plugins(mut self, plugins: Vec<Arc<dyn ActPlugin>>) -> Self {
self.plugins = plugins;
self
}
pub fn executor(&self) -> Arc<Executor> {
Arc::new(Executor::new(&self.runtime()))
}
pub fn channel(&self) -> Arc<Channel> {
Arc::new(Channel::new(&self.runtime()))
}
pub fn channel_with_options(&self, matcher: &ChannelOptions) -> Arc<Channel> {
Arc::new(Channel::channel(&self.runtime(), matcher))
}
pub fn extender(&self) -> Arc<Extender> {
Arc::new(Extender::new(&self.runtime()))
}
pub(crate) fn runtime(&self) -> Arc<Runtime> {
self.runtime.clone().expect("runtime not initialized")
}
pub fn close(&self) {
self.runtime().close();
}
pub fn signal<T: Clone>(&self, init: T) -> Signal<T> {
Signal::new(init)
}
pub fn start(mut self) -> crate::Result<Self> {
self.runtime = Some(Runtime::new(&self.config())?);
for plugin in self.plugins.iter() {
plugin.on_init(&self)?;
}
package::init(&self)?;
self.runtime().event_loop();
Ok(self)
}
}