mirror of
https://codeberg.org/demostf/parser.git
synced 2026-06-04 02:24:12 +02:00
202 lines
5.8 KiB
Rust
202 lines
5.8 KiB
Rust
pub use super::gameevent_gen::{GameEvent, GameEventType};
|
|
use crate::demo::data::MaybeUtf8String;
|
|
use crate::demo::message::gameevent::GameEventTypeId;
|
|
use crate::{GameEventError, Result, Stream};
|
|
use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
|
|
use parse_display::Display;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::cmp::Ordering;
|
|
|
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct GameEventDefinition {
|
|
pub id: GameEventTypeId,
|
|
pub event_type: GameEventType,
|
|
pub entries: Vec<GameEventEntry>,
|
|
}
|
|
|
|
impl PartialEq<GameEventDefinition> for GameEventDefinition {
|
|
fn eq(&self, other: &Self) -> bool {
|
|
self.id.eq(&other.id)
|
|
}
|
|
}
|
|
|
|
impl Eq for GameEventDefinition {}
|
|
|
|
impl PartialOrd for GameEventDefinition {
|
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
|
Some(self.id.cmp(&other.id))
|
|
}
|
|
}
|
|
|
|
impl Ord for GameEventDefinition {
|
|
fn cmp(&self, other: &Self) -> Ordering {
|
|
self.id.cmp(&other.id)
|
|
}
|
|
}
|
|
|
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub struct GameEventEntry {
|
|
pub name: String,
|
|
pub kind: GameEventValueType,
|
|
}
|
|
|
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
|
#[derive(BitRead, BitWrite, Debug, Clone, Copy, PartialEq, Display, Serialize, Deserialize)]
|
|
#[discriminant_bits = 3]
|
|
pub enum GameEventValueType {
|
|
None = 0,
|
|
String = 1,
|
|
Float = 2,
|
|
Long = 3,
|
|
Short = 4,
|
|
Byte = 5,
|
|
Boolean = 6,
|
|
Local = 7,
|
|
}
|
|
|
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
|
|
pub enum GameEventValue {
|
|
String(MaybeUtf8String),
|
|
Float(f32),
|
|
Long(u32),
|
|
Short(u16),
|
|
Byte(u8),
|
|
Boolean(bool),
|
|
Local,
|
|
}
|
|
|
|
fn read_event_value(stream: &mut Stream, definition: &GameEventEntry) -> Result<GameEventValue> {
|
|
Ok(match definition.kind {
|
|
GameEventValueType::String => GameEventValue::String(stream.read()?),
|
|
GameEventValueType::Float => GameEventValue::Float(stream.read()?),
|
|
GameEventValueType::Long => GameEventValue::Long(stream.read()?),
|
|
GameEventValueType::Short => GameEventValue::Short(stream.read()?),
|
|
GameEventValueType::Byte => GameEventValue::Byte(stream.read()?),
|
|
GameEventValueType::Boolean => GameEventValue::Boolean(stream.read()?),
|
|
GameEventValueType::Local => GameEventValue::Local,
|
|
GameEventValueType::None => return Err(GameEventError::NoneValue.into()),
|
|
})
|
|
}
|
|
|
|
impl BitWrite<LittleEndian> for GameEventValue {
|
|
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> bitbuffer::Result<()> {
|
|
match self {
|
|
GameEventValue::String(value) => value.write(stream),
|
|
GameEventValue::Float(value) => value.write(stream),
|
|
GameEventValue::Long(value) => value.write(stream),
|
|
GameEventValue::Short(value) => value.write(stream),
|
|
GameEventValue::Byte(value) => value.write(stream),
|
|
GameEventValue::Boolean(value) => value.write(stream),
|
|
GameEventValue::Local => Ok(()),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl GameEventValue {
|
|
pub fn get_type(&self) -> GameEventValueType {
|
|
match self {
|
|
GameEventValue::String(_) => GameEventValueType::String,
|
|
GameEventValue::Float(_) => GameEventValueType::Float,
|
|
GameEventValue::Long(_) => GameEventValueType::Long,
|
|
GameEventValue::Short(_) => GameEventValueType::Short,
|
|
GameEventValue::Byte(_) => GameEventValueType::Byte,
|
|
GameEventValue::Boolean(_) => GameEventValueType::Boolean,
|
|
GameEventValue::Local => GameEventValueType::Local,
|
|
}
|
|
}
|
|
}
|
|
|
|
pub trait EventValue: Sized {
|
|
fn value_type() -> GameEventValueType;
|
|
}
|
|
|
|
impl EventValue for String {
|
|
fn value_type() -> GameEventValueType {
|
|
GameEventValueType::String
|
|
}
|
|
}
|
|
|
|
impl EventValue for MaybeUtf8String {
|
|
fn value_type() -> GameEventValueType {
|
|
GameEventValueType::String
|
|
}
|
|
}
|
|
|
|
impl EventValue for f32 {
|
|
fn value_type() -> GameEventValueType {
|
|
GameEventValueType::Float
|
|
}
|
|
}
|
|
|
|
impl EventValue for u32 {
|
|
fn value_type() -> GameEventValueType {
|
|
GameEventValueType::Long
|
|
}
|
|
}
|
|
|
|
impl EventValue for u16 {
|
|
fn value_type() -> GameEventValueType {
|
|
GameEventValueType::Short
|
|
}
|
|
}
|
|
|
|
impl EventValue for u8 {
|
|
fn value_type() -> GameEventValueType {
|
|
GameEventValueType::Byte
|
|
}
|
|
}
|
|
|
|
impl EventValue for bool {
|
|
fn value_type() -> GameEventValueType {
|
|
GameEventValueType::Boolean
|
|
}
|
|
}
|
|
|
|
impl EventValue for () {
|
|
fn value_type() -> GameEventValueType {
|
|
GameEventValueType::Local
|
|
}
|
|
}
|
|
|
|
#[cfg_attr(feature = "schema", derive(schemars::JsonSchema))]
|
|
#[derive(Debug, PartialEq, Serialize, Deserialize, Clone)]
|
|
pub struct RawGameEvent {
|
|
pub event_type: GameEventType,
|
|
pub values: Vec<GameEventValue>,
|
|
}
|
|
|
|
impl RawGameEvent {
|
|
pub fn read(stream: &mut Stream, definition: &GameEventDefinition) -> Result<Self> {
|
|
let mut values: Vec<GameEventValue> = Vec::with_capacity(definition.entries.len());
|
|
for entry in &definition.entries {
|
|
values.push(read_event_value(stream, entry)?);
|
|
}
|
|
|
|
Ok(RawGameEvent {
|
|
event_type: definition.event_type.clone(),
|
|
values,
|
|
})
|
|
}
|
|
}
|
|
|
|
impl BitWrite<LittleEndian> for RawGameEvent {
|
|
fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> bitbuffer::Result<()> {
|
|
for value in self.values.iter() {
|
|
value.write(stream)?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
pub trait FromRawGameEvent: Sized {
|
|
fn from_raw_event(values: Vec<GameEventValue>) -> Result<Self>;
|
|
}
|
|
|
|
impl<T: FromRawGameEvent> FromRawGameEvent for Box<T> {
|
|
fn from_raw_event(values: Vec<GameEventValue>) -> Result<Self> {
|
|
Ok(Box::new(T::from_raw_event(values)?))
|
|
}
|
|
}
|