-
-
Notifications
You must be signed in to change notification settings - Fork 20
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Helgobox extension and Helgobox runtime API mechanism draft
- Loading branch information
Showing
11 changed files
with
206 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,6 @@ | ||
pub mod persistence; | ||
|
||
pub mod runtime; | ||
|
||
mod root; | ||
pub use root::*; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
use reaper_low::raw::ReaProject; | ||
use reaper_low::PluginContext; | ||
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) => { | ||
pub struct HelgoboxApiPointers { | ||
$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, | ||
)), | ||
} | ||
} | ||
} | ||
} | ||
|
||
pub struct HelgoboxApiSession { | ||
pointers: HelgoboxApiPointers, | ||
} | ||
|
||
impl HelgoboxApiSession { | ||
pub fn new(pointers: HelgoboxApiPointers) -> Self { | ||
Self { | ||
pointers | ||
} | ||
} | ||
|
||
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; | ||
} | ||
|
||
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, | ||
); | ||
} | ||
} | ||
}; | ||
} | ||
|
||
api![ | ||
HB_FindFirstInstanceInProject(project: *const ReaProject) -> c_long | ||
]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
[package] | ||
name = "helgobox-extension" | ||
version = "0.1.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
reaper-medium = { git = "https://github.com/helgoboss/reaper-rs.git", branch = "master" } | ||
reaper-low = { git = "https://github.com/helgoboss/reaper-rs.git", branch = "master" } | ||
reaper-macros = { git = "https://github.com/helgoboss/reaper-rs.git", branch = "master" } | ||
anyhow.workspace = true | ||
base.workspace = true | ||
realearn-api.workspace = true | ||
fragile.workspace = true | ||
|
||
[lib] | ||
name = "reaper_helgobox" | ||
crate-type = ["cdylib"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
use anyhow::Result; | ||
use fragile::Fragile; | ||
use realearn_api::runtime::{HelgoboxApiPointers, HelgoboxApiSession}; | ||
use reaper_low::PluginContext; | ||
use reaper_macros::reaper_extension_plugin; | ||
use reaper_medium::{reaper_str, CommandId, HookCommand, OwnedGaccelRegister, ReaperSession}; | ||
use std::error::Error; | ||
use std::ptr::null; | ||
use std::sync::OnceLock; | ||
|
||
static EXTENSION: OnceLock<HelgoboxExtension> = OnceLock::new(); | ||
|
||
fn extension() -> &'static HelgoboxExtension { | ||
EXTENSION | ||
.get() | ||
.expect("Helgobox extension not yet initialized") | ||
} | ||
|
||
#[reaper_extension_plugin] | ||
fn plugin_main(context: PluginContext) -> std::result::Result<(), Box<dyn Error>> { | ||
let _ = EXTENSION.set(HelgoboxExtension::load(context)?); | ||
Ok(()) | ||
} | ||
|
||
struct HelgoboxExtension { | ||
my_command_id: CommandId, | ||
reaper_session: Fragile<ReaperSession>, | ||
} | ||
|
||
impl HelgoboxExtension { | ||
pub fn load(context: PluginContext) -> Result<Self> { | ||
let mut session = ReaperSession::load(context); | ||
let my_command_id = | ||
session.plugin_register_add_command_id(reaper_str!("HB_SHOW_HIDE_PLAYTIME"))?; | ||
session.plugin_register_add_hook_command::<MyHookCommand>()?; | ||
session.plugin_register_add_gaccel(OwnedGaccelRegister::without_key_binding( | ||
my_command_id, | ||
"Show/hide Playtime", | ||
))?; | ||
let extension = Self { | ||
my_command_id, | ||
reaper_session: Fragile::new(session), | ||
}; | ||
Ok(extension) | ||
} | ||
} | ||
|
||
struct MyHookCommand; | ||
|
||
impl HookCommand for MyHookCommand { | ||
fn call(command_id: CommandId, _flag: i32) -> bool { | ||
if command_id != extension().my_command_id { | ||
return false; | ||
} | ||
let plugin_context = extension() | ||
.reaper_session | ||
.get() | ||
.reaper() | ||
.low() | ||
.plugin_context(); | ||
let pointers = HelgoboxApiPointers::load(&plugin_context); | ||
let session = HelgoboxApiSession::new(pointers); | ||
let res = session.HB_FindFirstInstanceInProject(null()); | ||
println!("Executing my command: {res}!"); | ||
true | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
use realearn_api::runtime::{register_helgobox_api, HelgoboxApi}; | ||
use reaper_high::Reaper; | ||
use reaper_low::raw::ReaProject; | ||
use reaper_medium::{ReaperStr, RegistrationObject}; | ||
use std::borrow::Cow; | ||
use std::ffi::c_long; | ||
|
||
struct HelgoboxApiImpl; | ||
|
||
impl HelgoboxApi for HelgoboxApiImpl { | ||
extern "C" fn HB_FindFirstInstanceInProject(project: *const ReaProject) -> c_long { | ||
42 | ||
} | ||
} | ||
|
||
pub fn register_api() { | ||
let mut session = Reaper::get().medium_session(); | ||
register_helgobox_api::<HelgoboxApiImpl>(|name, ptr| unsafe { | ||
session.plugin_register_add(RegistrationObject::Api( | ||
Cow::Borrowed(ReaperStr::from_ptr(name.as_ptr())), | ||
ptr, | ||
)); | ||
}); | ||
} | ||
|
||
// Finds the first Helgobox instance in the given project. | ||
// | ||
// If the given project is `null`, it will look in the current project. | ||
// | ||
// Returns the instance ID or -1 if none exists. | ||
|
||
// Shows or hides the app for the given Helgobox instance and makes sure that the app displays | ||
// Playtime. | ||
// | ||
// If necessary, this will also start the app and create a clip matrix for the given instance. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -33,6 +33,7 @@ use base::{ | |
use enum_iterator::IntoEnumIterator; | ||
|
||
use crate::base::allocator::{RealearnAllocatorIntegration, RealearnDeallocator, GLOBAL_ALLOCATOR}; | ||
use crate::infrastructure::plugin::api_impl::register_api; | ||
use crate::infrastructure::plugin::debug_util::resolve_symbols_from_clipboard; | ||
use crate::infrastructure::plugin::tracing_util::TracingHook; | ||
use crate::infrastructure::server::services::RealearnServices; | ||
|
@@ -186,6 +187,7 @@ impl App { | |
support_email_address: "[email protected]".to_string(), | ||
}, | ||
); | ||
register_api(); | ||
let config = AppConfig::load().unwrap_or_else(|e| { | ||
debug!(App::logger(), "{}", e); | ||
Default::default() | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
mod api_impl; | ||
mod debug_util; | ||
mod realearn_editor; | ||
mod tracing_util; | ||
|