1
0
Fork 0

Add an AsyncExecutor type for use with the GUI

This commit is contained in:
Robbert van der Helm 2022-10-22 14:34:32 +02:00
parent b676353589
commit f3bb816cb5
3 changed files with 39 additions and 3 deletions

View file

@ -1,8 +1,11 @@
//! A context passed to a plugin's editor. //! A context passed to a plugin's editor.
use std::sync::Arc;
use super::PluginApi; use super::PluginApi;
use crate::params::internals::ParamPtr; use crate::params::internals::ParamPtr;
use crate::params::Param; use crate::params::Param;
use crate::plugin::Plugin;
use crate::wrapper::state::PluginState; use crate::wrapper::state::PluginState;
/// Callbacks the plugin can make when the user interacts with its GUI such as updating parameter /// Callbacks the plugin can make when the user interacts with its GUI such as updating parameter
@ -65,6 +68,25 @@ pub trait GuiContext: Send + Sync + 'static {
fn set_state(&self, state: PluginState); fn set_state(&self, state: PluginState);
} }
/// An way to run background tasks from the plugin's GUI, equivalent to
/// [`ProcessContext::execute_async()`][crate::prelude::ProcessContext::execute_async()]. This is
/// passed directly to [`Plugin::editor()`] so the plugin can move it into its editor and use it
/// later.
///
/// # Note
///
/// This is only intended to be used from the GUI. Use the methods on
/// [`InitContext`][crate::prelude::InitContext] and
/// [`ProcessContext`][crate::prelude::ProcessContext] to run tasks during the `initialize()` and
/// `process()` functions.
//
// NOTE: This is separate from `GuiContext` because adding a type parameter there would clutter up a
// lot of structs, and may even be incompatible with the way certain GUI libraries work.
#[derive(Clone)]
pub struct AsyncExecutor<P: Plugin> {
pub(crate) inner: Arc<dyn Fn(P::BackgroundTask)>,
}
/// A convenience helper for setting parameter values. Any changes made here will be broadcasted to /// A convenience helper for setting parameter values. Any changes made here will be broadcasted to
/// the host and reflected in the plugin's [`Params`][crate::params::Params] object. These /// the host and reflected in the plugin's [`Params`][crate::params::Params] object. These
/// functions should only be called from the main thread. /// functions should only be called from the main thread.
@ -72,6 +94,20 @@ pub struct ParamSetter<'a> {
pub raw_context: &'a dyn GuiContext, pub raw_context: &'a dyn GuiContext,
} }
impl<P: Plugin> AsyncExecutor<P> {
/// Run a task on a background thread. This allows deferring expensive background tasks for
/// later. This task will likely still be executed on the GUI thread.
///
/// # Note
///
/// Scheduling the same task multiple times will cause those duplicate tasks to pile up. Try to
/// either prevent this from happening, or check whether the task still needs to be completed in
/// your task executor.
pub fn execute_async(&self, task: P::BackgroundTask) {
(self.inner)(task);
}
}
impl<'a> ParamSetter<'a> { impl<'a> ParamSetter<'a> {
pub fn new(context: &'a dyn GuiContext) -> Self { pub fn new(context: &'a dyn GuiContext) -> Self {
Self { Self {

View file

@ -17,13 +17,13 @@ pub trait ProcessContext<P: Plugin> {
/// Get the current plugin API. /// Get the current plugin API.
fn plugin_api(&self) -> PluginApi; fn plugin_api(&self) -> PluginApi;
/// Run a task on a background thread. This allows defering expensive background tasks for /// Run a task on a background thread. This allows deferring expensive background tasks for
/// alter. As long as creating the `task` is realtime-safe, this operation is too. /// alter. As long as creating the `task` is realtime-safe, this operation is too.
/// ///
/// # Note /// # Note
/// ///
/// Scheduling the same task multiple times will cause those duplicate tasks to pile up. Try to /// Scheduling the same task multiple times will cause those duplicate tasks to pile up. Try to
/// either prevnt this from happening, or check whether the task still needs to be completed in /// either prevent this from happening, or check whether the task still needs to be completed in
/// your task executor. /// your task executor.
fn execute_async(&self, task: P::BackgroundTask); fn execute_async(&self, task: P::BackgroundTask);

View file

@ -11,7 +11,7 @@ pub use crate::formatters;
pub use crate::util; pub use crate::util;
pub use crate::buffer::Buffer; pub use crate::buffer::Buffer;
pub use crate::context::gui::{GuiContext, ParamSetter}; pub use crate::context::gui::{AsyncExecutor, GuiContext, ParamSetter};
pub use crate::context::init::InitContext; pub use crate::context::init::InitContext;
pub use crate::context::process::ProcessContext; pub use crate::context::process::ProcessContext;
// This also includes the derive macro // This also includes the derive macro