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

View File

@ -17,6 +17,11 @@ pub struct Mesh <'data> {
ofs: usize, ofs: usize,
} }
pub struct HeaderFields <'data> {
model: &'data Model <'data>,
idx: usize,
}
pub struct VertexArrays <'data> { pub struct VertexArrays <'data> {
model: &'data Model <'data>, model: &'data Model <'data>,
idx: usize, idx: usize,
@ -49,6 +54,21 @@ fn usize_from (x: u32) -> usize {
usize::try_from (x).unwrap () 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> { impl <'data> Iterator for VertexArrays <'data> {
type Item = VertexArray <'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 { pub fn vertexarrays (&self) -> VertexArrays {
VertexArrays { VertexArrays {
model: self, model: self,