use std::sync::Arc;
use tokio::sync::mpsc;
use crate::event_bus::{EventContext, EventEnvelope, EventSource, EventType, SystemEvent};
use gromnie_events::{ClientEvent, ClientSystemEvent};
pub struct EventWrapper {
client_id: u32,
sequence_counter: u64,
event_bus: Arc<crate::event_bus::EventBus>,
}
impl EventWrapper {
pub fn new(client_id: u32, event_bus: Arc<crate::event_bus::EventBus>) -> Self {
Self {
client_id,
sequence_counter: 0,
event_bus,
}
}
pub async fn run(mut self, mut raw_rx: mpsc::Receiver<ClientEvent>) {
let sender = self.event_bus.create_sender(self.client_id);
tracing::info!(target: "event_wrapper", "EventWrapper started for client {}", self.client_id);
while let Some(raw_event) = raw_rx.recv().await {
tracing::debug!(target: "event_wrapper", "EventWrapper received ClientEvent: {:?}", std::mem::discriminant(&raw_event));
let envelope = self.wrap_event(raw_event);
tracing::debug!(target: "event_wrapper", "EventWrapper publishing envelope: {:?}", std::mem::discriminant(&envelope.event));
sender.publish(envelope);
self.sequence_counter += 1;
}
tracing::warn!(target: "event_wrapper", "EventWrapper stopped - no more events");
}
fn wrap_event(&mut self, raw: ClientEvent) -> EventEnvelope {
let source = self.determine_source(&raw);
let context = EventContext::new(self.client_id, self.sequence_counter);
let event = match raw {
ClientEvent::Protocol(protocol) => EventType::Protocol(protocol),
ClientEvent::State(state) => EventType::State(state),
ClientEvent::System(sys) => EventType::System(self.convert_system_event(sys)),
};
EventEnvelope::new(event, context, source)
}
fn determine_source(&self, raw: &ClientEvent) -> EventSource {
match raw {
ClientEvent::Protocol(_) => EventSource::Network,
ClientEvent::State(_) => EventSource::ClientInternal,
ClientEvent::System(_) => EventSource::System,
}
}
fn convert_system_event(&self, sys: ClientSystemEvent) -> SystemEvent {
match sys {
ClientSystemEvent::AuthenticationSucceeded => SystemEvent::AuthenticationSucceeded {
client_id: self.client_id,
},
ClientSystemEvent::AuthenticationFailed { reason } => {
SystemEvent::AuthenticationFailed {
client_id: self.client_id,
reason,
}
}
ClientSystemEvent::ConnectingStarted => SystemEvent::ConnectingStarted {
client_id: self.client_id,
},
ClientSystemEvent::ConnectingProgress { progress } => SystemEvent::ConnectingProgress {
client_id: self.client_id,
progress,
},
ClientSystemEvent::ConnectingDone => SystemEvent::ConnectingDone {
client_id: self.client_id,
},
ClientSystemEvent::UpdatingStarted => SystemEvent::UpdatingStarted {
client_id: self.client_id,
},
ClientSystemEvent::UpdatingProgress { progress } => SystemEvent::UpdatingProgress {
client_id: self.client_id,
progress,
},
ClientSystemEvent::UpdatingDone => SystemEvent::UpdatingDone {
client_id: self.client_id,
},
ClientSystemEvent::LoginSucceeded {
character_id,
character_name,
} => SystemEvent::LoginSucceeded {
character_id,
character_name,
},
ClientSystemEvent::Disconnected {
will_reconnect,
reconnect_attempt,
delay_secs,
} => SystemEvent::Disconnected {
client_id: self.client_id,
will_reconnect,
reconnect_attempt,
delay_secs,
},
ClientSystemEvent::Reconnecting {
attempt,
delay_secs,
} => SystemEvent::Reconnecting {
client_id: self.client_id,
attempt,
delay_secs,
},
}
}
}