Skip to content

Commit

Permalink
Take &mut self for editor() and task_executor()
Browse files Browse the repository at this point in the history
  • Loading branch information
robbert-vdh committed Apr 24, 2023
1 parent 44476ad commit 808782d
Show file tree
Hide file tree
Showing 11 changed files with 46 additions and 21 deletions.
14 changes: 14 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,20 @@ Since there is no stable release yet, the changes are organized per day in
reverse chronological order. The main purpose of this document in its current
state is to list breaking changes.

## [2023-04-24]

### Breaking changes

- `Plugin::editor()` and `Plugin::task_executor()` now take `&mut self` instead
of `&self` to make it easier to move data into these functions without
involving interior mutability.

### Changed

- The `Plugin` trait's documentation has been updated to better clarify the
structure and to more explicitly mention that the non-lifecycle methods are
called once immediately after creating the plugin object.

## [2023-04-22]

### Added
Expand Down
2 changes: 1 addition & 1 deletion plugins/crisp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ impl Plugin for Crisp {
self.params.clone()
}

fn editor(&self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
editor::create(self.params.clone(), self.params.editor_state.clone())
}

Expand Down
2 changes: 1 addition & 1 deletion plugins/diopser/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ impl Plugin for Diopser {
self.params.clone()
}

fn editor(&self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
editor::create(
editor::Data {
params: self.params.clone(),
Expand Down
2 changes: 1 addition & 1 deletion plugins/examples/gain_gui_egui/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ impl Plugin for Gain {
self.params.clone()
}

fn editor(&self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
let params = self.params.clone();
let peak_meter = self.peak_meter.clone();
create_egui_editor(
Expand Down
2 changes: 1 addition & 1 deletion plugins/examples/gain_gui_iced/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ impl Plugin for Gain {
self.params.clone()
}

fn editor(&self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
editor::create(
self.params.clone(),
self.peak_meter.clone(),
Expand Down
2 changes: 1 addition & 1 deletion plugins/examples/gain_gui_vizia/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ impl Plugin for Gain {
self.params.clone()
}

fn editor(&self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
editor::create(
self.params.clone(),
self.peak_meter.clone(),
Expand Down
2 changes: 1 addition & 1 deletion plugins/spectral_compressor/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,7 @@ impl Plugin for SpectralCompressor {
self.params.clone()
}

fn editor(&self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
fn editor(&mut self, _async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
editor::create(
self.params.editor_state.clone(),
editor::Data {
Expand Down
35 changes: 23 additions & 12 deletions src/plugin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -131,25 +131,36 @@ pub trait Plugin: Default + Send + 'static {
// NOTE: Sadly it's not yet possible to default this and the `async_executor()` function to
// `()`: https://github.com/rust-lang/rust/issues/29661
type BackgroundTask: Send;
/// A function that executes the plugin's tasks. Queried once when the plugin instance is
/// created. See [`BackgroundTask`][Self::BackgroundTask].
fn task_executor(&self) -> TaskExecutor<Self> {
/// A function that executes the plugin's tasks. When implementing this you will likely want to
/// pattern match on the task type, and then send any resulting data back over a channel or
/// triple buffer. See [`BackgroundTask`][Self::BackgroundTask].
///
/// Queried only once immediately after the plugin instance is created. This function takes
/// `&mut self` to make it easier to move data into the closure.
fn task_executor(&mut self) -> TaskExecutor<Self> {
// In the default implementation we can simply ignore the value
Box::new(|_| ())
}

/// The plugin's parameters. The host will update the parameter values before calling
/// `process()`. These parameters are identified by strings that should never change when the
/// plugin receives an update.
/// `process()`. These string parameter IDs parameters should never change as they are used to
/// distinguish between parameters.
///
/// Queried only once immediately after the plugin instance is created.
fn params(&self) -> Arc<dyn Params>;

/// The plugin's editor, if it has one. The actual editor instance is created in
/// [`Editor::spawn()`]. A plugin editor likely wants to interact with the plugin's parameters
/// and other shared data, so you'll need to move [`Arc`] pointing to any data you want to
/// access into the editor. You can later modify the parameters through the
/// [`GuiContext`][crate::prelude::GuiContext] and [`ParamSetter`][crate::prelude::ParamSetter] after the editor
/// GUI has been created.
fn editor(&self, async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
/// Returns an extension struct for interacting with the plugin's editor, if it has one. Later
/// the host may call [`Editor::spawn()`] to create an editor instance. To read the current
/// parameter values, you will need to clone and move the `Arc` containing your `Params` object
/// into the editor. You can later modify the parameters through the
/// [`GuiContext`][crate::prelude::GuiContext] and [`ParamSetter`][crate::prelude::ParamSetter]
/// after the editor GUI has been created. NIH-plug comes with wrappers for several common GUI
/// frameworks that may have their own ways of interacting with parameters. See the repo's
/// readme for more information.
///
/// Queried only once immediately after the plugin instance is created. This function takes
/// `&mut self` to make it easier to move data into the `Editor` implementation.
fn editor(&mut self, async_executor: AsyncExecutor<Self>) -> Option<Box<dyn Editor>> {
None
}

Expand Down
2 changes: 1 addition & 1 deletion src/wrapper/clap/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ impl<P: ClapPlugin> MainThreadExecutor<Task<P>> for Wrapper<P> {

impl<P: ClapPlugin> Wrapper<P> {
pub fn new(host_callback: *const clap_host) -> Arc<Self> {
let plugin = P::default();
let mut plugin = P::default();
let task_executor = Mutex::new(plugin.task_executor());

// This is used to allow the plugin to restore preset data from its editor, see the comment
Expand Down
2 changes: 1 addition & 1 deletion src/wrapper/standalone/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ impl<P: Plugin, B: Backend<P>> Wrapper<P, B> {
// the config itself. Right now clap doesn't support this.
let audio_io_layout = config.audio_io_layout_or_exit::<P>();

let plugin = P::default();
let mut plugin = P::default();
let task_executor = Mutex::new(plugin.task_executor());
let params = plugin.params();

Expand Down
2 changes: 1 addition & 1 deletion src/wrapper/vst3/inner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,7 @@ pub enum ProcessEvent<P: Plugin> {
impl<P: Vst3Plugin> WrapperInner<P> {
#[allow(unused_unsafe)]
pub fn new() -> Arc<Self> {
let plugin = P::default();
let mut plugin = P::default();
let task_executor = Mutex::new(plugin.task_executor());

// This is used to allow the plugin to restore preset data from its editor, see the comment
Expand Down

0 comments on commit 808782d

Please sign in to comment.