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.
use std::sync::Arc;
use super::PluginApi;
use crate::params::internals::ParamPtr;
use crate::params::Param;
use crate::plugin::Plugin;
use crate::wrapper::state::PluginState;
/// 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);
}
/// 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
/// the host and reflected in the plugin's [`Params`][crate::params::Params] object. These
/// functions should only be called from the main thread.
@ -72,6 +94,20 @@ pub struct ParamSetter<'a> {
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> {
pub fn new(context: &'a dyn GuiContext) -> Self {
Self {

View file

@ -17,13 +17,13 @@ pub trait ProcessContext<P: Plugin> {
/// Get the current plugin API.
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.
///
/// # Note
///
/// 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.
fn execute_async(&self, task: P::BackgroundTask);

View file

@ -11,7 +11,7 @@ pub use crate::formatters;
pub use crate::util;
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::process::ProcessContext;
// This also includes the derive macro