diff options
| author | Glenn Smith <glenn@vector35.com> | 2022-09-26 23:12:20 -0400 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2022-09-29 21:02:20 -0400 |
| commit | 207925956bb8ca0174d40523fda70bfb5bc7bd38 (patch) | |
| tree | 4d5c8cba9ee2ad2b061f1e420c681a793ad397b8 /rust/src/interaction.rs | |
| parent | 5c8aa2ad6c2c03b37cacad4021f81310be12f375 (diff) | |
Interaction::RunProgressDialog
Diffstat (limited to 'rust/src/interaction.rs')
| -rw-r--r-- | rust/src/interaction.rs | 49 |
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(()) + } +} |
