Rework Params trait API with Arc instead of Pin

This is a breaking change requiring a small change to plugin
implementations.

The reason why `Pin<&dyn Params>` was used was more as a hint to
indicate that the object must last for the plugin's lifetime, but `Pin`
doesn't enforce that. It also makes the APIs a lot more awkward.
Requiring the use of `Arc` fixes the following problems:

- When storing the params object in the wrapper, the `ParamPtr`s are
  guaranteed to be stable.
- This makes it possible to access the `Params` object without acquiring
  a lock on the plugin, this is very important for implementing
  plugin-side preset management.
- It enforces immutability on the `Params` object.
- And of course the API is much nicer without a bunch of unsafe code to
  work around Pin's limitations.
This commit is contained in:
Robbert van der Helm
2022-04-07 15:31:46 +02:00
parent 7cc05fce9a
commit 083885a40c
24 changed files with 105 additions and 115 deletions

View File

@@ -218,9 +218,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
quote! {
unsafe impl #impl_generics Params for #struct_name #ty_generics #where_clause {
fn param_map(
self: std::pin::Pin<&Self>,
) -> Vec<(String, nih_plug::prelude::ParamPtr, String)> {
fn param_map(&self) -> Vec<(String, nih_plug::prelude::ParamPtr, String)> {
// This may not be in scope otherwise, used to call .as_ptr()
use ::nih_plug::param::Param;
@@ -231,8 +229,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
for (nested_params, group_name) in
nested_params_fields.into_iter().zip(nested_params_groups)
{
let nested_param_map =
unsafe { std::pin::Pin::new_unchecked(*nested_params).param_map() };
let nested_param_map = nested_params.param_map();
let prefixed_nested_param_map =
nested_param_map
.into_iter()
@@ -260,7 +257,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
let nested_params_fields: &[&dyn Params] = &[#(&self.#nested_params_field_idents),*];
for nested_params in nested_params_fields {
unsafe { serialized.extend(Pin::new_unchecked(*nested_params).serialize_fields()) };
serialized.extend(nested_params.serialize_fields());
}
serialized
@@ -280,7 +277,7 @@ pub fn derive_params(input: TokenStream) -> TokenStream {
// once that gets stabilized.
let nested_params_fields: &[&dyn Params] = &[#(&self.#nested_params_field_idents),*];
for nested_params in nested_params_fields {
unsafe { Pin::new_unchecked(*nested_params).deserialize_fields(serialized) };
nested_params.deserialize_fields(serialized);
}
}
}