gmflib: perf fixes

main
q3k 2022-04-15 20:04:20 +00:00
parent 13efa89224
commit a2d47206ce
6 changed files with 36 additions and 17 deletions

7
Cargo.lock generated
View File

@ -28,6 +28,12 @@ version = "3.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4a45a46ab1f2412e53d3a0ade76ffad2025804294569aae387231a0cd6e0899"
[[package]]
name = "byteorder"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "cfg-if"
version = "1.0.0"
@ -51,6 +57,7 @@ dependencies = [
name = "gmflib"
version = "0.1.0"
dependencies = [
"byteorder",
"gmfmacros",
"serde",
]

View File

@ -8,5 +8,5 @@ members = [
]
[profile.release]
strip = true
lto = true
debug = true

View File

@ -1,3 +1,5 @@
use std::io::Write;
#[derive(Debug, Clone)]
pub struct WriteError {
pub msg: String,
@ -10,7 +12,7 @@ pub trait Serializable: Sized {
}
pub struct WriteStream<W: std::io::Write> {
backing: W,
backing: std::io::BufWriter<W>,
depth: usize,
}
@ -102,7 +104,7 @@ impl<A: Atom> Serializable for A {
impl <W: std::io::Write> WriteStream<W> {
pub fn new(w: W) -> Self {
Self {
backing: w,
backing: std::io::BufWriter::new(w),
depth: 0,
}
}

View File

@ -1,3 +1,6 @@
use byteorder::ReadBytesExt;
use std::io::Read;
pub struct ReadError {
pub msg: String,
pub stack: Vec<ParseFrame>,
@ -44,9 +47,14 @@ impl<T: Serializable> Serializable for Vec<T> {
}
}
impl<T: Serializable, const N: usize> Serializable for [T; N] {
impl<const N: usize> Serializable for [f32; N] {
fn read<R: std::io::Read>(r: &mut ReadStream<R>) -> ReadResult<Self> {
(0..N).map(|_| r.read("data")).collect::<ReadResult<Vec<T>>>()?.try_into().map_err(|_| r.error("eof"))
let mut buffer = [0f32; N];
r.backing.read_f32_into::<byteorder::LittleEndian>(&mut buffer[..]).map_err(|e| {
r.error("eof")
})?;
r.pos += 4 * N;
Ok(buffer)
}
}
@ -97,7 +105,7 @@ impl Serializable for f32 {
impl Serializable for String {
fn read<R: std::io::Read>(r: &mut ReadStream<R>) -> ReadResult<Self> {
let len: u32 = r.read("len")?;
r.push("bytes".to_string());
r.push("bytes");
let bytes = r.bytes(len as usize)?;
let bytes: Vec<u8> = bytes.into_iter().filter(|&b| b != 0).collect();
let res = std::str::from_utf8(&bytes).map_err(|_| r.error("invalid string")).map(String::from);
@ -107,7 +115,7 @@ impl Serializable for String {
}
pub struct ReadStream<R: std::io::Read> {
backing: R,
backing: std::io::BufReader<R>,
stack: Vec<ParseFrame>,
pos: usize,
}
@ -115,7 +123,7 @@ pub struct ReadStream<R: std::io::Read> {
impl<R: std::io::Read> ReadStream<R> {
pub fn new(r: R) -> Self {
Self {
backing: r,
backing: std::io::BufReader::new(r),
pos: 0,
stack: vec![
ParseFrame{name: "root".into(), loc: 0},
@ -123,9 +131,9 @@ impl<R: std::io::Read> ReadStream<R> {
}
}
fn push(&mut self, s: String) {
fn push<S: std::string::ToString>(&mut self, s: S) {
self.stack.push(ParseFrame {
name: s,
name: s.to_string(),
loc: self.pos,
});
}
@ -139,7 +147,7 @@ impl <R: std::io::Read> ReadStream<R> {
pub fn bytes(&mut self, n: usize) -> ReadResult<Vec<u8>> {
let mut buf: Vec<u8> = vec![0; n];
self.pos += n;
match self.backing.read(&mut buf) {
match self.backing.read_exact(&mut buf) {
Ok(_) => return Ok(buf),
Err(_) => return Err(self.error("eof")),
}
@ -156,14 +164,14 @@ impl <R: std::io::Read> ReadStream<R> {
}
pub fn read<T: Serializable, S: std::string::ToString>(&mut self, ctx: S) -> ReadResult<T> {
self.push(ctx.to_string());
self.push(ctx);
let res = T::read(self);
self.pop();
res
}
pub fn read_parametrized<T: Serializable, S: std::string::ToString>(&mut self, ctx: S, params: &[u32]) -> ReadResult<T> {
self.push(ctx.to_string());
self.push(ctx);
let res = T::read_parametrized(self, params);
self.pop();
res

View File

@ -600,7 +600,9 @@ impl MeshNormalList {
w.emit(&format!("*MESH_FACENORMAL\t{}\t{:.6}\t{:.6}\t{:.6}",
i, normal.face[0], normal.face[1], normal.face[2]))?;
for j in 0..3 {
let vn = normal.vertex[j];
let vnx = normal.vertex[j];
let vny = normal.vertex[j+1];
let vnz = normal.vertex[j+2];
let vno = match j {
0 => face.a,
1 => face.b,
@ -608,7 +610,7 @@ impl MeshNormalList {
_ => unreachable!(),
};
w.emit(&format!("\t*MESH_VERTEXNORMAL\t{}\t{:.6}\t{:.6}\t{:.6}",
vno, vn[0], vn[1], vn[2]))?;
vno, vnx, vny, vnz))?;
}
}
w.pop()?;
@ -641,7 +643,7 @@ pub struct TFace {
#[derive(Debug,GMISerializable,Serialize)]
pub struct FaceNormal {
pub face: [f32; 3],
pub vertex: [[f32; 3]; 3],
pub vertex: [f32; 9],
}
impl gma::Serializable for FaceNormal {

View File

@ -29,7 +29,7 @@ fn main() {
let gmf = match gmflib::GMF::read_gmi(f) {
Ok(gmf) => gmf,
Err(e) => {
log::error!("Reading GMI failed: {}", e.msg);
log::error!("Reading GMI {} failed: {}", gmf_path, e.msg);
log::info!("Parse stack:");
for frame in e.stack.iter() {
log::info!(" {} at offset {}", frame.name, frame.loc);