1use crate::ability::ActivateAbility;
4use crate::actor::{AlterAbilities, RegenerateAbilities};
5use crate::battle::{BattleRules, EndBattle, Version};
6use crate::character::{AlterStatistics, RegenerateStatistics};
7use crate::creature::{ConvertCreature, CreateCreature, RemoveCreature};
8use crate::entropy::ResetEntropy;
9use crate::event::{
10 ClientEventPrototype, DummyEvent, Event, EventId, EventKind, EventWrapper,
11 VersionedEventWrapper,
12};
13use crate::fight::ApplyImpact;
14use crate::object::{CreateObject, RemoveObject};
15use crate::player::PlayerId;
16use crate::power::InvokePower;
17use crate::round::{EndRound, EndTurn, EnvironmentTurn, ResetRounds, StartTurn};
18use crate::space::{AlterSpace, MoveEntity, ResetSpace};
19use crate::status::{AlterStatuses, ClearStatus, InflictStatus};
20use crate::team::{
21 AlterPowers, ConcludeObjectives, CreateTeam, RegeneratePowers, RemoveTeam, ResetObjectives,
22 SetRelations,
23};
24use crate::user::{UserEventPackage, UserEventPacker};
25use serde::{Deserialize, Serialize};
26
27macro_rules! bad_cast {
29 () => {{
30 panic!("incorrect cast!")
31 }};
32}
33
34macro_rules! flat_event_boxed {
36 ($( $x:ident ),* $(,)?) => {
37 pub fn boxed(self) -> Box<dyn Event<R> + Send> {
39 match self {
41 $(FlatEvent::$x(flat) => {
42 Box::new(flat) as Box<dyn Event<R> + Send>
43 })*
44 FlatEvent::UserEventPackage(packer) => {
45 packer.boxed().unwrap_or_else(|err| {
46 panic!("{:?}", err)
47 })
48 }
49 }
50 }
51 }
52}
53
54macro_rules! flat_event_flattened {
56 ($( $x:ident ),* $(,)?) => {
57 pub fn flattened(event: Box<dyn Event<R> + Send>) -> FlatEvent<R> {
59 match event.kind() {
61 $(EventKind::$x => {
62 match event.as_any().downcast_ref::<$x<R>>() {
63 Some(event) => {
64 FlatEvent::$x(event.clone())
65 },
66 None => bad_cast!(),
67 }
68 })*
69 EventKind::UserEvent(_) => {
70 let package = UserEventPackage::<R>::flattened(event).unwrap_or_else(|err| {
71 panic!("{:?}", err)
72 });
73 FlatEvent::UserEventPackage(package)
74 }
75 }
76 }
77 }
78}
79
80macro_rules! flat_event {
82 ($( $x:ident, $ser:expr, $de:expr ),* $(,)?) => {
83 #[derive(Serialize, Deserialize)]
85 pub enum FlatEvent<R: BattleRules> {
86 $(#[allow(missing_docs)]
87 #[serde(bound(
88 serialize = $ser,
89 deserialize = $de
90 ))]
91 $x($x<R>),)*
92 #[allow(missing_docs)]
93 #[serde(bound(
94 serialize = "UserEventPackage<R>: Serialize",
95 deserialize = "UserEventPackage<R>: Deserialize<'de>"
96 ))]
97 UserEventPackage(UserEventPackage<R>),
98 }
99
100 impl<R: BattleRules + 'static> FlatEvent<R> {
101 flat_event_boxed! { $($x),* }
102
103 flat_event_flattened! { $($x),* }
104 }
105 };
106}
107
108flat_event! {
109 DummyEvent, "DummyEvent<R>: Serialize", "DummyEvent<R>: Deserialize<'de>",
110 CreateTeam, "CreateTeam<R>: Serialize", "CreateTeam<R>: Deserialize<'de>",
111 CreateCreature, "CreateCreature<R>: Serialize", "CreateCreature<R>: Deserialize<'de>",
112 CreateObject, "CreateObject<R>: Serialize", "CreateObject<R>: Deserialize<'de>",
113 MoveEntity, "MoveEntity<R>: Serialize", "MoveEntity<R>: Deserialize<'de>",
114 StartTurn, "StartTurn<R>: Serialize", "StartTurn<R>: Deserialize<'de>",
115 EndTurn, "EndTurn<R>: Serialize", "EndTurn<R>: Deserialize<'de>",
116 EndRound, "EndRound<R>: Serialize", "EndRound<R>: Deserialize<'de>",
117 EnvironmentTurn, "EnvironmentTurn<R>: Serialize", "EnvironmentTurn<R>: Deserialize<'de>",
118 ActivateAbility, "ActivateAbility<R>: Serialize", "ActivateAbility<R>: Deserialize<'de>",
119 InvokePower, "InvokePower<R>: Serialize", "InvokePower<R>: Deserialize<'de>",
120 ApplyImpact, "ApplyImpact<R>: Serialize", "ApplyImpact<R>: Deserialize<'de>",
121 AlterStatistics, "AlterStatistics<R>: Serialize", "AlterStatistics<R>: Deserialize<'de>",
122 AlterStatuses, "AlterStatuses<R>: Serialize", "AlterStatuses<R>: Deserialize<'de>",
123 AlterAbilities, "AlterAbilities<R>: Serialize", "AlterAbilities<R>: Deserialize<'de>",
124 AlterPowers, "AlterPowers<R>: Serialize", "AlterPowers<R>: Deserialize<'de>",
125 RegenerateStatistics, "RegenerateStatistics<R>: Serialize", "RegenerateStatistics<R>: Deserialize<'de>",
126 RegenerateAbilities, "RegenerateAbilities<R>: Serialize", "RegenerateAbilities<R>: Deserialize<'de>",
127 RegeneratePowers, "RegeneratePowers<R>: Serialize", "RegeneratePowers<R>: Deserialize<'de>",
128 InflictStatus, "InflictStatus<R>: Serialize", "InflictStatus<R>: Deserialize<'de>",
129 ClearStatus, "ClearStatus<R>: Serialize", "ClearStatus<R>: Deserialize<'de>",
130 ConvertCreature, "ConvertCreature<R>: Serialize", "ConvertCreature<R>: Deserialize<'de>",
131 SetRelations, "SetRelations<R>: Serialize", "SetRelations<R>: Deserialize<'de>",
132 ConcludeObjectives, "ConcludeObjectives<R>: Serialize", "ConcludeObjectives<R>: Deserialize<'de>",
133 RemoveCreature, "RemoveCreature<R>: Serialize", "RemoveCreature<R>: Deserialize<'de>",
134 RemoveObject, "RemoveObject<R>: Serialize", "RemoveObject<R>: Deserialize<'de>",
135 RemoveTeam, "RemoveTeam<R>: Serialize", "RemoveTeam<R>: Deserialize<'de>",
136 AlterSpace, "AlterSpace<R>: Serialize", "AlterSpace<R>: Deserialize<'de>",
137 ResetEntropy, "ResetEntropy<R>: Serialize", "ResetEntropy<R>: Deserialize<'de>",
138 ResetObjectives, "ResetObjectives<R>: Serialize", "ResetObjectives<R>: Deserialize<'de>",
139 ResetRounds, "ResetRounds<R>: Serialize", "ResetRounds<R>: Deserialize<'de>",
140 ResetSpace, "ResetSpace<R>: Serialize", "ResetSpace<R>: Deserialize<'de>",
141 EndBattle, "EndBattle<R>: Serialize", "EndBattle<R>: Deserialize<'de>",
142}
143
144#[derive(Serialize, Deserialize)]
147pub struct FlatVersionedEvent<R: BattleRules> {
148 id: EventId,
149 origin: Option<EventId>,
150
151 #[serde(bound(
152 serialize = "FlatEvent<R>: Serialize",
153 deserialize = "FlatEvent<R>: Deserialize<'de>"
154 ))]
155 event: FlatEvent<R>,
156
157 #[serde(bound(
158 serialize = "Version<R>: Serialize",
159 deserialize = "Version<R>: Deserialize<'de>"
160 ))]
161 version: Version<R>,
162}
163
164impl<R: BattleRules> FlatVersionedEvent<R> {
165 pub fn id(&self) -> EventId {
167 self.id
168 }
169
170 pub fn origin(&self) -> Option<EventId> {
172 self.origin
173 }
174
175 pub fn event(&self) -> &FlatEvent<R> {
177 &self.event
178 }
179
180 pub fn version(&self) -> &Version<R> {
182 &self.version
183 }
184}
185
186impl<R: BattleRules + 'static> From<VersionedEventWrapper<R>> for FlatVersionedEvent<R> {
187 fn from(event: VersionedEventWrapper<R>) -> Self {
188 Self {
189 id: event.wrapper().id(),
190 origin: event.wrapper().origin(),
191 event: FlatEvent::flattened(event.wrapper.event),
192 version: event.version,
193 }
194 }
195}
196
197impl<R: BattleRules + 'static> From<FlatVersionedEvent<R>> for VersionedEventWrapper<R> {
198 fn from(event: FlatVersionedEvent<R>) -> Self {
199 Self::new(
200 EventWrapper::new(event.id, event.origin, event.event.boxed()),
201 event.version,
202 )
203 }
204}
205
206#[derive(Serialize, Deserialize)]
209pub struct FlatClientEvent<R: BattleRules> {
210 origin: Option<EventId>,
211
212 #[serde(bound(
213 serialize = "FlatEvent<R>: Serialize",
214 deserialize = "FlatEvent<R>: Deserialize<'de>"
215 ))]
216 event: FlatEvent<R>,
217
218 #[serde(bound(
219 serialize = "Version<R>: Serialize",
220 deserialize = "Version<R>: Deserialize<'de>"
221 ))]
222 version: Version<R>,
223
224 player: Option<PlayerId>,
225}
226
227impl<R: BattleRules> FlatClientEvent<R> {
228 pub fn origin(&self) -> Option<EventId> {
230 self.origin
231 }
232
233 pub fn event(&self) -> &FlatEvent<R> {
235 &self.event
236 }
237
238 pub fn version(&self) -> &Version<R> {
240 &self.version
241 }
242
243 pub fn player(&self) -> Option<PlayerId> {
245 self.player
246 }
247}
248
249impl<R: BattleRules + 'static> From<ClientEventPrototype<R>> for FlatClientEvent<R> {
250 fn from(event: ClientEventPrototype<R>) -> Self {
251 let player = event.player();
252 Self {
253 origin: event.origin(),
254 event: FlatEvent::flattened(event.event),
255 version: event.version,
256 player,
257 }
258 }
259}
260
261impl<R: BattleRules + 'static> From<FlatClientEvent<R>> for ClientEventPrototype<R> {
262 fn from(event: FlatClientEvent<R>) -> Self {
263 Self::new(
264 event.origin,
265 event.event.boxed(),
266 event.version,
267 event.player,
268 )
269 }
270}