Move the process context to its own module
This commit is contained in:
parent
37a8f529b0
commit
df76047419
3 changed files with 52 additions and 30 deletions
|
@ -14,9 +14,8 @@
|
||||||
// You should have received a copy of the GNU General Public License
|
// You should have received a copy of the GNU General Public License
|
||||||
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
use parking_lot::RwLockWriteGuard;
|
|
||||||
use std::cmp;
|
use std::cmp;
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::HashMap;
|
||||||
use std::ffi::c_void;
|
use std::ffi::c_void;
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
use std::mem::{self, MaybeUninit};
|
use std::mem::{self, MaybeUninit};
|
||||||
|
@ -33,6 +32,7 @@ use vst3_sys::vst::{
|
||||||
use vst3_sys::VST3;
|
use vst3_sys::VST3;
|
||||||
use widestring::U16CStr;
|
use widestring::U16CStr;
|
||||||
|
|
||||||
|
mod context;
|
||||||
mod inner;
|
mod inner;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod util;
|
mod util;
|
||||||
|
@ -41,7 +41,6 @@ mod view;
|
||||||
use self::inner::WrapperInner;
|
use self::inner::WrapperInner;
|
||||||
use self::util::{VstPtr, BYPASS_PARAM_HASH};
|
use self::util::{VstPtr, BYPASS_PARAM_HASH};
|
||||||
use self::view::WrapperView;
|
use self::view::WrapperView;
|
||||||
use crate::context::{EventLoop, ProcessContext};
|
|
||||||
use crate::param::internals::ParamPtr;
|
use crate::param::internals::ParamPtr;
|
||||||
use crate::param::range::Range;
|
use crate::param::range::Range;
|
||||||
use crate::param::Param;
|
use crate::param::Param;
|
||||||
|
@ -63,32 +62,6 @@ struct Wrapper<P: Plugin> {
|
||||||
inner: Arc<WrapperInner<P>>,
|
inner: Arc<WrapperInner<P>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A [ProcessContext] implementation for the wrapper. This is a separate object so it can hold on
|
|
||||||
/// to lock guards for event queues. Otherwise reading these events would require constant
|
|
||||||
/// unnecessary atomic operations to lock the uncontested RwLocks.
|
|
||||||
pub(crate) struct WrapperProcessContext<'a, P: Plugin> {
|
|
||||||
inner: &'a WrapperInner<P>,
|
|
||||||
input_events_guard: RwLockWriteGuard<'a, VecDeque<NoteEvent>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P: Plugin> ProcessContext for WrapperProcessContext<'_, P> {
|
|
||||||
fn set_latency_samples(&self, samples: u32) {
|
|
||||||
// Only trigger a restart if it's actually needed
|
|
||||||
let old_latency = self.inner.current_latency.swap(samples, Ordering::SeqCst);
|
|
||||||
if old_latency != samples {
|
|
||||||
let task_posted = unsafe { self.inner.event_loop.read().assume_init_ref() }
|
|
||||||
.do_maybe_async(inner::Task::TriggerRestart(
|
|
||||||
vst3_sys::vst::RestartFlags::kLatencyChanged as i32,
|
|
||||||
));
|
|
||||||
nih_debug_assert!(task_posted, "The task queue is full, dropping task...");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn next_midi_event(&mut self) -> Option<NoteEvent> {
|
|
||||||
self.input_events_guard.pop_front()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<P: Plugin> Wrapper<P> {
|
impl<P: Plugin> Wrapper<P> {
|
||||||
pub fn new() -> Box<Self> {
|
pub fn new() -> Box<Self> {
|
||||||
Self::allocate(WrapperInner::new())
|
Self::allocate(WrapperInner::new())
|
||||||
|
|
49
src/wrapper/vst3/context.rs
Normal file
49
src/wrapper/vst3/context.rs
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
// nih-plug: plugins, but rewritten in Rust
|
||||||
|
// Copyright (C) 2022 Robbert van der Helm
|
||||||
|
//
|
||||||
|
// This program is free software: you can redistribute it and/or modify
|
||||||
|
// it under the terms of the GNU General Public License as published by
|
||||||
|
// the Free Software Foundation, either version 3 of the License, or
|
||||||
|
// (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
use parking_lot::RwLockWriteGuard;
|
||||||
|
use std::collections::VecDeque;
|
||||||
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
|
use super::inner::{Task, WrapperInner};
|
||||||
|
use crate::context::{EventLoop, ProcessContext};
|
||||||
|
use crate::plugin::{NoteEvent, Plugin};
|
||||||
|
|
||||||
|
/// A [ProcessContext] implementation for the wrapper. This is a separate object so it can hold on
|
||||||
|
/// to lock guards for event queues. Otherwise reading these events would require constant
|
||||||
|
/// unnecessary atomic operations to lock the uncontested RwLocks.
|
||||||
|
pub(crate) struct WrapperProcessContext<'a, P: Plugin> {
|
||||||
|
pub inner: &'a WrapperInner<P>,
|
||||||
|
pub input_events_guard: RwLockWriteGuard<'a, VecDeque<NoteEvent>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<P: Plugin> ProcessContext for WrapperProcessContext<'_, P> {
|
||||||
|
fn set_latency_samples(&self, samples: u32) {
|
||||||
|
// Only trigger a restart if it's actually needed
|
||||||
|
let old_latency = self.inner.current_latency.swap(samples, Ordering::SeqCst);
|
||||||
|
if old_latency != samples {
|
||||||
|
let task_posted = unsafe { self.inner.event_loop.read().assume_init_ref() }
|
||||||
|
.do_maybe_async(Task::TriggerRestart(
|
||||||
|
vst3_sys::vst::RestartFlags::kLatencyChanged as i32,
|
||||||
|
));
|
||||||
|
nih_debug_assert!(task_posted, "The task queue is full, dropping task...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn next_midi_event(&mut self) -> Option<NoteEvent> {
|
||||||
|
self.input_events_guard.pop_front()
|
||||||
|
}
|
||||||
|
}
|
|
@ -23,8 +23,8 @@ use std::sync::Arc;
|
||||||
use vst3_sys::base::{kInvalidArgument, kResultOk, tresult};
|
use vst3_sys::base::{kInvalidArgument, kResultOk, tresult};
|
||||||
use vst3_sys::vst::IComponentHandler;
|
use vst3_sys::vst::IComponentHandler;
|
||||||
|
|
||||||
|
use super::context::WrapperProcessContext;
|
||||||
use super::util::{VstPtr, BYPASS_PARAM_HASH, BYPASS_PARAM_ID};
|
use super::util::{VstPtr, BYPASS_PARAM_HASH, BYPASS_PARAM_ID};
|
||||||
use super::WrapperProcessContext;
|
|
||||||
use crate::buffer::Buffer;
|
use crate::buffer::Buffer;
|
||||||
use crate::context::{EventLoop, GuiContext, MainThreadExecutor, OsEventLoop};
|
use crate::context::{EventLoop, GuiContext, MainThreadExecutor, OsEventLoop};
|
||||||
use crate::param::internals::ParamPtr;
|
use crate::param::internals::ParamPtr;
|
||||||
|
|
Loading…
Add table
Reference in a new issue