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 PartialEq<GameEventDefinition> for GameEventDefinition {
19 fn eq(&self, other: &Self) -> bool {
20 self.id.eq(&other.id)
21 }
22}
23
24impl Eq for GameEventDefinition {}
25
26impl PartialOrd for GameEventDefinition {
27 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
28 Some(self.id.cmp(&other.id))
29 }
30}
31
32impl Ord for GameEventDefinition {
33 fn cmp(&self, other: &Self) -> Ordering {
34 self.id.cmp(&other.id)
35 }
36}
37
38#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
39#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
40pub struct GameEventEntry {
41 pub name: String,
42 pub kind: GameEventValueType,
43}
44
45#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
46#[derive(BitRead, BitWrite, Debug, Clone, Copy, PartialEq, Display, Serialize, Deserialize)]
47#[discriminant_bits = 3]
48pub enum GameEventValueType {
49 None = 0,
50 String = 1,
51 Float = 2,
52 Long = 3,
53 Short = 4,
54 Byte = 5,
55 Boolean = 6,
56 Local = 7,
57}
58
59#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
60#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
61pub enum GameEventValue {
62 String(MaybeUtf8String),
63 Float(f32),
64 Long(u32),
65 Short(u16),
66 Byte(u8),
67 Boolean(bool),
68 Local,
69}
70
71fn read_event_value(stream: &mut Stream, definition: &GameEventEntry) -> Result<GameEventValue> {
72 Ok(match definition.kind {
73 GameEventValueType::String => GameEventValue::String(stream.read()?),
74 GameEventValueType::Float => GameEventValue::Float(stream.read()?),
75 GameEventValueType::Long => GameEventValue::Long(stream.read()?),
76 GameEventValueType::Short => GameEventValue::Short(stream.read()?),
77 GameEventValueType::Byte => GameEventValue::Byte(stream.read()?),
78 GameEventValueType::Boolean => GameEventValue::Boolean(stream.read()?),
79 GameEventValueType::Local => GameEventValue::Local,
80 GameEventValueType::None => return Err(GameEventError::NoneValue.into()),
81 })
82}
83
84impl BitWrite<LittleEndian> for GameEventValue {
85 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> bitbuffer::Result<()> {
86 match self {
87 GameEventValue::String(value) => value.write(stream),
88 GameEventValue::Float(value) => value.write(stream),
89 GameEventValue::Long(value) => value.write(stream),
90 GameEventValue::Short(value) => value.write(stream),
91 GameEventValue::Byte(value) => value.write(stream),
92 GameEventValue::Boolean(value) => value.write(stream),
93 GameEventValue::Local => Ok(()),
94 }
95 }
96}
97
98impl GameEventValue {
99 pub fn get_type(&self) -> GameEventValueType {
100 match self {
101 GameEventValue::String(_) => GameEventValueType::String,
102 GameEventValue::Float(_) => GameEventValueType::Float,
103 GameEventValue::Long(_) => GameEventValueType::Long,
104 GameEventValue::Short(_) => GameEventValueType::Short,
105 GameEventValue::Byte(_) => GameEventValueType::Byte,
106 GameEventValue::Boolean(_) => GameEventValueType::Boolean,
107 GameEventValue::Local => GameEventValueType::Local,
108 }
109 }
110}
111
112pub trait EventValue: Sized {
113 fn value_type() -> GameEventValueType;
114}
115
116impl EventValue for String {
117 fn value_type() -> GameEventValueType {
118 GameEventValueType::String
119 }
120}
121
122impl EventValue for MaybeUtf8String {
123 fn value_type() -> GameEventValueType {
124 GameEventValueType::String
125 }
126}
127
128impl EventValue for f32 {
129 fn value_type() -> GameEventValueType {
130 GameEventValueType::Float
131 }
132}
133
134impl EventValue for u32 {
135 fn value_type() -> GameEventValueType {
136 GameEventValueType::Long
137 }
138}
139
140impl EventValue for u16 {
141 fn value_type() -> GameEventValueType {
142 GameEventValueType::Short
143 }
144}
145
146impl EventValue for u8 {
147 fn value_type() -> GameEventValueType {
148 GameEventValueType::Byte
149 }
150}
151
152impl EventValue for bool {
153 fn value_type() -> GameEventValueType {
154 GameEventValueType::Boolean
155 }
156}
157
158impl EventValue for () {
159 fn value_type() -> GameEventValueType {
160 GameEventValueType::Local
161 }
162}
163
164#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
165#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
166pub struct RawGameEvent {
167 pub event_type: GameEventType,
168 pub values: Vec<GameEventValue>,
169}
170
171impl RawGameEvent {
172 pub fn read(stream: &mut Stream, definition: &GameEventDefinition) -> Result<Self> {
173 let mut values: Vec<GameEventValue> = Vec::with_capacity(definition.entries.len());
174 for entry in &definition.entries {
175 values.push(read_event_value(stream, entry)?);
176 }
177
178 Ok(RawGameEvent {
179 event_type: definition.event_type.clone(),
180 values,
181 })
182 }
183}
184
185impl BitWrite<LittleEndian> for RawGameEvent {
186 fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> bitbuffer::Result<()> {
187 for value in self.values.iter() {
188 value.write(stream)?;
189 }
190 Ok(())
191 }
192}
193
194pub trait FromRawGameEvent: Sized {
195 fn from_raw_event(values: Vec<GameEventValue>) -> Result<Self>;
196}
197
198impl<T: FromRawGameEvent> FromRawGameEvent for Box<T> {
199 fn from_raw_event(values: Vec<GameEventValue>) -> Result<Self> {
200 Ok(Box::new(T::from_raw_event(values)?))
201 }
202}