use std::collections::HashMap;
use std::sync::{Arc, Mutex, Once};
use bitvec::order::{Lsb0, Msb0};
use ctor::ctor;
use lazy_static::lazy_static;
#[cfg(any(feature = "tcp-client", feature = "ws-client"))]
use crate::client::prelude::versions::v1::r0x0001::HtmlFileResponse;
#[cfg(any(feature = "tcp-client", feature = "ws-client"))]
use crate::client::prelude::versions::v1::r0x0002::ErrorResponse;
#[cfg(any(feature = "tcp-client", feature = "ws-client"))]
use crate::client::prelude::versions::v1::r0x0003::ComponentNeedsResponse;
#[cfg(any(feature = "tcp-client", feature = "ws-client"))]
use crate::client::prelude::versions::v1::r0x0004::FullFyveResponse;
#[cfg(all(any(feature = "tcp-client", feature = "ws-client"), feature = "serde"))]
use crate::client::prelude::versions::v1::r0x0006::InteractionResponse;
use crate::protocol::managers::bits::prelude::BitReversible;
use crate::protocol::managers::event::EventDecoder;
#[cfg(any(feature = "tcp-server", feature = "ws-server"))]
use crate::protocol::server::versions::v1::r0x0000::ComponentNeedsRequest;
#[cfg(all(feature = "serde", any(feature = "tcp-server", feature = "ws-server")))]
use crate::protocol::server::versions::v1::r0x0005::InteractionRequest;
use crate::protocol::{args::Arg, managers::bits::decoder::BitDecoder};
pub type EventId = (u8, u16);
pub type EventFn<R> = fn(bit_decoder: BitDecoder<R>) -> Box<dyn EventDecoder<R>>;
pub type ListenerFn<R> = fn(event_decoder: Box<dyn EventDecoder<R>>) -> Box<[Arg]>;
pub struct EventRegistry<R: BitReversible> {
events: HashMap<EventId, EventFn<R>>,
listeners: HashMap<EventId, ListenerFn<R>>,
}
impl<R: BitReversible> EventRegistry<R> {
fn new() -> Self {
EventRegistry {
events: HashMap::new(),
listeners: HashMap::new(),
}
}
pub fn get_event(&self, event_id: EventId) -> Option<&EventFn<R>> {
self.events.get(&event_id)
}
pub fn get_listener(&self, event_id: EventId) -> Option<&ListenerFn<R>> {
self.listeners.get(&event_id)
}
pub fn add_event(&mut self, event_id: EventId, event_fn: EventFn<R>) {
self.events.insert(event_id, event_fn);
}
pub fn add_listener(&mut self, event_id: EventId, listener_fn: ListenerFn<R>) {
self.listeners.insert(event_id, listener_fn);
}
}
lazy_static! {
pub static ref EVENT_REGISTRY_MSB: Arc<Mutex<EventRegistry<Msb0>>> =
Arc::new(Mutex::new(EventRegistry::new()));
pub static ref EVENT_REGISTRY_LSB: Arc<Mutex<EventRegistry<Lsb0>>> =
Arc::new(Mutex::new(EventRegistry::new()));
}
static INIT: Once = Once::new();
#[ctor]
fn init() {
INIT.call_once(|| {
#[cfg(any(feature = "tcp-server", feature = "ws-server"))]
EVENT_REGISTRY_MSB
.lock()
.unwrap()
.add_event((1, 0x0000), |decoder| {
Box::new(ComponentNeedsRequest::new(decoder))
});
#[cfg(all(feature = "serde", any(feature = "tcp-server", feature = "ws-server")))]
EVENT_REGISTRY_MSB
.lock()
.unwrap()
.add_event((1, 0x0005), |decoder| {
Box::new(InteractionRequest::new(decoder))
});
#[cfg(any(feature = "tcp-client", feature = "ws-client"))]
EVENT_REGISTRY_MSB
.lock()
.unwrap()
.add_event((1, 0x0001), |decoder| {
Box::new(HtmlFileResponse::new(decoder))
});
#[cfg(any(feature = "tcp-client", feature = "ws-client"))]
EVENT_REGISTRY_MSB
.lock()
.unwrap()
.add_event((1, 0x0002), |decoder| Box::new(ErrorResponse::new(decoder)));
#[cfg(any(feature = "tcp-client", feature = "ws-client"))]
EVENT_REGISTRY_MSB
.lock()
.unwrap()
.add_event((1, 0x0003), |decoder| {
Box::new(ComponentNeedsResponse::new(decoder))
});
#[cfg(any(feature = "tcp-client", feature = "ws-client"))]
EVENT_REGISTRY_MSB
.lock()
.unwrap()
.add_event((1, 0x0004), |decoder| {
Box::new(FullFyveResponse::new(decoder))
});
#[cfg(all(any(feature = "tcp-client", feature = "ws-client"), feature = "serde"))]
EVENT_REGISTRY_MSB
.lock()
.unwrap()
.add_event((1, 0x0006), |decoder| {
Box::new(InteractionResponse::new(decoder))
});
})
}