From 8774ee8caec9c4a97ec97a66904f8e03e004c328 Mon Sep 17 00:00:00 2001 From: Cassandra de la Cruz-Munoz Date: Mon, 1 Jan 2024 11:49:30 -0500 Subject: [PATCH] make trait object safe, add constructor for VmcExtOk --- src/lib.rs | 505 +++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 396 insertions(+), 109 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 7e68958..9f6b40a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,11 +5,10 @@ use godot::{ use rosc::{OscMessage, OscType}; use std::fmt; -pub trait MessageBehavior { +pub trait VmcMessage { fn to_osc_message(&self) -> OscMessage; - fn from_osc_message(msg: OscMessage) -> Result - where - Self: Sized; + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> where Self: Sized; + fn get_addr(&self) -> String; } pub struct ArgCountErr { @@ -37,7 +36,7 @@ impl fmt::Display for ArgTypeErr { } } -pub struct IntRangeErr { +pub struct FromIntRangeErr { expected_lower: i32, expected_upper: i32, actual: i32, @@ -45,25 +44,12 @@ pub struct IntRangeErr { arg_count: usize, } -impl fmt::Display for IntRangeErr { +impl fmt::Display for FromIntRangeErr { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "Invalid value of integer argument {} for message with address {}. Expected in range [{}, {}], received {}.", self.arg_count, self.addr, self.expected_lower, self.expected_upper, self.actual) } } -pub struct IntValErr { - expected_in: Vec, - actual: i32, - addr: String, - arg_count: usize, -} - -impl fmt::Display for IntValErr { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "Invalid value of integer argument {} for message with address {}. Expected {:?}, received {:?}.", self.arg_count, self.addr, self.expected_in, self.actual) - } -} - pub struct StrValErr { expected_in: Vec, actual: String, @@ -77,12 +63,53 @@ impl fmt::Display for StrValErr { } } +pub struct AddrErr { + addr: String +} + +impl fmt::Display for AddrErr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Invalid address: {}", self.addr) + } +} + pub enum FromMessageErr { ArgCount(ArgCountErr), ArgType(ArgTypeErr), - IntRange(IntRangeErr), - IntVal(IntValErr), + IntRange(FromIntRangeErr), StrVal(StrValErr), + Addr(AddrErr), +} + +pub struct CreateIntRangeErr { + expected_lower: i32, + expected_upper: i32, + actual: i32, + calling_func: String, + arg_name: String, +} + +impl fmt::Display for CreateIntRangeErr { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "Invalid value of integer argument \"{}\" for function \"{}\". Expected in range [{}, {}], received {}.", self.arg_name, self.calling_func, self.expected_lower, self.expected_upper, self.actual) + } +} + +pub struct CreateOptionalArgsErr { + expected_sets: Vec, + actual: String, + calling_func: String, +} + +impl fmt::Display for CreateOptionalArgsErr { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "Invalid set of optional arguments for function \"{}\". Expected set from {:?}, received [{}].", self.calling_func, self.expected_sets, self.actual) + } +} + +pub enum MessageCreationErr { + IntRange(CreateIntRangeErr), + OptionalArgs(CreateOptionalArgsErr), } #[derive(Debug)] @@ -93,7 +120,7 @@ struct VmcExtOk { tracking_status: Option, } -impl MessageBehavior for VmcExtOk { +impl VmcMessage for VmcExtOk { fn to_osc_message(&self) -> OscMessage { let addr = String::from("/VMC/Ext/OK"); let mut args: Vec = vec![OscType::from(self.loaded)]; @@ -108,7 +135,7 @@ impl MessageBehavior for VmcExtOk { } return OscMessage { addr, args }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { let mut result = VmcExtOk { loaded: -1, calibration_state: None, @@ -124,6 +151,9 @@ impl MessageBehavior for VmcExtOk { return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(),addr: msg.addr.to_owned(), arg_count: 0})); } } + if result.loaded < 0 || result.loaded > 1 { + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: result.loaded, addr: msg.addr, arg_count: 0})); + } } else { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1, 3, 4], actual: msg.args.len(), addr: msg.addr.to_owned()})); } @@ -136,6 +166,9 @@ impl MessageBehavior for VmcExtOk { return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr.to_owned(), arg_count: 1})); } } + if result.calibration_state.unwrap() < 0 || result.calibration_state.unwrap() > 3 { + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 3, actual: result.loaded, addr: msg.addr, arg_count: 1})); + } match msg.args[2] { OscType::Int(i) => { result.calibration_mode = Some(i); @@ -144,6 +177,9 @@ impl MessageBehavior for VmcExtOk { return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr.to_owned(), arg_count: 2})); } } + if result.calibration_mode.unwrap() < 0 || result.calibration_mode.unwrap() > 2 { + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 2, actual: result.loaded, addr: msg.addr, arg_count: 2})); + } } if msg.args.len() == 4 { match msg.args[3] { @@ -154,8 +190,51 @@ impl MessageBehavior for VmcExtOk { return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[3].to_owned(), addr: msg.addr.to_owned(), arg_count: 3})); } } + if result.tracking_status.unwrap() < 0 || result.tracking_status.unwrap() > 1 { + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: result.loaded, addr: msg.addr, arg_count: 3})); + } } - return Ok(result); + let boxed_result: Box = Box::new(result); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/OK"); + } +} + +impl VmcExtOk { + fn new(loaded: i32, calibration_state: Option, calibration_mode: Option, tracking_status: Option) -> Result { + if loaded < 0 || loaded > 1 { + return Err(MessageCreationErr::IntRange(CreateIntRangeErr { expected_lower: 0, expected_upper: 1, actual: loaded, calling_func: String::from("VmcExtOk::new"), arg_name: String::from("loaded")})); + } + if calibration_state.is_some() && calibration_mode.is_some() { + if calibration_state.unwrap() < 0 || calibration_state.unwrap() > 3 { + return Err(MessageCreationErr::IntRange(CreateIntRangeErr { expected_lower: 0, expected_upper: 3, actual: loaded, calling_func: String::from("VmcExtOk::new"), arg_name: String::from("calibration_state")})); + } + if calibration_mode.unwrap() < 0 || calibration_mode.unwrap() > 2 { + return Err(MessageCreationErr::IntRange(CreateIntRangeErr { expected_lower: 0, expected_upper: 2, actual: loaded, calling_func: String::from("VmcExtOk::new"), arg_name: String::from("calibration_mode")})); + } + if tracking_status.is_some() && (tracking_status.unwrap() < 0 || tracking_status.unwrap() > 1) { + return Err(MessageCreationErr::IntRange(CreateIntRangeErr { expected_lower: 0, expected_upper: 1, actual: loaded, calling_func: String::from("VmcExtOk::new"), arg_name: String::from("tracking_status")})); + } + return Ok(VmcExtOk { loaded, calibration_state, calibration_mode, tracking_status}) + } + if calibration_state.is_some() && tracking_status.is_none() { + return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("calibration_state"), calling_func: String::from("VmcExtOk::new")})) + } + if calibration_mode.is_some() && tracking_status.is_none() { + return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("calibration_mode"), calling_func: String::from("VmcExtOk::new")})) + } + if calibration_state.is_some() && tracking_status.is_some() { + return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("calibration_state, tracking_status"), calling_func: String::from("VmcExtOk::new")})) + } + if calibration_mode.is_some() && tracking_status.is_some() { + return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("calibration_mode, tracking_status"), calling_func: String::from("VmcExtOk::new")})) + } + if tracking_status.is_some() { + return Err(MessageCreationErr::OptionalArgs(CreateOptionalArgsErr { expected_sets: vec![String::from("None"), String::from("calibration_state, calibration_mode"), String::from("calibration_state, calibration_mode, tracking_status")], actual: String::from("tracking_status"), calling_func: String::from("VmcExtOk::new")})) + } + return Ok(VmcExtOk { loaded, calibration_state: None, calibration_mode: None, tracking_status: None}) } } @@ -164,21 +243,27 @@ struct VmcExtT { time: f32, } -impl MessageBehavior for VmcExtT { +impl VmcMessage for VmcExtT { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/T"), args: vec![OscType::from(self.time)], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); } + let time: f32; match msg.args[0] { - OscType::Float(f) => return Ok(VmcExtT { time: f }), + OscType::Float(f) => time = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } + let boxed_result: Box = Box::new(VmcExtT{time}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/T"); } } @@ -190,7 +275,7 @@ struct VmcExtRootPos { mr_offset: Option, } -impl MessageBehavior for VmcExtRootPos { +impl VmcMessage for VmcExtRootPos { fn to_osc_message(&self) -> OscMessage { let addr = String::from("/VMC/Ext/Root/Pos"); let quat = self.transform.basis.to_quat(); @@ -216,7 +301,7 @@ impl MessageBehavior for VmcExtRootPos { } return OscMessage { addr, args }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { let mut result: VmcExtRootPos; if msg.args.len() == 8 || msg.args.len() == 14 { let mut origin = Vector3::new(0.0, 0.0, 0.0); @@ -304,7 +389,11 @@ impl MessageBehavior for VmcExtRootPos { _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[13].to_owned(), addr: msg.addr, arg_count: 13})), } } - return Ok(result); + let boxed_result: Box = Box::new(result); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Root/Pos"); } } @@ -314,7 +403,7 @@ struct VmcExtBonePos { transform: Transform3D, } -impl MessageBehavior for VmcExtBonePos { +impl VmcMessage for VmcExtBonePos { fn to_osc_message(&self) -> OscMessage { let quat = self.transform.basis.to_quat(); return OscMessage { @@ -331,7 +420,7 @@ impl MessageBehavior for VmcExtBonePos { ], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { let name: String; let mut origin = Vector3::new(0.0, 0.0, 0.0); if msg.args.len() != 8 { @@ -375,10 +464,14 @@ impl MessageBehavior for VmcExtBonePos { OscType::Float(f) => quat.w = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[7].to_owned(), addr: msg.addr, arg_count: 7})), } - return Ok(VmcExtBonePos { + let boxed_result: Box = Box::new(VmcExtBonePos { name, transform: Transform3D::new(Basis::from_quat(quat), origin), }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Bone/Pos"); } } @@ -388,7 +481,7 @@ struct VmcExtBlendVal { value: f32, } -impl MessageBehavior for VmcExtBlendVal { +impl VmcMessage for VmcExtBlendVal { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Blend/Val"), @@ -398,7 +491,7 @@ impl MessageBehavior for VmcExtBlendVal { ], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { let name: String; let value: f32; if msg.args.len() != 2 { @@ -412,7 +505,11 @@ impl MessageBehavior for VmcExtBlendVal { OscType::Float(f) => value = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } - return Ok(VmcExtBlendVal { name, value }); + let boxed_result: Box = Box::new(VmcExtBlendVal { name, value }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Blend/Val"); } } @@ -423,7 +520,7 @@ struct VmcExtCam { fov: f32, } -impl MessageBehavior for VmcExtCam { +impl VmcMessage for VmcExtCam { fn to_osc_message(&self) -> OscMessage { let quat = self.transform.basis.to_quat(); return OscMessage { @@ -441,7 +538,7 @@ impl MessageBehavior for VmcExtCam { ], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 9 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![9], actual: msg.args.len(), addr: msg.addr})); } @@ -485,11 +582,15 @@ impl MessageBehavior for VmcExtCam { OscType::Float(f) => fov = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[8].to_owned(), addr: msg.addr, arg_count: 8})), } - return Ok(VmcExtCam { + let boxed_result: Box = Box::new(VmcExtCam { name, transform: Transform3D::new(Basis::from_quat(quat), origin), fov, }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Cam"); } } @@ -502,10 +603,10 @@ struct VmcExtCon { axis: Vector3, } -impl MessageBehavior for VmcExtCon { +impl VmcMessage for VmcExtCon { fn to_osc_message(&self) -> OscMessage { return OscMessage { - addr: String::from("/VMC/Ext/Cam"), + addr: String::from("/VMC/Ext/Con"), args: vec![ OscType::from(self.active), OscType::from(self.name.to_owned()), @@ -517,7 +618,7 @@ impl MessageBehavior for VmcExtCon { ], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 7 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![7], actual: msg.args.len(), addr: msg.addr})); } @@ -531,7 +632,7 @@ impl MessageBehavior for VmcExtCon { _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } if active > 2 || active < 0 { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 2, actual: active, addr: msg.addr, arg_count: 0})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 2, actual: active, addr: msg.addr, arg_count: 0})); } match &msg.args[1] { OscType::String(s) => name = s.to_owned(), @@ -542,14 +643,14 @@ impl MessageBehavior for VmcExtCon { _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } if is_left < 0 || is_left > 1 { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 1, actual: active, addr: msg.addr, arg_count: 2})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: active, addr: msg.addr, arg_count: 2})); } match msg.args[3] { OscType::Int(i) => is_touch = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } if is_touch < 0 || is_touch > 1 { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 1, actual: active, addr: msg.addr, arg_count: 3})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: active, addr: msg.addr, arg_count: 3})); } match msg.args[4] { OscType::Float(f) => axis.x = f, @@ -563,13 +664,17 @@ impl MessageBehavior for VmcExtCon { OscType::Float(f) => axis.z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[6].to_owned(), addr: msg.addr, arg_count: 6})), } - return Ok(VmcExtCon { + let boxed_result: Box = Box::new(VmcExtCon { active, name, is_left, is_touch, axis, }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Con"); } } @@ -580,7 +685,7 @@ struct VmcExtKey { keycode: i32, } -impl MessageBehavior for VmcExtKey { +impl VmcMessage for VmcExtKey { fn to_osc_message(&self) -> OscMessage { let mut args: Vec; if self.active { @@ -597,7 +702,7 @@ impl MessageBehavior for VmcExtKey { args, }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 3 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![3], actual: msg.args.len(), addr: msg.addr})); } @@ -611,7 +716,7 @@ impl MessageBehavior for VmcExtKey { } else if i == 0 { active = false; } else { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), @@ -624,11 +729,15 @@ impl MessageBehavior for VmcExtKey { OscType::Int(i) => keycode = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } - return Ok(VmcExtKey { + let boxed_result: Box = Box::new(VmcExtKey { active, name, keycode, }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Key"); } } @@ -640,7 +749,7 @@ struct VmcExtMidiNote { velocity: f32, } -impl MessageBehavior for VmcExtMidiNote { +impl VmcMessage for VmcExtMidiNote { fn to_osc_message(&self) -> OscMessage { let mut args: Vec; if self.active { @@ -658,7 +767,7 @@ impl MessageBehavior for VmcExtMidiNote { args, }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 4 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![4], actual: msg.args.len(), addr: msg.addr})); } @@ -673,7 +782,7 @@ impl MessageBehavior for VmcExtMidiNote { } else if i == 0 { active = false; } else { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), @@ -690,12 +799,16 @@ impl MessageBehavior for VmcExtMidiNote { OscType::Float(f) => velocity = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } - return Ok(VmcExtMidiNote { + let boxed_result: Box = Box::new(VmcExtMidiNote { active, channel, note, velocity, }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Midi/Note"); } } @@ -705,14 +818,14 @@ struct VmcExtMidiCcVal { value: f32, } -impl MessageBehavior for VmcExtMidiCcVal { +impl VmcMessage for VmcExtMidiCcVal { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Midi/CC/Val"), args: vec![OscType::from(self.knob), OscType::from(self.value)], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 2 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2], actual: msg.args.len(), addr: msg.addr})); } @@ -726,7 +839,11 @@ impl MessageBehavior for VmcExtMidiCcVal { OscType::Float(f) => value = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } - return Ok(VmcExtMidiCcVal { knob, value }); + let boxed_result: Box = Box::new(VmcExtMidiCcVal { knob, value }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Midi/CC/Val"); } } @@ -736,7 +853,7 @@ struct VmcExtMidiCcBit { active: bool, } -impl MessageBehavior for VmcExtMidiCcBit { +impl VmcMessage for VmcExtMidiCcBit { fn to_osc_message(&self) -> OscMessage { let mut args = vec![OscType::from(self.knob)]; if self.active { @@ -745,11 +862,11 @@ impl MessageBehavior for VmcExtMidiCcBit { args.push(OscType::from(0)); } return OscMessage { - addr: String::from("/VMC/Ext/Midi/CC/Val"), + addr: String::from("/VMC/Ext/Midi/CC/Bit"), args, }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 2 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2], actual: msg.args.len(), addr: msg.addr})); } @@ -766,12 +883,16 @@ impl MessageBehavior for VmcExtMidiCcBit { } else if i == 1 { active = true; } else { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 1})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 1})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } - return Ok(VmcExtMidiCcBit { knob, active }); + let boxed_result: Box = Box::new(VmcExtMidiCcBit { knob, active }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Midi/CC/Bit"); } } @@ -782,7 +903,7 @@ struct DeviceTranform { transform: Transform3D, } -impl MessageBehavior for DeviceTranform { +impl VmcMessage for DeviceTranform { fn to_osc_message(&self) -> OscMessage { let quat = self.transform.basis.to_quat(); return OscMessage { @@ -799,7 +920,7 @@ impl MessageBehavior for DeviceTranform { ], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 8 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![8], actual: msg.args.len(), addr: msg.addr})); } @@ -838,11 +959,15 @@ impl MessageBehavior for DeviceTranform { OscType::Float(f) => quat.w = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[7].to_owned(), addr: msg.addr, arg_count: 7})), } - return Ok(DeviceTranform { + let boxed_result: Box = Box::new(DeviceTranform { addr: msg.addr.to_owned(), serial, transform: Transform3D::new(Basis::from_quat(quat), origin), }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return self.addr.to_owned(); } } @@ -853,7 +978,7 @@ struct VmcExtRvc { ip_addr: Option, } -impl MessageBehavior for VmcExtRvc { +impl VmcMessage for VmcExtRvc { fn to_osc_message(&self) -> OscMessage { let mut args: Vec; if self.enable { @@ -870,7 +995,7 @@ impl MessageBehavior for VmcExtRvc { args, }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() < 2 || msg.args.len() > 3 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2, 3], actual: msg.args.len(), addr: msg.addr})); } @@ -884,7 +1009,7 @@ impl MessageBehavior for VmcExtRvc { } else if i == 1 { enable = true; } else { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), @@ -894,7 +1019,7 @@ impl MessageBehavior for VmcExtRvc { if i >= 0 && i <= 65535 { port = i as u16; } else { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 65535, actual: i, addr: msg.addr, arg_count: 1})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 65535, actual: i, addr: msg.addr, arg_count: 1})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), @@ -905,11 +1030,15 @@ impl MessageBehavior for VmcExtRvc { _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } } - return Ok(VmcExtRvc { + let boxed_result: Box = Box::new(VmcExtRvc { enable, port, ip_addr, }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Rvc"); } } @@ -920,7 +1049,7 @@ struct VmcExtLight { color: Color, } -impl MessageBehavior for VmcExtLight { +impl VmcMessage for VmcExtLight { fn to_osc_message(&self) -> OscMessage { let quat = self.transform.basis.to_quat(); return OscMessage { @@ -941,7 +1070,7 @@ impl MessageBehavior for VmcExtLight { ], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 12 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![12], actual: msg.args.len(), addr: msg.addr})); } @@ -997,11 +1126,15 @@ impl MessageBehavior for VmcExtLight { OscType::Float(f) => color.a = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[11].to_owned(), addr: msg.addr, arg_count: 11})), } - return Ok(VmcExtLight { + let boxed_result: Box = Box::new(VmcExtLight { name, transform: Transform3D::new(Basis::from_quat(quat), origin), color, }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Light"); } } @@ -1012,7 +1145,7 @@ struct VmcExtVrm { hash: Option, } -impl MessageBehavior for VmcExtVrm { +impl VmcMessage for VmcExtVrm { fn to_osc_message(&self) -> OscMessage { let mut args = vec![ OscType::from(self.path.to_owned()), @@ -1026,7 +1159,7 @@ impl MessageBehavior for VmcExtVrm { args, }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() < 2 || msg.args.len() > 3 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2, 3], actual: msg.args.len(), addr: msg.addr})); } @@ -1047,7 +1180,11 @@ impl MessageBehavior for VmcExtVrm { _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[2].to_owned(), addr: msg.addr, arg_count: 2})), } } - return Ok(VmcExtVrm { path, title, hash }); + let boxed_result: Box = Box::new(VmcExtVrm { path, title, hash }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/Vmc/Ext/VRM"); } } @@ -1057,7 +1194,7 @@ struct VmcExtRemote { json: String, } -impl MessageBehavior for VmcExtRemote { +impl VmcMessage for VmcExtRemote { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Remote"), @@ -1067,7 +1204,7 @@ impl MessageBehavior for VmcExtRemote { ], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 2 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![2], actual: msg.args.len(), addr: msg.addr})); } @@ -1081,7 +1218,11 @@ impl MessageBehavior for VmcExtRemote { OscType::String(s) => json = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), } - return Ok(VmcExtRemote { service, json }); + let boxed_result: Box = Box::new(VmcExtRemote{ service, json }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Remote"); } } @@ -1090,25 +1231,29 @@ struct VmcExtOpt { option: String, } -impl MessageBehavior for VmcExtOpt { +impl VmcMessage for VmcExtOpt { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Opt"), args: vec![OscType::from(self.option.to_owned())], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); } + let option: String; match &msg.args[0] { - OscType::String(s) => { - return Ok(VmcExtOpt { - option: s.to_owned(), - }) - } + OscType::String(s) => + option = s.to_owned(), + _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } + let boxed_result: Box = Box::new(VmcExtOpt{option}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Opt"); } } @@ -1117,7 +1262,7 @@ struct VmcExtSettingColor { color: Color, } -impl MessageBehavior for VmcExtSettingColor { +impl VmcMessage for VmcExtSettingColor { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Setting/Color"), @@ -1129,7 +1274,7 @@ impl MessageBehavior for VmcExtSettingColor { ], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 4 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![4], actual: msg.args.len(), addr: msg.addr})); } @@ -1150,7 +1295,11 @@ impl MessageBehavior for VmcExtSettingColor { OscType::Float(f) => color.a = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } - return Ok(VmcExtSettingColor { color }); + let boxed_result: Box = Box::new(VmcExtSettingColor{color}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Setting/Color"); } } @@ -1162,7 +1311,7 @@ struct VmcExtSettingWin { hide_border: i32, } -impl MessageBehavior for VmcExtSettingWin { +impl VmcMessage for VmcExtSettingWin { fn to_osc_message(&self) -> OscMessage { let mut args: Vec; if self.is_top_most { @@ -1184,7 +1333,7 @@ impl MessageBehavior for VmcExtSettingWin { args, }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 4 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![4], actual: msg.args.len(), addr: msg.addr})); } @@ -1199,7 +1348,7 @@ impl MessageBehavior for VmcExtSettingWin { if i == 1 { result.is_top_most = true; } else if i != 0 { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 0})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), @@ -1209,7 +1358,7 @@ impl MessageBehavior for VmcExtSettingWin { if i == 1 { result.is_transparent = true; } else if i != 0 { - return Err(FromMessageErr::IntRange(IntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 1})); + return Err(FromMessageErr::IntRange(FromIntRangeErr { expected_lower: 0, expected_upper: 1, actual: i, addr: msg.addr, arg_count: 1})); } } _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})), @@ -1222,7 +1371,11 @@ impl MessageBehavior for VmcExtSettingWin { OscType::Int(i) => result.hide_border = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})), } - return Ok(result); + let boxed_result: Box = Box::new(result); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Setting/Win"); } } @@ -1231,21 +1384,27 @@ struct VmcExtConfig { path: String, } -impl MessageBehavior for VmcExtConfig { +impl VmcMessage for VmcExtConfig { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Config"), args: vec![OscType::from(self.path.to_owned())], }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr })); } + let path: String; match &msg.args[0] { - OscType::String(s) => return Ok(VmcExtConfig { path: s.to_owned() }), + OscType::String(s) => path = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})), } + let boxed_result: Box = Box::new(VmcExtConfig{path}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Config"); } } @@ -1262,7 +1421,7 @@ struct VmcThru { arg2: Option } -impl MessageBehavior for VmcThru { +impl VmcMessage for VmcThru { fn to_osc_message(&self) -> OscMessage { let mut args = vec![OscType::from(self.arg1.to_owned() )]; @@ -1274,7 +1433,7 @@ impl MessageBehavior for VmcThru { } return OscMessage { addr: self.addr.to_owned(), args} } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() > 2 || msg.args.len() < 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1, 2], actual: msg.args.len(), addr: msg.addr})); } @@ -1291,7 +1450,11 @@ impl MessageBehavior for VmcThru { _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0), OscType::Float(0.0)], actual: msg.args[1].to_owned(), addr: msg.addr, arg_count: 1})) } } - return Ok(VmcThru { addr: msg.addr, arg1 , arg2 }) + let boxed_result: Box = Box::new(VmcThru { addr: msg.addr, arg1 , arg2 }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return self.addr.to_owned(); } } @@ -1305,7 +1468,7 @@ struct VmcExtSetPeriod { devices: i32 } -impl MessageBehavior for VmcExtSetPeriod { +impl VmcMessage for VmcExtSetPeriod { fn to_osc_message(&self) -> OscMessage { return OscMessage { addr: String::from("/VMC/Ext/Set/Period"), args: vec![ OscType::from(self.status), @@ -1316,7 +1479,7 @@ impl MessageBehavior for VmcExtSetPeriod { OscType::from(self.devices), ] }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 6 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![6], actual: msg.args.len(), addr: msg.addr})); } @@ -1350,7 +1513,11 @@ impl MessageBehavior for VmcExtSetPeriod { OscType::Int(i) => devices = i, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[5].to_owned(), addr: msg.addr, arg_count: 5})) } - return Ok(VmcExtSetPeriod { status, root, bone, blendshape, camera, devices}) + let boxed_result: Box = Box::new(VmcExtSetPeriod { status, root, bone, blendshape, camera, devices}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Set/Period"); } } @@ -1360,7 +1527,7 @@ struct VmcExtSetEye { position: Vector3, } -impl MessageBehavior for VmcExtSetEye { +impl VmcMessage for VmcExtSetEye { fn to_osc_message(&self) -> OscMessage { return OscMessage{ addr: String::from("/VMC/Ext/Set/Eye"), args: vec![ OscType::from(self.enable), @@ -1370,7 +1537,7 @@ impl MessageBehavior for VmcExtSetEye { ] }; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 4 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![4], actual: msg.args.len(), addr: msg.addr})); } @@ -1395,7 +1562,11 @@ impl MessageBehavior for VmcExtSetEye { OscType::Float(f) => z = f, _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Float(0.0)], actual: msg.args[3].to_owned(), addr: msg.addr, arg_count: 3})) } - return Ok(VmcExtSetEye { enable, position: Vector3::new(x, y, z)}) + let boxed_result: Box = Box::new(VmcExtSetEye { enable, position: Vector3::new(x, y, z)}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Set/Eye"); } } @@ -1404,17 +1575,133 @@ struct VmcExtSetRes { response: String } -impl MessageBehavior for VmcExtSetRes { +impl VmcMessage for VmcExtSetRes { fn to_osc_message(&self) -> OscMessage { return OscMessage{addr: String::from("/VMC/Ext/Set/Res"), args: vec![OscType::from(self.response.to_owned())]}; } - fn from_osc_message(msg: OscMessage) -> Result { + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { if msg.args.len() != 1 { return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); } + let response: String; match &msg.args[0] { - OscType::String(s) => return Ok(VmcExtSetRes{response: s.to_owned()}), + OscType::String(s) => response = s.to_owned(), _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})) } + let boxed_result: Box = Box::new(VmcExtSetRes{response}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Set/Res"); + } +} + +#[derive(Debug)] +struct VmcExtSetCalibExec { + mode: i32 +} + +impl VmcMessage for VmcExtSetCalibExec { + fn to_osc_message(&self) -> OscMessage { + return OscMessage{addr: String::from("/VMC/Ext/Set/Calib/Exec"), args: vec![OscType::from(self.mode)]}; + } + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { + if msg.args.len() != 1 { + return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); + } + let mode: i32; + match msg.args[0] { + OscType::Int(i) => mode = i, + _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::Int(0)], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})) + } + let boxed_result: Box = Box::new(VmcExtSetCalibExec{mode}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Set/Calib/Exec"); + } +} + +#[derive(Debug)] +struct VmcExtSetConfig { + path: String +} + +impl VmcMessage for VmcExtSetConfig { + fn to_osc_message(&self) -> OscMessage { + return OscMessage{addr: String::from("/VMC/Ext/Set/Res"), args: vec![OscType::from(self.path.to_owned())]}; + } + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { + if msg.args.len() != 1 { + return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![1], actual: msg.args.len(), addr: msg.addr})); + } + let path: String; + match &msg.args[0] { + OscType::String(s) => path = s.to_owned(), + _ => return Err(FromMessageErr::ArgType(ArgTypeErr { expected: vec![OscType::String(String::new())], actual: msg.args[0].to_owned(), addr: msg.addr, arg_count: 0})) + } + let boxed_result: Box = Box::new(VmcExtSetConfig{path}); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return String::from("/VMC/Ext/Set/Res"); + } +} + +#[derive(Debug)] +struct VmcMessageNoArgs { + addr: String +} + +impl VmcMessage for VmcMessageNoArgs { + fn to_osc_message(&self) -> OscMessage { + return OscMessage { addr: self.addr.to_owned(), args: Vec::new()} + } + fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { + if msg.args.len() != 0 { + return Err(FromMessageErr::ArgCount(ArgCountErr { expected_in: vec![0], actual: msg.args.len(), addr: msg.addr})) + } + let boxed_result: Box = Box::new(VmcMessageNoArgs { addr: msg.addr }); + return Ok(boxed_result); + } + fn get_addr(&self) -> String { + return self.addr.to_owned(); + } +} + +pub fn from_osc_message(msg: OscMessage) -> Result, FromMessageErr> { + match msg.addr.as_str() { + "/VMC/Ext/OK" => VmcExtOk::from_osc_message(msg), + "/VMC/Ext/T" => VmcExtT::from_osc_message(msg), + "/VMC/Ext/Root/Pos" => VmcExtRootPos::from_osc_message(msg), + "/VMC/Ext/Bone/Pos" => VmcExtBonePos::from_osc_message(msg), + "/VMC/Ext/Blend/Val" => VmcExtBlendVal::from_osc_message(msg), + "/VMC/Ext/Blend/Apply" | "/VMC/Ext/Set/Req" | "/VMC/Ext/Set/Calib/Ready" => VmcMessageNoArgs::from_osc_message(msg), + "/VMC/Ext/Cam" => VmcExtCam::from_osc_message(msg), + "/VMC/Ext/Con" => VmcExtCon::from_osc_message(msg), + "/VMC/Ext/Key" => VmcExtKey::from_osc_message(msg), + "/VMC/Ext/Midi/Note" => VmcExtMidiNote::from_osc_message(msg), + "/VMC/Ext/Midi/CC/Val" => VmcExtMidiCcVal::from_osc_message(msg), + "/VMC/Ext/Midi/CC/Bit" => VmcExtMidiCcBit::from_osc_message(msg), + "/VMC/Ext/Hmd/Pos" | "/VMC/Ext/Con/Pos" | "/VMC/Ext/Tra/Pos" | "/VMC/Ext/Hmd/Pos/Local" | "/VMC/Ext/Con/Pos/Local" | "/VMC/Ext/Tra/Pos/Local" => DeviceTranform::from_osc_message(msg), + "/VMC/Ext/Rcv" => VmcExtRvc::from_osc_message(msg), + "/VMC/Ext/Light" => VmcExtLight::from_osc_message(msg), + "/VMC/Ext/VRM" => VmcExtVrm::from_osc_message(msg), + "/VMC/Ext/Remote" => VmcExtRemote::from_osc_message(msg), + "/VMC/Ext/Opt" => VmcExtOpt::from_osc_message(msg), + "/VMC/Ext/Setting/Color" => VmcExtSettingColor::from_osc_message(msg), + "/VMC/Ext/Setting/Win" => VmcExtSettingWin::from_osc_message(msg), + "/VMC/Ext/Config" => VmcExtConfig::from_osc_message(msg), + "/VMC/Ext/Set/Period" => VmcExtSetPeriod::from_osc_message(msg), + "/VMC/Ext/Set/Eye" => VmcExtSetEye::from_osc_message(msg), + "/VMC/Ext/Set/Res" => VmcExtSetRes::from_osc_message(msg), + "/VMC/Ext/Set/Calib/Exec" => VmcExtSetCalibExec::from_osc_message(msg), + "/VMC/Ext/Set/Config" => VmcExtSetConfig::from_osc_message(msg), + _ => { + if &msg.addr[0..10] == "/VMC/Thru/" { + return VmcThru::from_osc_message(msg) + } + Err(FromMessageErr::Addr(AddrErr { addr: msg.addr })) + } } }