use crate::{Context, EventExt, EventExtLayer, EventOnceExt, EventOnceExtLayer, EventSchedule};
use std::fmt::Debug;
use std::future::Future;
use wd_tools::AsBytes;
#[derive(Debug, Clone, Default)]
pub struct EventEngine {
schedule: EventSchedule,
}
impl EventEngine {
pub fn get_schedule(&self) -> EventSchedule {
self.schedule.clone()
}
pub async fn register_event<T, I, E>(&self, trigger: T, event: E)
where
T: AsBytes,
I: Debug + Sync + Send + 'static,
E: EventExt<I> + Send + 'static,
{
let trigger = trigger.as_byte();
let event_handle = EventExtLayer::<I, E>::new(event);
self.schedule
.raw_register_event(trigger.to_vec(), event_handle)
.await;
}
pub fn register_event_once<T, I, E>(&self, trigger: T, event: E)
where
T: AsBytes,
I: Debug + Sync + Send + 'static,
E: EventOnceExt<I> + Send + 'static,
{
let trigger = trigger.as_byte();
let event_handle = EventOnceExtLayer::<I, E>::new(event);
self.schedule
.raw_register_once_event(trigger.to_vec(), event_handle);
}
pub async fn invoke<T: AsBytes, V: Debug + Sync + Send + 'static>(
&self,
trigger: T,
input: V,
) -> anyhow::Result<Context> {
let trigger = trigger.as_byte();
let mut ctx = Context::new(input, trigger, &self.schedule).await;
ctx.raw_next().await?;
Ok(ctx)
}
pub fn launch<T: AsBytes + Send + 'static, V: Debug + Sync + Send + 'static>(
&self,
trigger: T,
input: V,
) {
let this = self.clone();
tokio::spawn(async move {
if let Err(e) = this.invoke(trigger, input).await {
wd_log::log_error_ln!("[WD_EVENT::launch] error:{}", e);
}
});
}
pub fn launch_fn<T: AsBytes + Send + 'static, V: Debug + Sync + Send + 'static>(
&self,
trigger: T,
input: V,
over_fn: impl FnOnce(Context) + Send + 'static,
) {
let this = self.clone();
tokio::spawn(async move {
match this.invoke(trigger, input).await {
Ok(ctx) => over_fn(ctx),
Err(e) => {
wd_log::log_error_ln!("[WD_EVENT::launch] error:{}", e);
}
}
});
}
pub fn launch_fut<
T: AsBytes + Send + 'static,
V: Debug + Sync + Send + 'static,
F: Future<Output = ()> + Send + 'static,
>(
&self,
trigger: T,
input: V,
over_fn: impl FnOnce(Context) -> F + Send + 'static,
) {
let this = self.clone();
tokio::spawn(async move {
match this.invoke(trigger, input).await {
Ok(ctx) => over_fn(ctx).await,
Err(e) => {
wd_log::log_error_ln!("[WD_EVENT::launch] error:{}", e);
}
}
});
}
}