1
0
Fork 0

Add a Send+Sync wrapper for CLAP object pointers

We'll need this for the extensions.
This commit is contained in:
Robbert van der Helm 2022-02-28 20:39:15 +01:00
parent 12075b1a24
commit af77d45877
3 changed files with 35 additions and 7 deletions

View file

@ -2,6 +2,7 @@ mod context;
mod descriptor;
mod factory;
mod plugin;
mod util;
/// Re-export for the wrapper.
pub use self::factory::Factory;

View file

@ -13,6 +13,7 @@ use std::thread::{self, ThreadId};
use super::context::WrapperProcessContext;
use super::descriptor::PluginDescriptor;
use super::util::ClapPtr;
use crate::event_loop::{EventLoop, MainThreadExecutor, TASK_QUEUE_CAPACITY};
use crate::plugin::{BufferConfig, BusConfig, ClapPlugin};
use crate::NoteEvent;
@ -43,7 +44,7 @@ pub struct Wrapper<P: ClapPlugin> {
/// TODO: Implement the latency extension.
pub current_latency: AtomicU32,
host_callback: HostCallback,
host_callback: ClapPtr<clap_host>,
/// Needs to be boxed because the plugin object is supposed to contain a static reference to
/// this.
plugin_descriptor: Box<PluginDescriptor<P>>,
@ -88,8 +89,8 @@ impl<P: ClapPlugin> EventLoop<Task, Wrapper<P>> for Wrapper<P> {
let success = self.tasks.push(task).is_ok();
if success {
// CLAP lets us use the host's event loop instead of having to implement our own
let host = self.host_callback.0;
unsafe { ((*host).request_callback)(host) };
let host = &self.host_callback;
unsafe { (host.request_callback)(&**host) };
}
success
@ -108,13 +109,11 @@ impl<P: ClapPlugin> MainThreadExecutor<Task> for Wrapper<P> {
}
}
unsafe impl Send for HostCallback {}
unsafe impl Sync for HostCallback {}
impl<P: ClapPlugin> Wrapper<P> {
pub fn new(host_callback: *const clap_host) -> Self {
let plugin_descriptor = Box::new(PluginDescriptor::default());
assert!(!host_callback.is_null());
Self {
clap_plugin: clap_plugin {
// This needs to live on the heap because the plugin object contains a direct
@ -145,7 +144,7 @@ impl<P: ClapPlugin> Wrapper<P> {
input_events: RwLock::new(VecDeque::with_capacity(512)),
current_latency: AtomicU32::new(0),
host_callback: HostCallback(host_callback),
host_callback: unsafe { ClapPtr::new(host_callback) },
plugin_descriptor,
tasks: ArrayQueue::new(TASK_QUEUE_CAPACITY),

28
src/wrapper/clap/util.rs Normal file
View file

@ -0,0 +1,28 @@
use std::ops::Deref;
/// Send+Sync wrapper around CLAP host extension pointers.
pub struct ClapPtr<T> {
inner: *const T,
}
impl<T> Deref for ClapPtr<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
unsafe { &*self.inner }
}
}
unsafe impl<T> Send for ClapPtr<T> {}
unsafe impl<T> Sync for ClapPtr<T> {}
impl<T> ClapPtr<T> {
/// Create a wrapper around a CLAP object pointer.
///
/// # Safety
///
/// The pointer must point to a valid object with a lifetime that exceeds this object.
pub unsafe fn new(ptr: *const T) -> Self {
Self { inner: ptr }
}
}