From 95f0183d27670d63237424264263f521203a2d0b Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Wed, 16 Feb 2022 20:23:22 +0100 Subject: [PATCH] Add VST3 smart pointers for regular objects --- src/wrapper/vst3/util.rs | 40 +++++++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/wrapper/vst3/util.rs b/src/wrapper/vst3/util.rs index 55520991..f70b4c8c 100644 --- a/src/wrapper/vst3/util.rs +++ b/src/wrapper/vst3/util.rs @@ -1,4 +1,6 @@ use lazy_static::lazy_static; +use std::ops::Deref; +use vst3_sys::{interfaces::IUnknown, ComInterface}; use crate::wrapper::util::hash_param_id; @@ -33,7 +35,14 @@ pub struct VstPtr { ptr: vst3_sys::VstPtr, } -impl std::ops::Deref for VstPtr { +/// The same as [VstPtr] with shared semnatics, but for objects we defined ourself since VstPtr only +/// works for interfaces. +#[repr(transparent)] +pub struct ObjectPtr { + ptr: *const T, +} + +impl Deref for VstPtr { type Target = vst3_sys::VstPtr; fn deref(&self) -> &Self::Target { @@ -41,13 +50,38 @@ impl std::ops::Deref for VstPtr { } } +impl Deref for ObjectPtr { + type Target = T; + + fn deref(&self) -> &Self::Target { + unsafe { &*self.ptr } + } +} + impl From> for VstPtr { fn from(ptr: vst3_sys::VstPtr) -> Self { Self { ptr } } } +impl Drop for ObjectPtr { + fn drop(&mut self) { + unsafe { (*self).release() }; + } +} + /// 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 {} +unsafe impl Send for VstPtr {} +unsafe impl Sync for VstPtr {} + +unsafe impl Send for ObjectPtr {} +unsafe impl Sync for ObjectPtr {} + +impl ObjectPtr { + /// Create a smart pointer for an existing reference counted object. + pub fn new(obj: &T) -> Self { + unsafe { obj.add_ref() }; + Self { ptr: obj } + } +}