1pub use super::gameevent_gen::{GameEvent, GameEventType};
2use crate::demo::data::MaybeUtf8String;
3use crate::demo::message::gameevent::GameEventTypeId;
4use crate::{GameEventError, Result, Stream};
5use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
6use parse_display::Display;
7use serde::{Deserialize, Serialize};
8use std::cmp::Ordering;
9
10#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
11#[derive(Debug, Clone, Serialize, Deserialize)]
12pub struct GameEventDefinition {
13 pub id: GameEventTypeId,
14 pub event_type: GameEventType,
15 pub entries: Vec<GameEventEntry>,
16}
17
18impl GameEventDefinition {
19 pub fn get_entry(&self, name: &str) -> Option<&GameEventEntry> {
20 self.entries.iter().find(|entry| entry.name == name)
21 }
22}
23
24impl PartialEq<GameEventDefinition> for GameEventDefinition {
25 fn eq(&self, other: &Self) -> bool {
26 self.id.eq(&other.id)
27 }
28}
29
30impl Eq for GameEventDefinition {}
31
32impl PartialOrd for GameEventDefinition {
33 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
34 Some(self.id.cmp(&other.id))
35 }
36}
37
38impl Ord for GameEventDefinition {
39 fn cmp(&self, other: &Self) -> Ordering {
40 self.id.cmp(&other.id)
41 }
42}
43
44#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
45#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
46pub struct GameEventEntry {
47 pub name: String,
48 pub kind: GameEventValueType,
49}
50
51#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
52#[derive(BitRead, BitWrite, Debug, Clone, Copy, PartialEq, Display, Serialize, Deserialize)]
53#[discriminant_bits = 3]
54pub enum GameEventValueType {
55 None = 0,
56 String = 1,
57 Float = 2,
58 Long = 3,
59 Short = 4,
60 Byte = 5,
61 Boolean = 6,
62 Local = 7,
63}
64
65impl GameEventValueType {
66 pub fn default_value(&self) -> GameEventValue {
67 match self {
68 GameEventValueType::None => GameEventValue::Local,
69 GameEventValueType::String => GameEventValue::String(Default::default()),
70 GameEventValueType::Float => GameEventValue::Float(Default::default()),
71 GameEventValueType::Long => GameEventValue::Long(Default::default()),
72 GameEventValueType::Short => GameEventValue::Short(Default::default()),
73 GameEventValueType::Byte => GameEventValue::Byte(Default::default()),
74 GameEventValueType::Boolean => GameEventValue::Boolean(Default::default()),
75 GameEventValueType::Local => GameEventValue::Local,
76 }
77 }
78}
79
80#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
81#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
82pub enum GameEventValue {
83 String(MaybeUtf8String),
84 Float(f32),
85 Long(u32),
86 Short(u16),
87 Byte(u8),
88 Boolean(bool),
89 Local,
90}
91
92impl From<MaybeUtf8String> for GameEventValue {
93 fn from(value: MaybeUtf8String) -> Self {
94 GameEventValue::String(value)
95 }
96}
97
98impl From<f32> for GameEventValue {
99 fn from(value: f32) -> Self {
100 GameEventValue::Float(value)
101 }
102}
103
104impl From<u32> for GameEventValue {
105 fn from(value: u32) -> Self {
106 GameEventValue::Long(value)
107 }
108}
109
110impl From<u16> for GameEventValue {
111 fn from(value: u16) -> Self {
112 GameEventValue::Short(value)
113 }
114}
115
116impl From<u8> for GameEventValue {
117 fn from(value: u8) -> Self {
118 GameEventValue::Byte(value)
119 }
120}
121
122impl From<bool> for GameEventValue {
123 fn from(value: bool) -> Self {
124 GameEventValue::Boolean(value)
125 }
126}
127
128fn read_event_value(stream: &mut Stream, definition: &GameEventEntry) -> Result<GameEventValue> {
129 Ok(match definition.kind {
130 GameEventValueType::String => GameEventValue::String(stream.read()?),
131 GameEventValueType::Float => GameEventValue::Float(stream.read()?),
132 GameEventValueType::Long => GameEventValue::Long(stream.read()?),
133 GameEventValueType::Short => GameEventValue::Short(stream.read()?),
134 GameEventValueType::Byte => GameEventValue::Byte(stream.read()?),
135 GameEventValueType::Boolean => GameEventValue::Boolean(stream.read()?),
136 GameEventValueType::Local => GameEventValue::Local,
137 GameEventValueType::None => return Err(GameEventError::NoneValue.into()),
138 })
139}
140
141impl BitWrite<LittleEndian> for GameEventValue {
142 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> bitbuffer::Result<()> {
143 match self {
144 GameEventValue::String(value) => value.write(stream),
145 GameEventValue::Float(value) => value.write(stream),
146 GameEventValue::Long(value) => value.write(stream),
147 GameEventValue::Short(value) => value.write(stream),
148 GameEventValue::Byte(value) => value.write(stream),
149 GameEventValue::Boolean(value) => value.write(stream),
150 GameEventValue::Local => Ok(()),
151 }
152 }
153}
154
155impl GameEventValue {
156 pub fn get_type(&self) -> GameEventValueType {
157 match self {
158 GameEventValue::String(_) => GameEventValueType::String,
159 GameEventValue::Float(_) => GameEventValueType::Float,
160 GameEventValue::Long(_) => GameEventValueType::Long,
161 GameEventValue::Short(_) => GameEventValueType::Short,
162 GameEventValue::Byte(_) => GameEventValueType::Byte,
163 GameEventValue::Boolean(_) => GameEventValueType::Boolean,
164 GameEventValue::Local => GameEventValueType::Local,
165 }
166 }
167}
168
169pub trait EventValue: Sized {
170 fn value_type() -> GameEventValueType;
171}
172
173impl EventValue for String {
174 fn value_type() -> GameEventValueType {
175 GameEventValueType::String
176 }
177}
178
179impl EventValue for MaybeUtf8String {
180 fn value_type() -> GameEventValueType {
181 GameEventValueType::String
182 }
183}
184
185impl EventValue for f32 {
186 fn value_type() -> GameEventValueType {
187 GameEventValueType::Float
188 }
189}
190
191impl EventValue for u32 {
192 fn value_type() -> GameEventValueType {
193 GameEventValueType::Long
194 }
195}
196
197impl EventValue for u16 {
198 fn value_type() -> GameEventValueType {
199 GameEventValueType::Short
200 }
201}
202
203impl EventValue for u8 {
204 fn value_type() -> GameEventValueType {
205 GameEventValueType::Byte
206 }
207}
208
209impl EventValue for bool {
210 fn value_type() -> GameEventValueType {
211 GameEventValueType::Boolean
212 }
213}
214
215impl EventValue for () {
216 fn value_type() -> GameEventValueType {
217 GameEventValueType::Local
218 }
219}
220
221#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
222#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
223pub struct RawGameEvent {
224 pub event_type: GameEventType,
225 pub values: Vec<GameEventValue>,
226}
227
228impl RawGameEvent {
229 pub fn read(stream: &mut Stream, definition: &GameEventDefinition) -> Result<Self> {
230 let mut values: Vec<GameEventValue> = Vec::with_capacity(definition.entries.len());
231 for entry in &definition.entries {
232 values.push(read_event_value(stream, entry)?);
233 }
234
235 Ok(RawGameEvent {
236 event_type: definition.event_type.clone(),
237 values,
238 })
239 }
240}
241
242impl BitWrite<LittleEndian> for RawGameEvent {
243 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> bitbuffer::Result<()> {
244 for value in self.values.iter() {
245 value.write(stream)?;
246 }
247 Ok(())
248 }
249}
250
251pub trait FromRawGameEvent: Sized {
252 fn from_raw_event(values: Vec<GameEventValue>) -> Result<Self>;
253}
254
255impl<T: FromRawGameEvent> FromRawGameEvent for Box<T> {
256 fn from_raw_event(values: Vec<GameEventValue>) -> Result<Self> {
257 Ok(Box::new(T::from_raw_event(values)?))
258 }
259}