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

normalize prop definitions during flatening

This commit is contained in:
Robin Appelman 2021-02-13 16:39:11 +01:00
commit 0a34318c65
5 changed files with 98 additions and 72 deletions

View file

@ -10,6 +10,7 @@ use serde::{Deserialize, Serialize};
use std::cmp::min;
use std::convert::TryFrom;
use std::rc::Rc;
#[derive(BitRead, Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, Display, FromStr)]
@ -121,14 +122,14 @@ impl ParseSendTable {
}
impl ParseSendTable {
pub fn flatten_props(&self, tables: &[ParseSendTable]) -> Vec<RawSendPropDefinition> {
pub fn flatten_props(&self, tables: &[ParseSendTable]) -> Result<Vec<SendPropDefinition>> {
let mut flat = Vec::with_capacity(32);
self.get_all_props(tables, &self.get_excludes(tables), &mut flat);
self.get_all_props(tables, &self.get_excludes(tables), &mut flat)?;
// sort often changed props before the others
let mut start = 0;
for i in 0..flat.len() {
if flat[i].flags.contains(SendPropFlag::ChangesOften) {
if flat[i].changes_often {
if i != start {
flat.swap(i, start);
}
@ -136,7 +137,7 @@ impl ParseSendTable {
}
}
flat
Ok(flat)
}
fn get_excludes<'a>(&'a self, tables: &'a [ParseSendTable]) -> Vec<SendPropIdentifier> {
@ -161,36 +162,40 @@ impl ParseSendTable {
&self,
tables: &[ParseSendTable],
excludes: &[SendPropIdentifier],
props: &mut Vec<RawSendPropDefinition>,
) {
props: &mut Vec<SendPropDefinition>,
) -> Result<()> {
let mut local_props = Vec::new();
self.get_all_props_iterator_props(tables, excludes, &mut local_props, props);
self.get_all_props_iterator_props(tables, excludes, &mut local_props, props)?;
props.extend_from_slice(&local_props);
Ok(())
}
fn get_all_props_iterator_props(
&self,
tables: &[ParseSendTable],
excludes: &[SendPropIdentifier],
local_props: &mut Vec<RawSendPropDefinition>,
props: &mut Vec<RawSendPropDefinition>,
) {
local_props: &mut Vec<SendPropDefinition>,
props: &mut Vec<SendPropDefinition>,
) -> Result<()> {
self.props
.iter()
.filter(|prop| !prop.is_exclude())
.filter(|prop| !excludes.iter().any(|exclude| *exclude == prop.identifier()))
.for_each(|prop| {
.map(|prop| {
if let Some(table) = prop.get_data_table(tables) {
if prop.flags.contains(SendPropFlag::Collapsible) {
table.get_all_props_iterator_props(tables, excludes, local_props, props);
table.get_all_props_iterator_props(tables, excludes, local_props, props)?;
} else {
table.get_all_props(tables, excludes, props);
table.get_all_props(tables, excludes, props)?;
}
} else {
local_props.push(prop.clone());
local_props.push(SendPropDefinition::try_from(prop)?);
}
Ok(())
})
.collect::<Result<()>>()?;
Ok(())
}
}
@ -198,6 +203,7 @@ impl ParseSendTable {
pub struct SendTable {
pub name: SendTableName,
pub needs_decoder: bool,
pub raw_props: Vec<RawSendPropDefinition>,
pub flattened_props: Vec<SendPropDefinition>,
}

View file

@ -11,11 +11,10 @@ use crate::demo::packet::datatable::{
};
use crate::demo::packet::stringtable::StringTableEntry;
use crate::demo::sendprop::{SendProp, SendPropDefinition};
use crate::demo::sendprop::SendProp;
use crate::nullhasher::NullHasherBuilder;
use crate::{Result, Stream};
use std::cell::RefCell;
use std::convert::TryFrom;
#[derive(Default, Clone)]
pub struct DemoMeta {
@ -106,25 +105,23 @@ impl<'a> ParserState {
let flat_props: Vec<_> = parse_tables
.iter()
.map(|table| table.flatten_props(&parse_tables))
.collect();
.collect::<Result<Vec<_>>>()?;
let mut send_tables: FnvHashMap<SendTableName, SendTable> = parse_tables
.into_iter()
.zip(flat_props.into_iter())
.map(|(parse_table, flat)| {
Ok((
(
parse_table.name.clone(),
SendTable {
name: parse_table.name,
needs_decoder: parse_table.needs_decoder,
flattened_props: flat
.into_iter()
.map(|raw| SendPropDefinition::try_from(raw))
.collect::<std::result::Result<Vec<_>, _>>()?,
raw_props: parse_table.props,
flattened_props: flat,
},
))
)
})
.collect::<Result<_>>()?;
.collect();
self.server_classes = server_classes;

View file

@ -16,6 +16,7 @@ use std::convert::{TryFrom, TryInto};
use fnv::FnvHasher;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::num::NonZeroU64;
use std::rc::Rc;
#[derive(
@ -347,16 +348,18 @@ impl FloatDefinition {
#[derive(Debug, Clone)]
pub struct SendPropDefinition {
pub changes_often: bool,
pub identifier: SendPropIdentifier,
pub parse_definition: SendPropParseDefinition,
}
impl TryFrom<RawSendPropDefinition> for SendPropDefinition {
impl TryFrom<&RawSendPropDefinition> for SendPropDefinition {
type Error = MalformedSendPropDefinitionError;
fn try_from(definition: RawSendPropDefinition) -> std::result::Result<Self, Self::Error> {
let parse_definition = (&definition).try_into()?;
fn try_from(definition: &RawSendPropDefinition) -> std::result::Result<Self, Self::Error> {
let parse_definition = definition.try_into()?;
Ok(SendPropDefinition {
changes_often: definition.flags.contains(SendPropFlag::ChangesOften),
parse_definition,
identifier: definition.identifier(),
})