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

cache flat props

This commit is contained in:
Robin Appelman 2019-08-10 20:36:32 +02:00
commit 164f88a32a
4 changed files with 54 additions and 22 deletions

View file

@ -9,7 +9,7 @@ use std::fs;
use pretty_assertions::assert_eq;
use tf_demo_parser::{Demo, DemoParser, MatchState, MessageTypeAnalyser, MessageType, ParserState};
use tf_demo_parser::demo::packet::datatable::{SendTable, SendTableName};
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName};
use tf_demo_parser::demo::packet::stringtable::StringTableEntry;
use tf_demo_parser::demo::message::Message;
use tf_demo_parser::demo::sendprop::SendPropDefinition;
@ -20,7 +20,7 @@ use test::Bencher;
pub struct SendPropAnalyser;
impl MessageHandler for SendPropAnalyser {
type Output = Vec<SendTable>;
type Output = Vec<ParseSendTable>;
fn does_handle(message_type: MessageType) -> bool {
false
@ -31,7 +31,11 @@ impl MessageHandler for SendPropAnalyser {
fn handle_string_entry(&mut self, table: &String, _index: usize, entry: &StringTableEntry) {}
fn get_output(self, state: ParserState) -> Self::Output {
state.send_tables.into_iter().map(|(_k, v)| v).collect()
state.send_tables.into_iter().map(|(_k, v)| ParseSendTable {
name: v.name,
props: v.props,
needs_decoder: v.needs_decoder
}).collect()
}
}

View file

@ -5,6 +5,8 @@ use crate::{Parse, ParseError, ParserState, Result, Stream, ReadResult};
use std::fmt;
use serde::{Serialize, Deserialize};
use std::rc::Rc;
use std::cell::{Cell, RefCell};
use std::ops::Deref;
#[derive(BitRead, Debug)]
pub struct ServerClass {
@ -41,14 +43,13 @@ impl BitRead<LittleEndian> for SendTableName {
}
#[derive(Debug)]
pub struct SendTable {
pub struct ParseSendTable {
pub name: SendTableName,
pub props: Vec<SendPropDefinition>,
pub needs_decoder: bool,
pub flattened_props: Option<Vec<SendPropDefinition>>,
}
impl Parse for SendTable {
impl Parse for ParseSendTable {
fn parse(stream: &mut Stream, _state: &ParserState) -> Result<Self> {
let needs_decoder = stream.read()?;
let raw_name: String = stream.read()?;
@ -83,17 +84,16 @@ impl Parse for SendTable {
}
}
Ok(SendTable {
Ok(ParseSendTable {
name,
flattened_props: None,
needs_decoder,
props,
})
}
}
impl SendTable {
pub fn flatten_props<'a>(&'a self, tables: &'a [SendTable]) -> Vec<&'a SendPropDefinition> {
impl ParseSendTable {
pub fn flatten_props(&self, tables: &[ParseSendTable]) -> Vec<SendPropDefinition> {
let mut flat = Vec::new();
self.get_all_props(tables, &self.get_excludes(tables), &mut flat);
@ -108,10 +108,10 @@ impl SendTable {
}
}
flat
flat.into_iter().map(|prop| prop.clone()).collect()
}
fn get_excludes<'a>(&'a self, tables: &'a [SendTable]) -> Vec<Exclude<'a>> {
fn get_excludes<'a>(&'a self, tables: &'a [ParseSendTable]) -> Vec<Exclude<'a>> {
let mut excludes = Vec::new();
for prop in self.props.iter() {
@ -131,14 +131,14 @@ impl SendTable {
}
// TODO: below is a direct port from the js which is a direct port from C++ and not very optimal
fn get_all_props<'a>(&'a self, tables: &'a [SendTable], excludes: &[Exclude], props: &mut Vec<&'a SendPropDefinition>) {
fn get_all_props<'a>(&'a self, tables: &'a [ParseSendTable], excludes: &[Exclude], props: &mut Vec<&'a SendPropDefinition>) {
let mut local_props = Vec::new();
self.get_all_props_iterator_props(tables, excludes, &mut local_props, props);
props.extend_from_slice(&local_props);
}
fn get_all_props_iterator_props<'a>(&'a self, tables: &'a [SendTable], excludes: &[Exclude], local_props: &mut Vec<&'a SendPropDefinition>, props: &mut Vec<&'a SendPropDefinition>) {
fn get_all_props_iterator_props<'a>(&'a self, tables: &'a [ParseSendTable], excludes: &[Exclude], local_props: &mut Vec<&'a SendPropDefinition>, props: &mut Vec<&'a SendPropDefinition>) {
for prop in self.props.iter() {
if prop.is_exclude() {
continue;
@ -175,6 +175,14 @@ impl<'a> Exclude<'a> {
}
}
#[derive(Debug)]
pub struct SendTable {
pub name: SendTableName,
pub props: Vec<SendPropDefinition>,
pub needs_decoder: bool,
pub flattened_props: Vec<SendPropDefinition>,
}
#[derive(Debug)]
pub struct DataTablePacket {
pub tick: u32,
@ -188,12 +196,28 @@ impl Parse for DataTablePacket {
let len = stream.read_int::<usize>(32)?;
let mut packet_data = stream.read_bits(len * 8)?;
let mut tables = Vec::new();
let mut parse_tables = Vec::new();
while packet_data.read_bool()? {
let table = SendTable::parse(&mut packet_data, state)?;
tables.push(table);
let table = ParseSendTable::parse(&mut packet_data, state)?;
parse_tables.push(table);
}
let flat_props: Vec<_> = parse_tables.iter()
.map(|table| table.flatten_props(&parse_tables))
.collect();
let tables = parse_tables.into_iter()
.zip(flat_props.into_iter())
.map(|(parse_table, flat)| {
SendTable {
name: parse_table.name,
props: parse_table.props,
needs_decoder: parse_table.needs_decoder,
flattened_props: flat,
}
})
.collect();
// TODO linked tables?
let server_class_count = packet_data.read_int(16)?;

View file

@ -4,7 +4,7 @@ use enumflags2_derive::EnumFlags;
use crate::{ReadResult, Result, Stream, Parse};
use super::packet::datatable::SendTable;
use super::packet::datatable::ParseSendTable;
use super::vector::{Vector, VectorXY};
use crate::demo::packet::datatable::SendTableName;
@ -41,7 +41,7 @@ impl SendPropDefinition {
/// Get the refered data table
///
/// Note that this is not the owner table
pub fn get_data_table<'a>(&self, tables: &'a [SendTable]) -> Option<&'a SendTable> {
pub fn get_data_table<'a>(&self, tables: &'a [ParseSendTable]) -> Option<&'a ParseSendTable> {
self.table_name.as_ref()
.and_then(|name| tables.iter().find(|table| table.name == *name))
}

View file

@ -6,7 +6,7 @@ use std::fs;
use pretty_assertions::assert_eq;
use tf_demo_parser::{Demo, DemoParser, MatchState, MessageTypeAnalyser, MessageType, ParserState};
use tf_demo_parser::demo::packet::datatable::{SendTable, SendTableName};
use tf_demo_parser::demo::packet::datatable::{ParseSendTable, SendTableName};
use tf_demo_parser::demo::packet::stringtable::StringTableEntry;
use tf_demo_parser::demo::message::Message;
use tf_demo_parser::demo::sendprop::SendPropDefinition;
@ -16,7 +16,7 @@ use tf_demo_parser::demo::parser::MessageHandler;
pub struct SendPropAnalyser;
impl MessageHandler for SendPropAnalyser {
type Output = Vec<SendTable>;
type Output = Vec<ParseSendTable>;
fn does_handle(message_type: MessageType) -> bool {
false
@ -27,7 +27,11 @@ impl MessageHandler for SendPropAnalyser {
fn handle_string_entry(&mut self, table: &String, _index: usize, entry: &StringTableEntry) {}
fn get_output(self, state: ParserState) -> Self::Output {
state.send_tables.into_iter().map(|(_k, v)| v).collect()
state.send_tables.into_iter().map(|(_k, v)| ParseSendTable {
name: v.name,
props: v.props,
needs_decoder: v.needs_decoder
}).collect()
}
}