diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/classes/texture2d.rs | 37 | ||||
-rw-r--r-- | src/classes/transform.rs | 21 | ||||
-rw-r--r-- | src/object/helper.rs | 45 | ||||
-rw-r--r-- | src/object/mod.rs | 2 |
4 files changed, 45 insertions, 60 deletions
diff --git a/src/classes/texture2d.rs b/src/classes/texture2d.rs index 147cb5d..752bfeb 100644 --- a/src/classes/texture2d.rs +++ b/src/classes/texture2d.rs @@ -1,10 +1,9 @@ use super::streaminginfo::StreamingInfo; use crate::object::{Value, parser::FromValue}; -use anyhow::{Result, bail}; +use anyhow::{Result, anyhow, bail}; use image::{DynamicImage, ImageBuffer, Luma, Rgb, Rgba}; use log::info; use serde::Serialize; -use std::mem::transmute; #[derive(Debug, Serialize)] pub struct Texture2D { @@ -23,25 +22,18 @@ impl FromValue for Texture2D { fn from_value(v: Value) -> Result<Self> { let mut fields = v.as_class("Texture2D").unwrap(); Ok(Texture2D { - width: fields.remove("m_Width").unwrap().as_i32().unwrap(), - height: fields.remove("m_Height").unwrap().as_i32().unwrap(), - mip_count: fields.remove("m_MipCount").unwrap().as_i32().unwrap(), - texture_dimension: fields - .remove("m_TextureDimension") - .unwrap() - .as_i32() - .unwrap(), - format: unsafe { - transmute::<_, TextureFormat>( - fields.remove("m_TextureFormat").unwrap().as_i32().unwrap(), - ) - }, - name: fields.remove("m_Name").unwrap().as_string().unwrap(), + width: fields.field("m_Width")?, + height: fields.field("m_Height")?, + mip_count: fields.field("m_MipCount")?, + texture_dimension: fields.field("m_TextureDimension")?, + format: fields.field("m_TextureFormat")?, + name: fields.field("m_Name")?, + stream_data: fields.field("m_StreamData")?, image_data: fields.remove("image data").unwrap().as_typeless().unwrap(), - stream_data: fields.remove("m_StreamData").unwrap().parse().unwrap(), }) } } + impl Texture2D { pub fn to_image(&self) -> Result<DynamicImage> { let w = self.width as usize; @@ -142,6 +134,17 @@ impl Texture2D { } } +impl FromValue for TextureFormat { + fn from_value(v: Value) -> Result<Self> { + let x = v.as_i32().ok_or(anyhow!("expected i32 TextureFormat"))?; + if x < 72 { + Ok(unsafe { std::mem::transmute(x) }) + } else { + bail!("TextureFormat out of range") + } + } +} + #[allow(non_camel_case_types)] #[repr(i32)] #[derive(Debug, Serialize, PartialEq, Clone, Copy)] diff --git a/src/classes/transform.rs b/src/classes/transform.rs index d31a7d6..2ec515a 100644 --- a/src/classes/transform.rs +++ b/src/classes/transform.rs @@ -18,28 +18,19 @@ impl FromValue for Transform { fn from_value(v: Value) -> Result<Self> { let mut fields = v.as_class("Transform").unwrap(); Ok(Self { + father: fields.field("m_Father")?, + gameobject: fields.field("m_GameObject")?, + local_position: fields.field("m_LocalPosition")?, + local_rotation: fields.field("m_LocalRotation")?, + local_scale: fields.field("m_LocalScale")?, children: fields .remove("m_Children") .unwrap() - .as_class("vector") - .unwrap() - .remove("Array") - .unwrap() - .as_array() + .as_vector() .unwrap() .into_iter() .map(|e| PPtr::from_value(e).unwrap().cast()) .collect(), - father: fields - .remove("m_Father") - .unwrap() - .parse::<PPtr>() - .unwrap() - .cast(), - gameobject: fields.remove("m_GameObject").unwrap().parse().unwrap(), - local_position: fields.remove("m_LocalPosition").unwrap().parse().unwrap(), - local_rotation: fields.remove("m_LocalRotation").unwrap().parse().unwrap(), - local_scale: fields.remove("m_LocalScale").unwrap().parse().unwrap(), }) } } diff --git a/src/object/helper.rs b/src/object/helper.rs index 3f41703..74d18ea 100644 --- a/src/object/helper.rs +++ b/src/object/helper.rs @@ -86,38 +86,29 @@ impl Value { } } pub fn to_json(self) -> serde_json::Value { + use serde_json::{Number, Value as V}; match self { - Value::Bool(x) => serde_json::Value::Bool(x), - Value::U8(x) => serde_json::Value::Number(x.into()), - Value::I8(x) => serde_json::Value::Number(x.into()), - Value::U16(x) => serde_json::Value::Number(x.into()), - Value::I16(x) => serde_json::Value::Number(x.into()), - Value::U32(x) => serde_json::Value::Number(x.into()), - Value::U64(x) => serde_json::Value::Number(x.into()), - Value::I32(x) => serde_json::Value::Number(x.into()), - Value::F32(x) => serde_json::Value::Number( - serde_json::Number::from_f64(x as f64).unwrap_or(0.into()), - ), - Value::I64(x) => serde_json::Value::Number(x.into()), - Value::F64(x) => serde_json::Value::Number(serde_json::Number::from_f64(x).unwrap()), - Value::String(x) => serde_json::Value::String(x), - Value::Typeless(values) => serde_json::Value::Array( - values - .into_iter() - .map(|e| serde_json::Value::Number(e.into())) - .collect(), - ), - Value::Array(values) => { - serde_json::Value::Array(values.into_iter().map(Value::to_json).collect()) + Value::Bool(x) => V::Bool(x), + Value::U8(x) => V::Number(x.into()), + Value::I8(x) => V::Number(x.into()), + Value::U16(x) => V::Number(x.into()), + Value::I16(x) => V::Number(x.into()), + Value::U32(x) => V::Number(x.into()), + Value::U64(x) => V::Number(x.into()), + Value::I32(x) => V::Number(x.into()), + Value::F32(x) => V::Number(Number::from_f64(x as f64).unwrap_or(0.into())), + Value::I64(x) => V::Number(x.into()), + Value::F64(x) => V::Number(Number::from_f64(x).unwrap()), + Value::String(x) => V::String(x), + Value::Typeless(values) => { + V::Array(values.into_iter().map(|e| V::Number(e.into())).collect()) } - Value::Object { class, fields } => serde_json::Value::Object( + Value::Array(values) => V::Array(values.into_iter().map(Value::to_json).collect()), + Value::Object { class, fields } => V::Object( fields .into_iter() .map(|(k, v)| (k, v.to_json())) - .chain(Some(( - "@class".to_string(), - serde_json::Value::String(class), - ))) + .chain(Some(("@class".to_string(), V::String(class)))) .collect(), ), } diff --git a/src/object/mod.rs b/src/object/mod.rs index 6e643de..efc1544 100644 --- a/src/object/mod.rs +++ b/src/object/mod.rs @@ -2,8 +2,8 @@ use serde::Serialize; use std::collections::BTreeMap; pub mod helper; -pub mod read; pub mod parser; +pub mod read; #[derive(Debug, Clone, Serialize)] pub enum Value { |