♻️ Making the old API a layer over the zero-copy API

master
_ 2020-05-25 22:14:59 +00:00
parent 86612f4d8e
commit f86fdc0c4f
2 changed files with 41 additions and 28 deletions

View File

@ -3,15 +3,15 @@ extern crate iota;
use std::convert::TryInto;
use std::io::Cursor;
use std::mem::size_of;
use byteorder::{ByteOrder, LittleEndian, ReadBytesExt};
use byteorder::{LittleEndian, ReadBytesExt};
pub mod names;
pub mod zero_copy;
pub use crate::names::consts;
pub use crate::names::types;
pub use zero_copy::Error;
#[derive (Debug, Default)]
pub struct Mesh {
@ -47,36 +47,20 @@ pub struct Model <'a> {
vertexarrays: Vec <VertexArray>,
}
#[derive (Debug)]
pub enum ModelLoadErr {
BadMagic,
UnsupportedVersion,
ParseMeshFailed,
ParseVertexArrayFailed,
}
use crate::names::MAGIC;
impl Header {
pub fn from_slice (input: &[u8]) -> Result <Header, ModelLoadErr> {
if &input [0..MAGIC.len ()] != MAGIC {
return Err (ModelLoadErr::BadMagic);
}
let input = &input [MAGIC.len ()..];
pub fn from_zc (zc: &zero_copy::Model) -> Header {
let mut header = Header::default ();
LittleEndian::read_u32_into (&input [0..header.fields.len () * size_of::<u32> ()], &mut header.fields);
if header.fields [consts::VERSION] != 2 {
return Err (ModelLoadErr::UnsupportedVersion);
for (i, value) in zc.header_fields ().enumerate () {
header.fields [i] = value;
}
Ok (header)
header
}
}
impl Mesh {
pub fn from_slice (input: &[u8]) -> Result <Mesh, ModelLoadErr> {
pub fn from_slice (input: &[u8]) -> Result <Mesh, Error> {
let mut mesh = Mesh::default ();
let mut rdr = Cursor::new (input);
@ -89,7 +73,7 @@ impl Mesh {
&mut mesh.first_triangle,
&mut mesh.num_triangles,
].iter_mut () {
**field = rdr.read_u32::<LittleEndian> ().map_err (|_| ModelLoadErr::ParseMeshFailed)?;
**field = rdr.read_u32::<LittleEndian> ().map_err (|_| Error::ParseMeshFailed)?;
}
Ok (mesh)
@ -97,7 +81,7 @@ impl Mesh {
}
impl VertexArray {
pub fn from_slice (input: &[u8]) -> Result <VertexArray, ModelLoadErr> {
pub fn from_slice (input: &[u8]) -> Result <VertexArray, Error> {
let mut va = VertexArray::default ();
let mut rdr = Cursor::new (input);
@ -109,7 +93,7 @@ impl VertexArray {
&mut va.va_size,
&mut va.va_offset,
].iter_mut () {
**field = rdr.read_u32::<LittleEndian> ().map_err (|_| ModelLoadErr::ParseVertexArrayFailed)?;
**field = rdr.read_u32::<LittleEndian> ().map_err (|_| Error::ParseVertexArrayFailed)?;
}
Ok (va)
@ -117,8 +101,10 @@ impl VertexArray {
}
impl <'a> Model <'a> {
pub fn from_slice (data: &'a [u8]) -> Result <Model <'a>, ModelLoadErr> {
let header = Header::from_slice (data)?;
pub fn from_slice (data: &'a [u8]) -> Result <Model <'a>, Error> {
let zc = zero_copy::Model::get_root (data)?;
let header = Header::from_zc (&zc);
let text = {
let offset: usize = header.fields [consts::OFS_TEXT].try_into ().unwrap ();

View File

@ -17,6 +17,11 @@ pub struct Mesh <'data> {
ofs: usize,
}
pub struct HeaderFields <'data> {
model: &'data Model <'data>,
idx: usize,
}
pub struct VertexArrays <'data> {
model: &'data Model <'data>,
idx: usize,
@ -49,6 +54,21 @@ fn usize_from (x: u32) -> usize {
usize::try_from (x).unwrap ()
}
impl <'data> Iterator for HeaderFields <'data> {
type Item = u32;
fn next (&mut self) -> Option <Self::Item> {
if self.idx >= HEADER_FIELD_COUNT {
return None;
}
let result = self.model.header_field (self.idx);
self.idx += 1;
Some (result)
}
}
impl <'data> Iterator for VertexArrays <'data> {
type Item = VertexArray <'data>;
@ -128,6 +148,13 @@ impl <'data> Model <'data> {
}
}
pub fn header_fields (&self) -> HeaderFields {
HeaderFields {
model: self,
idx: 0,
}
}
pub fn vertexarrays (&self) -> VertexArrays {
VertexArrays {
model: self,