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