Merge pull request #466 from hannobraun/parameters

Add dedicated type for model parameters
This commit is contained in:
Hanno Braun 2022-04-12 18:38:58 +02:00 committed by GitHub
commit 49c533fb82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 49 additions and 35 deletions

View File

@ -1,5 +1,7 @@
use std::{path::PathBuf, str::FromStr as _}; use std::{path::PathBuf, str::FromStr as _};
use anyhow::anyhow;
use fj_host::Parameters;
use fj_kernel::algorithms::Tolerance; use fj_kernel::algorithms::Tolerance;
use fj_math::Scalar; use fj_math::Scalar;
@ -15,8 +17,8 @@ pub struct Args {
pub export: Option<PathBuf>, pub export: Option<PathBuf>,
/// Parameters for the model, each in the form `key=value` /// Parameters for the model, each in the form `key=value`
#[clap(short, long)] #[clap(short, long, parse(try_from_str = parse_parameters))]
pub parameters: Vec<String>, pub parameters: Option<Parameters>,
/// Model deviation tolerance /// Model deviation tolerance
#[clap[short, long, parse(try_from_str = parse_tolerance)]] #[clap[short, long, parse(try_from_str = parse_tolerance)]]
@ -33,6 +35,27 @@ impl Args {
} }
} }
fn parse_parameters(input: &str) -> anyhow::Result<Parameters> {
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<Tolerance> { fn parse_tolerance(input: &str) -> anyhow::Result<Tolerance> {
let tolerance = f64::from_str(input)?; let tolerance = f64::from_str(input)?;
let tolerance = Scalar::from_f64(tolerance); let tolerance = Scalar::from_f64(tolerance);

View File

@ -6,9 +6,10 @@ mod input;
mod window; mod window;
use std::path::PathBuf; use std::path::PathBuf;
use std::{collections::HashMap, time::Instant}; use std::time::Instant;
use fj_host::Model; use anyhow::anyhow;
use fj_host::{Model, Parameters};
use fj_interop::{debug::DebugInfo, mesh::Mesh}; use fj_interop::{debug::DebugInfo, mesh::Mesh};
use fj_kernel::algorithms::{triangulate, Tolerance}; use fj_kernel::algorithms::{triangulate, Tolerance};
use fj_math::{Aabb, Point, Scalar}; use fj_math::{Aabb, Point, Scalar};
@ -48,35 +49,16 @@ fn main() -> anyhow::Result<()> {
let config = Config::load()?; let config = Config::load()?;
let mut path = config.default_path.unwrap_or_else(|| PathBuf::from("")); let mut path = config.default_path.unwrap_or_else(|| PathBuf::from(""));
match args.model.or(config.default_model) { let model = args.model.or(config.default_model).ok_or_else(|| {
Some(model) => { anyhow!(
path.push(model);
}
None => {
anyhow::bail!(
"No model specified, and no default model configured.\n\ "No model specified, and no default model configured.\n\
Specify a model by passing `--model path/to/model`." Specify a model by passing `--model path/to/model`."
); )
} })?;
} path.push(model);
let model = Model::from_path(path, config.target_dir)?; let model = Model::from_path(path, config.target_dir)?;
let parameters = args.parameters.unwrap_or_else(Parameters::empty);
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 shape_processor = ShapeProcessor { let shape_processor = ShapeProcessor {
tolerance: args.tolerance, tolerance: args.tolerance,

View File

@ -74,7 +74,7 @@ impl Model {
/// model for changes, reloading it continually. /// model for changes, reloading it continually.
pub fn load_once( pub fn load_once(
&self, &self,
arguments: &HashMap<String, String>, arguments: &Parameters,
) -> Result<fj::Shape, Error> { ) -> Result<fj::Shape, Error> {
let manifest_path = self.manifest_path.display().to_string(); let manifest_path = self.manifest_path.display().to_string();
@ -120,7 +120,7 @@ impl Model {
/// be queried for changes to the model. /// be queried for changes to the model.
pub fn load_and_watch( pub fn load_and_watch(
self, self,
parameters: HashMap<String, String>, parameters: Parameters,
) -> Result<Watcher, Error> { ) -> Result<Watcher, Error> {
let (tx, rx) = mpsc::sync_channel(0); let (tx, rx) = mpsc::sync_channel(0);
let tx2 = tx.clone(); let tx2 = tx.clone();
@ -202,7 +202,7 @@ pub struct Watcher {
_watcher: Box<dyn notify::Watcher>, _watcher: Box<dyn notify::Watcher>,
channel: mpsc::Receiver<()>, channel: mpsc::Receiver<()>,
model: Model, model: Model,
parameters: HashMap<String, String>, parameters: Parameters,
} }
impl Watcher { impl Watcher {
@ -243,6 +243,16 @@ impl Watcher {
} }
} }
/// Parameters that are passed to a model
pub struct Parameters(pub HashMap<String, String>);
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 /// An error that can occur when loading or reloading a model
#[derive(Debug, Error)] #[derive(Debug, Error)]
pub enum Error { pub enum Error {
@ -263,5 +273,4 @@ pub enum Error {
Notify(#[from] notify::Error), Notify(#[from] notify::Error),
} }
type ModelFn = type ModelFn = unsafe extern "C" fn(args: &Parameters) -> fj::Shape;
unsafe extern "C" fn(args: &HashMap<String, String>) -> fj::Shape;