Skip to content

Commit

Permalink
Helgobox runtime API mechanism: Support multiple API functions
Browse files Browse the repository at this point in the history
  • Loading branch information
helgoboss committed Nov 29, 2023
1 parent 97ce7e4 commit 9277da7
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 16 deletions.
39 changes: 25 additions & 14 deletions api/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,22 @@ use std::ffi::{c_char, c_long, c_void, CStr};
use std::mem::transmute;

macro_rules! api {
($func_name:ident ($( $param_name:ident: $param_type:ty ),*) -> $ret_type:ty) => {
($( $func_name:ident ($( $param_name:ident: $param_type:ty ),*) -> $ret_type:ty, )+) => {
pub struct HelgoboxApiPointers {
$func_name: Option<fn($( $param_name: $param_type ),*) -> $ret_type>,
$(
$func_name: Option<fn($( $param_name: $param_type ),*) -> $ret_type>
),+
}

impl HelgoboxApiPointers {
pub fn load(plugin_context: &PluginContext) -> Self {
unsafe {
Self {
$func_name: transmute(plugin_context.GetFunc(
concat!(stringify!($func_name), "\0").as_ptr() as *const c_char,
)),
$(
$func_name: transmute(plugin_context.GetFunc(
concat!(stringify!($func_name), "\0").as_ptr() as *const c_char,
))
),+
}
}
}
Expand All @@ -32,26 +36,33 @@ macro_rules! api {
}
}

pub fn $func_name(&self, $( $param_name: $param_type ),*) -> $ret_type {
self.pointers.$func_name.unwrap()($( $param_name ),*)
}
$(
pub fn $func_name(&self, $( $param_name: $param_type ),*) -> $ret_type {
self.pointers.$func_name.unwrap()($( $param_name ),*)
}
)+
}

pub trait HelgoboxApi {
extern "C" fn $func_name($( $param_name: $param_type ),*) -> $ret_type;
$(
extern "C" fn $func_name($( $param_name: $param_type ),*) -> $ret_type;
)+
}

pub fn register_helgobox_api<T: HelgoboxApi>(mut register_api_fn: impl FnMut(&CStr, *mut c_void)) {
unsafe {
register_api_fn(
CStr::from_ptr(concat!(stringify!($func_name), "\0").as_ptr() as *const c_char),
T::$func_name as *mut c_void,
);
$(
register_api_fn(
CStr::from_ptr(concat!(stringify!($func_name), "\0").as_ptr() as *const c_char),
T::$func_name as *mut c_void,
);
)+
}
}
};
}

api![
HB_FindFirstInstanceInProject(project: *const ReaProject) -> c_long
HB_FindFirstInstanceInProject(project: *const ReaProject) -> c_long,
HB_ShowOrHidePlaytime(instance_id: c_long) -> (),
];
4 changes: 2 additions & 2 deletions extension/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ impl HookCommand for MyHookCommand {
.plugin_context();
let pointers = HelgoboxApiPointers::load(&plugin_context);
let session = HelgoboxApiSession::new(pointers);
let res = session.HB_FindFirstInstanceInProject(null());
println!("Executing my command: {res}!");
session.HB_ShowOrHidePlaytime(45);
// println!("Executing my command: {res}!");
true
}
}
4 changes: 4 additions & 0 deletions main/src/infrastructure/plugin/api_impl.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ impl HelgoboxApi for HelgoboxApiImpl {
extern "C" fn HB_FindFirstInstanceInProject(project: *const ReaProject) -> c_long {
42
}

extern "C" fn HB_ShowOrHidePlaytime(instance_id: c_long) -> () {
Reaper::get().show_console_msg("Show or hide playtime");
}
}

pub fn register_api() {
Expand Down

0 comments on commit 9277da7

Please sign in to comment.