1use crate::plugin::Plugin;
2
3pub trait Latency<P>
4where
5 P: Plugin,
6{
7 fn get(plugin: &P) -> u32;
9}
10
11impl<P: Plugin> Latency<P> for () {
12 fn get(_: &P) -> u32 {
13 0
14 }
15}
16
17pub(crate) use ffi::PluginLatency;
18
19use crate::{ffi::clap_host_latency, host::Host};
20
21mod ffi {
22 use std::marker::PhantomData;
23
24 use crate::{
25 ext::latency::Latency,
26 ffi::{clap_plugin, clap_plugin_latency},
27 plugin::{ClapPlugin, Plugin},
28 };
29
30 extern "C-unwind" fn get<E, P>(plugin: *const clap_plugin) -> u32
31 where
32 E: Latency<P>,
33 P: Plugin,
34 {
35 if plugin.is_null() {
36 return 0;
37 }
38 let mut clap_plugin = unsafe { ClapPlugin::<P>::new_unchecked(plugin) };
41
42 let plugin = unsafe { clap_plugin.plugin() };
47
48 E::get(plugin)
49 }
50
51 pub struct PluginLatency<P> {
52 #[allow(unused)]
53 clap_plugin_latency: clap_plugin_latency,
54 _marker: PhantomData<P>,
55 }
56
57 impl<P: Plugin> PluginLatency<P> {
58 pub fn new<E: Latency<P>>(_: E) -> Self {
59 Self {
60 clap_plugin_latency: clap_plugin_latency {
61 get: Some(get::<E, P>),
62 },
63 _marker: PhantomData,
64 }
65 }
66 }
67}
68
69#[derive(Debug)]
70pub struct HostLatency<'a> {
71 host: &'a Host,
72 clap_host_latency: &'a clap_host_latency,
73}
74
75impl<'a> HostLatency<'a> {
76 pub(crate) const unsafe fn new_unchecked(
81 host: &'a Host,
82 clap_host_latency: &'a clap_host_latency,
83 ) -> Self {
84 Self {
85 host,
86 clap_host_latency,
87 }
88 }
89
90 pub fn changed(&self) {
91 unsafe {
94 self.clap_host_latency.changed.unwrap()(self.host.clap_host());
95 }
96 }
97}