From 556de36cd664dc9109d980f1c78fe4d478a37e8c Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 12 Apr 2022 17:17:45 +0200 Subject: [PATCH 1/3] Add dedicated type for model parameters --- fj-app/src/main.rs | 6 +++--- fj-host/src/lib.rs | 19 ++++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/fj-app/src/main.rs b/fj-app/src/main.rs index 6589f1553..39c79a531 100644 --- a/fj-app/src/main.rs +++ b/fj-app/src/main.rs @@ -8,7 +8,7 @@ mod window; use std::path::PathBuf; use std::{collections::HashMap, time::Instant}; -use fj_host::Model; +use fj_host::{Model, Parameters}; use fj_interop::{debug::DebugInfo, mesh::Mesh}; use fj_kernel::algorithms::{triangulate, Tolerance}; use fj_math::{Aabb, Point, Scalar}; @@ -83,7 +83,7 @@ fn main() -> anyhow::Result<()> { }; if let Some(path) = args.export { - let shape = model.load_once(¶meters)?; + let shape = model.load_once(&Parameters(parameters))?; let shape = shape_processor.process(&shape); let vertices = @@ -111,7 +111,7 @@ fn main() -> anyhow::Result<()> { return Ok(()); } - let watcher = model.load_and_watch(parameters)?; + let watcher = model.load_and_watch(Parameters(parameters))?; let event_loop = EventLoop::new(); let window = Window::new(&event_loop); diff --git a/fj-host/src/lib.rs b/fj-host/src/lib.rs index 9689a68cb..64ba006e7 100644 --- a/fj-host/src/lib.rs +++ b/fj-host/src/lib.rs @@ -74,7 +74,7 @@ impl Model { /// model for changes, reloading it continually. pub fn load_once( &self, - arguments: &HashMap, + arguments: &Parameters, ) -> Result { let manifest_path = self.manifest_path.display().to_string(); @@ -120,7 +120,7 @@ impl Model { /// be queried for changes to the model. pub fn load_and_watch( self, - parameters: HashMap, + parameters: Parameters, ) -> Result { let (tx, rx) = mpsc::sync_channel(0); let tx2 = tx.clone(); @@ -202,7 +202,7 @@ pub struct Watcher { _watcher: Box, channel: mpsc::Receiver<()>, model: Model, - parameters: HashMap, + parameters: Parameters, } impl Watcher { @@ -243,6 +243,16 @@ impl Watcher { } } +/// Parameters that are passed to a model +pub struct Parameters(pub HashMap); + +impl Parameters { + /// Construct an empty instance of `Parameters` + pub fn empty() -> Self { + Self(HashMap::new()) + } +} + /// An error that can occur when loading or reloading a model #[derive(Debug, Error)] pub enum Error { @@ -263,5 +273,4 @@ pub enum Error { Notify(#[from] notify::Error), } -type ModelFn = - unsafe extern "C" fn(args: &HashMap) -> fj::Shape; +type ModelFn = unsafe extern "C" fn(args: &Parameters) -> fj::Shape; From f1a0b020651852f19764e43b0b24b261ea3ddd93 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 12 Apr 2022 17:32:51 +0200 Subject: [PATCH 2/3] Move model parameter parsing out of `main` --- fj-app/src/args.rs | 27 +++++++++++++++++++++++++-- fj-app/src/main.rs | 23 ++++------------------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/fj-app/src/args.rs b/fj-app/src/args.rs index 16cada701..aabaa3e60 100644 --- a/fj-app/src/args.rs +++ b/fj-app/src/args.rs @@ -1,5 +1,7 @@ use std::{path::PathBuf, str::FromStr as _}; +use anyhow::anyhow; +use fj_host::Parameters; use fj_kernel::algorithms::Tolerance; use fj_math::Scalar; @@ -15,8 +17,8 @@ pub struct Args { pub export: Option, /// Parameters for the model, each in the form `key=value` - #[clap(short, long)] - pub parameters: Vec, + #[clap(short, long, parse(try_from_str = parse_parameters))] + pub parameters: Option, /// Model deviation tolerance #[clap[short, long, parse(try_from_str = parse_tolerance)]] @@ -33,6 +35,27 @@ impl Args { } } +fn parse_parameters(input: &str) -> anyhow::Result { + let mut parameters = Parameters::empty(); + + for parameter in input.split(',') { + let mut parameter = parameter.splitn(2, '='); + + let key = parameter + .next() + .ok_or_else(|| anyhow!("Expected model parameter key"))? + .to_owned(); + let value = parameter + .next() + .ok_or_else(|| anyhow!("Expected model parameter value"))? + .to_owned(); + + parameters.0.insert(key, value); + } + + Ok(parameters) +} + fn parse_tolerance(input: &str) -> anyhow::Result { let tolerance = f64::from_str(input)?; let tolerance = Scalar::from_f64(tolerance); diff --git a/fj-app/src/main.rs b/fj-app/src/main.rs index 39c79a531..461a1cbbf 100644 --- a/fj-app/src/main.rs +++ b/fj-app/src/main.rs @@ -6,7 +6,7 @@ mod input; mod window; use std::path::PathBuf; -use std::{collections::HashMap, time::Instant}; +use std::time::Instant; use fj_host::{Model, Parameters}; use fj_interop::{debug::DebugInfo, mesh::Mesh}; @@ -61,29 +61,14 @@ fn main() -> anyhow::Result<()> { } let model = Model::from_path(path, config.target_dir)?; - - let mut parameters = HashMap::new(); - for parameter in args.parameters { - let mut parameter = parameter.splitn(2, '='); - - let key = parameter - .next() - .expect("model parameter: key not found") - .to_owned(); - let value = parameter - .next() - .expect("model parameter: value not found") - .to_owned(); - - parameters.insert(key, value); - } + let parameters = args.parameters.unwrap_or_else(Parameters::empty); let shape_processor = ShapeProcessor { tolerance: args.tolerance, }; if let Some(path) = args.export { - let shape = model.load_once(&Parameters(parameters))?; + let shape = model.load_once(¶meters)?; let shape = shape_processor.process(&shape); let vertices = @@ -111,7 +96,7 @@ fn main() -> anyhow::Result<()> { return Ok(()); } - let watcher = model.load_and_watch(Parameters(parameters))?; + let watcher = model.load_and_watch(parameters)?; let event_loop = EventLoop::new(); let window = Window::new(&event_loop); From b7a1b3439710e79411c313b6e52cc50a6a6f6118 Mon Sep 17 00:00:00 2001 From: Hanno Braun Date: Tue, 12 Apr 2022 17:48:08 +0200 Subject: [PATCH 3/3] Refactor --- fj-app/src/main.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/fj-app/src/main.rs b/fj-app/src/main.rs index 461a1cbbf..b44061526 100644 --- a/fj-app/src/main.rs +++ b/fj-app/src/main.rs @@ -8,6 +8,7 @@ mod window; use std::path::PathBuf; use std::time::Instant; +use anyhow::anyhow; use fj_host::{Model, Parameters}; use fj_interop::{debug::DebugInfo, mesh::Mesh}; use fj_kernel::algorithms::{triangulate, Tolerance}; @@ -48,17 +49,13 @@ fn main() -> anyhow::Result<()> { let config = Config::load()?; let mut path = config.default_path.unwrap_or_else(|| PathBuf::from("")); - match args.model.or(config.default_model) { - Some(model) => { - path.push(model); - } - None => { - anyhow::bail!( - "No model specified, and no default model configured.\n\ + let model = args.model.or(config.default_model).ok_or_else(|| { + anyhow!( + "No model specified, and no default model configured.\n\ Specify a model by passing `--model path/to/model`." - ); - } - } + ) + })?; + path.push(model); let model = Model::from_path(path, config.target_dir)?; let parameters = args.parameters.unwrap_or_else(Parameters::empty);