1use crate::chat::ChatMessage;
5use crate::continent::Coord;
6use crate::player::PlayerId;
7use crate::report::ReportId;
8use crate::round::Round;
9use bytes::Bytes;
10use serde::{Deserialize, Serialize};
11use std::fmt;
12use strum::Display;
13use tokio::sync::broadcast::{Receiver, Sender, channel};
14
15pub type Listener = Receiver<(Bytes, EventTarget)>;
16
17#[derive(Clone)]
18pub(crate) struct Emitter {
19 sender: Sender<(Bytes, EventTarget)>,
20}
21
22impl Emitter {
23 fn new(capacity: usize) -> Self {
24 let (sender, _) = channel(capacity);
25 Self { sender }
26 }
27
28 pub(crate) fn emit(&self, event: Event, target: EventTarget) {
29 tracing::info!(?target, ?event);
30 let bytes = Bytes::from(event);
31 let _ = self.sender.send((bytes, target));
32 }
33
34 pub(crate) fn emit_to(&self, target: PlayerId, event: Event) {
35 self.emit(event, EventTarget::Player(target));
36 }
37
38 pub(crate) fn broadcast(&self, event: Event) {
39 self.emit(event, EventTarget::Broadcast);
40 }
41
42 pub(crate) fn subscribe(&self) -> Listener {
43 self.sender.subscribe()
44 }
45}
46
47impl Default for Emitter {
48 fn default() -> Self {
49 Self::new(100)
50 }
51}
52
53impl fmt::Debug for Emitter {
54 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
55 f.debug_struct("Emitter")
56 .field("sender", &self.sender.receiver_count())
57 .finish()
58 }
59}
60
61#[derive(Clone, Debug, Display, Deserialize, Serialize)]
62#[serde(tag = "kind", rename_all = "kebab-case")]
63#[strum(serialize_all = "kebab-case")]
64#[remain::sorted]
65pub enum Event {
66 ChatUpdated { message: ChatMessage },
68
69 CityUpdated { coord: Coord },
75
76 MilitaryUpdated { player: PlayerId },
80
81 PlayerUpdated { player: PlayerId },
83
84 PublicCityUpdated { coord: Coord },
92
93 Report { report: ReportId },
95
96 RoundUpdated { round: Round },
103}
104
105impl From<Event> for Bytes {
106 fn from(event: Event) -> Self {
107 serde_json::to_vec(&event)
108 .map(Bytes::from)
109 .unwrap()
110 }
111}
112
113impl From<Bytes> for Event {
114 fn from(bytes: Bytes) -> Self {
115 serde_json::from_slice(&bytes).unwrap()
116 }
117}
118
119#[derive(Clone, Debug)]
120pub enum EventTarget {
121 Broadcast,
122 Player(PlayerId),
123}