Use String instead of &'static str in Params
This may hurt performance in generic UIs a bit, but it will allow you to programatically generate custom Params implementations for repeated Parameters structs.
This commit is contained in:
parent
1a9db3ab8e
commit
b9d79771cc
|
@ -149,12 +149,12 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
|
||||||
// The specific parameter types know how to convert themselves into the correct ParamPtr
|
// The specific parameter types know how to convert themselves into the correct ParamPtr
|
||||||
// variant
|
// variant
|
||||||
param_mapping_insert_tokens
|
param_mapping_insert_tokens
|
||||||
.push(quote! { param_map.insert(#param_id, self.#field_name.as_ptr()); });
|
.push(quote! { param_map.insert(String::from(#param_id), self.#field_name.as_ptr()); });
|
||||||
// Top-level parameters have no group, and we'll prefix the group name specified in
|
// Top-level parameters have no group, and we'll prefix the group name specified in
|
||||||
// the `#[nested = "..."]` attribute to fields coming from nested groups
|
// the `#[nested = "..."]` attribute to fields coming from nested groups
|
||||||
param_groups_insert_tokens
|
param_groups_insert_tokens
|
||||||
.push(quote! { param_groups.insert(#param_id, String::new()); });
|
.push(quote! { param_groups.insert(String::from(#param_id), String::new()); });
|
||||||
param_id_string_tokens.push(quote! { #param_id, });
|
param_id_string_tokens.push(quote! { String::from(#param_id), });
|
||||||
}
|
}
|
||||||
(None, Some(stable_name)) => {
|
(None, Some(stable_name)) => {
|
||||||
if !persist_ids.insert(stable_name.clone()) {
|
if !persist_ids.insert(stable_name.clone()) {
|
||||||
|
@ -224,7 +224,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
|
||||||
impl #impl_generics Params for #struct_name #ty_generics #where_clause {
|
impl #impl_generics Params for #struct_name #ty_generics #where_clause {
|
||||||
fn param_map(
|
fn param_map(
|
||||||
self: std::pin::Pin<&Self>,
|
self: std::pin::Pin<&Self>,
|
||||||
) -> std::collections::HashMap<&'static str, nih_plug::param::internals::ParamPtr> {
|
) -> std::collections::HashMap<String, nih_plug::param::internals::ParamPtr> {
|
||||||
// This may not be in scope otherwise, used to call .as_ptr()
|
// This may not be in scope otherwise, used to call .as_ptr()
|
||||||
use ::nih_plug::param::Param;
|
use ::nih_plug::param::Param;
|
||||||
|
|
||||||
|
@ -241,12 +241,12 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
|
||||||
|
|
||||||
fn param_groups(
|
fn param_groups(
|
||||||
self: std::pin::Pin<&Self>,
|
self: std::pin::Pin<&Self>,
|
||||||
) -> std::collections::HashMap<&'static str, String> {
|
) -> std::collections::HashMap<String, String> {
|
||||||
let mut param_groups = std::collections::HashMap::new();
|
let mut param_groups = std::collections::HashMap::new();
|
||||||
#(#param_groups_insert_tokens)*
|
#(#param_groups_insert_tokens)*
|
||||||
|
|
||||||
let nested_params_fields: &[&dyn Params] = &[#(&self.#nested_params_field_idents),*];
|
let nested_params_fields: &[&dyn Params] = &[#(&self.#nested_params_field_idents),*];
|
||||||
let nested_params_groups: &[&'static str] = &[#(#nested_params_group_names),*];
|
let nested_params_groups: &[String] = &[#(String::from(#nested_params_group_names)),*];
|
||||||
for (nested_params, group_name) in
|
for (nested_params, group_name) in
|
||||||
nested_params_fields.into_iter().zip(nested_params_groups)
|
nested_params_fields.into_iter().zip(nested_params_groups)
|
||||||
{
|
{
|
||||||
|
@ -272,8 +272,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
|
||||||
param_groups
|
param_groups
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn param_ids(self: std::pin::Pin<&Self>) -> Vec<String> {
|
||||||
fn param_ids(self: std::pin::Pin<&Self>) -> Vec<&'static str> {
|
|
||||||
let mut ids = vec![#(#param_id_string_tokens)*];
|
let mut ids = vec![#(#param_id_string_tokens)*];
|
||||||
|
|
||||||
let nested_params_fields: &[&dyn Params] = &[#(&self.#nested_params_field_idents),*];
|
let nested_params_fields: &[&dyn Params] = &[#(&self.#nested_params_field_idents),*];
|
||||||
|
|
|
@ -50,7 +50,7 @@ pub fn create(
|
||||||
.auto_shrink([false, false])
|
.auto_shrink([false, false])
|
||||||
.show(ui, |ui| {
|
.show(ui, |ui| {
|
||||||
for (widget_idx, id) in param_ids.into_iter().enumerate() {
|
for (widget_idx, id) in param_ids.into_iter().enumerate() {
|
||||||
let param = param_map[id];
|
let param = param_map[&id];
|
||||||
|
|
||||||
// This list looks weird without a little padding
|
// This list looks weird without a little padding
|
||||||
if widget_idx > 0 {
|
if widget_idx > 0 {
|
||||||
|
|
|
@ -177,7 +177,7 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
for param_id in param_ids {
|
for param_id in param_ids {
|
||||||
let param_ptr = param_map[param_id];
|
let param_ptr = param_map[¶m_id];
|
||||||
// SAFETY: We only borrow each item once, and the plugin framework statically asserted
|
// SAFETY: We only borrow each item once, and the plugin framework statically asserted
|
||||||
// that parameter indices are unique and this widget state cannot outlive this
|
// that parameter indices are unique and this widget state cannot outlive this
|
||||||
// function
|
// function
|
||||||
|
|
|
@ -40,15 +40,18 @@ pub use serde_json::to_string as serialize_field;
|
||||||
/// This implementation is safe when using from the wrapper because the plugin object needs to be
|
/// This implementation is safe when using from the wrapper because the plugin object needs to be
|
||||||
/// pinned, and it can never outlive the wrapper.
|
/// pinned, and it can never outlive the wrapper.
|
||||||
pub trait Params {
|
pub trait Params {
|
||||||
|
// NOTE: These types use `String` even though for the `Params` derive macro `&'static str` would
|
||||||
|
// have been fine to be able to support custom reusable Params implemnetations.
|
||||||
|
|
||||||
/// Create a mapping from unique parameter IDs to parameters. This is done for every parameter
|
/// Create a mapping from unique parameter IDs to parameters. This is done for every parameter
|
||||||
/// field marked with `#[id = "stable_name"]`. Dereferencing the pointers stored in the values
|
/// field marked with `#[id = "stable_name"]`. Dereferencing the pointers stored in the values
|
||||||
/// is only valid as long as this pinned object is valid.
|
/// is only valid as long as this pinned object is valid.
|
||||||
fn param_map(self: Pin<&Self>) -> HashMap<&'static str, ParamPtr>;
|
fn param_map(self: Pin<&Self>) -> HashMap<String, ParamPtr>;
|
||||||
|
|
||||||
/// Contains group names for each parameter in [`param_map()`][Self::param_map()]. This is
|
/// Contains group names for each parameter in [`param_map()`][Self::param_map()]. This is
|
||||||
/// either an empty string for top level parameters, or a slash/delimited `"Group Name 1/Group
|
/// either an empty string for top level parameters, or a slash/delimited `"Group Name 1/Group
|
||||||
/// Name 2"` string for parameters that belong to `#[nested = "Name"]` parameter objects.
|
/// Name 2"` string for parameters that belong to `#[nested = "Name"]` parameter objects.
|
||||||
fn param_groups(self: Pin<&Self>) -> HashMap<&'static str, String>;
|
fn param_groups(self: Pin<&Self>) -> HashMap<String, String>;
|
||||||
|
|
||||||
/// All parameter IDs from [`param_map()`][Self::param_map()], in a stable order. This order
|
/// All parameter IDs from [`param_map()`][Self::param_map()], in a stable order. This order
|
||||||
/// will be used to display the parameters.
|
/// will be used to display the parameters.
|
||||||
|
@ -57,7 +60,7 @@ pub trait Params {
|
||||||
/// that's become a bit more difficult since Rust does not have a convenient way to
|
/// that's become a bit more difficult since Rust does not have a convenient way to
|
||||||
/// concatenate an arbitrary number of static slices. There's probably a better way to do
|
/// concatenate an arbitrary number of static slices. There's probably a better way to do
|
||||||
/// this.
|
/// this.
|
||||||
fn param_ids(self: Pin<&Self>) -> Vec<&'static str>;
|
fn param_ids(self: Pin<&Self>) -> Vec<String>;
|
||||||
|
|
||||||
/// Serialize all fields marked with `#[persist = "stable_name"]` into a hash map containing
|
/// Serialize all fields marked with `#[persist = "stable_name"]` into a hash map containing
|
||||||
/// JSON-representations of those fields so they can be written to the plugin's state and
|
/// JSON-representations of those fields so they can be written to the plugin's state and
|
||||||
|
|
|
@ -184,7 +184,7 @@ pub struct Wrapper<P: ClapPlugin> {
|
||||||
pub param_defaults_normalized: HashMap<u32, f32>,
|
pub param_defaults_normalized: HashMap<u32, f32>,
|
||||||
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
||||||
/// and when storing and restoring plugin state.
|
/// and when storing and restoring plugin state.
|
||||||
param_id_to_hash: HashMap<&'static str, u32>,
|
param_id_to_hash: HashMap<String, u32>,
|
||||||
/// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
|
/// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
|
||||||
/// to have an ergonomic parameter setting API that uses references to the parameters instead of
|
/// to have an ergonomic parameter setting API that uses references to the parameters instead of
|
||||||
/// having to add a setter function to the parameter (or even worse, have it be completely
|
/// having to add a setter function to the parameter (or even worse, have it be completely
|
||||||
|
@ -365,7 +365,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
.collect();
|
.collect();
|
||||||
let param_id_to_hash = param_id_hashes_ptrs_groups
|
let param_id_to_hash = param_id_hashes_ptrs_groups
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(id, hash, _, _)| (*id, hash))
|
.map(|&(id, hash, _, _)| (id.clone(), hash))
|
||||||
.collect();
|
.collect();
|
||||||
let param_ptr_to_hash = param_id_hashes_ptrs_groups
|
let param_ptr_to_hash = param_id_hashes_ptrs_groups
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
|
@ -39,7 +39,7 @@ pub(crate) struct State {
|
||||||
pub(crate) unsafe fn serialize(
|
pub(crate) unsafe fn serialize(
|
||||||
plugin_params: Pin<&dyn Params>,
|
plugin_params: Pin<&dyn Params>,
|
||||||
param_by_hash: &HashMap<u32, ParamPtr>,
|
param_by_hash: &HashMap<u32, ParamPtr>,
|
||||||
param_id_to_hash: &HashMap<&'static str, u32>,
|
param_id_to_hash: &HashMap<String, u32>,
|
||||||
bypass_param_id: &str,
|
bypass_param_id: &str,
|
||||||
bypass_state: &AtomicBool,
|
bypass_state: &AtomicBool,
|
||||||
) -> serde_json::Result<Vec<u8>> {
|
) -> serde_json::Result<Vec<u8>> {
|
||||||
|
@ -50,7 +50,7 @@ pub(crate) unsafe fn serialize(
|
||||||
let param_ptr = param_by_hash.get(hash)?;
|
let param_ptr = param_by_hash.get(hash)?;
|
||||||
Some((param_id_str, param_ptr))
|
Some((param_id_str, param_ptr))
|
||||||
})
|
})
|
||||||
.map(|(¶m_id_str, ¶m_ptr)| match param_ptr {
|
.map(|(param_id_str, ¶m_ptr)| match param_ptr {
|
||||||
ParamPtr::FloatParam(p) => (
|
ParamPtr::FloatParam(p) => (
|
||||||
param_id_str.to_string(),
|
param_id_str.to_string(),
|
||||||
ParamValue::F32((*p).plain_value()),
|
ParamValue::F32((*p).plain_value()),
|
||||||
|
@ -95,7 +95,7 @@ pub(crate) unsafe fn deserialize(
|
||||||
state: &[u8],
|
state: &[u8],
|
||||||
plugin_params: Pin<&dyn Params>,
|
plugin_params: Pin<&dyn Params>,
|
||||||
param_by_hash: &HashMap<u32, ParamPtr>,
|
param_by_hash: &HashMap<u32, ParamPtr>,
|
||||||
param_id_to_hash: &HashMap<&'static str, u32>,
|
param_id_to_hash: &HashMap<String, u32>,
|
||||||
current_buffer_config: Option<&BufferConfig>,
|
current_buffer_config: Option<&BufferConfig>,
|
||||||
bypass_param_id: &str,
|
bypass_param_id: &str,
|
||||||
bypass_state: &AtomicBool,
|
bypass_state: &AtomicBool,
|
||||||
|
|
|
@ -92,7 +92,7 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
|
||||||
pub param_defaults_normalized: HashMap<u32, f32>,
|
pub param_defaults_normalized: HashMap<u32, f32>,
|
||||||
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
/// Mappings from string parameter indentifiers to parameter hashes. Useful for debug logging
|
||||||
/// and when storing and restorign plugin state.
|
/// and when storing and restorign plugin state.
|
||||||
pub param_id_to_hash: HashMap<&'static str, u32>,
|
pub param_id_to_hash: HashMap<String, u32>,
|
||||||
/// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
|
/// The inverse mapping from [`param_by_hash`][Self::param_by_hash]. This is needed to be able
|
||||||
/// to have an ergonomic parameter setting API that uses references to the parameters instead of
|
/// to have an ergonomic parameter setting API that uses references to the parameters instead of
|
||||||
/// having to add a setter function to the parameter (or even worse, have it be completely
|
/// having to add a setter function to the parameter (or even worse, have it be completely
|
||||||
|
@ -177,7 +177,7 @@ impl<P: Vst3Plugin> WrapperInner<P> {
|
||||||
.collect();
|
.collect();
|
||||||
let param_id_to_hash = param_id_hashes_ptrs_groups
|
let param_id_to_hash = param_id_hashes_ptrs_groups
|
||||||
.iter()
|
.iter()
|
||||||
.map(|&(id, hash, _, _)| (*id, hash))
|
.map(|&(id, hash, _, _)| (id.clone(), hash))
|
||||||
.collect();
|
.collect();
|
||||||
let param_ptr_to_hash = param_id_hashes_ptrs_groups
|
let param_ptr_to_hash = param_id_hashes_ptrs_groups
|
||||||
.into_iter()
|
.into_iter()
|
||||||
|
|
Loading…
Reference in a new issue