Use a stable ordering for the parameters
As the fields are specified on the parameters struct.
This commit is contained in:
parent
260d38580b
commit
fe8f1d27d6
|
@ -29,6 +29,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
|
||||||
// `persist` function we'll create functions that serialize and deserialize those fields
|
// `persist` function we'll create functions that serialize and deserialize those fields
|
||||||
// individually (so they can be added and removed independently of eachother) using JSON.
|
// individually (so they can be added and removed independently of eachother) using JSON.
|
||||||
let mut param_mapping_insert_tokens = Vec::new();
|
let mut param_mapping_insert_tokens = Vec::new();
|
||||||
|
let mut param_id_string_tokens = Vec::new();
|
||||||
let mut field_serialize_tokens = Vec::new();
|
let mut field_serialize_tokens = Vec::new();
|
||||||
let mut field_deserialize_tokens = Vec::new();
|
let mut field_deserialize_tokens = Vec::new();
|
||||||
for field in fields.named {
|
for field in fields.named {
|
||||||
|
@ -96,6 +97,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
|
||||||
// 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(#param_id, self.#field_name.as_ptr()); });
|
||||||
|
param_id_string_tokens.push(quote! { #param_id, });
|
||||||
}
|
}
|
||||||
(None, Some(stable_name)) => {
|
(None, Some(stable_name)) => {
|
||||||
// We don't know anything about the field types, but because we can generate this
|
// We don't know anything about the field types, but because we can generate this
|
||||||
|
@ -158,6 +160,10 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
|
||||||
param_map
|
param_map
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn param_ids(self: std::pin::Pin<&Self>) -> &'static [&'static str] {
|
||||||
|
&[#(#param_id_string_tokens)*]
|
||||||
|
}
|
||||||
|
|
||||||
fn serialize_fields(&self) -> ::std::collections::HashMap<String, String> {
|
fn serialize_fields(&self) -> ::std::collections::HashMap<String, String> {
|
||||||
let mut serialized = ::std::collections::HashMap::new();
|
let mut serialized = ::std::collections::HashMap::new();
|
||||||
|
|
||||||
|
|
|
@ -369,6 +369,10 @@ pub trait Params {
|
||||||
/// 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<&'static str, ParamPtr>;
|
||||||
|
|
||||||
|
/// All parameter IDs from `param_map`, in a stable order. This order will be used to display
|
||||||
|
/// the parameters.
|
||||||
|
fn param_ids(self: Pin<&Self>) -> &'static [&'static str];
|
||||||
|
|
||||||
/// 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
|
||||||
/// recalled later. This uses [serialize_field] under the hood.
|
/// recalled later. This uses [serialize_field] under the hood.
|
||||||
|
|
|
@ -111,12 +111,12 @@ struct WrapperInner<'a, P: Plugin> {
|
||||||
/// between process calls.
|
/// between process calls.
|
||||||
output_slices: RwLock<Vec<&'a mut [f32]>>,
|
output_slices: RwLock<Vec<&'a mut [f32]>>,
|
||||||
|
|
||||||
|
/// The keys from `param_map` in a stable order.
|
||||||
|
param_hashes: Vec<u32>,
|
||||||
/// A mapping from parameter ID hashes (obtained from the string parameter IDs) to pointers to
|
/// A mapping from parameter ID hashes (obtained from the string parameter IDs) to pointers to
|
||||||
/// parameters belonging to the plugin. As long as `plugin` does not get recreated, these
|
/// parameters belonging to the plugin. As long as `plugin` does not get recreated, these
|
||||||
/// addresses will remain stable, as they are obtained from a pinned object.
|
/// addresses will remain stable, as they are obtained from a pinned object.
|
||||||
param_by_hash: HashMap<u32, ParamPtr>,
|
param_by_hash: HashMap<u32, ParamPtr>,
|
||||||
/// The keys from `param_map` in a stable order.
|
|
||||||
param_hashes: Vec<u32>,
|
|
||||||
/// The default normalized parameter value for every parameter in `param_ids`. We need to store
|
/// The default normalized parameter value for every parameter in `param_ids`. We need to store
|
||||||
/// this in case the host requeries the parmaeter later.
|
/// this in case the host requeries the parmaeter later.
|
||||||
param_defaults_normalized: Vec<f32>,
|
param_defaults_normalized: Vec<f32>,
|
||||||
|
@ -168,10 +168,10 @@ impl<P: Plugin> WrapperInner<'_, P> {
|
||||||
is_processing:
|
is_processing:
|
||||||
AtomicBool::new(false),
|
AtomicBool::new(false),
|
||||||
output_slices: RwLock::new(Vec::new()),
|
output_slices: RwLock::new(Vec::new()),
|
||||||
param_by_hash:
|
|
||||||
HashMap::new(),
|
|
||||||
param_hashes:
|
param_hashes:
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
|
param_by_hash:
|
||||||
|
HashMap::new(),
|
||||||
param_defaults_normalized:
|
param_defaults_normalized:
|
||||||
Vec::new(),
|
Vec::new(),
|
||||||
param_id_to_hash:
|
param_id_to_hash:
|
||||||
|
@ -186,29 +186,35 @@ impl<P: Plugin> WrapperInner<'_, P> {
|
||||||
// XXX: This unsafe block is unnecessary. rust-analyzer gets a bit confused and this this
|
// XXX: This unsafe block is unnecessary. rust-analyzer gets a bit confused and this this
|
||||||
// `read()` function is from `IBStream` which it definitely is not.
|
// `read()` function is from `IBStream` which it definitely is not.
|
||||||
let param_map = unsafe { wrapper.plugin.read() }.params().param_map();
|
let param_map = unsafe { wrapper.plugin.read() }.params().param_map();
|
||||||
|
let param_ids = unsafe { wrapper.plugin.read() }.params().param_ids();
|
||||||
nih_debug_assert!(
|
nih_debug_assert!(
|
||||||
!param_map.contains_key(BYPASS_PARAM_ID),
|
!param_map.contains_key(BYPASS_PARAM_ID),
|
||||||
"The wrapper alread yadds its own bypass parameter"
|
"The wrapper alread yadds its own bypass parameter"
|
||||||
);
|
);
|
||||||
|
|
||||||
wrapper.param_by_hash = param_map
|
// Only calculate these hashes once, and in the stable order defined by the plugin
|
||||||
.iter()
|
let param_id_hashes_ptrs = param_ids.iter().filter_map(|id| {
|
||||||
.map(|(id, p)| (hash_param_id(id), *p))
|
let param_ptr = param_map.get(id)?;
|
||||||
|
Some((id, hash_param_id(id), param_ptr))
|
||||||
|
});
|
||||||
|
wrapper.param_hashes = param_id_hashes_ptrs
|
||||||
|
.clone()
|
||||||
|
.map(|(_, hash, _)| hash)
|
||||||
.collect();
|
.collect();
|
||||||
wrapper.param_hashes = wrapper.param_by_hash.keys().copied().collect();
|
wrapper.param_by_hash = param_id_hashes_ptrs
|
||||||
wrapper.param_defaults_normalized = wrapper
|
.clone()
|
||||||
.param_hashes
|
.map(|(_, hash, ptr)| (hash, *ptr))
|
||||||
.iter()
|
|
||||||
.map(|hash| unsafe { wrapper.param_by_hash[hash].normalized_value() })
|
|
||||||
.collect();
|
.collect();
|
||||||
wrapper.param_id_to_hash = param_map
|
wrapper.param_defaults_normalized = param_id_hashes_ptrs
|
||||||
.into_keys()
|
.clone()
|
||||||
.map(|id| (hash_param_id(id), id))
|
.map(|(_, _, ptr)| unsafe { ptr.normalized_value() })
|
||||||
.collect();
|
.collect();
|
||||||
wrapper.param_hash_to_id = wrapper
|
wrapper.param_id_to_hash = param_id_hashes_ptrs
|
||||||
.param_id_to_hash
|
.clone()
|
||||||
.iter()
|
.map(|(id, hash, _)| (hash, *id))
|
||||||
.map(|(&hash, &id)| (id, hash))
|
.collect();
|
||||||
|
wrapper.param_hash_to_id = param_id_hashes_ptrs
|
||||||
|
.map(|(id, hash, _)| (*id, hash))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
// FIXME: Right now this is safe, but if we are going to have a singleton main thread queue
|
// FIXME: Right now this is safe, but if we are going to have a singleton main thread queue
|
||||||
|
|
Loading…
Reference in a new issue