1
0
Fork 0
mirror of https://codeberg.org/demostf/parser.git synced 2026-06-03 10:14:06 +02:00

game event write work

This commit is contained in:
Robin Appelman 2021-07-17 15:02:16 +02:00
commit 71f85bfe45
4 changed files with 1672 additions and 913 deletions

File diff suppressed because it is too large Load diff

View file

@ -225,10 +225,10 @@ pub fn generate_game_events(demo: Demo) -> TokenStream {
let span = Span::call_site(); let span = Span::call_site();
let imports = quote!( let imports = quote!(
use super::gamevent::{FromGameEventValue, GameEventDefinition, GameEventEntry, RawGameEvent}; use super::gamevent::{EventValue, GameEventDefinition, GameEventEntry, RawGameEvent};
use crate::demo::Stream; use crate::demo::Stream;
use crate::{ParseError, Result}; use crate::{ParseError, Result};
use bitbuffer::{BitRead, LittleEndian}; use bitbuffer::{BitRead, LittleEndian, BitWrite, BitWriteStream};
); );
let event_definitions = events.iter().map(|event| { let event_definitions = events.iter().map(|event| {
@ -260,7 +260,7 @@ pub fn generate_game_events(demo: Demo) -> TokenStream {
}; };
quote!( quote!(
#[derive(Debug)] #[derive(Debug, BitWrite)]
pub struct #name { pub struct #name {
#(#fields)* #(#fields)*
} }
@ -332,6 +332,15 @@ pub fn generate_game_events(demo: Demo) -> TokenStream {
} }
}); });
let write_events = events.iter().map(|event| {
let name = get_event_name(&event.name);
let variant_name = Ident::new(&name, span);
quote!(
GameEvent::#variant_name(event) => event.write(stream),
)
});
let sizes = events.iter().map(|event| { let sizes = events.iter().map(|event| {
let name = get_event_name(&event.name); let name = get_event_name(&event.name);
let struct_name = Ident::new(&format!("{}Event", name), span); let struct_name = Ident::new(&format!("{}Event", name), span);
@ -344,7 +353,7 @@ pub fn generate_game_events(demo: Demo) -> TokenStream {
quote!( quote!(
#imports #imports
fn read_value<'a, T: FromGameEventValue + BitRead<'a, LittleEndian> + Default>( fn read_value<'a, T: EventValue + BitRead<'a, LittleEndian> + Default>(
stream: &mut Stream<'a>, stream: &mut Stream<'a>,
entry: Option<&GameEventEntry>, entry: Option<&GameEventEntry>,
name: &'static str, name: &'static str,
@ -401,6 +410,12 @@ pub fn generate_game_events(demo: Demo) -> TokenStream {
GameEventType::Unknown => GameEvent::Unknown(RawGameEvent::read(stream, definition)?), GameEventType::Unknown => GameEvent::Unknown(RawGameEvent::read(stream, definition)?),
}) })
} }
pub fn write(&self, stream: &mut BitWriteStream<LittleEndian>) -> bitbuffer::Result<()> {
match &self {
#(#write_events)*
GameEvent::Unknown(raw) => raw.write(stream),
}
}
} }
pub fn get_sizes() -> fnv::FnvHashMap<&'static str, usize> { pub fn get_sizes() -> fnv::FnvHashMap<&'static str, usize> {

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
use bitbuffer::{BitRead, BitWrite}; use bitbuffer::{BitRead, BitWrite, BitWriteStream, LittleEndian};
use crate::{GameEventError, ParseError, Result, Stream}; use crate::{GameEventError, Result, Stream};
pub use super::gameevent_gen::{GameEvent, GameEventType}; pub use super::gameevent_gen::{GameEvent, GameEventType};
use crate::demo::handle_utf8_error; use crate::demo::handle_utf8_error;
@ -81,6 +81,20 @@ fn read_event_value(stream: &mut Stream, definition: &GameEventEntry) -> Result<
}) })
} }
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 { impl GameEventValue {
pub fn get_type(&self) -> GameEventValueType { pub fn get_type(&self) -> GameEventValueType {
match self { match self {
@ -95,138 +109,47 @@ impl GameEventValue {
} }
} }
pub trait FromGameEventValue: Sized { pub trait EventValue: Sized {
fn from_value(value: Option<GameEventValue>, name: &'static str) -> Result<Self>;
fn value_type() -> GameEventValueType; fn value_type() -> GameEventValueType;
} }
impl FromGameEventValue for String { impl EventValue for String {
fn from_value(value: Option<GameEventValue>, name: &'static str) -> Result<Self> {
match value {
Some(GameEventValue::String(val)) => Ok(val),
None => Ok(String::default()),
Some(value) => Err(ParseError::InvalidGameEvent {
expected_type: GameEventValueType::String,
name,
found_type: value.get_type(),
}),
}
}
fn value_type() -> GameEventValueType { fn value_type() -> GameEventValueType {
GameEventValueType::String GameEventValueType::String
} }
} }
impl FromGameEventValue for f32 { impl EventValue for f32 {
fn from_value(value: Option<GameEventValue>, name: &'static str) -> Result<Self> {
match value {
Some(GameEventValue::Float(val)) => Ok(val),
None => Ok(f32::default()),
Some(value) => Err(ParseError::InvalidGameEvent {
expected_type: GameEventValueType::Float,
name,
found_type: value.get_type(),
}),
}
}
fn value_type() -> GameEventValueType { fn value_type() -> GameEventValueType {
GameEventValueType::Float GameEventValueType::Float
} }
} }
impl FromGameEventValue for u32 { impl EventValue for u32 {
fn from_value(value: Option<GameEventValue>, name: &'static str) -> Result<Self> {
match value {
Some(GameEventValue::Long(val)) => Ok(val),
Some(GameEventValue::Short(val)) => Ok(val as u32),
Some(GameEventValue::Byte(val)) => Ok(val as u32),
None => Ok(u32::default()),
Some(value) => Err(ParseError::InvalidGameEvent {
expected_type: GameEventValueType::Long,
name,
found_type: value.get_type(),
}),
}
}
fn value_type() -> GameEventValueType { fn value_type() -> GameEventValueType {
GameEventValueType::Long GameEventValueType::Long
} }
} }
impl FromGameEventValue for u16 { impl EventValue for u16 {
fn from_value(value: Option<GameEventValue>, name: &'static str) -> Result<Self> {
match value {
Some(GameEventValue::Long(val)) => Ok(val as u16),
Some(GameEventValue::Short(val)) => Ok(val),
Some(GameEventValue::Byte(val)) => Ok(val as u16),
None => Ok(u16::default()),
Some(value) => Err(ParseError::InvalidGameEvent {
expected_type: GameEventValueType::Short,
name,
found_type: value.get_type(),
}),
}
}
fn value_type() -> GameEventValueType { fn value_type() -> GameEventValueType {
GameEventValueType::Short GameEventValueType::Short
} }
} }
impl FromGameEventValue for u8 { impl EventValue for u8 {
fn from_value(value: Option<GameEventValue>, name: &'static str) -> Result<Self> {
match value {
Some(GameEventValue::Long(val)) => Ok(val as u8),
Some(GameEventValue::Short(val)) => Ok(val as u8),
Some(GameEventValue::Byte(val)) => Ok(val),
None => Ok(u8::default()),
Some(value) => Err(ParseError::InvalidGameEvent {
expected_type: GameEventValueType::Byte,
name,
found_type: value.get_type(),
}),
}
}
fn value_type() -> GameEventValueType { fn value_type() -> GameEventValueType {
GameEventValueType::Byte GameEventValueType::Byte
} }
} }
impl FromGameEventValue for bool { impl EventValue for bool {
fn from_value(value: Option<GameEventValue>, name: &'static str) -> Result<Self> {
match value {
Some(GameEventValue::Boolean(val)) => Ok(val),
None => Ok(bool::default()),
Some(value) => Err(ParseError::InvalidGameEvent {
expected_type: GameEventValueType::Boolean,
name,
found_type: value.get_type(),
}),
}
}
fn value_type() -> GameEventValueType { fn value_type() -> GameEventValueType {
GameEventValueType::Boolean GameEventValueType::Boolean
} }
} }
impl FromGameEventValue for () { impl EventValue for () {
fn from_value(value: Option<GameEventValue>, name: &'static str) -> Result<Self> {
match value {
Some(GameEventValue::Local) | None => Ok(()),
Some(value) => Err(ParseError::InvalidGameEvent {
expected_type: GameEventValueType::Local,
name,
found_type: value.get_type(),
}),
}
}
fn value_type() -> GameEventValueType { fn value_type() -> GameEventValueType {
GameEventValueType::Local GameEventValueType::Local
} }
@ -252,6 +175,15 @@ impl RawGameEvent {
} }
} }
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 { pub trait FromRawGameEvent: Sized {
fn from_raw_event(values: Vec<GameEventValue>) -> Result<Self>; fn from_raw_event(values: Vec<GameEventValue>) -> Result<Self>;
} }