1
0
Fork 0

Move the process context to its own module

This commit is contained in:
Robbert van der Helm 2022-02-06 18:51:46 +01:00
parent 37a8f529b0
commit df76047419
3 changed files with 52 additions and 30 deletions

View file

@ -14,9 +14,8 @@
// 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::cmp;
use std::collections::{HashMap, VecDeque};
use std::collections::HashMap;
use std::ffi::c_void;
use std::marker::PhantomData;
use std::mem::{self, MaybeUninit};
@ -33,6 +32,7 @@ use vst3_sys::vst::{
use vst3_sys::VST3;
use widestring::U16CStr;
mod context;
mod inner;
#[macro_use]
mod util;
@ -41,7 +41,6 @@ mod view;
use self::inner::WrapperInner;
use self::util::{VstPtr, BYPASS_PARAM_HASH};
use self::view::WrapperView;
use crate::context::{EventLoop, ProcessContext};
use crate::param::internals::ParamPtr;
use crate::param::range::Range;
use crate::param::Param;
@ -63,32 +62,6 @@ struct Wrapper<P: Plugin> {
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> {
pub fn new() -> Box<Self> {
Self::allocate(WrapperInner::new())

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

View file

@ -23,8 +23,8 @@ use std::sync::Arc;
use vst3_sys::base::{kInvalidArgument, kResultOk, tresult};
use vst3_sys::vst::IComponentHandler;
use super::context::WrapperProcessContext;
use super::util::{VstPtr, BYPASS_PARAM_HASH, BYPASS_PARAM_ID};
use super::WrapperProcessContext;
use crate::buffer::Buffer;
use crate::context::{EventLoop, GuiContext, MainThreadExecutor, OsEventLoop};
use crate::param::internals::ParamPtr;