summaryrefslogtreecommitdiff
path: root/rust/src
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2022-09-26 23:12:20 -0400
committerGlenn Smith <glenn@vector35.com>2022-09-29 21:02:20 -0400
commit207925956bb8ca0174d40523fda70bfb5bc7bd38 (patch)
tree4d5c8cba9ee2ad2b061f1e420c681a793ad397b8 /rust/src
parent5c8aa2ad6c2c03b37cacad4021f81310be12f375 (diff)
Interaction::RunProgressDialog
Diffstat (limited to 'rust/src')
-rw-r--r--rust/src/interaction.rs49
1 files changed, 49 insertions, 0 deletions
diff --git a/rust/src/interaction.rs b/rust/src/interaction.rs
index 96af3daa..41289a14 100644
--- a/rust/src/interaction.rs
+++ b/rust/src/interaction.rs
@@ -17,6 +17,7 @@
use binaryninjacore_sys::*;
use std::ffi::CString;
+use std::os::raw::c_void;
use std::path::PathBuf;
use crate::string::BnString;
@@ -121,3 +122,51 @@ pub fn get_directory_name_input(prompt: &str, default_name: &str) -> Option<Path
let string = unsafe { BnString::from_raw(value) };
Some(PathBuf::from(string.as_str()))
}
+
+struct TaskContext<F: Fn(Box<dyn Fn(usize, usize) -> Result<(), ()>>)>(F);
+
+pub fn run_progress_dialog<F: Fn(Box<dyn Fn(usize, usize) -> Result<(), ()>>)>(
+ title: &str,
+ can_cancel: bool,
+ task: F,
+) -> Result<(), ()> {
+ let title = CString::new(title).unwrap();
+
+ let mut ctxt = TaskContext::<F>(task);
+
+ unsafe extern "C" fn cb_task<F: Fn(Box<dyn Fn(usize, usize) -> Result<(), ()>>)>(
+ ctxt: *mut c_void,
+ progress: Option<unsafe extern "C" fn(*mut c_void, usize, usize) -> bool>,
+ progress_ctxt: *mut c_void,
+ ) {
+ ffi_wrap!("run_progress_dialog", unsafe {
+ let context = ctxt as *mut TaskContext<F>;
+ let progress_fn = Box::new(move |cur: usize, max: usize| -> Result<(), ()> {
+ match progress {
+ Some(func) => {
+ if (func)(progress_ctxt, cur, max) {
+ Ok(())
+ } else {
+ Err(())
+ }
+ }
+ None => Ok(()),
+ }
+ });
+ ((*context).0)(progress_fn);
+ })
+ }
+
+ if unsafe {
+ BNRunProgressDialog(
+ title.as_ptr(),
+ can_cancel,
+ Some(cb_task::<F>),
+ &mut ctxt as *mut _ as *mut c_void,
+ )
+ } {
+ Ok(())
+ } else {
+ Err(())
+ }
+}