2022-04-23 06:59:58 +10:00
|
|
|
use crossbeam::channel;
|
2022-04-23 03:22:23 +10:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
2022-04-23 04:41:21 +10:00
|
|
|
use super::backend::Backend;
|
2022-04-23 06:59:58 +10:00
|
|
|
use super::wrapper::{GuiTask, Wrapper};
|
2022-04-23 03:22:23 +10:00
|
|
|
use crate::context::{GuiContext, PluginApi, ProcessContext, Transport};
|
2022-04-23 02:29:00 +10:00
|
|
|
use crate::midi::NoteEvent;
|
2022-04-23 03:22:23 +10:00
|
|
|
use crate::param::internals::ParamPtr;
|
2022-04-23 02:29:00 +10:00
|
|
|
use crate::plugin::Plugin;
|
|
|
|
|
2022-04-23 03:22:23 +10:00
|
|
|
/// A [`GuiContext`] implementation for the wrapper. This is passed to the plugin in
|
|
|
|
/// [`Editor::spawn()`][crate::prelude::Editor::spawn()] so it can interact with the rest of the plugin and
|
|
|
|
/// with the host for things like setting parameters.
|
2022-04-23 04:41:21 +10:00
|
|
|
pub(crate) struct WrapperGuiContext<P: Plugin, B: Backend> {
|
|
|
|
pub(super) wrapper: Arc<Wrapper<P, B>>,
|
2022-04-23 03:36:19 +10:00
|
|
|
|
2022-04-23 06:59:58 +10:00
|
|
|
/// This allows us to send tasks to the parent view that will be handled at the start of its
|
|
|
|
/// next frame.
|
|
|
|
pub(super) gui_task_sender: channel::Sender<GuiTask>,
|
2022-04-23 03:22:23 +10:00
|
|
|
}
|
|
|
|
|
2022-04-23 02:29:00 +10:00
|
|
|
/// A [`ProcessContext`] implementation for the standalone 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.
|
2022-04-23 04:41:21 +10:00
|
|
|
pub(crate) struct WrapperProcessContext<'a, P: Plugin, B: Backend> {
|
|
|
|
pub(super) wrapper: &'a Wrapper<P, B>,
|
2022-04-23 02:29:00 +10:00
|
|
|
// TODO: Events
|
|
|
|
// pub(super) input_events_guard: AtomicRefMut<'a, VecDeque<NoteEvent>>,
|
|
|
|
// pub(super) output_events_guard: AtomicRefMut<'a, VecDeque<NoteEvent>>,
|
|
|
|
pub(super) transport: Transport,
|
|
|
|
}
|
|
|
|
|
2022-04-23 04:41:21 +10:00
|
|
|
impl<P: Plugin, B: Backend> GuiContext for WrapperGuiContext<P, B> {
|
2022-04-23 03:22:23 +10:00
|
|
|
fn plugin_api(&self) -> PluginApi {
|
|
|
|
PluginApi::Standalone
|
|
|
|
}
|
|
|
|
|
|
|
|
fn request_resize(&self) -> bool {
|
2022-04-23 06:59:58 +10:00
|
|
|
let (unscaled_width, unscaled_height) = self.wrapper.editor.as_ref().unwrap().size();
|
2022-04-23 03:36:19 +10:00
|
|
|
|
2022-04-23 06:59:58 +10:00
|
|
|
// This will cause the editor to be resized at the start of the next frame
|
|
|
|
let dpi_scale = self.wrapper.dpi_scale();
|
|
|
|
let push_successful = self
|
|
|
|
.gui_task_sender
|
|
|
|
.send(GuiTask::Resize(
|
|
|
|
(unscaled_width as f32 * dpi_scale).round() as u32,
|
|
|
|
(unscaled_height as f32 * dpi_scale).round() as u32,
|
|
|
|
))
|
|
|
|
.is_ok();
|
|
|
|
nih_debug_assert!(push_successful, "Could not queue window resize");
|
2022-04-23 03:22:23 +10:00
|
|
|
|
|
|
|
true
|
|
|
|
}
|
|
|
|
|
2022-04-23 06:28:12 +10:00
|
|
|
unsafe fn raw_begin_set_parameter(&self, _param: ParamPtr) {
|
|
|
|
// Since there's no autmoation being recorded here, gestures don't mean anything
|
2022-04-23 03:22:23 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
unsafe fn raw_set_parameter_normalized(&self, param: ParamPtr, normalized: f32) {
|
2022-04-23 06:28:12 +10:00
|
|
|
self.wrapper.set_parameter(param, normalized);
|
2022-04-23 03:22:23 +10:00
|
|
|
}
|
|
|
|
|
2022-04-23 06:28:12 +10:00
|
|
|
unsafe fn raw_end_set_parameter(&self, _param: ParamPtr) {}
|
2022-04-23 03:22:23 +10:00
|
|
|
|
|
|
|
fn get_state(&self) -> crate::wrapper::state::PluginState {
|
|
|
|
todo!("WrapperGuiContext::get_state()");
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_state(&self, state: crate::wrapper::state::PluginState) {
|
|
|
|
nih_debug_assert_failure!("TODO: WrapperGuiContext::set_state()");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-23 04:41:21 +10:00
|
|
|
impl<P: Plugin, B: Backend> ProcessContext for WrapperProcessContext<'_, P, B> {
|
2022-04-23 02:29:00 +10:00
|
|
|
fn plugin_api(&self) -> PluginApi {
|
|
|
|
PluginApi::Standalone
|
|
|
|
}
|
|
|
|
|
|
|
|
fn transport(&self) -> &Transport {
|
|
|
|
&self.transport
|
|
|
|
}
|
|
|
|
|
|
|
|
fn next_event(&mut self) -> Option<NoteEvent> {
|
|
|
|
nih_debug_assert_failure!("TODO: WrapperProcessContext::next_event()");
|
|
|
|
|
|
|
|
// self.input_events_guard.pop_front()
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
|
|
|
fn send_event(&mut self, event: NoteEvent) {
|
|
|
|
nih_debug_assert_failure!("TODO: WrapperProcessContext::send_event()");
|
|
|
|
|
|
|
|
// self.output_events_guard.push_back(event);
|
|
|
|
}
|
|
|
|
|
|
|
|
fn set_latency_samples(&self, samples: u32) {
|
|
|
|
nih_debug_assert_failure!("TODO: WrapperProcessContext::set_latency_samples()");
|
|
|
|
}
|
|
|
|
}
|