Initialize parameter fields earlier
This seems a bit nicer than initializing them on the struct as empty and then mutating the struct.
This commit is contained in:
parent
63a7aadb75
commit
ea30ba7ffb
|
@ -326,7 +326,80 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
assert!(!host_callback.is_null());
|
assert!(!host_callback.is_null());
|
||||||
let host_callback = unsafe { ClapPtr::new(host_callback) };
|
let host_callback = unsafe { ClapPtr::new(host_callback) };
|
||||||
|
|
||||||
let mut wrapper = Self {
|
// This is a mapping from the parameter IDs specified by the plugin to pointers to thsoe
|
||||||
|
// parameters. Since the object returned by `params()` is pinned, these pointers are safe to
|
||||||
|
// dereference as long as `wrapper.plugin` is alive
|
||||||
|
let param_map = plugin.read().params().param_map();
|
||||||
|
let param_ids = plugin.read().params().param_ids();
|
||||||
|
let param_groups = plugin.read().params().param_groups();
|
||||||
|
nih_debug_assert!(
|
||||||
|
!param_map.contains_key(BYPASS_PARAM_ID),
|
||||||
|
"The wrapper already adds its own bypass parameter"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Only calculate these hashes once, and in the stable order defined by the plugin
|
||||||
|
let param_id_hashes_ptrs_groups: Vec<_> = param_ids
|
||||||
|
.iter()
|
||||||
|
.map(|id| {
|
||||||
|
// If any of these keys are missing then that's a bug in the Params implementation
|
||||||
|
let param_ptr = param_map[id];
|
||||||
|
let param_group = ¶m_groups[id];
|
||||||
|
(id, hash_param_id(id), param_ptr, param_group)
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
let param_hashes = param_id_hashes_ptrs_groups
|
||||||
|
.iter()
|
||||||
|
.map(|&(_, hash, _, _)| hash)
|
||||||
|
.collect();
|
||||||
|
let param_by_hash = param_id_hashes_ptrs_groups
|
||||||
|
.iter()
|
||||||
|
.map(|&(_, hash, ptr, _)| (hash, ptr))
|
||||||
|
.collect();
|
||||||
|
let param_group_by_hash = param_id_hashes_ptrs_groups
|
||||||
|
.iter()
|
||||||
|
.map(|&(_, hash, _, group)| (hash, group.to_string()))
|
||||||
|
.collect();
|
||||||
|
let param_defaults_normalized = param_id_hashes_ptrs_groups
|
||||||
|
.iter()
|
||||||
|
.map(|&(_, hash, ptr, _)| (hash, unsafe { ptr.normalized_value() }))
|
||||||
|
.collect();
|
||||||
|
let param_id_to_hash = param_id_hashes_ptrs_groups
|
||||||
|
.iter()
|
||||||
|
.map(|&(id, hash, _, _)| (*id, hash))
|
||||||
|
.collect();
|
||||||
|
let param_ptr_to_hash = param_id_hashes_ptrs_groups
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_, hash, ptr, _)| (ptr, hash))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
// Query all sensible bus configurations supported by the plugin. We don't do surround or
|
||||||
|
// anything beyond stereo right now.
|
||||||
|
let mut supported_bus_configs = Vec::new();
|
||||||
|
for num_output_channels in [1, 2] {
|
||||||
|
for num_input_channels in [0, num_output_channels] {
|
||||||
|
let bus_config = BusConfig {
|
||||||
|
num_input_channels,
|
||||||
|
num_output_channels,
|
||||||
|
};
|
||||||
|
if plugin.read().accepts_bus_config(&bus_config) {
|
||||||
|
supported_bus_configs.push(bus_config);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the off chance that the default config specified by the plugin is not in the above
|
||||||
|
// list, we'll try that as well.
|
||||||
|
let default_bus_config = BusConfig {
|
||||||
|
num_input_channels: P::DEFAULT_NUM_INPUTS,
|
||||||
|
num_output_channels: P::DEFAULT_NUM_OUTPUTS,
|
||||||
|
};
|
||||||
|
if !supported_bus_configs.contains(&default_bus_config)
|
||||||
|
&& plugin.read().accepts_bus_config(&default_bus_config)
|
||||||
|
{
|
||||||
|
supported_bus_configs.push(default_bus_config);
|
||||||
|
}
|
||||||
|
|
||||||
|
let wrapper = Self {
|
||||||
clap_plugin: clap_plugin {
|
clap_plugin: clap_plugin {
|
||||||
// This needs to live on the heap because the plugin object contains a direct
|
// This needs to live on the heap because the plugin object contains a direct
|
||||||
// reference to the manifest as a value. We could share this between instances of
|
// reference to the manifest as a value. We could share this between instances of
|
||||||
|
@ -376,7 +449,7 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
get: Self::ext_audio_ports_config_get,
|
get: Self::ext_audio_ports_config_get,
|
||||||
select: Self::ext_audio_ports_config_select,
|
select: Self::ext_audio_ports_config_select,
|
||||||
},
|
},
|
||||||
supported_bus_configs: Vec::new(),
|
supported_bus_configs,
|
||||||
|
|
||||||
clap_plugin_audio_ports: clap_plugin_audio_ports {
|
clap_plugin_audio_ports: clap_plugin_audio_ports {
|
||||||
count: Self::ext_audio_ports_count,
|
count: Self::ext_audio_ports_count,
|
||||||
|
@ -422,12 +495,12 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
flush: Self::ext_params_flush,
|
flush: Self::ext_params_flush,
|
||||||
},
|
},
|
||||||
host_params: AtomicRefCell::new(None),
|
host_params: AtomicRefCell::new(None),
|
||||||
param_hashes: Vec::new(),
|
param_hashes,
|
||||||
param_by_hash: HashMap::new(),
|
param_by_hash,
|
||||||
param_group_by_hash: HashMap::new(),
|
param_group_by_hash,
|
||||||
param_defaults_normalized: HashMap::new(),
|
param_defaults_normalized,
|
||||||
param_id_to_hash: HashMap::new(),
|
param_id_to_hash,
|
||||||
param_ptr_to_hash: HashMap::new(),
|
param_ptr_to_hash,
|
||||||
output_parameter_events: ArrayQueue::new(OUTPUT_EVENT_QUEUE_CAPACITY),
|
output_parameter_events: ArrayQueue::new(OUTPUT_EVENT_QUEUE_CAPACITY),
|
||||||
|
|
||||||
host_thread_check: AtomicRefCell::new(None),
|
host_thread_check: AtomicRefCell::new(None),
|
||||||
|
@ -445,81 +518,6 @@ impl<P: ClapPlugin> Wrapper<P> {
|
||||||
main_thread_id: thread::current().id(),
|
main_thread_id: thread::current().id(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Query all sensible bus configurations supported by the plugin. We don't do surround or
|
|
||||||
// anything beyond stereo right now.
|
|
||||||
for num_output_channels in [1, 2] {
|
|
||||||
for num_input_channels in [0, num_output_channels] {
|
|
||||||
let bus_config = BusConfig {
|
|
||||||
num_input_channels,
|
|
||||||
num_output_channels,
|
|
||||||
};
|
|
||||||
if wrapper.plugin.read().accepts_bus_config(&bus_config) {
|
|
||||||
wrapper.supported_bus_configs.push(bus_config);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// In the off chance that the default config specified by the plugin is not in the above
|
|
||||||
// list, we'll try that as well.
|
|
||||||
let default_bus_config = BusConfig {
|
|
||||||
num_input_channels: P::DEFAULT_NUM_INPUTS,
|
|
||||||
num_output_channels: P::DEFAULT_NUM_OUTPUTS,
|
|
||||||
};
|
|
||||||
if !wrapper.supported_bus_configs.contains(&default_bus_config)
|
|
||||||
&& wrapper
|
|
||||||
.plugin
|
|
||||||
.read()
|
|
||||||
.accepts_bus_config(&default_bus_config)
|
|
||||||
{
|
|
||||||
wrapper.supported_bus_configs.push(default_bus_config);
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is a mapping from the parameter IDs specified by the plugin to pointers to thsoe
|
|
||||||
// parameters. Since the object returned by `params()` is pinned, these pointers are safe to
|
|
||||||
// dereference as long as `wrapper.plugin` is alive
|
|
||||||
let param_map = wrapper.plugin.read().params().param_map();
|
|
||||||
let param_ids = wrapper.plugin.read().params().param_ids();
|
|
||||||
let param_groups = wrapper.plugin.read().params().param_groups();
|
|
||||||
nih_debug_assert!(
|
|
||||||
!param_map.contains_key(BYPASS_PARAM_ID),
|
|
||||||
"The wrapper already adds its own bypass parameter"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only calculate these hashes once, and in the stable order defined by the plugin
|
|
||||||
let param_id_hashes_ptrs_groups: Vec<_> = param_ids
|
|
||||||
.iter()
|
|
||||||
.map(|id| {
|
|
||||||
// If any of these keys are missing then that's a bug in the Params implementation
|
|
||||||
let param_ptr = param_map[id];
|
|
||||||
let param_group = ¶m_groups[id];
|
|
||||||
(id, hash_param_id(id), param_ptr, param_group)
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
wrapper.param_hashes = param_id_hashes_ptrs_groups
|
|
||||||
.iter()
|
|
||||||
.map(|&(_, hash, _, _)| hash)
|
|
||||||
.collect();
|
|
||||||
wrapper.param_by_hash = param_id_hashes_ptrs_groups
|
|
||||||
.iter()
|
|
||||||
.map(|&(_, hash, ptr, _)| (hash, ptr))
|
|
||||||
.collect();
|
|
||||||
wrapper.param_group_by_hash = param_id_hashes_ptrs_groups
|
|
||||||
.iter()
|
|
||||||
.map(|&(_, hash, _, group)| (hash, group.to_string()))
|
|
||||||
.collect();
|
|
||||||
wrapper.param_defaults_normalized = param_id_hashes_ptrs_groups
|
|
||||||
.iter()
|
|
||||||
.map(|&(_, hash, ptr, _)| (hash, unsafe { ptr.normalized_value() }))
|
|
||||||
.collect();
|
|
||||||
wrapper.param_id_to_hash = param_id_hashes_ptrs_groups
|
|
||||||
.iter()
|
|
||||||
.map(|&(id, hash, _, _)| (*id, hash))
|
|
||||||
.collect();
|
|
||||||
wrapper.param_ptr_to_hash = param_id_hashes_ptrs_groups
|
|
||||||
.into_iter()
|
|
||||||
.map(|(_, hash, ptr, _)| (ptr, hash))
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
// Finally, the wrapper needs to contain a reference to itself so we can create GuiContexts
|
// Finally, the wrapper needs to contain a reference to itself so we can create GuiContexts
|
||||||
// when opening plugin editors
|
// when opening plugin editors
|
||||||
let wrapper = Arc::new(wrapper);
|
let wrapper = Arc::new(wrapper);
|
||||||
|
|
|
@ -134,7 +134,47 @@ impl<P: Vst3Plugin> WrapperInner<P> {
|
||||||
let plugin = RwLock::new(P::default());
|
let plugin = RwLock::new(P::default());
|
||||||
let editor = plugin.read().editor().map(Arc::from);
|
let editor = plugin.read().editor().map(Arc::from);
|
||||||
|
|
||||||
let mut wrapper = Self {
|
// This is a mapping from the parameter IDs specified by the plugin to pointers to thsoe
|
||||||
|
// parameters. Since the object returned by `params()` is pinned, these pointers are safe to
|
||||||
|
// dereference as long as `wrapper.plugin` is alive
|
||||||
|
let param_map = plugin.read().params().param_map();
|
||||||
|
let param_ids = plugin.read().params().param_ids();
|
||||||
|
nih_debug_assert!(
|
||||||
|
!param_map.contains_key(BYPASS_PARAM_ID),
|
||||||
|
"The wrapper already adds its own bypass parameter"
|
||||||
|
);
|
||||||
|
|
||||||
|
// Only calculate these hashes once, and in the stable order defined by the plugin
|
||||||
|
let param_id_hashes_ptrs: Vec<_> = param_ids
|
||||||
|
.iter()
|
||||||
|
.filter_map(|id| {
|
||||||
|
let param_ptr = param_map.get(id)?;
|
||||||
|
Some((id, hash_param_id(id), param_ptr))
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let param_hashes = param_id_hashes_ptrs
|
||||||
|
.iter()
|
||||||
|
.map(|&(_, hash, _)| hash)
|
||||||
|
.collect();
|
||||||
|
let param_by_hash = param_id_hashes_ptrs
|
||||||
|
.iter()
|
||||||
|
.map(|&(_, hash, ptr)| (hash, *ptr))
|
||||||
|
.collect();
|
||||||
|
let param_defaults_normalized = param_id_hashes_ptrs
|
||||||
|
.iter()
|
||||||
|
.map(|&(_, hash, ptr)| (hash, unsafe { ptr.normalized_value() }))
|
||||||
|
.collect();
|
||||||
|
let param_id_to_hash = param_id_hashes_ptrs
|
||||||
|
.iter()
|
||||||
|
.map(|&(id, hash, _)| (*id, hash))
|
||||||
|
.collect();
|
||||||
|
let param_ptr_to_hash = param_id_hashes_ptrs
|
||||||
|
.into_iter()
|
||||||
|
.map(|(_, hash, ptr)| (*ptr, hash))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let wrapper = Self {
|
||||||
plugin,
|
plugin,
|
||||||
editor,
|
editor,
|
||||||
|
|
||||||
|
@ -167,52 +207,13 @@ impl<P: Vst3Plugin> WrapperInner<P> {
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
|
|
||||||
param_hashes: Vec::new(),
|
param_hashes,
|
||||||
param_by_hash: HashMap::new(),
|
param_by_hash,
|
||||||
param_defaults_normalized: HashMap::new(),
|
param_defaults_normalized,
|
||||||
param_id_to_hash: HashMap::new(),
|
param_id_to_hash,
|
||||||
param_ptr_to_hash: HashMap::new(),
|
param_ptr_to_hash,
|
||||||
};
|
};
|
||||||
|
|
||||||
// This is a mapping from the parameter IDs specified by the plugin to pointers to thsoe
|
|
||||||
// parameters. Since the object returned by `params()` is pinned, these pointers are safe to
|
|
||||||
// dereference as long as `wrapper.plugin` is alive
|
|
||||||
let param_map = wrapper.plugin.read().params().param_map();
|
|
||||||
let param_ids = wrapper.plugin.read().params().param_ids();
|
|
||||||
nih_debug_assert!(
|
|
||||||
!param_map.contains_key(BYPASS_PARAM_ID),
|
|
||||||
"The wrapper already adds its own bypass parameter"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Only calculate these hashes once, and in the stable order defined by the plugin
|
|
||||||
let param_id_hashes_ptrs: Vec<_> = param_ids
|
|
||||||
.iter()
|
|
||||||
.filter_map(|id| {
|
|
||||||
let param_ptr = param_map.get(id)?;
|
|
||||||
Some((id, hash_param_id(id), param_ptr))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
wrapper.param_hashes = param_id_hashes_ptrs
|
|
||||||
.iter()
|
|
||||||
.map(|&(_, hash, _)| hash)
|
|
||||||
.collect();
|
|
||||||
wrapper.param_by_hash = param_id_hashes_ptrs
|
|
||||||
.iter()
|
|
||||||
.map(|&(_, hash, ptr)| (hash, *ptr))
|
|
||||||
.collect();
|
|
||||||
wrapper.param_defaults_normalized = param_id_hashes_ptrs
|
|
||||||
.iter()
|
|
||||||
.map(|&(_, hash, ptr)| (hash, unsafe { ptr.normalized_value() }))
|
|
||||||
.collect();
|
|
||||||
wrapper.param_id_to_hash = param_id_hashes_ptrs
|
|
||||||
.iter()
|
|
||||||
.map(|&(id, hash, _)| (*id, hash))
|
|
||||||
.collect();
|
|
||||||
wrapper.param_ptr_to_hash = param_id_hashes_ptrs
|
|
||||||
.into_iter()
|
|
||||||
.map(|(_, hash, ptr)| (*ptr, hash))
|
|
||||||
.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
|
||||||
// serving multiple plugin instances, Arc can't be used because its reference count
|
// serving multiple plugin instances, Arc can't be used because its reference count
|
||||||
// is separate from the internal COM-style reference count.
|
// is separate from the internal COM-style reference count.
|
||||||
|
|
Loading…
Reference in a new issue