use std::sync::Arc;
use tokio::sync::{Mutex, broadcast};
pub use gromnie_events::{
ClientStateEvent, EventContext, EventEnvelope, EventSource, EventType, ScriptEventType,
SystemEvent,
};
#[derive(Debug, Clone)]
pub struct EventSender {
sender: broadcast::Sender<EventEnvelope>,
client_id: u32,
}
impl EventSender {
pub fn new(sender: broadcast::Sender<EventEnvelope>, client_id: u32) -> Self {
Self { sender, client_id }
}
pub fn publish(&self, envelope: EventEnvelope) {
let _ = self.sender.send(envelope);
}
pub fn client_id(&self) -> u32 {
self.client_id
}
}
#[derive(Debug, Clone)]
pub struct EventBus {
sender: broadcast::Sender<EventEnvelope>,
#[allow(dead_code)]
global_sequence_counter: Arc<Mutex<u64>>,
}
impl EventBus {
pub fn new(capacity: usize) -> (Self, broadcast::Receiver<EventEnvelope>) {
let (sender, receiver) = broadcast::channel(capacity);
let bus = EventBus {
sender: sender.clone(),
global_sequence_counter: Arc::new(Mutex::new(0)),
};
(bus, receiver)
}
pub fn create_sender(&self, client_id: u32) -> EventSender {
EventSender::new(self.sender.clone(), client_id)
}
pub fn subscribe(&self) -> broadcast::Receiver<EventEnvelope> {
self.sender.subscribe()
}
pub fn subscriber_count(&self) -> usize {
self.sender.receiver_count()
}
}
#[derive(Debug, Clone)]
pub enum TuiEvent {
Protocol(gromnie_events::ProtocolEvent),
System(SystemEvent),
State(ClientStateEvent),
}
impl From<gromnie_events::ProtocolEvent> for TuiEvent {
fn from(event: gromnie_events::ProtocolEvent) -> Self {
TuiEvent::Protocol(event)
}
}
impl From<SystemEvent> for TuiEvent {
fn from(event: SystemEvent) -> Self {
TuiEvent::System(event)
}
}
impl From<ClientStateEvent> for TuiEvent {
fn from(event: ClientStateEvent) -> Self {
TuiEvent::State(event)
}
}
pub trait EventHandler: Send + 'static {
fn handle_event(&mut self, envelope: EventEnvelope);
}
pub struct LoggingEventHandler;
impl EventHandler for LoggingEventHandler {
fn handle_event(&mut self, envelope: EventEnvelope) {
match envelope.event {
EventType::Protocol(protocol_event) => {
tracing::debug!(target: "events", "Protocol Event: {:?}", protocol_event);
}
EventType::State(state_event) => {
tracing::info!(target: "events", "State Event: {:?}", state_event);
}
EventType::System(system_event) => {
tracing::info!(target: "events", "System Event: {:?}", system_event);
}
}
}
}