reaper_low/
reaper_plugin_context.rs1use super::raw::{reaper_plugin_info_t, REAPER_PLUGIN_VERSION};
2use std::os::raw::{c_int, c_void};
3use std::ptr::null_mut;
4use vst::api::HostCallbackProc;
5use vst::plugin::HostCallback;
6
7type FunctionProvider = Box<dyn Fn(&std::ffi::CStr) -> isize>;
8
9pub struct ReaperPluginContext {
15 pub(crate) function_provider: FunctionProvider,
17}
18
19impl ReaperPluginContext {
20 pub fn from_extension_plugin(
31 rec: *mut reaper_plugin_info_t,
32 ) -> Result<ReaperPluginContext, &'static str> {
33 let function_provider = create_extension_plugin_function_provider(rec)?;
34 Ok(ReaperPluginContext { function_provider })
35 }
36
37 pub fn from_vst_plugin(host: HostCallback) -> Result<ReaperPluginContext, &'static str> {
44 let host_callback = host.raw_callback().ok_or("Host callback not available")?;
45 let function_provider = create_vst_plugin_function_provider(host_callback);
46 Ok(ReaperPluginContext { function_provider })
47 }
48}
49
50fn create_extension_plugin_function_provider(
51 rec: *mut reaper_plugin_info_t,
52) -> Result<FunctionProvider, &'static str> {
53 if rec.is_null() {
54 return Err("rec not available");
55 }
56 let rec = unsafe { *rec };
57 if rec.caller_version != REAPER_PLUGIN_VERSION as c_int {
58 return Err("Caller version doesn't match");
59 }
60 let get_func = rec.GetFunc.ok_or("GetFunc function pointer not set")?;
61 Ok(Box::new(move |name| unsafe {
62 get_func(name.as_ptr()) as isize
63 }))
64}
65
66fn create_vst_plugin_function_provider(host_callback: HostCallbackProc) -> FunctionProvider {
67 Box::new(move |name| {
68 #[allow(overflowing_literals)]
69 host_callback(
70 null_mut(),
71 0xdeadbeef,
72 0xdeadf00d,
73 0,
74 name.as_ptr() as *mut c_void,
75 0.0,
76 )
77 })
78}