Modify the editor API to use trait objects
The alternative isn't really feasible without specialization, and NIH-plug should work on the stable compiler.
This commit is contained in:
parent
e4c6c6c25b
commit
b075d1b1bb
|
@ -18,8 +18,8 @@
|
||||||
extern crate nih_plug;
|
extern crate nih_plug;
|
||||||
|
|
||||||
use nih_plug::{
|
use nih_plug::{
|
||||||
formatters, util, Buffer, BufferConfig, BusConfig, NoEditor, Plugin, ProcessContext,
|
formatters, util, Buffer, BufferConfig, BusConfig, Plugin, ProcessContext, ProcessStatus,
|
||||||
ProcessStatus, Vst3Plugin,
|
Vst3Plugin,
|
||||||
};
|
};
|
||||||
use nih_plug::{BoolParam, FloatParam, Param, Params, Range, Smoother, SmoothingStyle};
|
use nih_plug::{BoolParam, FloatParam, Param, Params, Range, Smoother, SmoothingStyle};
|
||||||
use parking_lot::RwLock;
|
use parking_lot::RwLock;
|
||||||
|
@ -86,8 +86,6 @@ impl Default for GainParams {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Plugin for Gain {
|
impl Plugin for Gain {
|
||||||
type Editor = NoEditor;
|
|
||||||
|
|
||||||
const NAME: &'static str = "Gain";
|
const NAME: &'static str = "Gain";
|
||||||
const VENDOR: &'static str = "Moist Plugins GmbH";
|
const VENDOR: &'static str = "Moist Plugins GmbH";
|
||||||
const URL: &'static str = "https://youtu.be/dQw4w9WgXcQ";
|
const URL: &'static str = "https://youtu.be/dQw4w9WgXcQ";
|
||||||
|
|
|
@ -18,8 +18,8 @@
|
||||||
extern crate nih_plug;
|
extern crate nih_plug;
|
||||||
|
|
||||||
use nih_plug::{
|
use nih_plug::{
|
||||||
formatters, util, Buffer, BufferConfig, BusConfig, NoEditor, Plugin, ProcessContext,
|
formatters, util, Buffer, BufferConfig, BusConfig, Plugin, ProcessContext, ProcessStatus,
|
||||||
ProcessStatus, Vst3Plugin,
|
Vst3Plugin,
|
||||||
};
|
};
|
||||||
use nih_plug::{BoolParam, FloatParam, Param, Params, Range, Smoother, SmoothingStyle};
|
use nih_plug::{BoolParam, FloatParam, Param, Params, Range, Smoother, SmoothingStyle};
|
||||||
use std::f32::consts;
|
use std::f32::consts;
|
||||||
|
@ -123,8 +123,6 @@ impl Sine {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Plugin for Sine {
|
impl Plugin for Sine {
|
||||||
type Editor = NoEditor;
|
|
||||||
|
|
||||||
const NAME: &'static str = "Sine Test Tone";
|
const NAME: &'static str = "Sine Test Tone";
|
||||||
const VENDOR: &'static str = "Moist Plugins GmbH";
|
const VENDOR: &'static str = "Moist Plugins GmbH";
|
||||||
const URL: &'static str = "https://youtu.be/dQw4w9WgXcQ";
|
const URL: &'static str = "https://youtu.be/dQw4w9WgXcQ";
|
||||||
|
|
|
@ -33,7 +33,7 @@ pub use param::range::Range;
|
||||||
pub use param::smoothing::{Smoother, SmoothingStyle};
|
pub use param::smoothing::{Smoother, SmoothingStyle};
|
||||||
pub use param::{BoolParam, FloatParam, IntParam, Param};
|
pub use param::{BoolParam, FloatParam, IntParam, Param};
|
||||||
pub use plugin::{
|
pub use plugin::{
|
||||||
BufferConfig, BusConfig, Editor, NoEditor, NoteEvent, Plugin, ProcessStatus, Vst3Plugin,
|
BufferConfig, BusConfig, Editor, NoteEvent, Plugin, ProcessStatus, RawWindowHandle, Vst3Plugin,
|
||||||
};
|
};
|
||||||
|
|
||||||
// The rest is either internal or already re-exported
|
// The rest is either internal or already re-exported
|
||||||
|
|
|
@ -14,13 +14,16 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use raw_window_handle::RawWindowHandle;
|
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use crate::buffer::Buffer;
|
use crate::buffer::Buffer;
|
||||||
use crate::context::{GuiContext, ProcessContext};
|
use crate::context::{GuiContext, ProcessContext};
|
||||||
use crate::param::internals::Params;
|
use crate::param::internals::Params;
|
||||||
|
|
||||||
|
/// A raw window handle for platform and GUI framework agnostic editors.
|
||||||
|
pub use raw_window_handle::RawWindowHandle;
|
||||||
|
|
||||||
/// Basic functionality that needs to be implemented by a plugin. The wrappers will use this to
|
/// Basic functionality that needs to be implemented by a plugin. The wrappers will use this to
|
||||||
/// expose the plugin in a particular plugin format.
|
/// expose the plugin in a particular plugin format.
|
||||||
///
|
///
|
||||||
|
@ -41,11 +44,6 @@ use crate::param::internals::Params;
|
||||||
/// - GUIs
|
/// - GUIs
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub trait Plugin: Default + Send + Sync + 'static {
|
pub trait Plugin: Default + Send + Sync + 'static {
|
||||||
/// The type of the GUI editor instance belonging to this plugin. Use [NoEditor] when you don't
|
|
||||||
/// need an editor. Make sure to implement both the [Self::create_editor()] and
|
|
||||||
/// [Self::editor_size()] functions when you do add an editor.
|
|
||||||
type Editor: Editor;
|
|
||||||
|
|
||||||
const NAME: &'static str;
|
const NAME: &'static str;
|
||||||
const VENDOR: &'static str;
|
const VENDOR: &'static str;
|
||||||
const URL: &'static str;
|
const URL: &'static str;
|
||||||
|
@ -71,11 +69,13 @@ pub trait Plugin: Default + Send + Sync + 'static {
|
||||||
/// plugin receives an update.
|
/// plugin receives an update.
|
||||||
fn params(&self) -> Pin<&dyn Params>;
|
fn params(&self) -> Pin<&dyn Params>;
|
||||||
|
|
||||||
/// Create an editor for this plugin and embed it in the parent window. The idea is that you
|
/// Create an editor for this plugin and embed it in the parent window. A plugin editor will
|
||||||
/// take a reference to your [Params] in your editor to be able to read the current values. Then
|
/// likely want to interact with the plugin's parameters, so the idea is that you take a
|
||||||
/// whenever you need to change any of those values, you can use the methods on the [GuiContext]
|
/// reference to your [Params] object in your editor as well as the [GuiContext] that's passed
|
||||||
/// that's passed to this function. When you change a parameter value there it will be
|
/// to this function. You can then read the parameter values directly from your [Params] object,
|
||||||
/// broadcasted to the host and also updated in your [Params] struct.
|
/// and modifying the values can be done using the functions on [GuiContext::setter()]. When you
|
||||||
|
/// change a parameter value that way it will be broadcasted to the host and also updated in
|
||||||
|
/// your [Params] struct.
|
||||||
//
|
//
|
||||||
// TODO: Think of how this would work with the event loop. On Linux the wrapper must provide a
|
// TODO: Think of how this would work with the event loop. On Linux the wrapper must provide a
|
||||||
// timer using VST3's `IRunLoop` interface, but on Window and macOS the window would
|
// timer using VST3's `IRunLoop` interface, but on Window and macOS the window would
|
||||||
|
@ -83,15 +83,16 @@ pub trait Plugin: Default + Send + Sync + 'static {
|
||||||
// otherwise be basically impossible to have this still be GUI-framework agnostic. Any
|
// otherwise be basically impossible to have this still be GUI-framework agnostic. Any
|
||||||
// callback that deos involve actual GUI operations will still be spooled to the IRunLoop
|
// callback that deos involve actual GUI operations will still be spooled to the IRunLoop
|
||||||
// instance.
|
// instance.
|
||||||
fn create_editor(
|
fn create_editor<'a, 'context: 'a>(
|
||||||
&self,
|
&'a self,
|
||||||
parent: RawWindowHandle,
|
parent: RawWindowHandle,
|
||||||
context: &impl GuiContext,
|
context: Arc<dyn GuiContext + 'context>,
|
||||||
) -> Option<Self::Editor> {
|
) -> Option<Box<dyn Editor + 'context>> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the current size of the plugin's editor, if it has one.
|
/// Return the current size of the plugin's editor, if it has one. This is also used to check
|
||||||
|
/// whether the plugin has an editor without creating one.
|
||||||
fn editor_size(&self) -> Option<(u32, u32)> {
|
fn editor_size(&self) -> Option<(u32, u32)> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
@ -149,13 +150,12 @@ pub trait Vst3Plugin: Plugin {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An editor for a [Plugin]. The [Drop] implementation gets called when the host closes the editor.
|
/// An editor for a [Plugin]. The [Drop] implementation gets called when the host closes the editor.
|
||||||
/// If you don't have or need an editor, then you can use the [NoEditor] struct as a placeholder.
|
|
||||||
//
|
//
|
||||||
// XXX: Requiring a [Drop] bound is a bit unorthodox, but together with [Plugin::create_editor] it
|
// XXX: Requiring a [Drop] bound is a bit unorthodox, but together with [Plugin::create_editor] it
|
||||||
// encodes the lifecycle of an editor perfectly as you cannot have duplicate (or missing)
|
// encodes the lifecycle of an editor perfectly as you cannot have duplicate (or missing)
|
||||||
// initialize and close calls. Maybe think this over again later.
|
// initialize and close calls. Maybe think this over again later.
|
||||||
#[allow(drop_bounds)]
|
#[allow(drop_bounds)]
|
||||||
pub trait Editor: Drop {
|
pub trait Editor: Drop + Send + Sync {
|
||||||
/// Return the (currnent) size of the editor in pixels as a `(width, height)` pair.
|
/// Return the (currnent) size of the editor in pixels as a `(width, height)` pair.
|
||||||
fn size(&self) -> (u32, u32);
|
fn size(&self) -> (u32, u32);
|
||||||
|
|
||||||
|
@ -163,18 +163,6 @@ pub trait Editor: Drop {
|
||||||
// TODO: Resizing
|
// TODO: Resizing
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct NoEditor;
|
|
||||||
|
|
||||||
impl Editor for NoEditor {
|
|
||||||
fn size(&self) -> (u32, u32) {
|
|
||||||
(0, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for NoEditor {
|
|
||||||
fn drop(&mut self) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// We only support a single main input and output bus at the moment.
|
/// We only support a single main input and output bus at the moment.
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub struct BusConfig {
|
pub struct BusConfig {
|
||||||
|
|
Loading…
Reference in a new issue