1
0
Fork 0

Take &mut self for editor() and task_executor()

This commit is contained in:
Robbert van der Helm 2023-04-24 14:51:40 +02:00
parent 44476ad696
commit 808782df05
11 changed files with 46 additions and 21 deletions

View file

@ -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

View file

@ -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())
}

View file

@ -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(),

View file

@ -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(

View file

@ -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(),

View file

@ -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(),

View file

@ -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 {

View file

@ -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
}

View file

@ -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

View file

@ -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();

View file

@ -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