forked from StrafesNET/strafe-project
read_all
This commit is contained in:
parent
4a1e26e5be
commit
38d106d008
102
src/v1.rs
102
src/v1.rs
@ -249,8 +249,8 @@ struct EventChunkHeader{
|
|||||||
// first time I've managed to write BinRead generics without this stupid T::Args<'a>:Required thing blocking me
|
// first time I've managed to write BinRead generics without this stupid T::Args<'a>:Required thing blocking me
|
||||||
fn read_data_into_events<'a,R:BinReaderExt,T>(data:&mut R,events:&mut Vec<T>,num_events:usize)->binrw::BinResult<()>
|
fn read_data_into_events<'a,R:BinReaderExt,T>(data:&mut R,events:&mut Vec<T>,num_events:usize)->binrw::BinResult<()>
|
||||||
where
|
where
|
||||||
T:binrw::BinRead,
|
T:binrw::BinRead,
|
||||||
T::Args<'a>:binrw::__private::Required,
|
T::Args<'a>:binrw::__private::Required,
|
||||||
{
|
{
|
||||||
// there is only supposed to be at most one of each type of event chunk per block, so no need to amortize.
|
// there is only supposed to be at most one of each type of event chunk per block, so no need to amortize.
|
||||||
events.reserve_exact(num_events);
|
events.reserve_exact(num_events);
|
||||||
@ -259,10 +259,26 @@ where
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
fn read_data_into_events_amortized<'a,R:BinReaderExt,T>(data:&mut R,events:&mut Vec<T>,num_events:usize)->binrw::BinResult<()>
|
||||||
|
where
|
||||||
|
T:binrw::BinRead,
|
||||||
|
T::Args<'a>:binrw::__private::Required,
|
||||||
|
{
|
||||||
|
// this is used when reading multiple blocks into a single object, so amortize the allocation cost.
|
||||||
|
events.reserve(num_events);
|
||||||
|
for _ in 0..num_events{
|
||||||
|
events.push(data.read_le()?);
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
impl Block{
|
impl Block{
|
||||||
fn read<R:BinReaderExt>(mut data:R)->binrw::BinResult<Block>{
|
fn read<R:BinReaderExt>(data:R)->binrw::BinResult<Block>{
|
||||||
let mut block=Block::default();
|
let mut block=Block::default();
|
||||||
|
Block::read_into(data,&mut block)?;
|
||||||
|
Ok(block)
|
||||||
|
}
|
||||||
|
fn read_into<R:BinReaderExt>(mut data:R,block:&mut Block)->binrw::BinResult<()>{
|
||||||
// well... this looks error prone
|
// well... this looks error prone
|
||||||
while let Ok(event_chunk_header)=data.read_le::<EventChunkHeader>(){
|
while let Ok(event_chunk_header)=data.read_le::<EventChunkHeader>(){
|
||||||
match event_chunk_header.event_type{
|
match event_chunk_header.event_type{
|
||||||
@ -276,7 +292,23 @@ impl Block{
|
|||||||
EventType::Setting=>read_data_into_events(&mut data,&mut block.setting_events,event_chunk_header.num_events as usize)?,
|
EventType::Setting=>read_data_into_events(&mut data,&mut block.setting_events,event_chunk_header.num_events as usize)?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(block)
|
Ok(())
|
||||||
|
}
|
||||||
|
fn read_into_amortized<R:BinReaderExt>(mut data:R,block:&mut Block)->binrw::BinResult<()>{
|
||||||
|
// sad code duplication
|
||||||
|
while let Ok(event_chunk_header)=data.read_le::<EventChunkHeader>(){
|
||||||
|
match event_chunk_header.event_type{
|
||||||
|
EventType::Input=>read_data_into_events_amortized(&mut data,&mut block.input_events,event_chunk_header.num_events as usize)?,
|
||||||
|
EventType::Output=>read_data_into_events_amortized(&mut data,&mut block.output_events,event_chunk_header.num_events as usize)?,
|
||||||
|
EventType::Sound=>read_data_into_events_amortized(&mut data,&mut block.sound_events,event_chunk_header.num_events as usize)?,
|
||||||
|
EventType::World=>read_data_into_events_amortized(&mut data,&mut block.world_events,event_chunk_header.num_events as usize)?,
|
||||||
|
EventType::Gravity=>read_data_into_events_amortized(&mut data,&mut block.gravity_events,event_chunk_header.num_events as usize)?,
|
||||||
|
EventType::Run=>read_data_into_events_amortized(&mut data,&mut block.run_events,event_chunk_header.num_events as usize)?,
|
||||||
|
EventType::Camera=>read_data_into_events_amortized(&mut data,&mut block.camera_events,event_chunk_header.num_events as usize)?,
|
||||||
|
EventType::Setting=>read_data_into_events_amortized(&mut data,&mut block.setting_events,event_chunk_header.num_events as usize)?,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,6 +338,16 @@ pub struct TimedBlockId{
|
|||||||
pub time:f64,
|
pub time:f64,
|
||||||
pub block_id:BlockId,
|
pub block_id:BlockId,
|
||||||
}
|
}
|
||||||
|
impl PartialEq for TimedBlockId{
|
||||||
|
fn eq(&self,other:&Self)->bool{
|
||||||
|
self.time.eq(&other.time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl PartialOrd for TimedBlockId{
|
||||||
|
fn partial_cmp(&self,other:&Self)->Option<core::cmp::Ordering>{
|
||||||
|
self.time.partial_cmp(&other.time)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[binrw]
|
#[binrw]
|
||||||
#[brw(little)]
|
#[brw(little)]
|
||||||
@ -337,6 +379,41 @@ impl FileHeader{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct MergeIter<T,It0:Iterator<Item=T>,It1:Iterator<Item=T>>{
|
||||||
|
it0:It0,
|
||||||
|
it1:It1,
|
||||||
|
item0:Option<T>,
|
||||||
|
item1:Option<T>,
|
||||||
|
}
|
||||||
|
impl<T,It0:Iterator<Item=T>,It1:Iterator<Item=T>> MergeIter<T,It0,It1>{
|
||||||
|
fn new(mut it0:It0,mut it1:It1)->Self{
|
||||||
|
Self{
|
||||||
|
item0:it0.next(),
|
||||||
|
item1:it1.next(),
|
||||||
|
it0,
|
||||||
|
it1,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T:PartialOrd,It0:Iterator<Item=T>,It1:Iterator<Item=T>> Iterator for MergeIter<T,It0,It1>{
|
||||||
|
type Item=T;
|
||||||
|
fn next(&mut self)->Option<Self::Item>{
|
||||||
|
match (&self.item0,&self.item1){
|
||||||
|
(None,None)=>None,
|
||||||
|
(Some(_),None)=>core::mem::replace(&mut self.item0,self.it0.next()),
|
||||||
|
(None,Some(_))=>core::mem::replace(&mut self.item1,self.it1.next()),
|
||||||
|
(Some(item0),Some(item1))=>match item0.partial_cmp(item1){
|
||||||
|
Some(core::cmp::Ordering::Less)
|
||||||
|
|Some(core::cmp::Ordering::Equal)
|
||||||
|
|None
|
||||||
|
=>core::mem::replace(&mut self.item0,self.it0.next()),
|
||||||
|
Some(core::cmp::Ordering::Greater)
|
||||||
|
=>core::mem::replace(&mut self.item1,self.it1.next()),
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub struct File<R:BinReaderExt>{
|
pub struct File<R:BinReaderExt>{
|
||||||
pub header:FileHeader,
|
pub header:FileHeader,
|
||||||
pub data:FileData<R>,
|
pub data:FileData<R>,
|
||||||
@ -348,6 +425,18 @@ impl<R:BinReaderExt> File<R>{
|
|||||||
data:FileData{data},
|
data:FileData{data},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
pub fn read_all(&mut self)->Result<Block,Error>{
|
||||||
|
let block_iter=MergeIter::new(
|
||||||
|
self.header.offline_blocks_timeline.iter(),
|
||||||
|
self.header.realtime_blocks_timeline.iter(),
|
||||||
|
);
|
||||||
|
let mut big_block=Block::default();
|
||||||
|
for &TimedBlockId{time:_,block_id} in block_iter{
|
||||||
|
let block_info=self.header.block_info(block_id)?;
|
||||||
|
self.data.read_block_info_into(block_info,&mut big_block)?;
|
||||||
|
}
|
||||||
|
Ok(big_block)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct FileData<R:BinReaderExt>{
|
pub struct FileData<R:BinReaderExt>{
|
||||||
@ -366,4 +455,9 @@ impl<R:BinReaderExt> FileData<R>{
|
|||||||
let block=Block::read(data).map_err(Error::InvalidData)?;
|
let block=Block::read(data).map_err(Error::InvalidData)?;
|
||||||
Ok(block)
|
Ok(block)
|
||||||
}
|
}
|
||||||
|
pub fn read_block_info_into(&mut self,block_info:BlockInfo,block:&mut Block)->Result<(),Error>{
|
||||||
|
let data=self.block_reader(block_info)?;
|
||||||
|
Block::read_into_amortized(data,block).map_err(Error::InvalidData)?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user