Store plugin version in the state
This may later be used to allow migrations between breaking plugin versions.
This commit is contained in:
parent
ee62a45d0d
commit
8a9c98943e
5 changed files with 26 additions and 11 deletions
|
@ -1544,7 +1544,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
|||
/// the JSON in the relevant plugin API methods instead.
|
||||
pub fn get_state_object(&self) -> PluginState {
|
||||
unsafe {
|
||||
state::serialize_object(
|
||||
state::serialize_object::<P>(
|
||||
self.params.clone(),
|
||||
state::make_params_iter(&self.param_by_hash, &self.param_id_to_hash),
|
||||
)
|
||||
|
@ -3067,7 +3067,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
|||
check_null_ptr!(false, plugin, stream);
|
||||
let wrapper = &*(plugin as *const Self);
|
||||
|
||||
let serialized = state::serialize_json(
|
||||
let serialized = state::serialize_json::<P>(
|
||||
wrapper.params.clone(),
|
||||
state::make_params_iter(&wrapper.param_by_hash, &wrapper.param_id_to_hash),
|
||||
);
|
||||
|
|
|
@ -338,7 +338,7 @@ impl<P: Plugin, B: Backend> Wrapper<P, B> {
|
|||
/// the JSON in the relevant plugin API methods instead.
|
||||
pub fn get_state_object(&self) -> PluginState {
|
||||
unsafe {
|
||||
state::serialize_object(
|
||||
state::serialize_object::<P>(
|
||||
self.params.clone(),
|
||||
self.param_map
|
||||
.iter()
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::sync::Arc;
|
|||
|
||||
use crate::param::internals::{ParamPtr, Params};
|
||||
use crate::param::{Param, ParamMut};
|
||||
use crate::plugin::BufferConfig;
|
||||
use crate::plugin::{BufferConfig, Plugin};
|
||||
|
||||
// These state objects are also exposed directly to the plugin so it can do its own internal preset
|
||||
// management
|
||||
|
@ -30,6 +30,16 @@ pub enum ParamValue {
|
|||
/// The fields are stored as `BTreeMap`s so the order in the serialized file is consistent.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct PluginState {
|
||||
/// The plugin version this state was saved with. Right now this is not used, but later versions
|
||||
/// of NIH-plug may allow you to modify the plugin state object directly before it is loaded to
|
||||
/// allow migrating plugin states between breaking parameter changes.
|
||||
///
|
||||
/// # Notes
|
||||
///
|
||||
/// If the saved state is very old, then this field may be empty.
|
||||
#[serde(default)]
|
||||
pub version: String,
|
||||
|
||||
/// The plugin's parameter values. These are stored unnormalized. This mean sthe old values will
|
||||
/// be recalled when when the parameter's range gets increased. Doing so may still mess with
|
||||
/// parameter automation though, depending on how the host impelments that.
|
||||
|
@ -73,7 +83,7 @@ pub(crate) fn make_params_getter<'a>(
|
|||
/// allow passing the raw object directly to the plugin. The parameters are not pulled directly from
|
||||
/// `plugin_params` by default to avoid unnecessary allocations in the `.param_map()` method, as the
|
||||
/// plugin wrappers will already have a list of parameters handy. See [`make_params_iter()`].
|
||||
pub(crate) unsafe fn serialize_object<'a>(
|
||||
pub(crate) unsafe fn serialize_object<'a, P: Plugin>(
|
||||
plugin_params: Arc<dyn Params>,
|
||||
params_iter: impl IntoIterator<Item = (&'a String, ParamPtr)>,
|
||||
) -> PluginState {
|
||||
|
@ -112,17 +122,21 @@ pub(crate) unsafe fn serialize_object<'a>(
|
|||
// storing things like sample data.
|
||||
let fields = plugin_params.serialize_fields();
|
||||
|
||||
PluginState { params, fields }
|
||||
PluginState {
|
||||
version: String::from(P::VERSION),
|
||||
params,
|
||||
fields,
|
||||
}
|
||||
}
|
||||
|
||||
/// Serialize a plugin's state to a vector containing JSON data. This can (and should) be shared
|
||||
/// across plugin formats. If the `zstd` feature is enabled, then the state will be compressed using
|
||||
/// Zstandard.
|
||||
pub(crate) unsafe fn serialize_json<'a>(
|
||||
pub(crate) unsafe fn serialize_json<'a, P: Plugin>(
|
||||
plugin_params: Arc<dyn Params>,
|
||||
params_iter: impl IntoIterator<Item = (&'a String, ParamPtr)>,
|
||||
) -> Result<Vec<u8>> {
|
||||
let plugin_state = serialize_object(plugin_params, params_iter);
|
||||
let plugin_state = serialize_object::<P>(plugin_params, params_iter);
|
||||
let json = serde_json::to_vec(&plugin_state).context("Could not format as JSON")?;
|
||||
|
||||
#[cfg(feature = "zstd")]
|
||||
|
|
|
@ -415,7 +415,7 @@ impl<P: Vst3Plugin> WrapperInner<P> {
|
|||
/// the JSON in the relevant plugin API methods instead.
|
||||
pub fn get_state_object(&self) -> PluginState {
|
||||
unsafe {
|
||||
state::serialize_object(
|
||||
state::serialize_object::<P>(
|
||||
self.params.clone(),
|
||||
state::make_params_iter(&self.param_by_hash, &self.param_id_to_hash),
|
||||
)
|
||||
|
|
|
@ -537,7 +537,7 @@ impl<P: Vst3Plugin> IComponent for Wrapper<P> {
|
|||
|
||||
let state = state.upgrade().unwrap();
|
||||
|
||||
let serialized = state::serialize_json(
|
||||
let serialized = state::serialize_json::<P>(
|
||||
self.inner.params.clone(),
|
||||
state::make_params_iter(&self.inner.param_by_hash, &self.inner.param_id_to_hash),
|
||||
);
|
||||
|
@ -913,7 +913,8 @@ impl<P: Vst3Plugin> IAudioProcessor for Wrapper<P> {
|
|||
return kInvalidArgument;
|
||||
}
|
||||
} else if dir == vst3_sys::vst::BusDirections::kOutput as i32 {
|
||||
let aux_outputs_only = P::DEFAULT_OUTPUT_CHANNELS == 0 && P::DEFAULT_AUX_OUTPUTS.is_some();
|
||||
let aux_outputs_only =
|
||||
P::DEFAULT_OUTPUT_CHANNELS == 0 && P::DEFAULT_AUX_OUTPUTS.is_some();
|
||||
let aux_output_start_idx = if aux_outputs_only { 0 } else { 1 };
|
||||
if (!aux_outputs_only || no_main_audio_io) && index == 0 {
|
||||
bus_config.num_output_channels
|
||||
|
|
Loading…
Add table
Reference in a new issue