From 223d0c3a90e76265c369ab54c39026f6a73718d5 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Tue, 1 Feb 2022 16:52:55 +0100 Subject: [PATCH] Take a reference to the component handler --- src/wrapper/vst3.rs | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/src/wrapper/vst3.rs b/src/wrapper/vst3.rs index 3c957f6c..165908fa 100644 --- a/src/wrapper/vst3.rs +++ b/src/wrapper/vst3.rs @@ -34,7 +34,8 @@ use vst3_sys::base::{kInvalidArgument, kNoInterface, kResultFalse, kResultOk, tr use vst3_sys::base::{IBStream, IPluginBase, IPluginFactory, IPluginFactory2, IPluginFactory3}; use vst3_sys::utils::SharedVstPtr; use vst3_sys::vst::{ - IAudioProcessor, IComponent, IEditController, IParamValueQueue, IParameterChanges, TChar, + IAudioProcessor, IComponent, IComponentHandler, IEditController, IParamValueQueue, + IParameterChanges, TChar, }; use vst3_sys::VST3; use widestring::U16CStr; @@ -85,6 +86,10 @@ struct WrapperInner<'a, P: Plugin> { /// The wrapped plugin instance. plugin: Pin>>, + /// The host's `IComponentHandler` instance, if passed through + /// `IEditController::set_component_handler`. + component_handler: RwLock>>, + /// A realtime-safe task queue so the plugin can schedule tasks that need to be run later on the /// GUI thread. /// @@ -140,6 +145,31 @@ enum Task { TriggerRestart(u32), } +/// Send+Sync wrapper for these interface pointers. +#[repr(transparent)] +struct VstPtr { + ptr: vst3_sys::VstPtr, +} + +impl std::ops::Deref for VstPtr { + type Target = vst3_sys::VstPtr; + + fn deref(&self) -> &Self::Target { + &self.ptr + } +} + +impl From> for VstPtr { + fn from(ptr: vst3_sys::VstPtr) -> Self { + Self { ptr } + } +} + +/// SAFETY: Sharing these pointers across thread is s safe as they have internal atomic reference +/// counting, so as long as a `VstPtr` handle exists the object will stay alive. +unsafe impl Send for VstPtr {} +unsafe impl Sync for VstPtr {} + impl WrapperInner<'_, P> { // XXX: The unsafe blocks in this function are unnecessary. but rust-analyzer gets a bit // confused by all of these vtables @@ -148,6 +178,8 @@ impl WrapperInner<'_, P> { let mut wrapper = Self { plugin: Box::pin(RwLock::default()), + component_handler: RwLock::new(None), + event_loop: RwLock::new(MaybeUninit::uninit()), is_processing: AtomicBool::new(false), @@ -720,9 +752,10 @@ impl IEditController for Wrapper<'_, P> { unsafe fn set_component_handler( &self, - _handler: SharedVstPtr, + handler: SharedVstPtr, ) -> tresult { - // TODO: Use this when we add GUI support + *self.inner.component_handler.write() = handler.upgrade().map(VstPtr::from); + kResultOk }