diff --git a/crates/aionbot-core/src/entry.rs b/crates/aionbot-core/src/entry.rs index ccd5369..ed521f4 100644 --- a/crates/aionbot-core/src/entry.rs +++ b/crates/aionbot-core/src/entry.rs @@ -3,10 +3,7 @@ use std::{hash::Hash, sync::Arc}; use crate::{router::Router, types::Callback}; #[derive(Clone)] -pub struct Entry -where - Self: Send, -{ +pub struct Entry { pub id: &'static str, pub priority: i8, pub router: Arc>, diff --git a/crates/aionbot-core/src/event.rs b/crates/aionbot-core/src/event.rs index 4d23765..41f3d40 100644 --- a/crates/aionbot-core/src/event.rs +++ b/crates/aionbot-core/src/event.rs @@ -5,7 +5,7 @@ use anyhow::{anyhow, Result}; pub trait Event: Any + Send + Sync { /// Get the name of the event. fn name(&self) -> &str { - "UnknownEvent" + "unknown_event" } /// Get the type of the event. fn event_type(&self) -> &str; diff --git a/crates/aionbot-core/src/handler.rs b/crates/aionbot-core/src/handler.rs index 9f61bd7..e713a28 100644 --- a/crates/aionbot-core/src/handler.rs +++ b/crates/aionbot-core/src/handler.rs @@ -18,8 +18,12 @@ impl Handler { Self { entries: vec![] } } - pub async fn input(&self, event: &Arc>) -> Result<()> { - let mut queue = self.matches(&***event); + pub fn extend>(&mut self, entries: E) { + self.entries.extend(entries); + } + + pub async fn input(&self, event: Arc>) -> Result<()> { + let mut queue = self.matches(&**event); while let Some(entry) = queue.pop() { entry.get_handler()(event.clone()).await?; } diff --git a/crates/aionbot-core/src/lib.rs b/crates/aionbot-core/src/lib.rs index 38bc095..33d5b34 100644 --- a/crates/aionbot-core/src/lib.rs +++ b/crates/aionbot-core/src/lib.rs @@ -1,6 +1,7 @@ pub mod entry; pub mod event; pub mod handler; +pub mod plugin; pub mod prelude; pub mod queue; pub mod router; diff --git a/crates/aionbot-core/src/plugin.rs b/crates/aionbot-core/src/plugin.rs new file mode 100644 index 0000000..b0805f0 --- /dev/null +++ b/crates/aionbot-core/src/plugin.rs @@ -0,0 +1,29 @@ +use crate::entry::Entry; + +#[derive(Default)] +pub struct AionPlugin { + name: &'static str, + entries: Vec, +} + +impl AionPlugin { + pub fn new(name: &'static str) -> Self { + Self { + name, + ..Default::default() + } + } + + pub fn name(&self) -> &'static str { + self.name + } + + pub(crate) fn entries(&self) -> &[Entry] { + &self.entries + } + + pub fn invoke_handler(mut self, entries: Vec) -> Self { + self.entries.extend(entries); + self + } +} diff --git a/crates/aionbot-core/src/runtime.rs b/crates/aionbot-core/src/runtime.rs index 5e7f20d..33cebd1 100644 --- a/crates/aionbot-core/src/runtime.rs +++ b/crates/aionbot-core/src/runtime.rs @@ -1,9 +1,9 @@ -use std::sync::Arc; +use std::{cell::UnsafeCell, sync::Arc}; use anyhow::Result; use state::TypeMap; -use crate::{entry::Entry, event::Event, handler::Handler, types::SetupFn}; +use crate::{entry::Entry, event::Event, handler::Handler, plugin::AionPlugin, types::SetupFn}; #[derive(Default)] pub struct StateManager(pub(crate) TypeMap!(Send + Sync)); @@ -13,7 +13,7 @@ impl StateManager { StateManager(::new()) } - pub fn set(&mut self, state: T) { + pub fn set(&self, state: T) { self.0.set::(state); } @@ -31,7 +31,7 @@ impl StateManager { } pub struct Builder { - handler: Arc>, + handler: UnsafeCell, runtime: R, state: Arc, setup: Option>, @@ -45,13 +45,17 @@ where self.setup = Some(setup); } - pub fn invoke_handler(mut self, entries: Vec) -> Self { - self.handler = Arc::new(Some(Handler::new(entries))); + pub fn invoke_handler>(mut self, entries: E) -> Self { + self.handler.get_mut().extend(entries); self } + pub fn plugin(self, plugin: AionPlugin) -> Self { + self.invoke_handler(plugin.entries().to_vec()) + } + pub fn manage(self, state: T) -> Self { - self.state.0.set(state); + self.state.set(state); self } @@ -79,15 +83,9 @@ where self.runtime.prepare().await?; } RuntimeStatus::Event(event) => { - let handler = self.handler.clone(); + let handler = unsafe { self.handler.get().as_mut() }.unwrap(); tokio::spawn(async move { - if let Err(e) = handler - .as_ref() - .clone() - .unwrap() - .input(&Arc::new(event)) - .await - { + if let Err(e) = handler.input(Arc::new(event)).await { log::error!("Error handling event: {}", e); }; }); @@ -106,7 +104,7 @@ where let manager = Arc::new(StateManager::new()); let runtime = R::default().set_manager(manager.clone()); Self { - handler: Arc::new(None), + handler: UnsafeCell::new(Handler::empty()), runtime, state: Arc::clone(&manager), setup: None,