1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
use super::raw::{reaper_plugin_info_t, HINSTANCE}; use super::ReaperPluginContext; use std::error::Error; use std::panic::{catch_unwind, UnwindSafe}; /// This function catches panics before they reach REAPER. /// /// This function is supposed to be wrapped around all Rust code that is called directly by REAPER, /// e.g. control surface callbacks or command hooks. Its purpose it to establish a fault barrier in /// order to prevent REAPER from crashing if a non-recoverable error occurs in the plug-in (a /// panic). /// /// Right now this doesn't do anything else than calling `catch_unwind()` but it might do more in /// future. Please note that logging is *not* supposed to be done here. It should be done in the /// panic hook instead. pub fn firewall<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Option<R> { catch_unwind(f).ok() } /// This is a convenience function for bootstrapping extension plug-ins. /// /// This function basically translates the REAPER extension plug-in main entry point signature /// (`ReaperPluginEntry()`) to a typical Rust main entry point signature (`main()`). It is /// intended to be used by macros in the `reaper-macros` crate. pub fn bootstrap_extension_plugin( _h_instance: HINSTANCE, rec: *mut reaper_plugin_info_t, init: fn(&ReaperPluginContext) -> Result<(), Box<dyn Error>>, ) -> i32 { // TODO-low Log early errors firewall(|| { let context = match ReaperPluginContext::from_extension_plugin(rec) { Err(_) => return 0, Ok(c) => c, }; match init(&context) { Ok(_) => 1, Err(_) => 0, } }) .unwrap_or(0) }