Remove Sync bound from TaskExecutor
This commit is contained in:
parent
f6ad85de01
commit
5a974219b8
7 changed files with 16 additions and 13 deletions
|
@ -10,7 +10,10 @@ use crate::params::Params;
|
||||||
use crate::wrapper::clap::features::ClapFeature;
|
use crate::wrapper::clap::features::ClapFeature;
|
||||||
use crate::wrapper::state::PluginState;
|
use crate::wrapper::state::PluginState;
|
||||||
|
|
||||||
pub type TaskExecutor<P> = Box<dyn Fn(<P as Plugin>::BackgroundTask) + Send + Sync>;
|
/// A function that can execute a plugin's [`BackgroundTask`][Plugin::BackgroundTask]s. A plugin can
|
||||||
|
/// dispatch these tasks from the `initialize()` function, the `process()` function, or the GUI, so
|
||||||
|
/// they can be deferred for later to avoid blocking realtime contexts.
|
||||||
|
pub type TaskExecutor<P> = Box<dyn Fn(<P as Plugin>::BackgroundTask) + Send>;
|
||||||
|
|
||||||
/// 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.
|
||||||
|
|
|
@ -115,7 +115,7 @@ impl<P: ClapPlugin> GuiContext for WrapperGuiContext<P> {
|
||||||
|
|
||||||
impl<P: ClapPlugin> InitContext<P> for WrapperInitContext<'_, P> {
|
impl<P: ClapPlugin> InitContext<P> for WrapperInitContext<'_, P> {
|
||||||
fn execute(&self, task: P::BackgroundTask) {
|
fn execute(&self, task: P::BackgroundTask) {
|
||||||
(self.wrapper.task_executor)(task);
|
(self.wrapper.task_executor.lock())(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn plugin_api(&self) -> PluginApi {
|
fn plugin_api(&self) -> PluginApi {
|
||||||
|
|
|
@ -107,7 +107,7 @@ pub struct Wrapper<P: ClapPlugin> {
|
||||||
/// The wrapped plugin instance.
|
/// The wrapped plugin instance.
|
||||||
plugin: Mutex<P>,
|
plugin: Mutex<P>,
|
||||||
/// The plugin's background task executor closure.
|
/// The plugin's background task executor closure.
|
||||||
pub task_executor: TaskExecutor<P>,
|
pub task_executor: Mutex<TaskExecutor<P>>,
|
||||||
/// The plugin's parameters. These are fetched once during initialization. That way the
|
/// The plugin's parameters. These are fetched once during initialization. That way the
|
||||||
/// `ParamPtr`s are guaranteed to live at least as long as this object and we can interact with
|
/// `ParamPtr`s are guaranteed to live at least as long as this object and we can interact with
|
||||||
/// the `Params` object without having to acquire a lock on `plugin`.
|
/// the `Params` object without having to acquire a lock on `plugin`.
|
||||||
|
@ -353,7 +353,7 @@ impl<P: ClapPlugin> MainThreadExecutor<Task<P>> for Wrapper<P> {
|
||||||
unsafe fn execute(&self, task: Task<P>) {
|
unsafe fn execute(&self, task: Task<P>) {
|
||||||
// This function is always called from the main thread, from [Self::on_main_thread].
|
// This function is always called from the main thread, from [Self::on_main_thread].
|
||||||
match task {
|
match task {
|
||||||
Task::PluginTask(task) => (self.task_executor)(task),
|
Task::PluginTask(task) => (self.task_executor.lock())(task),
|
||||||
Task::LatencyChanged => match &*self.host_latency.borrow() {
|
Task::LatencyChanged => match &*self.host_latency.borrow() {
|
||||||
Some(host_latency) => {
|
Some(host_latency) => {
|
||||||
// XXX: The CLAP docs mention that you should request a restart if this happens
|
// XXX: The CLAP docs mention that you should request a restart if this happens
|
||||||
|
@ -387,7 +387,7 @@ impl<P: ClapPlugin> MainThreadExecutor<Task<P>> for Wrapper<P> {
|
||||||
impl<P: ClapPlugin> Wrapper<P> {
|
impl<P: ClapPlugin> Wrapper<P> {
|
||||||
pub fn new(host_callback: *const clap_host) -> Arc<Self> {
|
pub fn new(host_callback: *const clap_host) -> Arc<Self> {
|
||||||
let plugin = P::default();
|
let plugin = P::default();
|
||||||
let task_executor = plugin.task_executor();
|
let task_executor = Mutex::new(plugin.task_executor());
|
||||||
let editor = plugin.editor().map(Mutex::new);
|
let editor = plugin.editor().map(Mutex::new);
|
||||||
|
|
||||||
// This is used to allow the plugin to restore preset data from its editor, see the comment
|
// This is used to allow the plugin to restore preset data from its editor, see the comment
|
||||||
|
|
|
@ -80,7 +80,7 @@ impl<P: Plugin, B: Backend> GuiContext for WrapperGuiContext<P, B> {
|
||||||
|
|
||||||
impl<P: Plugin, B: Backend> InitContext<P> for WrapperInitContext<'_, P, B> {
|
impl<P: Plugin, B: Backend> InitContext<P> for WrapperInitContext<'_, P, B> {
|
||||||
fn execute(&self, task: P::BackgroundTask) {
|
fn execute(&self, task: P::BackgroundTask) {
|
||||||
(self.wrapper.task_executor_wrapper.task_executor)(task);
|
(self.wrapper.task_executor_wrapper.task_executor.lock())(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn plugin_api(&self) -> PluginApi {
|
fn plugin_api(&self) -> PluginApi {
|
||||||
|
|
|
@ -141,12 +141,12 @@ impl WindowHandler for WrapperWindowHandler {
|
||||||
|
|
||||||
/// Adapter to make `TaskExecutor<P>` work as a `MainThreadExecutor`.
|
/// Adapter to make `TaskExecutor<P>` work as a `MainThreadExecutor`.
|
||||||
pub struct TaskExecutorWrapper<P: Plugin> {
|
pub struct TaskExecutorWrapper<P: Plugin> {
|
||||||
pub task_executor: TaskExecutor<P>,
|
pub task_executor: Mutex<TaskExecutor<P>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P: Plugin> MainThreadExecutor<P::BackgroundTask> for TaskExecutorWrapper<P> {
|
impl<P: Plugin> MainThreadExecutor<P::BackgroundTask> for TaskExecutorWrapper<P> {
|
||||||
unsafe fn execute(&self, task: P::BackgroundTask) {
|
unsafe fn execute(&self, task: P::BackgroundTask) {
|
||||||
(self.task_executor)(task)
|
(self.task_executor.lock())(task)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +156,7 @@ impl<P: Plugin, B: Backend> Wrapper<P, B> {
|
||||||
pub fn new(backend: B, config: WrapperConfig) -> Result<Arc<Self>, WrapperError> {
|
pub fn new(backend: B, config: WrapperConfig) -> Result<Arc<Self>, WrapperError> {
|
||||||
let plugin = P::default();
|
let plugin = P::default();
|
||||||
let task_executor_wrapper = Arc::new(TaskExecutorWrapper {
|
let task_executor_wrapper = Arc::new(TaskExecutorWrapper {
|
||||||
task_executor: plugin.task_executor(),
|
task_executor: Mutex::new(plugin.task_executor()),
|
||||||
});
|
});
|
||||||
let params = plugin.params();
|
let params = plugin.params();
|
||||||
let editor = plugin.editor().map(|editor| Arc::new(Mutex::new(editor)));
|
let editor = plugin.editor().map(|editor| Arc::new(Mutex::new(editor)));
|
||||||
|
|
|
@ -117,7 +117,7 @@ impl<P: Vst3Plugin> GuiContext for WrapperGuiContext<P> {
|
||||||
|
|
||||||
impl<P: Vst3Plugin> InitContext<P> for WrapperInitContext<'_, P> {
|
impl<P: Vst3Plugin> InitContext<P> for WrapperInitContext<'_, P> {
|
||||||
fn execute(&self, task: P::BackgroundTask) {
|
fn execute(&self, task: P::BackgroundTask) {
|
||||||
(self.inner.task_executor)(task);
|
(self.inner.task_executor.lock())(task);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn plugin_api(&self) -> PluginApi {
|
fn plugin_api(&self) -> PluginApi {
|
||||||
|
|
|
@ -34,7 +34,7 @@ pub(crate) struct WrapperInner<P: Vst3Plugin> {
|
||||||
/// The wrapped plugin instance.
|
/// The wrapped plugin instance.
|
||||||
pub plugin: Mutex<P>,
|
pub plugin: Mutex<P>,
|
||||||
/// The plugin's background task executor closure.
|
/// The plugin's background task executor closure.
|
||||||
pub task_executor: TaskExecutor<P>,
|
pub task_executor: Mutex<TaskExecutor<P>>,
|
||||||
/// The plugin's parameters. These are fetched once during initialization. That way the
|
/// The plugin's parameters. These are fetched once during initialization. That way the
|
||||||
/// `ParamPtr`s are guaranteed to live at least as long as this object and we can interact with
|
/// `ParamPtr`s are guaranteed to live at least as long as this object and we can interact with
|
||||||
/// the `Params` object without having to acquire a lock on `plugin`.
|
/// the `Params` object without having to acquire a lock on `plugin`.
|
||||||
|
@ -197,7 +197,7 @@ impl<P: Vst3Plugin> WrapperInner<P> {
|
||||||
#[allow(unused_unsafe)]
|
#[allow(unused_unsafe)]
|
||||||
pub fn new() -> Arc<Self> {
|
pub fn new() -> Arc<Self> {
|
||||||
let plugin = P::default();
|
let plugin = P::default();
|
||||||
let task_executor = plugin.task_executor();
|
let task_executor = Mutex::new(plugin.task_executor());
|
||||||
let editor = plugin.editor().map(|editor| Arc::new(Mutex::new(editor)));
|
let editor = plugin.editor().map(|editor| Arc::new(Mutex::new(editor)));
|
||||||
|
|
||||||
// This is used to allow the plugin to restore preset data from its editor, see the comment
|
// This is used to allow the plugin to restore preset data from its editor, see the comment
|
||||||
|
@ -527,7 +527,7 @@ impl<P: Vst3Plugin> MainThreadExecutor<Task<P>> for WrapperInner<P> {
|
||||||
// function for checking if a to be scheduled task can be handled right there and
|
// function for checking if a to be scheduled task can be handled right there and
|
||||||
// then).
|
// then).
|
||||||
match task {
|
match task {
|
||||||
Task::PluginTask(task) => (self.task_executor)(task),
|
Task::PluginTask(task) => (self.task_executor.lock())(task),
|
||||||
Task::TriggerRestart(flags) => match &*self.component_handler.borrow() {
|
Task::TriggerRestart(flags) => match &*self.component_handler.borrow() {
|
||||||
Some(handler) => {
|
Some(handler) => {
|
||||||
handler.restart_component(flags);
|
handler.restart_component(flags);
|
||||||
|
|
Loading…
Add table
Reference in a new issue