diff --git a/nih_plug/src/params.rs b/nih_plug/src/params.rs index 53b22133..11e29618 100644 --- a/nih_plug/src/params.rs +++ b/nih_plug/src/params.rs @@ -62,88 +62,6 @@ pub struct PlainParam<T> { pub string_to_value: Option<Box<dyn Fn(&str) -> Option<T>>>, } -/// Describes a single normalized parameter and also stores its value. -/// -/// TODO: This is an implementation detail, maybe hide this somewhere else -#[derive(Debug)] -pub enum ParamPtr { - FloatParam(*mut FloatParam), - IntParam(*mut IntParam), -} - -/// Describes a struct containing parameters. The idea is that we can have a normal struct -/// containing [FloatParam] and other parameter types with attributes describing a unique identifier -/// for each parameter. We can then build a mapping from those parameter IDs to the parameters using -/// the [param_map] function. That way we can have easy to work with JUCE-style parameter objects in -/// the plugin without needing to manually register each parameter, like you would in JUCE. -/// -/// # Safety -/// -/// This implementation is safe when using from the wrapper because the plugin object needs to be -/// pinned, and it can never outlive the wrapper. -/// -/// TODO: Create a derive macro for this -pub trait Params { - /// Create a mapping from unique parameter IDs to parameters. Dereferencing the pointers stored - /// in the values is only valid as long as this pinned object is valid. - fn param_map(self: Pin<&Self>) -> HashMap<&'static str, ParamPtr>; -} - -impl ParamPtr { - /// Get the human readable name for this parameter. - /// - /// # Safety - /// - /// Calling this function is only safe as long as the object this `ParamPtr` was created for is - /// still alive. - pub unsafe fn name(&self) -> &'static str { - match &self { - ParamPtr::FloatParam(p) => (**p).name, - ParamPtr::IntParam(p) => (**p).name, - } - } - - /// Set this parameter based on a string. Returns whether the updating succeeded. That can fail - /// if the string cannot be parsed. - /// - /// # Safety - /// - /// Calling this function is only safe as long as the object this `ParamPtr` was created for is - /// still alive. - pub unsafe fn from_string(&mut self, string: &str) -> bool { - match &self { - ParamPtr::FloatParam(p) => (**p).from_string(string), - ParamPtr::IntParam(p) => (**p).from_string(string), - } - } - - /// Get the normalized `[0, 1]` value for this parameter. - /// - /// # Safety - /// - /// Calling this function is only safe as long as the object this `ParamPtr` was created for is - /// still alive. - pub unsafe fn normalized_value(&self) -> f32 { - match &self { - ParamPtr::FloatParam(p) => (**p).normalized_value(), - ParamPtr::IntParam(p) => (**p).normalized_value(), - } - } - - /// Set this parameter based on a normalized value. - /// - /// # Safety - /// - /// Calling this function is only safe as long as the object this `ParamPtr` was created for is - /// still alive. - pub unsafe fn set_normalized_value(&self, normalized: f32) { - match &self { - ParamPtr::FloatParam(p) => (**p).set_normalized_value(normalized), - ParamPtr::IntParam(p) => (**p).set_normalized_value(normalized), - } - } -} - macro_rules! impl_plainparam { ($ty:ident) => { impl $ty { @@ -227,6 +145,86 @@ impl NormalizebleRange<i32> for Range<i32> { } } +/// Describes a struct containing parameters. The idea is that we can have a normal struct +/// containing [FloatParam] and other parameter types with attributes describing a unique identifier +/// for each parameter. We can then build a mapping from those parameter IDs to the parameters using +/// the [param_map] function. That way we can have easy to work with JUCE-style parameter objects in +/// the plugin without needing to manually register each parameter, like you would in JUCE. +/// +/// # Safety +/// +/// This implementation is safe when using from the wrapper because the plugin object needs to be +/// pinned, and it can never outlive the wrapper. +/// +/// TODO: Create a derive macro for this +pub trait Params { + /// Create a mapping from unique parameter IDs to parameters. Dereferencing the pointers stored + /// in the values is only valid as long as this pinned object is valid. + fn param_map(self: Pin<&Self>) -> HashMap<&'static str, ParamPtr>; +} + +/// Internal pointers to parameters. This is an implementation detail used by the wrappers. +#[derive(Debug)] +pub enum ParamPtr { + FloatParam(*mut FloatParam), + IntParam(*mut IntParam), +} + +impl ParamPtr { + /// Get the human readable name for this parameter. + /// + /// # Safety + /// + /// Calling this function is only safe as long as the object this `ParamPtr` was created for is + /// still alive. + pub unsafe fn name(&self) -> &'static str { + match &self { + ParamPtr::FloatParam(p) => (**p).name, + ParamPtr::IntParam(p) => (**p).name, + } + } + + /// Set this parameter based on a string. Returns whether the updating succeeded. That can fail + /// if the string cannot be parsed. + /// + /// # Safety + /// + /// Calling this function is only safe as long as the object this `ParamPtr` was created for is + /// still alive. + pub unsafe fn from_string(&mut self, string: &str) -> bool { + match &self { + ParamPtr::FloatParam(p) => (**p).from_string(string), + ParamPtr::IntParam(p) => (**p).from_string(string), + } + } + + /// Get the normalized `[0, 1]` value for this parameter. + /// + /// # Safety + /// + /// Calling this function is only safe as long as the object this `ParamPtr` was created for is + /// still alive. + pub unsafe fn normalized_value(&self) -> f32 { + match &self { + ParamPtr::FloatParam(p) => (**p).normalized_value(), + ParamPtr::IntParam(p) => (**p).normalized_value(), + } + } + + /// Set this parameter based on a normalized value. + /// + /// # Safety + /// + /// Calling this function is only safe as long as the object this `ParamPtr` was created for is + /// still alive. + pub unsafe fn set_normalized_value(&self, normalized: f32) { + match &self { + ParamPtr::FloatParam(p) => (**p).set_normalized_value(normalized), + ParamPtr::IntParam(p) => (**p).set_normalized_value(normalized), + } + } +} + #[cfg(test)] mod tests { use super::*;