Skip to content

Commit 11c3b17

Browse files
committed
feat: add panic handling
1 parent ec5c9f4 commit 11c3b17

2 files changed

Lines changed: 53 additions & 20 deletions

File tree

src/lib.rs

Lines changed: 52 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,30 @@ use image::BGRImage;
1010
use interface::{Interface, RecognizeEnemyInput, WrappedPixels};
1111

1212
use std::ffi::{c_char, c_int, c_void};
13+
use std::panic;
14+
15+
/// Helper function to catch panics and log stack trace
16+
fn catch_panic<F, R>(f: F) -> Result<R, ()>
17+
where
18+
F: FnOnce() -> R + panic::UnwindSafe,
19+
{
20+
panic::catch_unwind(f).map_err(|panic_info| {
21+
eprintln!("Panic occurred in image-autowsgrs library:");
22+
23+
// Print panic message
24+
if let Some(s) = panic_info.downcast_ref::<&str>() {
25+
eprintln!("Panic message: {s}");
26+
} else if let Some(s) = panic_info.downcast_ref::<String>() {
27+
eprintln!("Panic message: {s}");
28+
} else {
29+
eprintln!("Panic message: <unknown>");
30+
}
31+
32+
// Print backtrace if available
33+
eprintln!("Stack backtrace:");
34+
eprintln!("{}", std::backtrace::Backtrace::capture());
35+
})
36+
}
1337

1438
/// # Safety
1539
/// The input pointer must be freed by caller
@@ -23,14 +47,17 @@ use std::ffi::{c_char, c_int, c_void};
2347
/// e.g. [[0, 1], [2, 3], [4, 5]]
2448
#[no_mangle]
2549
pub unsafe extern "C" fn locate(input: *const c_void, output: *mut c_int) -> c_int {
26-
let image = BGRImage::from_wrapped_pixels(WrappedPixels::from_raw(input));
27-
let result = locator::locate(&image);
28-
if result.is_empty() || result.len() >= 32 {
29-
return -1;
30-
}
31-
let len = result.len();
32-
output.copy_from_nonoverlapping(result.as_ptr() as *const c_int, len);
33-
len as c_int
50+
catch_panic(|| {
51+
let image = BGRImage::from_wrapped_pixels(WrappedPixels::from_raw(input));
52+
let result = locator::locate(&image);
53+
if result.is_empty() || result.len() >= 32 {
54+
return -1;
55+
}
56+
let len = result.len();
57+
output.copy_from_nonoverlapping(result.as_ptr() as *const c_int, len);
58+
len as c_int
59+
})
60+
.unwrap_or(-1)
3461
}
3562

3663
/// # Safety
@@ -45,20 +72,23 @@ pub unsafe extern "C" fn locate(input: *const c_void, output: *mut c_int) -> c_i
4572
/// e.g. "DD SS NO NO NO NO"
4673
#[no_mangle]
4774
pub unsafe extern "C" fn recognize_enemy(input: *const c_void, output: *mut c_char) -> c_int {
48-
let input = RecognizeEnemyInput::from_raw(input);
49-
let result = recognize_enemy::recognize_enemy(
50-
&input.images,
51-
&recognize_enemy::templates::Template::init_templates(),
52-
);
75+
catch_panic(|| {
76+
let input = RecognizeEnemyInput::from_raw(input);
77+
let result = recognize_enemy::recognize_enemy(
78+
&input.images,
79+
&recognize_enemy::templates::Template::init_templates(),
80+
);
5381

54-
output.copy_from(result.as_ptr() as *const c_char, result.len());
55-
0
82+
output.copy_from(result.as_ptr() as *const c_char, result.len());
83+
0
84+
})
85+
.unwrap_or(-1)
5686
}
5787

5888
/// # Safety
5989
/// The input pointer must be freed by caller
6090
///
61-
/// cant be failed, always return a character
91+
/// return '\0' if failed (panic occurred), otherwise return the recognized character
6292
///
6393
/// # Usage
6494
///
@@ -67,7 +97,10 @@ pub unsafe extern "C" fn recognize_enemy(input: *const c_void, output: *mut c_ch
6797
/// e.g. 'J'
6898
#[no_mangle]
6999
pub unsafe extern "C" fn recognize_map(input: *const c_void) -> c_char {
70-
let image = BGRImage::from_wrapped_pixels(WrappedPixels::from_raw(input));
71-
let result = recognize_map::recognize_map(&image);
72-
result as c_char
100+
catch_panic(|| {
101+
let image = BGRImage::from_wrapped_pixels(WrappedPixels::from_raw(input));
102+
let result = recognize_map::recognize_map(&image);
103+
result as c_char
104+
})
105+
.unwrap_or_default()
73106
}

src/recognize_map.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ pub fn recognize_map(image: &BGRImage) -> char {
172172
}
173173
}
174174
6 | 7 => 'G',
175-
_ => '0',
175+
_ => '\0',
176176
}
177177
} else {
178178
'H'

0 commit comments

Comments
 (0)