use parking_lot::{RawRwLock, RwLock, lock_api::RwLockReadGuard};
use std::{
any::TypeId,
collections::{HashMap, HashSet},
};
pub type ControllerMap = HashMap<Controller, HashSet<TypeId>>;
pub type ControllerIds = HashSet<TypeId>;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Controller {
Web,
SocketIo,
Grpc,
EventHandler,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum EventSource {
Memory,
}
pub trait ControllerSpec {
fn kind() -> Controller;
}
pub struct ControllerRegistry {
controllers: RwLock<HashMap<Controller, HashSet<TypeId>>>,
}
impl ControllerRegistry {
#[doc(hidden)]
pub fn new() -> Self {
Self {
controllers: RwLock::new(HashMap::new()),
}
}
pub fn register<C: ControllerSpec + 'static>(&self) {
self.controllers
.write()
.entry(C::kind())
.or_default()
.insert(TypeId::of::<C>());
}
#[doc(hidden)]
pub fn read(&self) -> RwLockReadGuard<'_, RawRwLock, HashMap<Controller, HashSet<TypeId>>> {
self.controllers.read()
}
#[doc(hidden)]
pub fn snapshot(&self) -> ControllerMap {
self.controllers.read().clone()
}
#[doc(hidden)]
pub fn get_by_kind(&self, kind: Controller) -> ControllerIds {
self.controllers
.read()
.get(&kind)
.cloned()
.unwrap_or(HashSet::new())
}
}
impl Default for ControllerRegistry {
fn default() -> Self {
Self::new()
}
}