2 Commits

Author SHA1 Message Date
8b2c8de6f6 wip: quatdata 2025-03-20 20:11:16 -07:00
77af5e386a refine BinRead Args tech 2025-03-20 20:06:05 -07:00

@ -171,6 +171,7 @@ pub struct WorldEventReset{
#[binrw]
#[brw(little)]
pub struct WorldEventButton{
// TODO: figure out magic_after without a dummy field
#[br(pad_after=8)]
pub button_id:u32,
}
@ -279,8 +280,7 @@ pub enum FlagReason{
Teleport,
#[brw(magic=9u32)]
Practice,
// b"data"
#[brw(magic=1635017060u32)]
#[brw(magic=b"data")]
None,
}
#[binrw]
@ -390,12 +390,8 @@ struct EventChunkHeader{
num_events:u32,
}
// 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<()>
where
T:binrw::BinRead,
T::Args<'a>:binrw::__private::Required,
{
// binread args tech has been further refined
fn read_data_into_events<'a,R:BinReaderExt,T:binrw::BinRead<Args<'a>=()>>(data:&mut R,events:&mut Vec<T>,num_events:usize)->binrw::BinResult<()>{
// 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);
for _ in 0..num_events{
@ -403,11 +399,7 @@ where
}
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,
{
fn read_data_into_events_amortized<'a,R:BinReaderExt,T:binrw::BinRead<Args<'a>=()>>(data:&mut R,events:&mut Vec<T>,num_events:usize)->binrw::BinResult<()>{
// 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{
@ -419,37 +411,37 @@ where
impl Block{
fn read<R:BinReaderExt>(data:R)->binrw::BinResult<Block>{
let mut block=Block::default();
block.read_into(data)?;
Block::read_into(data,&mut block)?;
Ok(block)
}
fn read_into<R:BinReaderExt>(&mut self,mut data:R)->binrw::BinResult<()>{
fn read_into<R:BinReaderExt>(mut data:R,block:&mut Block)->binrw::BinResult<()>{
// well... this looks error prone
while let Ok(event_chunk_header)=data.read_le::<EventChunkHeader>(){
match event_chunk_header.event_type{
EventType::Input=>read_data_into_events(&mut data,&mut self.input_events,event_chunk_header.num_events as usize)?,
EventType::Output=>read_data_into_events(&mut data,&mut self.output_events,event_chunk_header.num_events as usize)?,
EventType::Sound=>read_data_into_events(&mut data,&mut self.sound_events,event_chunk_header.num_events as usize)?,
EventType::World=>read_data_into_events(&mut data,&mut self.world_events,event_chunk_header.num_events as usize)?,
EventType::Gravity=>read_data_into_events(&mut data,&mut self.gravity_events,event_chunk_header.num_events as usize)?,
EventType::Run=>read_data_into_events(&mut data,&mut self.run_events,event_chunk_header.num_events as usize)?,
EventType::Camera=>read_data_into_events(&mut data,&mut self.camera_events,event_chunk_header.num_events as usize)?,
EventType::Setting=>read_data_into_events(&mut data,&mut self.setting_events,event_chunk_header.num_events as usize)?,
EventType::Input=>read_data_into_events(&mut data,&mut block.input_events,event_chunk_header.num_events as usize)?,
EventType::Output=>read_data_into_events(&mut data,&mut block.output_events,event_chunk_header.num_events as usize)?,
EventType::Sound=>read_data_into_events(&mut data,&mut block.sound_events,event_chunk_header.num_events as usize)?,
EventType::World=>read_data_into_events(&mut data,&mut block.world_events,event_chunk_header.num_events as usize)?,
EventType::Gravity=>read_data_into_events(&mut data,&mut block.gravity_events,event_chunk_header.num_events as usize)?,
EventType::Run=>read_data_into_events(&mut data,&mut block.run_events,event_chunk_header.num_events as usize)?,
EventType::Camera=>read_data_into_events(&mut data,&mut block.camera_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(())
}
fn read_into_amortized<R:BinReaderExt>(&mut self,mut data:R)->binrw::BinResult<()>{
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 self.input_events,event_chunk_header.num_events as usize)?,
EventType::Output=>read_data_into_events_amortized(&mut data,&mut self.output_events,event_chunk_header.num_events as usize)?,
EventType::Sound=>read_data_into_events_amortized(&mut data,&mut self.sound_events,event_chunk_header.num_events as usize)?,
EventType::World=>read_data_into_events_amortized(&mut data,&mut self.world_events,event_chunk_header.num_events as usize)?,
EventType::Gravity=>read_data_into_events_amortized(&mut data,&mut self.gravity_events,event_chunk_header.num_events as usize)?,
EventType::Run=>read_data_into_events_amortized(&mut data,&mut self.run_events,event_chunk_header.num_events as usize)?,
EventType::Camera=>read_data_into_events_amortized(&mut data,&mut self.camera_events,event_chunk_header.num_events as usize)?,
EventType::Setting=>read_data_into_events_amortized(&mut data,&mut self.setting_events,event_chunk_header.num_events as usize)?,
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(())
@ -605,7 +597,7 @@ impl<R:BinReaderExt> FileData<R>{
}
pub fn read_block_info_into_block(&mut self,block_info:BlockInfo,block:&mut Block)->Result<(),Error>{
let data=self.block_reader(block_info)?;
block.read_into_amortized(data).map_err(Error::InvalidData)?;
Block::read_into_amortized(data,block).map_err(Error::InvalidData)?;
Ok(())
}
}