From 017c1077339312f54b96625239f9f030ca737b06 Mon Sep 17 00:00:00 2001 From: Ruiqi Niu Date: Wed, 6 Mar 2024 18:45:18 -0500 Subject: [PATCH 1/6] Put data def and parsing code to proper places. `try_from()` and associated error types for string->enum mappings should go under format/ node data should all be defined under node/ --- inox2d/src/formats.rs | 1 + inox2d/src/formats/enums.rs | 121 ++++++++++++++++++++++++++++++++++ inox2d/src/formats/payload.rs | 37 +++++------ inox2d/src/math/interp.rs | 24 +------ inox2d/src/math/transform.rs | 49 +------------- inox2d/src/node.rs | 4 +- inox2d/src/node/data.rs | 69 +++++++++---------- inox2d/src/params.rs | 5 +- inox2d/src/puppet.rs | 51 -------------- inox2d/src/render.rs | 3 +- 10 files changed, 177 insertions(+), 187 deletions(-) create mode 100644 inox2d/src/formats/enums.rs diff --git a/inox2d/src/formats.rs b/inox2d/src/formats.rs index da5b130..7e4ed8e 100644 --- a/inox2d/src/formats.rs +++ b/inox2d/src/formats.rs @@ -1,3 +1,4 @@ +mod enums; pub mod inp; mod json; mod payload; diff --git a/inox2d/src/formats/enums.rs b/inox2d/src/formats/enums.rs new file mode 100644 index 0000000..0e69465 --- /dev/null +++ b/inox2d/src/formats/enums.rs @@ -0,0 +1,121 @@ +use crate::node::data::{BlendMode, InterpolateMode, MaskMode, ParamMapMode}; +use crate::puppet::{PuppetAllowedModification, PuppetAllowedRedistribution, PuppetAllowedUsers}; + +#[derive(Debug, Clone, thiserror::Error)] +#[error("Unknown param map mode {0:?}")] +pub struct UnknownParamMapModeError(String); + +impl TryFrom<&str> for ParamMapMode { + type Error = UnknownBlendModeError; + + fn try_from(value: &str) -> Result { + match value { + "AngleLength" => Ok(ParamMapMode::AngleLength), + "XY" => Ok(ParamMapMode::AngleLength), + a => todo!("Param map mode {} unimplemented", a), + } + } +} + +#[derive(Debug, Clone, thiserror::Error)] +#[error("Unknown interpolate mode {0:?}")] +pub struct UnknownInterpolateModeError(String); + +impl TryFrom<&str> for InterpolateMode { + type Error = UnknownInterpolateModeError; + + fn try_from(value: &str) -> Result { + match value { + "Linear" => Ok(InterpolateMode::Linear), + unknown => Err(UnknownInterpolateModeError(unknown.to_owned())), + } + } +} + +#[derive(Debug, Clone, thiserror::Error)] +#[error("Unknown blend mode {0:?}")] +pub struct UnknownBlendModeError(String); + +impl TryFrom<&str> for BlendMode { + type Error = UnknownBlendModeError; + + fn try_from(value: &str) -> Result { + match value { + "Normal" => Ok(BlendMode::Normal), + "Multiply" => Ok(BlendMode::Multiply), + "ColorDodge" => Ok(BlendMode::ColorDodge), + "LinearDodge" => Ok(BlendMode::LinearDodge), + "Screen" => Ok(BlendMode::Screen), + "ClipToLower" => Ok(BlendMode::ClipToLower), + "SliceFromLower" => Ok(BlendMode::SliceFromLower), + unknown => Err(UnknownBlendModeError(unknown.to_owned())), + } + } +} + +#[derive(Debug, Clone, thiserror::Error)] +#[error("Unknown mask mode {0:?}")] +pub struct UnknownMaskModeError(String); + +impl TryFrom<&str> for MaskMode { + type Error = UnknownMaskModeError; + + fn try_from(value: &str) -> Result { + match value { + "Mask" => Ok(MaskMode::Mask), + "DodgeMask" => Ok(MaskMode::Dodge), + unknown => Err(UnknownMaskModeError(unknown.to_owned())), + } + } +} + +#[derive(Debug, Clone, thiserror::Error)] +#[error("Unknown allowed users {0:?}")] +pub struct UnknownPuppetAllowedUsersError(String); + +impl TryFrom<&str> for PuppetAllowedUsers { + type Error = UnknownPuppetAllowedUsersError; + + fn try_from(value: &str) -> Result { + match value { + "OnlyAuthor" => Ok(PuppetAllowedUsers::OnlyAuthor), + "OnlyLicensee" => Ok(PuppetAllowedUsers::OnlyLicensee), + "Everyone" => Ok(PuppetAllowedUsers::Everyone), + unknown => Err(UnknownPuppetAllowedUsersError(unknown.to_owned())), + } + } +} + +#[derive(Debug, Clone, thiserror::Error)] +#[error("Unknown allowed redistribution {0:?}")] +pub struct UnknownPuppetAllowedRedistributionError(String); + +impl TryFrom<&str> for PuppetAllowedRedistribution { + type Error = UnknownPuppetAllowedRedistributionError; + + fn try_from(value: &str) -> Result { + match value { + "Prohibited" => Ok(PuppetAllowedRedistribution::Prohibited), + "ViralLicense" => Ok(PuppetAllowedRedistribution::ViralLicense), + "CopyleftLicense" => Ok(PuppetAllowedRedistribution::CopyleftLicense), + unknown => Err(UnknownPuppetAllowedRedistributionError(unknown.to_owned())), + } + } +} + +#[derive(Debug, Clone, thiserror::Error)] +#[error("Unknown allowed users {0:?}")] +pub struct UnknownPuppetAllowedModificationError(String); + +impl TryFrom<&str> for PuppetAllowedModification { + type Error = UnknownPuppetAllowedModificationError; + + fn try_from(value: &str) -> Result { + match value { + "Prohibited" => Ok(PuppetAllowedModification::Prohibited), + "AllowPersonal" => Ok(PuppetAllowedModification::AllowPersonal), + "AllowRedistribute" => Ok(PuppetAllowedModification::AllowRedistribute), + unknown => Err(UnknownPuppetAllowedModificationError(unknown.to_owned())), + } + } +} diff --git a/inox2d/src/formats/payload.rs b/inox2d/src/formats/payload.rs index 5455162..2cb0bb0 100644 --- a/inox2d/src/formats/payload.rs +++ b/inox2d/src/formats/payload.rs @@ -4,13 +4,13 @@ use glam::{vec2, vec3, Vec2}; use indextree::Arena; use json::JsonValue; -use crate::math::interp::{InterpolateMode, UnknownInterpolateModeError}; +use super::enums::*; + use crate::math::matrix::{Matrix2d, Matrix2dFromSliceVecsError}; -use crate::math::transform::TransformOffset; use crate::mesh::{f32s_as_vec2s, Mesh}; use crate::node::data::{ - BlendMode, Composite, Drawable, InoxData, Mask, MaskMode, ParamMapMode, Part, PhysicsModel, PhysicsProps, - SimplePhysics, UnknownBlendModeError, UnknownMaskModeError, + BlendMode, Composite, Drawable, InoxData, InterpolateMode, Mask, MaskMode, ParamMapMode, Part, PhysicsModel, + PhysicsProps, SimplePhysics, TransformOffset, }; use crate::node::tree::InoxNodeTree; use crate::node::{InoxNode, InoxNodeUuid}; @@ -18,8 +18,7 @@ use crate::params::{AxisPoints, Binding, BindingValues, Param, ParamUuid}; use crate::physics::runge_kutta::PhysicsState; use crate::puppet::{ Puppet, PuppetAllowedModification, PuppetAllowedRedistribution, PuppetAllowedUsers, PuppetMeta, PuppetPhysics, - PuppetUsageRights, UnknownPuppetAllowedModificationError, UnknownPuppetAllowedRedistributionError, - UnknownPuppetAllowedUsersError, + PuppetUsageRights, }; use crate::texture::TextureId; @@ -40,6 +39,8 @@ pub enum InoxParseError { #[error(transparent)] InvalidMatrix2dData(#[from] Matrix2dFromSliceVecsError), #[error(transparent)] + UnknownParamMapMode(#[from] UnknownParamMapModeError), + #[error(transparent)] UnknownBlendMode(#[from] UnknownBlendModeError), #[error(transparent)] UnknownMaskMode(#[from] UnknownMaskModeError), @@ -160,11 +161,7 @@ fn deserialize_simple_physics(obj: &JsonObject) -> InoxParseResult todo!("{}", a), }; - let map_mode = match obj.get_str("map_mode")? { - "AngleLength" => ParamMapMode::AngleLength, - "XY" => ParamMapMode::XY, - a => todo!("{}", a), - }; + let map_mode = ParamMapMode::try_from(obj.get_str("map_mode")?)?; let local_only = obj.get_bool("local_only").unwrap_or_default(); @@ -198,7 +195,7 @@ fn deserialize_simple_physics(obj: &JsonObject) -> InoxParseResult InoxParseResult { Ok(Drawable { - blend_mode: BlendMode::try_from(obj.get_str("blend_mode").unwrap_or_default()).unwrap_or_default(), + blend_mode: BlendMode::try_from(obj.get_str("blend_mode")?).unwrap_or_default(), tint: obj.get_vec3("tint").unwrap_or(vec3(1.0, 1.0, 1.0)), screen_tint: obj.get_vec3("screenTint").unwrap_or(vec3(0.0, 0.0, 0.0)), mask_threshold: obj.get_f32("mask_threshold").unwrap_or(0.5), @@ -237,16 +234,12 @@ fn deserialize_mask(obj: &JsonObject) -> InoxParseResult { } fn deserialize_transform(obj: &JsonObject) -> InoxParseResult { - let translation = obj.get_vec3("trans")?; - let rotation = obj.get_vec3("rot")?; - let scale = obj.get_vec2("scale")?; - let pixel_snap = obj.get_bool("pixel_snap").unwrap_or_default(); - - Ok(TransformOffset::new() - .with_translation(translation) - .with_rotation(rotation) - .with_scale(scale) - .with_pixel_snap(pixel_snap)) + Ok(TransformOffset { + translation: obj.get_vec3("trans")?, + rotation: obj.get_vec3("rot")?, + scale: obj.get_vec2("scale")?, + pixel_snap: obj.get_bool("pixel_snap").unwrap_or_default(), + }) } fn deserialize_f32s(val: &[json::JsonValue]) -> Vec { diff --git a/inox2d/src/math/interp.rs b/inox2d/src/math/interp.rs index 005d201..a4a4f9d 100644 --- a/inox2d/src/math/interp.rs +++ b/inox2d/src/math/interp.rs @@ -1,28 +1,6 @@ use glam::Vec2; -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum InterpolateMode { - /// Round to nearest - Nearest, - /// Linear interpolation - Linear, - // there's more but I'm not adding them for now. -} - -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown interpolate mode {0:?}")] -pub struct UnknownInterpolateModeError(String); - -impl TryFrom<&str> for InterpolateMode { - type Error = UnknownInterpolateModeError; - - fn try_from(value: &str) -> Result { - match value { - "Linear" => Ok(InterpolateMode::Linear), - unknown => Err(UnknownInterpolateModeError(unknown.to_owned())), - } - } -} +use crate::node::data::InterpolateMode; #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] pub struct InterpRange { diff --git a/inox2d/src/math/transform.rs b/inox2d/src/math/transform.rs index 61a94a9..453fbb0 100644 --- a/inox2d/src/math/transform.rs +++ b/inox2d/src/math/transform.rs @@ -1,53 +1,8 @@ -use glam::{EulerRot, Mat4, Quat, Vec2, Vec3}; +use glam::{EulerRot, Mat4, Quat, Vec3}; -#[derive(Debug, Clone, Copy)] -pub struct TransformOffset { - /// X Y Z - pub translation: Vec3, - /// Euler angles - pub rotation: Vec3, - /// X Y zoom - pub scale: Vec2, - /// Whether the transform should snap to pixels - pub pixel_snap: bool, -} - -impl Default for TransformOffset { - fn default() -> Self { - Self { - translation: Vec3::ZERO, - rotation: Vec3::ZERO, - scale: Vec2::ONE, - pixel_snap: false, - } - } -} +use crate::node::data::TransformOffset; impl TransformOffset { - pub fn new() -> Self { - Self::default() - } - - pub fn with_translation(mut self, translation: Vec3) -> Self { - self.translation = translation; - self - } - - pub fn with_rotation(mut self, rotation: Vec3) -> Self { - self.rotation = rotation; - self - } - - pub fn with_scale(mut self, scale: Vec2) -> Self { - self.scale = scale; - self - } - - pub fn with_pixel_snap(mut self, pixel_snap: bool) -> Self { - self.pixel_snap = pixel_snap; - self - } - pub fn to_matrix(&self) -> Mat4 { Mat4::from_translation(self.translation) * Mat4::from_quat(Quat::from_euler( diff --git a/inox2d/src/node.rs b/inox2d/src/node.rs index 75f56f2..3143920 100644 --- a/inox2d/src/node.rs +++ b/inox2d/src/node.rs @@ -3,9 +3,7 @@ pub mod tree; use std::fmt::Debug; -use crate::math::transform::TransformOffset; - -use data::InoxData; +use data::{InoxData, TransformOffset}; #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] diff --git a/inox2d/src/node/data.rs b/inox2d/src/node/data.rs index eb1c17c..558f19f 100644 --- a/inox2d/src/node/data.rs +++ b/inox2d/src/node/data.rs @@ -9,6 +9,38 @@ use crate::texture::TextureId; use super::InoxNodeUuid; +#[derive(Debug, Clone, Copy)] +pub struct TransformOffset { + /// X Y Z + pub translation: Vec3, + /// Euler angles + pub rotation: Vec3, + /// X Y zoom + pub scale: Vec2, + /// Whether the transform should snap to pixels + pub pixel_snap: bool, +} + +impl Default for TransformOffset { + fn default() -> Self { + Self { + translation: Vec3::ZERO, + rotation: Vec3::ZERO, + scale: Vec2::ONE, + pixel_snap: false, + } + } +} + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum InterpolateMode { + /// Round to nearest + Nearest, + /// Linear interpolation + Linear, + // there's more but I'm not adding them for now. +} + /// Blending mode. #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BlendMode { @@ -46,27 +78,6 @@ impl BlendMode { ]; } -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown blend mode {0:?}")] -pub struct UnknownBlendModeError(String); - -impl TryFrom<&str> for BlendMode { - type Error = UnknownBlendModeError; - - fn try_from(value: &str) -> Result { - match value { - "Normal" => Ok(BlendMode::Normal), - "Multiply" => Ok(BlendMode::Multiply), - "ColorDodge" => Ok(BlendMode::ColorDodge), - "LinearDodge" => Ok(BlendMode::LinearDodge), - "Screen" => Ok(BlendMode::Screen), - "ClipToLower" => Ok(BlendMode::ClipToLower), - "SliceFromLower" => Ok(BlendMode::SliceFromLower), - unknown => Err(UnknownBlendModeError(unknown.to_owned())), - } - } -} - #[derive(Debug, Clone, Copy, PartialEq)] pub enum MaskMode { /// The part should be masked by the drawables specified. @@ -75,22 +86,6 @@ pub enum MaskMode { Dodge, } -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown mask mode {0:?}")] -pub struct UnknownMaskModeError(String); - -impl TryFrom<&str> for MaskMode { - type Error = UnknownMaskModeError; - - fn try_from(value: &str) -> Result { - match value { - "Mask" => Ok(MaskMode::Mask), - "DodgeMask" => Ok(MaskMode::Dodge), - unknown => Err(UnknownMaskModeError(unknown.to_owned())), - } - } -} - #[derive(Debug, Clone, PartialEq)] pub struct Mask { pub source: InoxNodeUuid, diff --git a/inox2d/src/params.rs b/inox2d/src/params.rs index ac748dc..c22f7f0 100644 --- a/inox2d/src/params.rs +++ b/inox2d/src/params.rs @@ -1,7 +1,8 @@ use glam::{vec2, Vec2}; -use crate::math::interp::{bi_interpolate_f32, bi_interpolate_vec2s_additive, InterpRange, InterpolateMode}; +use crate::math::interp::{bi_interpolate_f32, bi_interpolate_vec2s_additive, InterpRange}; use crate::math::matrix::Matrix2d; +use crate::node::data::InterpolateMode; use crate::node::InoxNodeUuid; use crate::puppet::Puppet; use crate::render::{NodeRenderCtxs, PartRenderCtx, RenderCtxKind}; @@ -242,4 +243,4 @@ impl Puppet { Ok(()) } -} \ No newline at end of file +} diff --git a/inox2d/src/puppet.rs b/inox2d/src/puppet.rs index 9dbb89b..af256fd 100644 --- a/inox2d/src/puppet.rs +++ b/inox2d/src/puppet.rs @@ -35,23 +35,6 @@ impl fmt::Display for PuppetAllowedUsers { } } -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown allowed users {0:?}")] -pub struct UnknownPuppetAllowedUsersError(String); - -impl TryFrom<&str> for PuppetAllowedUsers { - type Error = UnknownPuppetAllowedUsersError; - - fn try_from(value: &str) -> Result { - match value { - "OnlyAuthor" => Ok(PuppetAllowedUsers::OnlyAuthor), - "OnlyLicensee" => Ok(PuppetAllowedUsers::OnlyLicensee), - "Everyone" => Ok(PuppetAllowedUsers::Everyone), - unknown => Err(UnknownPuppetAllowedUsersError(unknown.to_owned())), - } - } -} - /// Can the puppet be redistributed? #[derive(Clone, Copy, Debug, Default)] pub enum PuppetAllowedRedistribution { @@ -82,23 +65,6 @@ impl fmt::Display for PuppetAllowedRedistribution { } } -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown allowed redistribution {0:?}")] -pub struct UnknownPuppetAllowedRedistributionError(String); - -impl TryFrom<&str> for PuppetAllowedRedistribution { - type Error = UnknownPuppetAllowedRedistributionError; - - fn try_from(value: &str) -> Result { - match value { - "Prohibited" => Ok(PuppetAllowedRedistribution::Prohibited), - "ViralLicense" => Ok(PuppetAllowedRedistribution::ViralLicense), - "CopyleftLicense" => Ok(PuppetAllowedRedistribution::CopyleftLicense), - unknown => Err(UnknownPuppetAllowedRedistributionError(unknown.to_owned())), - } - } -} - /// Can the puppet be modified? #[derive(Clone, Copy, Debug, Default)] pub enum PuppetAllowedModification { @@ -126,23 +92,6 @@ impl fmt::Display for PuppetAllowedModification { } } -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown allowed users {0:?}")] -pub struct UnknownPuppetAllowedModificationError(String); - -impl TryFrom<&str> for PuppetAllowedModification { - type Error = UnknownPuppetAllowedModificationError; - - fn try_from(value: &str) -> Result { - match value { - "Prohibited" => Ok(PuppetAllowedModification::Prohibited), - "AllowPersonal" => Ok(PuppetAllowedModification::AllowPersonal), - "AllowRedistribute" => Ok(PuppetAllowedModification::AllowRedistribute), - unknown => Err(UnknownPuppetAllowedModificationError(unknown.to_owned())), - } - } -} - /// Terms of usage of the puppet. #[derive(Clone, Debug, Default)] pub struct PuppetUsageRights { diff --git a/inox2d/src/render.rs b/inox2d/src/render.rs index 376b4b1..d2e2167 100644 --- a/inox2d/src/render.rs +++ b/inox2d/src/render.rs @@ -2,10 +2,9 @@ use std::collections::HashMap; use glam::{vec2, Mat4, Vec2}; -use crate::math::transform::TransformOffset; use crate::mesh::Mesh; use crate::model::Model; -use crate::node::data::{Composite, InoxData, MaskMode, Part}; +use crate::node::data::{Composite, InoxData, MaskMode, Part, TransformOffset}; use crate::node::tree::InoxNodeTree; use crate::node::InoxNodeUuid; use crate::puppet::Puppet; From 7a9fae5ce64d31e7015fb22b46f2877a667edb55 Mon Sep 17 00:00:00 2001 From: Ruiqi Niu Date: Wed, 6 Mar 2024 18:55:38 -0500 Subject: [PATCH 2/6] Typo. I am sorry. --- inox2d/src/formats/enums.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/inox2d/src/formats/enums.rs b/inox2d/src/formats/enums.rs index 0e69465..e2950a1 100644 --- a/inox2d/src/formats/enums.rs +++ b/inox2d/src/formats/enums.rs @@ -11,7 +11,7 @@ impl TryFrom<&str> for ParamMapMode { fn try_from(value: &str) -> Result { match value { "AngleLength" => Ok(ParamMapMode::AngleLength), - "XY" => Ok(ParamMapMode::AngleLength), + "XY" => Ok(ParamMapMode::XY), a => todo!("Param map mode {} unimplemented", a), } } From 3b6d89c80f8cc09dc590ae9cc236f48b01fbec85 Mon Sep 17 00:00:00 2001 From: Ruiqi Niu Date: Thu, 7 Mar 2024 10:43:32 -0500 Subject: [PATCH 3/6] Remove `enums.rs`. Inline enum variant matching, like the rest of `payload.rs`. --- inox2d/src/formats.rs | 1 - inox2d/src/formats/enums.rs | 121 ---------------------------------- inox2d/src/formats/payload.rs | 78 +++++++++++++++------- 3 files changed, 55 insertions(+), 145 deletions(-) delete mode 100644 inox2d/src/formats/enums.rs diff --git a/inox2d/src/formats.rs b/inox2d/src/formats.rs index 7e4ed8e..da5b130 100644 --- a/inox2d/src/formats.rs +++ b/inox2d/src/formats.rs @@ -1,4 +1,3 @@ -mod enums; pub mod inp; mod json; mod payload; diff --git a/inox2d/src/formats/enums.rs b/inox2d/src/formats/enums.rs deleted file mode 100644 index e2950a1..0000000 --- a/inox2d/src/formats/enums.rs +++ /dev/null @@ -1,121 +0,0 @@ -use crate::node::data::{BlendMode, InterpolateMode, MaskMode, ParamMapMode}; -use crate::puppet::{PuppetAllowedModification, PuppetAllowedRedistribution, PuppetAllowedUsers}; - -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown param map mode {0:?}")] -pub struct UnknownParamMapModeError(String); - -impl TryFrom<&str> for ParamMapMode { - type Error = UnknownBlendModeError; - - fn try_from(value: &str) -> Result { - match value { - "AngleLength" => Ok(ParamMapMode::AngleLength), - "XY" => Ok(ParamMapMode::XY), - a => todo!("Param map mode {} unimplemented", a), - } - } -} - -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown interpolate mode {0:?}")] -pub struct UnknownInterpolateModeError(String); - -impl TryFrom<&str> for InterpolateMode { - type Error = UnknownInterpolateModeError; - - fn try_from(value: &str) -> Result { - match value { - "Linear" => Ok(InterpolateMode::Linear), - unknown => Err(UnknownInterpolateModeError(unknown.to_owned())), - } - } -} - -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown blend mode {0:?}")] -pub struct UnknownBlendModeError(String); - -impl TryFrom<&str> for BlendMode { - type Error = UnknownBlendModeError; - - fn try_from(value: &str) -> Result { - match value { - "Normal" => Ok(BlendMode::Normal), - "Multiply" => Ok(BlendMode::Multiply), - "ColorDodge" => Ok(BlendMode::ColorDodge), - "LinearDodge" => Ok(BlendMode::LinearDodge), - "Screen" => Ok(BlendMode::Screen), - "ClipToLower" => Ok(BlendMode::ClipToLower), - "SliceFromLower" => Ok(BlendMode::SliceFromLower), - unknown => Err(UnknownBlendModeError(unknown.to_owned())), - } - } -} - -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown mask mode {0:?}")] -pub struct UnknownMaskModeError(String); - -impl TryFrom<&str> for MaskMode { - type Error = UnknownMaskModeError; - - fn try_from(value: &str) -> Result { - match value { - "Mask" => Ok(MaskMode::Mask), - "DodgeMask" => Ok(MaskMode::Dodge), - unknown => Err(UnknownMaskModeError(unknown.to_owned())), - } - } -} - -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown allowed users {0:?}")] -pub struct UnknownPuppetAllowedUsersError(String); - -impl TryFrom<&str> for PuppetAllowedUsers { - type Error = UnknownPuppetAllowedUsersError; - - fn try_from(value: &str) -> Result { - match value { - "OnlyAuthor" => Ok(PuppetAllowedUsers::OnlyAuthor), - "OnlyLicensee" => Ok(PuppetAllowedUsers::OnlyLicensee), - "Everyone" => Ok(PuppetAllowedUsers::Everyone), - unknown => Err(UnknownPuppetAllowedUsersError(unknown.to_owned())), - } - } -} - -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown allowed redistribution {0:?}")] -pub struct UnknownPuppetAllowedRedistributionError(String); - -impl TryFrom<&str> for PuppetAllowedRedistribution { - type Error = UnknownPuppetAllowedRedistributionError; - - fn try_from(value: &str) -> Result { - match value { - "Prohibited" => Ok(PuppetAllowedRedistribution::Prohibited), - "ViralLicense" => Ok(PuppetAllowedRedistribution::ViralLicense), - "CopyleftLicense" => Ok(PuppetAllowedRedistribution::CopyleftLicense), - unknown => Err(UnknownPuppetAllowedRedistributionError(unknown.to_owned())), - } - } -} - -#[derive(Debug, Clone, thiserror::Error)] -#[error("Unknown allowed users {0:?}")] -pub struct UnknownPuppetAllowedModificationError(String); - -impl TryFrom<&str> for PuppetAllowedModification { - type Error = UnknownPuppetAllowedModificationError; - - fn try_from(value: &str) -> Result { - match value { - "Prohibited" => Ok(PuppetAllowedModification::Prohibited), - "AllowPersonal" => Ok(PuppetAllowedModification::AllowPersonal), - "AllowRedistribute" => Ok(PuppetAllowedModification::AllowRedistribute), - unknown => Err(UnknownPuppetAllowedModificationError(unknown.to_owned())), - } - } -} diff --git a/inox2d/src/formats/payload.rs b/inox2d/src/formats/payload.rs index 2cb0bb0..a5b4f18 100644 --- a/inox2d/src/formats/payload.rs +++ b/inox2d/src/formats/payload.rs @@ -4,8 +4,6 @@ use glam::{vec2, vec3, Vec2}; use indextree::Arena; use json::JsonValue; -use super::enums::*; - use crate::math::matrix::{Matrix2d, Matrix2dFromSliceVecsError}; use crate::mesh::{f32s_as_vec2s, Mesh}; use crate::node::data::{ @@ -38,20 +36,18 @@ pub enum InoxParseError { NoAlbedoTexture, #[error(transparent)] InvalidMatrix2dData(#[from] Matrix2dFromSliceVecsError), - #[error(transparent)] - UnknownParamMapMode(#[from] UnknownParamMapModeError), - #[error(transparent)] - UnknownBlendMode(#[from] UnknownBlendModeError), - #[error(transparent)] - UnknownMaskMode(#[from] UnknownMaskModeError), - #[error(transparent)] - UnknownInterpolateMode(#[from] UnknownInterpolateModeError), - #[error(transparent)] - UnknownPuppetAllowedUsers(#[from] UnknownPuppetAllowedUsersError), - #[error(transparent)] - UnknownPuppetAllowedRedistribution(#[from] UnknownPuppetAllowedRedistributionError), - #[error(transparent)] - UnknownPuppetAllowedModification(#[from] UnknownPuppetAllowedModificationError), + #[error("Unknown param map mode {0:?}")] + UnknownParamMapMode(String), + #[error("Unknown mask mode {0:?}")] + UnknownMaskMode(String), + #[error("Unknown interpolate mode {0:?}")] + UnknownInterpolateMode(String), + #[error("Unknown allowed users {0:?}")] + UnknownPuppetAllowedUsers(String), + #[error("Unknown allowed redistribution {0:?}")] + UnknownPuppetAllowedRedistribution(String), + #[error("Unknown allowed modification {0:?}")] + UnknownPuppetAllowedModification(String), #[error("Expected even number of floats in list, got {0}")] OddNumberOfFloatsInList(usize), #[error("Expected 2 floats in list, got {0}")] @@ -161,7 +157,11 @@ fn deserialize_simple_physics(obj: &JsonObject) -> InoxParseResult todo!("{}", a), }; - let map_mode = ParamMapMode::try_from(obj.get_str("map_mode")?)?; + let map_mode = match obj.get_str("map_mode")? { + "AngleLength" => ParamMapMode::AngleLength, + "XY" => ParamMapMode::XY, + unknown => return Err(InoxParseError::UnknownParamMapMode(unknown.to_owned())), + }; let local_only = obj.get_bool("local_only").unwrap_or_default(); @@ -195,7 +195,16 @@ fn deserialize_simple_physics(obj: &JsonObject) -> InoxParseResult InoxParseResult { Ok(Drawable { - blend_mode: BlendMode::try_from(obj.get_str("blend_mode")?).unwrap_or_default(), + blend_mode: match obj.get_str("blend_mode")? { + "Normal" => BlendMode::Normal, + "Multiply" => BlendMode::Multiply, + "ColorDodge" => BlendMode::ColorDodge, + "LinearDodge" => BlendMode::LinearDodge, + "Screen" => BlendMode::Screen, + "ClipToLower" => BlendMode::ClipToLower, + "SliceFromLower" => BlendMode::SliceFromLower, + _ => BlendMode::default(), + }, tint: obj.get_vec3("tint").unwrap_or(vec3(1.0, 1.0, 1.0)), screen_tint: obj.get_vec3("screenTint").unwrap_or(vec3(0.0, 0.0, 0.0)), mask_threshold: obj.get_f32("mask_threshold").unwrap_or(0.5), @@ -229,7 +238,11 @@ fn deserialize_mesh(obj: &JsonObject) -> InoxParseResult { fn deserialize_mask(obj: &JsonObject) -> InoxParseResult { Ok(Mask { source: InoxNodeUuid(obj.get_u32("source")?), - mode: MaskMode::try_from(obj.get_str("mode")?)?, + mode: match obj.get_str("mode")? { + "Mask" => MaskMode::Mask, + "DodgeMask" => MaskMode::Dodge, + unknown => return Err(InoxParseError::UnknownMaskMode(unknown.to_owned())), + }, }) } @@ -346,7 +359,11 @@ fn deserialize_binding(obj: &JsonObject) -> InoxParseResult { Ok(Binding { node: InoxNodeUuid(obj.get_u32("node")?), is_set: Matrix2d::from_slice_vecs(&is_set, true)?, - interpolate_mode: InterpolateMode::try_from(obj.get_str("interpolate_mode")?)?, + interpolate_mode: match obj.get_str("interpolate_mode")? { + "Linear" => InterpolateMode::Linear, + "Nearest" => InterpolateMode::Nearest, + a => return Err(InoxParseError::UnknownInterpolateMode(a.to_owned())), + }, values: deserialize_binding_values(obj.get_str("param_name")?, obj.get_list("values")?)?, }) } @@ -484,12 +501,27 @@ fn deserialize_puppet_meta(obj: &JsonObject) -> InoxParseResult { fn deserialize_puppet_usage_rights(obj: &JsonObject) -> InoxParseResult { Ok(PuppetUsageRights { - allowed_users: PuppetAllowedUsers::try_from(obj.get_str("allowed_users")?)?, + allowed_users: match obj.get_str("allowed_users")? { + "OnlyAuthor" => PuppetAllowedUsers::OnlyAuthor, + "OnlyLicensee" => PuppetAllowedUsers::OnlyLicensee, + "Everyone" => PuppetAllowedUsers::Everyone, + unknown => return Err(InoxParseError::UnknownPuppetAllowedUsers(unknown.to_owned())), + }, allow_violence: obj.get_bool("allow_violence")?, allow_sexual: obj.get_bool("allow_sexual")?, allow_commercial: obj.get_bool("allow_commercial")?, - allow_redistribution: PuppetAllowedRedistribution::try_from(obj.get_str("allow_redistribution")?)?, - allow_modification: PuppetAllowedModification::try_from(obj.get_str("allow_modification")?)?, + allow_redistribution: match obj.get_str("allow_redistribution")? { + "Prohibited" => PuppetAllowedRedistribution::Prohibited, + "ViralLicense" => PuppetAllowedRedistribution::ViralLicense, + "CopyleftLicense" => PuppetAllowedRedistribution::CopyleftLicense, + unknown => return Err(InoxParseError::UnknownPuppetAllowedRedistribution(unknown.to_owned())), + }, + allow_modification: match obj.get_str("allow_modification")? { + "Prohibited" => PuppetAllowedModification::Prohibited, + "AllowPersonal" => PuppetAllowedModification::AllowPersonal, + "AllowRedistribute" => PuppetAllowedModification::AllowRedistribute, + unknown => return Err(InoxParseError::UnknownPuppetAllowedModification(unknown.to_owned())), + }, require_attribution: obj.get_bool("require_attribution")?, }) } From efa417f03111e9fc970d39ce5c0491f0c0440544 Mon Sep 17 00:00:00 2001 From: Ruiqi Niu Date: Thu, 7 Mar 2024 10:54:35 -0500 Subject: [PATCH 4/6] Put `TransformOffset` `InterpolateMode` back. --- inox2d/src/formats/payload.rs | 6 ++++-- inox2d/src/math/interp.rs | 9 ++++++++- inox2d/src/math/transform.rs | 25 +++++++++++++++++++++++-- inox2d/src/node.rs | 4 +++- inox2d/src/node/data.rs | 32 -------------------------------- inox2d/src/params.rs | 3 +-- inox2d/src/render.rs | 3 ++- 7 files changed, 41 insertions(+), 41 deletions(-) diff --git a/inox2d/src/formats/payload.rs b/inox2d/src/formats/payload.rs index a5b4f18..ecb4181 100644 --- a/inox2d/src/formats/payload.rs +++ b/inox2d/src/formats/payload.rs @@ -4,11 +4,13 @@ use glam::{vec2, vec3, Vec2}; use indextree::Arena; use json::JsonValue; +use crate::math::interp::InterpolateMode; use crate::math::matrix::{Matrix2d, Matrix2dFromSliceVecsError}; +use crate::math::transform::TransformOffset; use crate::mesh::{f32s_as_vec2s, Mesh}; use crate::node::data::{ - BlendMode, Composite, Drawable, InoxData, InterpolateMode, Mask, MaskMode, ParamMapMode, Part, PhysicsModel, - PhysicsProps, SimplePhysics, TransformOffset, + BlendMode, Composite, Drawable, InoxData, Mask, MaskMode, ParamMapMode, Part, PhysicsModel, PhysicsProps, + SimplePhysics, }; use crate::node::tree::InoxNodeTree; use crate::node::{InoxNode, InoxNodeUuid}; diff --git a/inox2d/src/math/interp.rs b/inox2d/src/math/interp.rs index a4a4f9d..ce5e969 100644 --- a/inox2d/src/math/interp.rs +++ b/inox2d/src/math/interp.rs @@ -1,6 +1,13 @@ use glam::Vec2; -use crate::node::data::InterpolateMode; +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +pub enum InterpolateMode { + /// Round to nearest + Nearest, + /// Linear interpolation + Linear, + // there's more but I'm not adding them for now. +} #[derive(Debug, Clone, Copy, Default, PartialEq, Eq)] pub struct InterpRange { diff --git a/inox2d/src/math/transform.rs b/inox2d/src/math/transform.rs index 453fbb0..33ff865 100644 --- a/inox2d/src/math/transform.rs +++ b/inox2d/src/math/transform.rs @@ -1,6 +1,27 @@ -use glam::{EulerRot, Mat4, Quat, Vec3}; +use glam::{EulerRot, Mat4, Quat, Vec2, Vec3}; -use crate::node::data::TransformOffset; +#[derive(Debug, Clone, Copy)] +pub struct TransformOffset { + /// X Y Z + pub translation: Vec3, + /// Euler angles + pub rotation: Vec3, + /// X Y zoom + pub scale: Vec2, + /// Whether the transform should snap to pixels + pub pixel_snap: bool, +} + +impl Default for TransformOffset { + fn default() -> Self { + Self { + translation: Vec3::ZERO, + rotation: Vec3::ZERO, + scale: Vec2::ONE, + pixel_snap: false, + } + } +} impl TransformOffset { pub fn to_matrix(&self) -> Mat4 { diff --git a/inox2d/src/node.rs b/inox2d/src/node.rs index 3143920..75f56f2 100644 --- a/inox2d/src/node.rs +++ b/inox2d/src/node.rs @@ -3,7 +3,9 @@ pub mod tree; use std::fmt::Debug; -use data::{InoxData, TransformOffset}; +use crate::math::transform::TransformOffset; + +use data::InoxData; #[derive(Debug, Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(transparent)] diff --git a/inox2d/src/node/data.rs b/inox2d/src/node/data.rs index 558f19f..805f68d 100644 --- a/inox2d/src/node/data.rs +++ b/inox2d/src/node/data.rs @@ -9,38 +9,6 @@ use crate::texture::TextureId; use super::InoxNodeUuid; -#[derive(Debug, Clone, Copy)] -pub struct TransformOffset { - /// X Y Z - pub translation: Vec3, - /// Euler angles - pub rotation: Vec3, - /// X Y zoom - pub scale: Vec2, - /// Whether the transform should snap to pixels - pub pixel_snap: bool, -} - -impl Default for TransformOffset { - fn default() -> Self { - Self { - translation: Vec3::ZERO, - rotation: Vec3::ZERO, - scale: Vec2::ONE, - pixel_snap: false, - } - } -} - -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum InterpolateMode { - /// Round to nearest - Nearest, - /// Linear interpolation - Linear, - // there's more but I'm not adding them for now. -} - /// Blending mode. #[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum BlendMode { diff --git a/inox2d/src/params.rs b/inox2d/src/params.rs index c22f7f0..71d471f 100644 --- a/inox2d/src/params.rs +++ b/inox2d/src/params.rs @@ -1,8 +1,7 @@ use glam::{vec2, Vec2}; -use crate::math::interp::{bi_interpolate_f32, bi_interpolate_vec2s_additive, InterpRange}; +use crate::math::interp::{bi_interpolate_f32, bi_interpolate_vec2s_additive, InterpRange, InterpolateMode}; use crate::math::matrix::Matrix2d; -use crate::node::data::InterpolateMode; use crate::node::InoxNodeUuid; use crate::puppet::Puppet; use crate::render::{NodeRenderCtxs, PartRenderCtx, RenderCtxKind}; diff --git a/inox2d/src/render.rs b/inox2d/src/render.rs index d2e2167..376b4b1 100644 --- a/inox2d/src/render.rs +++ b/inox2d/src/render.rs @@ -2,9 +2,10 @@ use std::collections::HashMap; use glam::{vec2, Mat4, Vec2}; +use crate::math::transform::TransformOffset; use crate::mesh::Mesh; use crate::model::Model; -use crate::node::data::{Composite, InoxData, MaskMode, Part, TransformOffset}; +use crate::node::data::{Composite, InoxData, MaskMode, Part}; use crate::node::tree::InoxNodeTree; use crate::node::InoxNodeUuid; use crate::puppet::Puppet; From 6d5414e37deeddb4d48e62ba4df6049bebc5d77f Mon Sep 17 00:00:00 2001 From: Ruiqi Niu Date: Thu, 7 Mar 2024 10:55:26 -0500 Subject: [PATCH 5/6] Collapse `deserialize_simple_physics()` like the rest of the code. --- inox2d/src/formats/payload.rs | 51 +++++++++++++---------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/inox2d/src/formats/payload.rs b/inox2d/src/formats/payload.rs index ecb4181..348b41d 100644 --- a/inox2d/src/formats/payload.rs +++ b/inox2d/src/formats/payload.rs @@ -151,45 +151,30 @@ fn deserialize_composite(obj: &JsonObject) -> InoxParseResult { } fn deserialize_simple_physics(obj: &JsonObject) -> InoxParseResult { - let param = ParamUuid(obj.get_u32("param")?); - - let model_type = match obj.get_str("model_type")? { - "Pendulum" => PhysicsModel::RigidPendulum(PhysicsState::default()), - "SpringPendulum" => PhysicsModel::SpringPendulum(PhysicsState::default()), - a => todo!("{}", a), - }; - - let map_mode = match obj.get_str("map_mode")? { - "AngleLength" => ParamMapMode::AngleLength, - "XY" => ParamMapMode::XY, - unknown => return Err(InoxParseError::UnknownParamMapMode(unknown.to_owned())), - }; - - let local_only = obj.get_bool("local_only").unwrap_or_default(); - - let gravity = obj.get_f32("gravity")?; - let length = obj.get_f32("length")?; - let frequency = obj.get_f32("frequency")?; - let angle_damping = obj.get_f32("angle_damping")?; - let length_damping = obj.get_f32("length_damping")?; - let output_scale = obj.get_vec2("output_scale")?; - Ok(SimplePhysics { - param, + param: ParamUuid(obj.get_u32("param")?), - model_type, - map_mode, + model_type: match obj.get_str("model_type")? { + "Pendulum" => PhysicsModel::RigidPendulum(PhysicsState::default()), + "SpringPendulum" => PhysicsModel::SpringPendulum(PhysicsState::default()), + a => todo!("{}", a), + }, + map_mode: match obj.get_str("map_mode")? { + "AngleLength" => ParamMapMode::AngleLength, + "XY" => ParamMapMode::XY, + unknown => return Err(InoxParseError::UnknownParamMapMode(unknown.to_owned())), + }, props: PhysicsProps { - gravity, - length, - frequency, - angle_damping, - length_damping, - output_scale, + gravity: obj.get_f32("gravity")?, + length: obj.get_f32("length")?, + frequency: obj.get_f32("frequency")?, + angle_damping: obj.get_f32("angle_damping")?, + length_damping: obj.get_f32("length_damping")?, + output_scale: obj.get_vec2("output_scale")?, }, - local_only, + local_only: obj.get_bool("local_only").unwrap_or_default(), bob: Vec2::ZERO, }) From b0bd7b805ba98b63bccdb47c65921175e8522267 Mon Sep 17 00:00:00 2001 From: Ruiqi Niu Date: Thu, 7 Mar 2024 10:59:08 -0500 Subject: [PATCH 6/6] `as_nested_list` helper used at multiple places to the top for readability. --- inox2d/src/formats/payload.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/inox2d/src/formats/payload.rs b/inox2d/src/formats/payload.rs index 348b41d..163db9c 100644 --- a/inox2d/src/formats/payload.rs +++ b/inox2d/src/formats/payload.rs @@ -69,6 +69,13 @@ fn vals(key: &str, res: InoxParseResult) -> InoxParseResult { res.map_err(|e| e.nested(key)) } +fn as_nested_list(index: usize, val: &json::JsonValue) -> InoxParseResult<&[json::JsonValue]> { + match val { + json::JsonValue::Array(arr) => Ok(arr), + _ => Err(InoxParseError::JsonError(JsonError::ValueIsNotList(index.to_string()))), + } +} + fn default_deserialize_custom(node_type: &str, _obj: &JsonObject) -> InoxParseResult { Err(InoxParseError::UnknownNodeType(node_type.to_owned())) } @@ -392,13 +399,6 @@ fn deserialize_inner_binding_values(values: &[JsonValue]) -> Result InoxParseResult<&[json::JsonValue]> { - match val { - json::JsonValue::Array(arr) => Ok(arr), - _ => Err(InoxParseError::JsonError(JsonError::ValueIsNotList(index.to_string()))), - } -} - fn deserialize_axis_points(vals: &[json::JsonValue]) -> InoxParseResult { let x = deserialize_f32s(as_nested_list(0, &vals[0])?); let y = deserialize_f32s(as_nested_list(1, &vals[1])?);