Skip to content

Commit

Permalink
introduce EditorHost type; move param gesture methods from Host to Ed…
Browse files Browse the repository at this point in the history
…itorHost
  • Loading branch information
micahrj committed Aug 28, 2024
1 parent 3135ab9 commit ea2c115
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 83 deletions.
2 changes: 1 addition & 1 deletion examples/gain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ impl Plugin for Gain {
}
}

fn editor(&mut self, parent: &ParentWindow) -> Self::Editor {
fn editor(&mut self, _host: EditorHost, parent: &ParentWindow) -> Self::Editor {
GainEditor::open(parent).unwrap()
}
}
Expand Down
36 changes: 36 additions & 0 deletions src/editor.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,43 @@
use std::ffi::{c_ulong, c_void};
use std::marker::PhantomData;
use std::rc::Rc;

use crate::params::{ParamId, ParamValue};

pub trait EditorHostInner {
fn begin_gesture(&self, id: ParamId);
fn end_gesture(&self, id: ParamId);
fn set_param(&self, id: ParamId, value: ParamValue);
}

#[derive(Clone)]
pub struct EditorHost {
inner: Rc<dyn EditorHostInner>,
// Ensure !Send and !Sync
_marker: PhantomData<*mut ()>,
}

impl EditorHost {
pub fn from_inner(inner: Rc<dyn EditorHostInner>) -> EditorHost {
EditorHost {
inner,
_marker: PhantomData,
}
}

pub fn begin_gesture(&self, id: ParamId) {
self.inner.begin_gesture(id);
}

pub fn end_gesture(&self, id: ParamId) {
self.inner.end_gesture(id);
}

pub fn set_param(&self, id: ParamId, value: ParamValue) {
self.inner.set_param(id, value);
}
}

#[derive(Copy, Clone)]
pub enum RawParent {
Win32(*mut c_void),
Expand Down
16 changes: 14 additions & 2 deletions src/format/clap/gui.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,22 @@
use std::ffi::{c_char, CStr};
use std::rc::Rc;

use clap_sys::ext::gui::*;
use clap_sys::plugin::*;

use super::instance::Instance;
use crate::editor::{Editor, ParentWindow, RawParent};
use crate::editor::{Editor, EditorHost, EditorHostInner, ParentWindow, RawParent};
use crate::params::{ParamId, ParamValue};
use crate::plugin::Plugin;

struct ClapEditorHost {}

impl EditorHostInner for ClapEditorHost {
fn begin_gesture(&self, _id: ParamId) {}
fn end_gesture(&self, _id: ParamId) {}
fn set_param(&self, _id: ParamId, _value: ParamValue) {}
}

impl<P: Plugin> Instance<P> {
pub(super) const GUI: clap_plugin_gui = clap_plugin_gui {
is_api_supported: Some(Self::gui_is_api_supported),
Expand Down Expand Up @@ -151,7 +161,9 @@ impl<P: Plugin> Instance<P> {
let instance = &*(plugin as *const Self);
let main_thread_state = &mut *instance.main_thread_state.get();

let editor = main_thread_state.plugin.editor(&ParentWindow::from_raw(raw_parent));
let host = EditorHost::from_inner(Rc::new(ClapEditorHost {}));
let parent = ParentWindow::from_raw(raw_parent);
let editor = main_thread_state.plugin.editor(host, &parent);
main_thread_state.editor = Some(editor);

true
Expand Down
7 changes: 1 addition & 6 deletions src/format/clap/host.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
use crate::host::HostInner;
use crate::params::{ParamId, ParamValue};

pub struct ClapHost {}

impl HostInner for ClapHost {
fn begin_gesture(&self, _id: ParamId) {}
fn end_gesture(&self, _id: ParamId) {}
fn set_param(&self, _id: ParamId, _value: ParamValue) {}
}
impl HostInner for ClapHost {}
13 changes: 9 additions & 4 deletions src/format/vst3/component.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ use std::cell::UnsafeCell;
use std::collections::{HashMap, HashSet};
use std::ffi::{c_void, CStr};
use std::ptr;
use std::rc::Rc;
use std::sync::Arc;

use vst3::{Class, ComRef, ComWrapper, Steinberg::Vst::*, Steinberg::*};

use super::buffers::ScratchBuffers;
use super::host::Vst3Host;
use super::util::{copy_wstring, utf16_from_ptr};
use super::view::View;
use super::view::{View, Vst3EditorHost};
use crate::bus::{BusDir, Format, Layout};
use crate::editor::Editor;
use crate::events::{Data, Event, Events};
Expand Down Expand Up @@ -39,6 +40,7 @@ pub struct MainThreadState<P: Plugin> {
pub config: Config,
pub plugin: P,
pub editor_params: Vec<f64>,
pub editor_host: Rc<Vst3EditorHost>,
pub editor: Option<P::Editor>,
}

Expand All @@ -57,7 +59,7 @@ pub struct Component<P: Plugin> {
param_map: HashMap<ParamId, usize>,
plugin_params: ParamValues,
processor_params: ParamValues,
host: Arc<Vst3Host>,
_host: Arc<Vst3Host>,
main_thread_state: Arc<UnsafeCell<MainThreadState<P>>>,
// 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
Expand Down Expand Up @@ -107,11 +109,12 @@ impl<P: Plugin> Component<P> {
param_map,
plugin_params: ParamValues::new(&info.params),
processor_params: ParamValues::new(&info.params),
host: host.clone(),
_host: host.clone(),
main_thread_state: Arc::new(UnsafeCell::new(MainThreadState {
config: config.clone(),
plugin: P::new(Host::from_inner(host)),
editor_params,
editor_host: Rc::new(Vst3EditorHost::new()),
editor: None,
})),
process_state: UnsafeCell::new(ProcessState {
Expand Down Expand Up @@ -693,7 +696,9 @@ impl<P: Plugin> IEditControllerTrait for Component<P> {
}

unsafe fn setComponentHandler(&self, handler: *mut IComponentHandler) -> tresult {
let mut current_handler = self.host.handler.write().unwrap();
let main_thread_state = &mut *self.main_thread_state.get();

let mut current_handler = main_thread_state.editor_host.handler.borrow_mut();
if let Some(handler) = ComRef::from_raw(handler) {
*current_handler = Some(handler.to_com_ptr());
} else {
Expand Down
46 changes: 3 additions & 43 deletions src/format/vst3/host.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,11 @@
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 handler: RwLock<Option<ComPtr<IComponentHandler>>>,
}
pub struct Vst3Host {}

impl Vst3Host {
pub fn new() -> Vst3Host {
Vst3Host {
handler: RwLock::new(None),
}
Vst3Host {}
}
}

impl HostInner for Vst3Host {
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);
}
}
}
}
impl HostInner for Vst3Host {}
53 changes: 49 additions & 4 deletions src/format/vst3/view.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,56 @@
use std::cell::UnsafeCell;
use std::cell::{RefCell, UnsafeCell};
use std::ffi::{c_void, CStr};
use std::sync::Arc;

use vst3::{Class, Steinberg::*};
use vst3::Steinberg::Vst::{IComponentHandler, IComponentHandlerTrait};
use vst3::{Class, ComPtr, Steinberg::*};

use super::component::MainThreadState;
use crate::editor::{Editor, ParentWindow, RawParent};
use crate::editor::{Editor, EditorHost, EditorHostInner, ParentWindow, RawParent};
use crate::params::{ParamId, ParamValue};
use crate::plugin::Plugin;

pub struct Vst3EditorHost {
pub handler: RefCell<Option<ComPtr<IComponentHandler>>>,
}

impl Vst3EditorHost {
pub fn new() -> Vst3EditorHost {
Vst3EditorHost {
handler: RefCell::new(None),
}
}
}

impl EditorHostInner for Vst3EditorHost {
fn begin_gesture(&self, id: ParamId) {
let handler = self.handler.borrow();
if let Some(handler) = &*handler {
unsafe {
handler.beginEdit(id);
}
}
}

fn end_gesture(&self, id: ParamId) {
let handler = self.handler.borrow();
if let Some(handler) = &*handler {
unsafe {
handler.endEdit(id);
}
}
}

fn set_param(&self, id: ParamId, value: ParamValue) {
let handler = self.handler.borrow();
if let Some(handler) = &*handler {
unsafe {
handler.performEdit(id, value);
}
}
}
}

pub struct View<P: Plugin> {
main_thread_state: Arc<UnsafeCell<MainThreadState<P>>>,
}
Expand Down Expand Up @@ -60,7 +103,9 @@ impl<P: Plugin> IPlugViewTrait for View<P> {

let main_thread_state = &mut *self.main_thread_state.get();

let editor = main_thread_state.plugin.editor(&ParentWindow::from_raw(raw_parent));
let host = EditorHost::from_inner(main_thread_state.editor_host.clone());
let parent = ParentWindow::from_raw(raw_parent);
let editor = main_thread_state.plugin.editor(host, &parent);
main_thread_state.editor = Some(editor);

kResultOk
Expand Down
24 changes: 3 additions & 21 deletions src/host.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,14 @@
use std::sync::Arc;

use crate::params::{ParamId, ParamValue};

pub trait HostInner {
fn begin_gesture(&self, id: ParamId);
fn end_gesture(&self, id: ParamId);
fn set_param(&self, id: ParamId, value: ParamValue);
}
pub trait HostInner {}

#[derive(Clone)]
pub struct Host {
inner: Arc<dyn HostInner + Send + Sync>,
_inner: Arc<dyn HostInner + Send + Sync>,
}

impl Host {
pub fn from_inner(inner: Arc<dyn HostInner + Send + Sync>) -> Host {
Host { inner }
}

pub fn begin_gesture(&self, id: ParamId) {
self.inner.begin_gesture(id);
}

pub fn end_gesture(&self, id: ParamId) {
self.inner.end_gesture(id);
}

pub fn set_param(&self, id: ParamId, value: ParamValue) {
self.inner.set_param(id, value);
Host { _inner: inner }
}
}
4 changes: 2 additions & 2 deletions src/plugin.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::io::{self, Read, Write};

use crate::bus::{BusInfo, Layout};
use crate::editor::{Editor, ParentWindow};
use crate::editor::{Editor, EditorHost, ParentWindow};
use crate::host::Host;
use crate::params::{ParamId, ParamInfo, ParamValue};
use crate::process::{Config, Processor};
Expand Down Expand Up @@ -46,7 +46,7 @@ pub trait Plugin: Send + Sized + 'static {
fn save(&self, output: &mut impl Write) -> io::Result<()>;
fn load(&mut self, input: &mut impl Read) -> io::Result<()>;
fn processor(&mut self, config: Config) -> Self::Processor;
fn editor(&mut self, parent: &ParentWindow) -> Self::Editor;
fn editor(&mut self, host: EditorHost, parent: &ParentWindow) -> Self::Editor;

#[allow(unused_variables)]
fn latency(&self, config: &Config) -> u64 {
Expand Down

0 comments on commit ea2c115

Please sign in to comment.