Skip to content

Commit

Permalink
feat(plugin): support runtime plugins (#19)
Browse files Browse the repository at this point in the history
* feat(plugin): support runtime plugins

* fix: rust fmt
  • Loading branch information
fu050409 authored Oct 27, 2024
1 parent cb558fa commit c2cbbe5
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 23 deletions.
5 changes: 1 addition & 4 deletions crates/aionbot-core/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Box<dyn Router>>,
Expand Down
2 changes: 1 addition & 1 deletion crates/aionbot-core/src/event.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions crates/aionbot-core/src/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,12 @@ impl Handler {
Self { entries: vec![] }
}

pub async fn input(&self, event: &Arc<Box<dyn Event>>) -> Result<()> {
let mut queue = self.matches(&***event);
pub fn extend<E: IntoIterator<Item = Entry>>(&mut self, entries: E) {
self.entries.extend(entries);
}

pub async fn input(&self, event: Arc<Box<dyn Event>>) -> Result<()> {
let mut queue = self.matches(&**event);
while let Some(entry) = queue.pop() {
entry.get_handler()(event.clone()).await?;
}
Expand Down
1 change: 1 addition & 0 deletions crates/aionbot-core/src/lib.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
29 changes: 29 additions & 0 deletions crates/aionbot-core/src/plugin.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use crate::entry::Entry;

#[derive(Default)]
pub struct AionPlugin {
name: &'static str,
entries: Vec<Entry>,
}

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<Entry>) -> Self {
self.entries.extend(entries);
self
}
}
30 changes: 14 additions & 16 deletions crates/aionbot-core/src/runtime.rs
Original file line number Diff line number Diff line change
@@ -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));
Expand All @@ -13,7 +13,7 @@ impl StateManager {
StateManager(<TypeMap![Send + Sync]>::new())
}

pub fn set<T: Send + Sync + 'static>(&mut self, state: T) {
pub fn set<T: Send + Sync + 'static>(&self, state: T) {
self.0.set::<T>(state);
}

Expand All @@ -31,7 +31,7 @@ impl StateManager {
}

pub struct Builder<R: Runtime + Default> {
handler: Arc<Option<Handler>>,
handler: UnsafeCell<Handler>,
runtime: R,
state: Arc<StateManager>,
setup: Option<SetupFn<R>>,
Expand All @@ -45,13 +45,17 @@ where
self.setup = Some(setup);
}

pub fn invoke_handler(mut self, entries: Vec<Entry>) -> Self {
self.handler = Arc::new(Some(Handler::new(entries)));
pub fn invoke_handler<E: IntoIterator<Item = Entry>>(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<T: Send + Sync + 'static>(self, state: T) -> Self {
self.state.0.set(state);
self.state.set(state);
self
}

Expand Down Expand Up @@ -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);
};
});
Expand All @@ -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,
Expand Down

0 comments on commit c2cbbe5

Please sign in to comment.