write a bunch of binrw
This commit is contained in:
parent
14e7e4df29
commit
d5af08730b
55
src/bot.rs
55
src/bot.rs
@ -1,6 +1,10 @@
|
|||||||
|
use binrw::{BinReaderExt, binrw};
|
||||||
|
|
||||||
pub enum Error{
|
pub enum Error{
|
||||||
InvalidHeader,
|
InvalidHeader,
|
||||||
InvalidSegment,
|
InvalidSegment(binrw::Error),
|
||||||
|
InvalidSegmentId(u64),
|
||||||
|
File(crate::file::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* block types
|
/* block types
|
||||||
@ -28,40 +32,63 @@ loop{
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//xdd
|
//error hiding mock code
|
||||||
mod simulation{
|
mod simulation{
|
||||||
|
#[super::binrw]
|
||||||
|
#[brw(little)]
|
||||||
pub struct State{}
|
pub struct State{}
|
||||||
|
#[super::binrw]
|
||||||
|
#[brw(little)]
|
||||||
pub struct Instruction{}
|
pub struct Instruction{}
|
||||||
}
|
}
|
||||||
mod instruction{
|
mod instruction{
|
||||||
pub struct TimedInstruction<Instruction>{instruction:Instruction}
|
#[super::binrw]
|
||||||
|
#[brw(little)]
|
||||||
|
pub struct TimedInstruction<Instruction:binrw::BinRead+binrw::BinWrite>{
|
||||||
|
time:u64,
|
||||||
|
instruction:Instruction
|
||||||
|
}
|
||||||
}
|
}
|
||||||
mod timeline{
|
mod timeline{
|
||||||
pub struct Timeline<Instruction>{timeline:Vec<super::instruction::TimedInstruction<Instruction>>}
|
#[super::binrw]
|
||||||
|
#[brw(little)]
|
||||||
|
pub struct Timeline<Instruction:binrw::BinRead+binrw::BinWrite>{
|
||||||
|
#[bw(try_calc(u32::try_from(instructions.len())))]
|
||||||
|
instruction_count:u32,
|
||||||
|
#[br(count=instruction_count)]
|
||||||
|
instructions:Vec<super::instruction::TimedInstruction<Instruction>>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//serious code
|
//serious code
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[brw(little)]
|
||||||
struct SegmentId(u64);
|
struct SegmentId(u64);
|
||||||
|
|
||||||
|
#[binrw]
|
||||||
|
#[brw(little)]
|
||||||
pub struct Segment{
|
pub struct Segment{
|
||||||
state:simulation::State,
|
state:simulation::State,
|
||||||
|
#[bw(try_calc(u32::try_from(instructions.len())))]
|
||||||
|
instruction_count:u32,
|
||||||
|
#[br(count=instruction_count)]
|
||||||
instructions:Vec<instruction::TimedInstruction<simulation::Instruction>>
|
instructions:Vec<instruction::TimedInstruction<simulation::Instruction>>
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct StreamableBot{
|
pub struct StreamableBot<R:BinReaderExt>{
|
||||||
file:crate::file::File,
|
file:crate::file::File<R>,
|
||||||
timeline:timeline::Timeline<SegmentId>,
|
timeline:timeline::Timeline<SegmentId>,
|
||||||
|
segment_id_to_block_id:Vec<crate::file::BlockId>,
|
||||||
}
|
}
|
||||||
impl StreamableBot{
|
impl<R:BinReaderExt> StreamableBot<R>{
|
||||||
pub fn new(file:crate::file::File)->Result<Self,Error>{
|
pub(crate) fn new(file:crate::file::File<R>)->Result<Self,Error>{
|
||||||
Err(Error::InvalidHeader)
|
Err(Error::InvalidHeader)
|
||||||
}
|
}
|
||||||
pub fn load_segment(&mut self,segment_id:u64)->Result<Segment,Error>{
|
pub fn load_segment(&mut self,segment_id:SegmentId)->Result<Segment,Error>{
|
||||||
//load region from disk
|
let block_id=*self.segment_id_to_block_id.get(segment_id.0 as usize).ok_or(Error::InvalidSegmentId(segment_id.0))?;
|
||||||
//parse the models and determine what resources need to be loaded
|
let mut block=self.file.take_block(block_id).map_err(|e|Error::File(e))?;
|
||||||
//load resources into self.resources
|
let segment=block.read_le().map_err(|e|Error::InvalidSegment(e))?;
|
||||||
//return Region
|
Ok(segment)
|
||||||
Err(Error::InvalidSegment)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
12
src/demo.rs
12
src/demo.rs
@ -1,3 +1,5 @@
|
|||||||
|
use binrw::BinReaderExt;
|
||||||
|
|
||||||
pub enum Error{
|
pub enum Error{
|
||||||
InvalidHeader,
|
InvalidHeader,
|
||||||
}
|
}
|
||||||
@ -17,12 +19,12 @@ how to do worldstate for deathrun!?
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
pub struct StreamableDemo{
|
pub struct StreamableDemo<R:BinReaderExt>{
|
||||||
map:Box<crate::map::StreamableMap>,
|
map:Box<crate::map::StreamableMap<R>>,
|
||||||
bots:Vec<crate::bot::StreamableBot>,
|
bots:Vec<crate::bot::StreamableBot<R>>,
|
||||||
}
|
}
|
||||||
impl StreamableDemo{
|
impl<R:BinReaderExt> StreamableDemo<R>{
|
||||||
pub fn new(file:crate::file::File)->Result<Self,Error>{
|
pub(crate) fn new(file:crate::file::File<R>)->Result<Self,Error>{
|
||||||
Err(Error::InvalidHeader)
|
Err(Error::InvalidHeader)
|
||||||
}
|
}
|
||||||
}
|
}
|
29
src/file.rs
29
src/file.rs
@ -1,10 +1,12 @@
|
|||||||
//file format "sniff"
|
//file format "sniff"
|
||||||
|
|
||||||
use binrw::{binrw, BinReaderExt};
|
use binrw::{binrw, BinReaderExt, io::TakeSeekExt};
|
||||||
|
|
||||||
pub enum Error{
|
pub enum Error{
|
||||||
InvalidHeader(binrw::Error),
|
InvalidHeader(binrw::Error),
|
||||||
UnexpectedEOF,
|
UnexpectedEOF,
|
||||||
|
InvalidBlockId(usize),
|
||||||
|
Seek(std::io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* spec
|
/* spec
|
||||||
@ -56,26 +58,35 @@ struct Header{
|
|||||||
priming:u64,
|
priming:u64,
|
||||||
/// uuid for this file
|
/// uuid for this file
|
||||||
resource:u128,
|
resource:u128,
|
||||||
#[bw(try_calc(u64::try_from(block_location.len())))]
|
#[bw(try_calc(u64::try_from(block_location.len()-1)))]
|
||||||
block_count:u64,
|
block_count:u64,
|
||||||
#[br(count=block_count)]
|
#[br(count=block_count+1)]
|
||||||
block_location:Vec<u64>,
|
block_location:Vec<u64>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct BlockId(usize);
|
||||||
|
|
||||||
pub(crate) struct File{
|
pub(crate) struct File<R:BinReaderExt>{
|
||||||
header:Header,
|
header:Header,
|
||||||
//reference to the data
|
//reference to the data
|
||||||
|
data:R,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl File{
|
impl<R:BinReaderExt> File<R>{
|
||||||
pub(crate) fn new<R:BinReaderExt>(mut input:R)->Result<Self,Error>{
|
pub(crate) fn new(mut input:R)->Result<File<R>,Error>{
|
||||||
Ok(Self{
|
Ok(File{
|
||||||
header:input.read_le().map_err(|e|Error::InvalidHeader(e))?,
|
header:input.read_le().map_err(|e|Error::InvalidHeader(e))?,
|
||||||
|
data:input,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub(crate) fn read_block(&mut self,block_id:u64)->Result<Vec<u8>,Error>{
|
pub(crate) fn take_block(&mut self,block_id:BlockId)->Result<binrw::io::TakeSeek<&mut R>,Error>{
|
||||||
Err(Error::UnexpectedEOF)
|
if self.header.block_location.len()<=block_id.0{
|
||||||
|
return Err(Error::InvalidBlockId(block_id.0))
|
||||||
|
}
|
||||||
|
let block_start=self.header.block_location[block_id.0];
|
||||||
|
let block_end=self.header.block_location[block_id.0+1];
|
||||||
|
self.data.seek(std::io::SeekFrom::Start(block_start)).map_err(|e|Error::Seek(e))?;
|
||||||
|
Ok((&mut self.data).take_seek(block_end-block_start))
|
||||||
}
|
}
|
||||||
pub(crate) fn fourcc(&self)->FourCC{
|
pub(crate) fn fourcc(&self)->FourCC{
|
||||||
self.header.fourcc
|
self.header.fourcc
|
||||||
|
16
src/lib.rs
16
src/lib.rs
@ -13,13 +13,13 @@ pub enum Error{
|
|||||||
Demo(demo::Error),
|
Demo(demo::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum SNF{
|
pub enum SNF<R:BinReaderExt>{
|
||||||
Map(map::StreamableMap),
|
Map(map::StreamableMap<R>),
|
||||||
Bot(bot::StreamableBot),
|
Bot(bot::StreamableBot<R>),
|
||||||
Demo(demo::StreamableDemo),
|
Demo(demo::StreamableDemo<R>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn read_snf<R:BinReaderExt>(input:R)->Result<SNF,Error>{
|
pub fn read_snf<R:BinReaderExt>(input:R)->Result<SNF<R>,Error>{
|
||||||
let file=file::File::new(input).map_err(|e|Error::Header(e))?;
|
let file=file::File::new(input).map_err(|e|Error::Header(e))?;
|
||||||
Ok(match file.fourcc(){
|
Ok(match file.fourcc(){
|
||||||
file::FourCC::Map=>SNF::Map(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?),
|
file::FourCC::Map=>SNF::Map(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?),
|
||||||
@ -27,21 +27,21 @@ pub fn read_snf<R:BinReaderExt>(input:R)->Result<SNF,Error>{
|
|||||||
file::FourCC::Demo=>SNF::Demo(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?),
|
file::FourCC::Demo=>SNF::Demo(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
pub fn read_map<R:BinReaderExt>(input:R)->Result<map::StreamableMap,Error>{
|
pub fn read_map<R:BinReaderExt>(input:R)->Result<map::StreamableMap<R>,Error>{
|
||||||
let file=file::File::new(input).map_err(|e|Error::Header(e))?;
|
let file=file::File::new(input).map_err(|e|Error::Header(e))?;
|
||||||
match file.fourcc(){
|
match file.fourcc(){
|
||||||
file::FourCC::Map=>Ok(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?),
|
file::FourCC::Map=>Ok(map::StreamableMap::new(file).map_err(|e|Error::Map(e))?),
|
||||||
_=>Err(Error::UnexpectedFourCC)
|
_=>Err(Error::UnexpectedFourCC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn read_bot<R:BinReaderExt>(input:R)->Result<bot::StreamableBot,Error>{
|
pub fn read_bot<R:BinReaderExt>(input:R)->Result<bot::StreamableBot<R>,Error>{
|
||||||
let file=file::File::new(input).map_err(|e|Error::Header(e))?;
|
let file=file::File::new(input).map_err(|e|Error::Header(e))?;
|
||||||
match file.fourcc(){
|
match file.fourcc(){
|
||||||
file::FourCC::Bot=>Ok(bot::StreamableBot::new(file).map_err(|e|Error::Bot(e))?),
|
file::FourCC::Bot=>Ok(bot::StreamableBot::new(file).map_err(|e|Error::Bot(e))?),
|
||||||
_=>Err(Error::UnexpectedFourCC)
|
_=>Err(Error::UnexpectedFourCC)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn read_demo<R:BinReaderExt>(input:R)->Result<demo::StreamableDemo,Error>{
|
pub fn read_demo<R:BinReaderExt>(input:R)->Result<demo::StreamableDemo<R>,Error>{
|
||||||
let file=file::File::new(input).map_err(|e|Error::Header(e))?;
|
let file=file::File::new(input).map_err(|e|Error::Header(e))?;
|
||||||
match file.fourcc(){
|
match file.fourcc(){
|
||||||
file::FourCC::Demo=>Ok(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?),
|
file::FourCC::Demo=>Ok(demo::StreamableDemo::new(file).map_err(|e|Error::Demo(e))?),
|
||||||
|
32
src/map.rs
32
src/map.rs
@ -1,6 +1,10 @@
|
|||||||
|
use binrw::{BinReaderExt, binrw};
|
||||||
|
|
||||||
pub enum Error{
|
pub enum Error{
|
||||||
InvalidHeader,
|
InvalidHeader,
|
||||||
InvalidNode,
|
InvalidNodeId(u64),
|
||||||
|
InvalidRegion(binrw::Error),
|
||||||
|
File(crate::file::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
/* block types
|
/* block types
|
||||||
@ -53,12 +57,14 @@ for model_id in 0..num_models{
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
//xdd
|
//error hiding mock code
|
||||||
mod physics{
|
mod physics{
|
||||||
pub struct StyleModifiers{}
|
pub struct StyleModifiers{}
|
||||||
}
|
}
|
||||||
mod model{
|
mod model{
|
||||||
pub struct IndexedModel{}
|
pub struct IndexedModel{}
|
||||||
|
#[super::binrw]
|
||||||
|
#[brw(little)]
|
||||||
pub struct ModelInstance{}
|
pub struct ModelInstance{}
|
||||||
}
|
}
|
||||||
mod image{
|
mod image{
|
||||||
@ -73,17 +79,26 @@ pub struct BvhNodeId(u64);
|
|||||||
struct BvhNode{
|
struct BvhNode{
|
||||||
//
|
//
|
||||||
}
|
}
|
||||||
|
#[binrw]
|
||||||
|
#[brw(little)]
|
||||||
|
struct Region{
|
||||||
|
#[bw(try_calc(u32::try_from(models.len())))]
|
||||||
|
model_count:u32,
|
||||||
|
#[br(count=model_count)]
|
||||||
|
models:Vec<model::ModelInstance>,
|
||||||
|
}
|
||||||
|
|
||||||
pub struct StreamableMap{
|
pub struct StreamableMap<R:BinReaderExt>{
|
||||||
file:crate::file::File,
|
file:crate::file::File<R>,
|
||||||
style:physics::StyleModifiers,//probably should move this out of physics
|
style:physics::StyleModifiers,//probably should move this out of physics
|
||||||
bvh:BvhNode,
|
bvh:BvhNode,
|
||||||
|
node_id_to_block_id:Vec<crate::file::BlockId>,
|
||||||
//do not need this? return only new data with load_node
|
//do not need this? return only new data with load_node
|
||||||
resource_model:std::collections::HashMap<ModelUuid,model::IndexedModel>,
|
resource_model:std::collections::HashMap<ModelUuid,model::IndexedModel>,
|
||||||
resource_image:std::collections::HashMap<ImageUuid,image::Image>,
|
resource_image:std::collections::HashMap<ImageUuid,image::Image>,
|
||||||
}
|
}
|
||||||
impl StreamableMap{
|
impl<R:BinReaderExt> StreamableMap<R>{
|
||||||
pub fn new(file:crate::file::File)->Result<Self,Error>{
|
pub(crate) fn new(file:crate::file::File<R>)->Result<Self,Error>{
|
||||||
Err(Error::InvalidHeader)
|
Err(Error::InvalidHeader)
|
||||||
}
|
}
|
||||||
pub fn load_node(&mut self,node_id:BvhNodeId)->Result<Vec<model::ModelInstance>,Error>{
|
pub fn load_node(&mut self,node_id:BvhNodeId)->Result<Vec<model::ModelInstance>,Error>{
|
||||||
@ -91,6 +106,9 @@ impl StreamableMap{
|
|||||||
//parse the models and determine what resources need to be loaded
|
//parse the models and determine what resources need to be loaded
|
||||||
//load resources into self.resources
|
//load resources into self.resources
|
||||||
//return Region
|
//return Region
|
||||||
Err(Error::InvalidNode)
|
let block_id=*self.node_id_to_block_id.get(node_id.0 as usize).ok_or(Error::InvalidNodeId(node_id.0))?;
|
||||||
|
let mut block=self.file.take_block(block_id).map_err(|e|Error::File(e))?;
|
||||||
|
let region:Region=block.read_le().map_err(|e|Error::InvalidRegion(e))?;
|
||||||
|
Ok(region.models)
|
||||||
}
|
}
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user