diff --git a/src/network/frame_decoder.rs b/src/network/frame_decoder.rs index dfacfcc..0196692 100644 --- a/src/network/frame_decoder.rs +++ b/src/network/frame_decoder.rs @@ -11,12 +11,12 @@ use crate::network::{CacheInfo, VersionTriplet}; use crate::parser::ReplayBody; #[derive(Debug)] -pub(crate) struct SegmentedArray { +pub(crate) struct RawSegmentedArray { array: Vec>, map: FnvHashMap, } -impl SegmentedArray { +impl RawSegmentedArray { pub(crate) fn new(size: usize) -> Self { let mut array = Vec::with_capacity(size); array.resize_with(size, || None); @@ -54,6 +54,36 @@ impl SegmentedArray { } } +#[derive(Debug)] +pub(crate) struct SegmentedArray { + raw: RawSegmentedArray, + marker: std::marker::PhantomData, +} + +impl SegmentedArray +where + K: Into, +{ + pub(crate) fn new(size: usize) -> Self { + Self { + raw: RawSegmentedArray::new(size), + marker: std::marker::PhantomData, + } + } + + pub(crate) fn insert(&mut self, key: K, value: V) { + self.raw.insert(key.into(), value); + } + + pub(crate) fn get(&self, key: K) -> Option<&V> { + self.raw.get(key.into()) + } + + pub(crate) fn delete(&mut self, key: K) { + self.raw.delete(key.into()); + } +} + pub(crate) struct FrameDecoder<'a, 'b: 'a> { pub frames_len: usize, pub product_decoder: ProductValueDecoder, @@ -117,7 +147,7 @@ impl<'a, 'b> FrameDecoder<'a, 'b> { attr_decoder: &AttributeDecoder, bits: &mut LittleEndianReader<'_>, buf: &mut [u8], - actors: &mut SegmentedArray<(ObjectId, &'c CacheInfo)>, + actors: &mut SegmentedArray, new_actors: &mut Vec, deleted_actors: &mut Vec, updated_actors: &mut Vec, @@ -169,20 +199,20 @@ impl<'a, 'b> FrameDecoder<'a, 'b> { // overwrite it. let cache_info = self .object_ind_attributes - .get(actor.object_id.0 as usize) + .get(usize::from(actor.object_id)) .and_then(|x| x.as_ref()) .ok_or(FrameError::MissingCache { actor: actor_id, actor_object: actor.object_id, })?; - actors.insert(actor.actor_id.0 as usize, (actor.object_id, cache_info)); + actors.insert(actor.actor_id, (actor.object_id, cache_info)); new_actors.push(actor); } else { // We'll be updating an existing actor with some attributes so we need // to track down what the actor's type is and what attributes are available let (object_id, cache_info) = actors - .get(actor_id.0 as usize) + .get(actor_id) .ok_or(FrameError::MissingActor { actor: actor_id })?; // While there are more attributes to update for our actor: @@ -208,7 +238,7 @@ impl<'a, 'b> FrameDecoder<'a, 'b> { // decoding function. Experience has told me replays that fail to // parse, fail to do so here, so a large chunk is dedicated to // generating an error message with context - let attr = cache_info.attributes.get(stream_id.0 as usize).ok_or( + let attr = cache_info.attributes.get(stream_id).ok_or( FrameError::MissingAttribute { actor: actor_id, actor_object: *object_id, @@ -242,7 +272,7 @@ impl<'a, 'b> FrameDecoder<'a, 'b> { } } else { deleted_actors.push(actor_id); - actors.delete(actor_id.0 as usize); + actors.delete(actor_id); } } @@ -296,6 +326,7 @@ impl<'a, 'b> FrameDecoder<'a, 'b> { ObjectId(key as i32), value .attributes + .raw .map .iter() .enumerate() @@ -308,6 +339,7 @@ impl<'a, 'b> FrameDecoder<'a, 'b> { .collect(), frames: frames.clone(), actors: actors + .raw .map .iter() .map(|(k, (o, _))| (ActorId(*k as i32), *o)) diff --git a/src/network/mod.rs b/src/network/mod.rs index d77fe71..665bbea 100644 --- a/src/network/mod.rs +++ b/src/network/mod.rs @@ -21,7 +21,7 @@ use std::cmp; pub(crate) struct CacheInfo { max_prop_id: u32, prop_id_bits: u32, - attributes: SegmentedArray, + attributes: SegmentedArray, } #[derive(Debug, Clone, Copy, PartialEq, Eq)] @@ -148,7 +148,7 @@ pub(crate) fn parse(header: &Header, body: &ReplayBody) -> Result for i32 { } } +impl From for usize { + fn from(val: StreamId) -> Self { + val.0 as usize + } +} + impl fmt::Display for StreamId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0) @@ -276,6 +282,12 @@ impl From for i32 { } } +impl From for usize { + fn from(val: ActorId) -> Self { + val.0 as usize + } +} + impl fmt::Display for ActorId { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { write!(f, "{}", self.0)