diff --git a/src/format/vst3/component.rs b/src/format/vst3/component.rs index 65c5783..91c413a 100644 --- a/src/format/vst3/component.rs +++ b/src/format/vst3/component.rs @@ -57,6 +57,7 @@ pub struct Component { param_map: HashMap, plugin_params: ParamValues, processor_params: ParamValues, + host: Arc, main_thread_state: Arc>>, // When the audio processor is *not* active, references to ProcessState may only be formed from // the main thread. When the audio processor *is* active, references to ProcessState may only @@ -96,6 +97,8 @@ impl Component

{ let scratch_buffers = ScratchBuffers::new(input_bus_map.len(), output_bus_map.len()); + let host = Arc::new(Vst3Host::new()); + Component { info: info.clone(), input_bus_map, @@ -104,9 +107,10 @@ impl Component

{ param_map, plugin_params: ParamValues::new(&info.params), processor_params: ParamValues::new(&info.params), + host: host.clone(), main_thread_state: Arc::new(UnsafeCell::new(MainThreadState { config: config.clone(), - plugin: P::new(Host::from_inner(Arc::new(Vst3Host {}))), + plugin: P::new(Host::from_inner(host)), editor_params, editor: None, })), @@ -688,7 +692,14 @@ impl IEditControllerTrait for Component

{ kInvalidArgument } - unsafe fn setComponentHandler(&self, _handler: *mut IComponentHandler) -> tresult { + unsafe fn setComponentHandler(&self, handler: *mut IComponentHandler) -> tresult { + let mut current_handler = self.host.handler.write().unwrap(); + if let Some(handler) = ComRef::from_raw(handler) { + *current_handler = Some(handler.to_com_ptr()); + } else { + *current_handler = None; + } + kResultOk } diff --git a/src/format/vst3/host.rs b/src/format/vst3/host.rs index d5eeef8..de628a5 100644 --- a/src/format/vst3/host.rs +++ b/src/format/vst3/host.rs @@ -1,10 +1,51 @@ +use std::sync::RwLock; + +use vst3::ComPtr; +use vst3::Steinberg::Vst::{IComponentHandler, IComponentHandlerTrait}; + use crate::host::HostInner; use crate::params::{ParamId, ParamValue}; -pub struct Vst3Host {} +pub struct Vst3Host { + pub handler: RwLock>>, +} + +impl Vst3Host { + pub fn new() -> Vst3Host { + Vst3Host { + handler: RwLock::new(None), + } + } +} impl HostInner for Vst3Host { - fn begin_gesture(&self, _id: ParamId) {} - fn end_gesture(&self, _id: ParamId) {} - fn set_param(&self, _id: ParamId, _value: ParamValue) {} + fn begin_gesture(&self, id: ParamId) { + let handler = self.handler.read().unwrap(); + if let Some(handler) = &*handler { + // TODO: only call this on main thread + unsafe { + handler.beginEdit(id); + } + } + } + + fn end_gesture(&self, id: ParamId) { + let handler = self.handler.read().unwrap(); + if let Some(handler) = &*handler { + // TODO: only call this on main thread + unsafe { + handler.endEdit(id); + } + } + } + + fn set_param(&self, id: ParamId, value: ParamValue) { + let handler = self.handler.read().unwrap(); + if let Some(handler) = &*handler { + // TODO: only call this on main thread + unsafe { + handler.performEdit(id, value); + } + } + } }