use sim_lib_audio_graph_core::{PrepareConfig, ProcessBlock, Processor};
use crate::{PluginDescriptor, PluginState};
pub trait PluginInstance: Send {
fn descriptor(&self) -> &PluginDescriptor;
fn state(&self) -> PluginState {
PluginState::new()
}
fn set_state(&mut self, _state: PluginState) {}
fn prepare(&mut self, cfg: PrepareConfig);
fn reset(&mut self);
fn process(&mut self, block: &mut ProcessBlock<'_>);
fn latency_frames(&self) -> u32 {
self.descriptor().latency_frames
}
}
#[derive(Clone, Debug)]
pub struct HostedPluginProcessor<I> {
instance: I,
}
impl<I> HostedPluginProcessor<I> {
pub fn new(instance: I) -> Self {
Self { instance }
}
pub fn instance(&self) -> &I {
&self.instance
}
pub fn instance_mut(&mut self) -> &mut I {
&mut self.instance
}
pub fn into_inner(self) -> I {
self.instance
}
}
impl<I: PluginInstance> Processor for HostedPluginProcessor<I> {
fn prepare(&mut self, cfg: PrepareConfig) {
self.instance.prepare(cfg);
}
fn reset(&mut self) {
self.instance.reset();
}
fn process(&mut self, block: &mut ProcessBlock<'_>) {
self.instance.process(block);
}
fn tail_frames(&self) -> u64 {
u64::from(self.instance.latency_frames())
}
}
#[derive(Clone, Debug)]
pub struct ProcessorPlugin<P> {
descriptor: PluginDescriptor,
processor: P,
state: PluginState,
}
impl<P> ProcessorPlugin<P> {
pub fn new(descriptor: PluginDescriptor, processor: P) -> Self {
Self {
descriptor,
processor,
state: PluginState::new(),
}
}
pub fn processor(&self) -> &P {
&self.processor
}
pub fn processor_mut(&mut self) -> &mut P {
&mut self.processor
}
pub fn into_processor(self) -> P {
self.processor
}
}
impl<P: Processor> PluginInstance for ProcessorPlugin<P> {
fn descriptor(&self) -> &PluginDescriptor {
&self.descriptor
}
fn state(&self) -> PluginState {
self.state.clone()
}
fn set_state(&mut self, state: PluginState) {
self.state = state;
}
fn prepare(&mut self, cfg: PrepareConfig) {
self.processor.prepare(cfg);
}
fn reset(&mut self) {
self.processor.reset();
}
fn process(&mut self, block: &mut ProcessBlock<'_>) {
self.processor.process(block);
}
}
#[macro_export]
macro_rules! forward_plugin_instance {
($ty:ident) => {
impl<P: Processor> PluginInstance for $ty<P> {
fn descriptor(&self) -> &PluginDescriptor {
self.inner.descriptor()
}
fn state(&self) -> PluginState {
self.inner.state()
}
fn set_state(&mut self, state: PluginState) {
self.inner.set_state(state);
}
fn prepare(&mut self, cfg: PrepareConfig) {
self.inner.prepare(cfg);
}
fn reset(&mut self) {
self.inner.reset();
}
fn process(&mut self, block: &mut ProcessBlock<'_>) {
self.inner.process(block);
}
}
};
}