Add a builder interface for constructing params
This commit is contained in:
parent
342aebee89
commit
34fa536acb
1 changed files with 118 additions and 7 deletions
125
src/param.rs
125
src/param.rs
|
@ -1,4 +1,6 @@
|
||||||
//! TODO: Document how to use the [Param] trait. For the moment, just look at the gain example.
|
//! TODO: Document how to use the [Param] trait. Also mention both interfaces: direct initialization
|
||||||
|
//! + `..Default::default()`, and the builder interface. For the moment, just look at the gain
|
||||||
|
//! example.
|
||||||
|
|
||||||
use std::fmt::Display;
|
use std::fmt::Display;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -13,10 +15,6 @@ pub mod smoothing;
|
||||||
pub type FloatParam = PlainParam<f32>;
|
pub type FloatParam = PlainParam<f32>;
|
||||||
pub type IntParam = PlainParam<i32>;
|
pub type IntParam = PlainParam<i32>;
|
||||||
|
|
||||||
// TODO: Instead of having just structs with public fields and a Default instance, consider also
|
|
||||||
// adding `new` functions that take just the essentials (name, default value, range) and then
|
|
||||||
// have builders for the other fields. That might make the params object a bit less verbose.
|
|
||||||
|
|
||||||
/// Describes a single parameter of any type.
|
/// Describes a single parameter of any type.
|
||||||
pub trait Param: Display {
|
pub trait Param: Display {
|
||||||
/// The plain parameter type.
|
/// The plain parameter type.
|
||||||
|
@ -75,6 +73,9 @@ pub trait Param: Display {
|
||||||
|
|
||||||
/// A numerical parameter that's stored unnormalized. The range is used for the normalization
|
/// A numerical parameter that's stored unnormalized. The range is used for the normalization
|
||||||
/// process.
|
/// process.
|
||||||
|
///
|
||||||
|
/// You can either initialize the struct directly, using `..Default::default()` to fill in the
|
||||||
|
/// unused fields, or you can use the builder interface with [Self::new()].
|
||||||
//
|
//
|
||||||
// XXX: To keep the API simple and to allow the optimizer to do its thing, the values are stored as
|
// XXX: To keep the API simple and to allow the optimizer to do its thing, the values are stored as
|
||||||
// plain primitive values that are modified through the `*mut` pointers from the plugin's
|
// plain primitive values that are modified through the `*mut` pointers from the plugin's
|
||||||
|
@ -90,6 +91,8 @@ pub struct PlainParam<T> {
|
||||||
/// Storing parameter values like this instead of in a single contiguous array is bad for cache
|
/// Storing parameter values like this instead of in a single contiguous array is bad for cache
|
||||||
/// locality, but it does allow for a much nicer declarative API.
|
/// locality, but it does allow for a much nicer declarative API.
|
||||||
pub value: T,
|
pub value: T,
|
||||||
|
/// An optional smoother that will automatically interpolate between the new automation values
|
||||||
|
/// set by the host.
|
||||||
pub smoothed: Smoother<T>,
|
pub smoothed: Smoother<T>,
|
||||||
/// Optional callback for listening to value changes. The argument passed to this function is
|
/// Optional callback for listening to value changes. The argument passed to this function is
|
||||||
/// the parameter's new **plain** value. This should not do anything expensive as it may be
|
/// the parameter's new **plain** value. This should not do anything expensive as it may be
|
||||||
|
@ -97,13 +100,16 @@ pub struct PlainParam<T> {
|
||||||
///
|
///
|
||||||
/// To use this, you'll probably want to store an `Arc<Atomic*>` alongside the parmater in the
|
/// To use this, you'll probably want to store an `Arc<Atomic*>` alongside the parmater in the
|
||||||
/// parmaeters struct, move a clone of that `Arc` into this closure, and then modify that.
|
/// parmaeters struct, move a clone of that `Arc` into this closure, and then modify that.
|
||||||
|
///
|
||||||
|
/// TODO: We probably also want to pass the old value to this function.
|
||||||
pub value_changed: Option<Arc<dyn Fn(T) + Send + Sync>>,
|
pub value_changed: Option<Arc<dyn Fn(T) + Send + Sync>>,
|
||||||
|
|
||||||
/// The distribution of the parameter's values.
|
/// The distribution of the parameter's values.
|
||||||
pub range: Range<T>,
|
pub range: Range<T>,
|
||||||
/// The parameter's human readable display name.
|
/// The parameter's human readable display name.
|
||||||
pub name: &'static str,
|
pub name: &'static str,
|
||||||
/// The parameter value's unit, added after `value_to_string` if that is set.
|
/// The parameter value's unit, added after `value_to_string` if that is set. NIH-plug will not
|
||||||
|
/// automatically add a space before the unit.
|
||||||
pub unit: &'static str,
|
pub unit: &'static str,
|
||||||
/// Optional custom conversion function from a plain **unnormalized** value to a string.
|
/// Optional custom conversion function from a plain **unnormalized** value to a string.
|
||||||
pub value_to_string: Option<Arc<dyn Fn(T) -> String + Send + Sync>>,
|
pub value_to_string: Option<Arc<dyn Fn(T) -> String + Send + Sync>>,
|
||||||
|
@ -121,7 +127,8 @@ pub struct BoolParam {
|
||||||
|
|
||||||
/// Optional callback for listening to value changes. The argument passed to this function is
|
/// Optional callback for listening to value changes. The argument passed to this function is
|
||||||
/// the parameter's new value. This should not do anything expensive as it may be called
|
/// the parameter's new value. This should not do anything expensive as it may be called
|
||||||
/// multiple times in rapid succession.
|
/// multiple times in rapid succession, and it can be run from both the GUI and the audio
|
||||||
|
/// thread.
|
||||||
pub value_changed: Option<Arc<dyn Fn(bool) + Send + Sync>>,
|
pub value_changed: Option<Arc<dyn Fn(bool) + Send + Sync>>,
|
||||||
|
|
||||||
/// The parameter's human readable display name.
|
/// The parameter's human readable display name.
|
||||||
|
@ -350,3 +357,107 @@ impl Display for BoolParam {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T: Default> PlainParam<T>
|
||||||
|
where
|
||||||
|
Range<T>: Default,
|
||||||
|
{
|
||||||
|
/// Build a new [Self]. Use the other associated functions to modify the behavior of the
|
||||||
|
/// parameter.
|
||||||
|
pub fn new(name: &'static str, default: T, range: Range<T>) -> Self {
|
||||||
|
Self {
|
||||||
|
value: default,
|
||||||
|
range,
|
||||||
|
name,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run a callback whenever this parameter's value changes. The argument passed to this function
|
||||||
|
/// is the parameter's new value. This should not do anything expensive as it may be called
|
||||||
|
/// multiple times in rapid succession, and it can be run from both the GUI and the audio
|
||||||
|
/// thread.
|
||||||
|
pub fn with_smoother(mut self, smoother: Smoother<T>) -> Self {
|
||||||
|
self.smoothed = smoother;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run a callback whenever this parameter's value changes. The argument passed to this function
|
||||||
|
/// is the parameter's new value. This should not do anything expensive as it may be called
|
||||||
|
/// multiple times in rapid succession, and it can be run from both the GUI and the audio
|
||||||
|
/// thread.
|
||||||
|
pub fn with_callback(mut self, callback: Arc<dyn Fn(T) + Send + Sync>) -> Self {
|
||||||
|
self.value_changed = Some(callback);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Display a unit when rendering this parameter to a string. Appended after the
|
||||||
|
/// [Self::value_to_string] function if that is also set. NIH-plug will not
|
||||||
|
/// automatically add a space before the unit.
|
||||||
|
pub fn with_unit(mut self, unit: &'static str) -> Self {
|
||||||
|
self.unit = unit;
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use a custom conversion function to convert the plain, unnormalized value to a
|
||||||
|
/// string.
|
||||||
|
pub fn with_value_to_string(
|
||||||
|
mut self,
|
||||||
|
callback: Arc<dyn Fn(T) -> String + Send + Sync>,
|
||||||
|
) -> Self {
|
||||||
|
self.value_to_string = Some(callback);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use a custom conversion function to convert from a string to a plain, unnormalized
|
||||||
|
/// value. If the string cannot be parsed, then this should return a `None`. If this
|
||||||
|
/// happens while the parameter is being updated then the update will be canceled.
|
||||||
|
pub fn with_string_to_value<F>(
|
||||||
|
mut self,
|
||||||
|
callback: Arc<dyn Fn(&str) -> Option<T> + Send + Sync>,
|
||||||
|
) -> Self {
|
||||||
|
self.string_to_value = Some(callback);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BoolParam {
|
||||||
|
/// Build a new [Self]. Use the other associated functions to modify the behavior of the
|
||||||
|
/// parameter.
|
||||||
|
pub fn new(name: &'static str, default: bool) -> Self {
|
||||||
|
Self {
|
||||||
|
value: default,
|
||||||
|
name,
|
||||||
|
..Default::default()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Run a callback whenever this parameter's value changes. The argument passed to this function
|
||||||
|
/// is the parameter's new value. This should not do anything expensive as it may be called
|
||||||
|
/// multiple times in rapid succession, and it can be run from both the GUI and the audio
|
||||||
|
/// thread.
|
||||||
|
pub fn with_callback(mut self, callback: Arc<dyn Fn(bool) + Send + Sync>) -> Self {
|
||||||
|
self.value_changed = Some(callback);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use a custom conversion function to convert the boolean value to a string.
|
||||||
|
pub fn with_value_to_string(
|
||||||
|
mut self,
|
||||||
|
callback: Arc<dyn Fn(bool) -> String + Send + Sync>,
|
||||||
|
) -> Self {
|
||||||
|
self.value_to_string = Some(callback);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Use a custom conversion function to convert from a string to a boolean value. If the string
|
||||||
|
/// cannot be parsed, then this should return a `None`. If this happens while the parameter is
|
||||||
|
/// being updated then the update will be canceled.
|
||||||
|
pub fn with_string_to_value(
|
||||||
|
mut self,
|
||||||
|
callback: Arc<dyn Fn(&str) -> Option<bool> + Send + Sync>,
|
||||||
|
) -> Self {
|
||||||
|
self.string_to_value = Some(callback);
|
||||||
|
self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue