From 6c84fec09ec6c8fc2995b007b0fae6011d2d6a75 Mon Sep 17 00:00:00 2001 From: Robbert van der Helm Date: Fri, 22 Apr 2022 18:54:39 +0200 Subject: [PATCH] Add a (not yet functional) standalone run function --- src/wrapper/standalone.rs | 31 ++++++++++++++++++++----------- src/wrapper/standalone/wrapper.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 45 insertions(+), 13 deletions(-) diff --git a/src/wrapper/standalone.rs b/src/wrapper/standalone.rs index 078b3e56..2593afe7 100644 --- a/src/wrapper/standalone.rs +++ b/src/wrapper/standalone.rs @@ -72,19 +72,28 @@ pub fn nih_export_standalone_with_args::new(config.clone()) { Ok(wrapper) => wrapper, - Err(WrapperError::IncompatibleConfig) => { - eprintln!("The plugin does not support the {} channel input and {} channel output configuration", config.input_channels, config.output_channels); - return false; - } - Err(WrapperError::InitializationFailed) => { - eprintln!("The plugin failed to initialize"); + Err(err) => { + print_error(err, &config); return false; } }; - // TODO: Open the editor if available, do IO things - // TODO: If the plugin has an editor, block until the editor is closed. Otherwise block - // indefinitely or until SIGINT (how do signal handlers work in Rust?) - - true + match wrapper.run() { + Ok(()) => true, + Err(err) => { + print_error(err, &config); + false + } + } +} + +fn print_error(error: WrapperError, config: &WrapperConfig) { + match error { + WrapperError::IncompatibleConfig => { + eprintln!("The plugin does not support the {} channel input and {} channel output configuration", config.input_channels, config.output_channels); + } + WrapperError::InitializationFailed => { + eprintln!("The plugin failed to initialize"); + } + } } diff --git a/src/wrapper/standalone/wrapper.rs b/src/wrapper/standalone/wrapper.rs index 6e6e9c1d..103e654a 100644 --- a/src/wrapper/standalone/wrapper.rs +++ b/src/wrapper/standalone/wrapper.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use super::context::WrapperProcessContext; use crate::context::Transport; -use crate::plugin::{BufferConfig, BusConfig, Plugin}; +use crate::plugin::{BufferConfig, BusConfig, Editor, Plugin}; /// Configuration for a standalone plugin that would normally be provided by the DAW. #[derive(Debug, Clone)] @@ -28,6 +28,10 @@ pub struct WrapperConfig { pub struct Wrapper { /// The wrapped plugin instance. plugin: RwLock

, + /// The plugin's editor, if it has one. This object does not do anything on its own, but we need + /// to instantiate this in advance so we don't need to lock the entire [`Plugin`] object when + /// creating an editor. + editor: Option>, config: WrapperConfig, @@ -37,6 +41,7 @@ pub struct Wrapper { } /// Errors that may arise while initializing the wrapped plugins. +#[derive(Debug, Clone, Copy)] pub enum WrapperError { /// The plugin does not accept the IO configuration from the config. IncompatibleConfig, @@ -48,8 +53,13 @@ impl Wrapper

{ /// Instantiate a new instance of the standalone wrapper. Returns an error if the plugin does /// not accept the IO configuration from the wrapper config. pub fn new(config: WrapperConfig) -> Result, WrapperError> { + let plugin = P::default(); + let editor = plugin.editor(); + let wrapper = Arc::new(Wrapper { - plugin: RwLock::new(P::default()), + plugin: RwLock::new(plugin), + editor, + bus_config: BusConfig { num_input_channels: config.input_channels, num_output_channels: config.output_channels, @@ -81,6 +91,19 @@ impl Wrapper

{ Ok(wrapper) } + /// Open the editor, start processing audio, and block this thread until the editor is closed. + /// If the plugin does not have an editor, then this will block until SIGINT is received. + /// + /// Will return an error if the plugin threw an error during audio processing or if the editor + /// could not be opened. + pub fn run(self: Arc) -> Result<(), WrapperError> { + // TODO: Open the editor and block until it is closed + // TODO: Do IO things + // TODO: Block until SIGINT is received if the plugin does not have an editor + + Ok(()) + } + fn make_process_context(&self, transport: Transport) -> WrapperProcessContext<'_, P> { WrapperProcessContext { wrapper: self,