use std::collections::HashMap;
use polariton::operation::{ParameterTable, Event as EventData};
use super::{Event, EventCode};
pub struct EventsHandler<U: Send + Sync, C: Send + Sync> {
event_map: HashMap<u8, Box<dyn Event<C, User=U>>>,
}
impl <U: Send + Sync, C: Send + Sync + Clone + std::fmt::Debug + 'static> EventsHandler<U, C> {
pub fn new() -> Self {
Self {
event_map: Default::default(),
}
}
pub fn add<E: Event<C, User=U> + EventCode + 'static>(mut self, event: E) -> Self {
self.insert_handler(E::event_code(), Box::new(event));
self
}
fn insert_handler(&mut self, code: u8, handler: Box<dyn Event<C, User=U>>) {
if self.event_map.insert(code, handler).is_some() {
log::warn!("Replacing event handler for code {}", code);
}
}
fn try_pass_to_handler(&self, code: u8, params: ParameterTable<C>, user: &U) {
if let Some(handler) = self.event_map.get(&code) {
handler.handle(params, user);
} else {
#[cfg(debug_assertions)]
panic!("No handler for event code {}, pls fix!! params: {:?}", code, params.clone().to_dict());
#[cfg(not(debug_assertions))]
{
log::warn!("No handler for event code {}", code);
log::debug!("Unhandled event code {}, params {:?}", code, params.clone().to_dict());
}
}
}
#[cfg(feature = "async")]
async fn try_pass_to_handler_async(&self, code: u8, params: ParameterTable<C>, user: &U) {
if let Some(handler) = self.event_map.get(&code) {
handler.handle_async(params, user).await;
} else {
#[cfg(debug_assertions)]
panic!("No handler for event code {}, pls fix!! params: {:?}", code, params.clone().to_dict());
#[cfg(not(debug_assertions))]
{
log::warn!("No handler for event code {}", code);
log::debug!("Unhandled event code {}, params {:?}", code, params.clone().to_dict());
}
}
}
pub fn handle_event(&self, user: &U, req: EventData<C>) {
self.try_pass_to_handler(req.code, req.params, user);
}
#[cfg(feature = "async")]
pub async fn handle_event_async(&self, user: &U, req: EventData<C>) {
self.try_pass_to_handler_async(req.code, req.params, user).await;
}
}