aboutsummaryrefslogtreecommitdiff
path: root/src/callback.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/callback.rs')
-rw-r--r--src/callback.rs55
1 files changed, 47 insertions, 8 deletions
diff --git a/src/callback.rs b/src/callback.rs
index d249207..6808a45 100644
--- a/src/callback.rs
+++ b/src/callback.rs
@@ -5,6 +5,9 @@ use sys;
use std::mem;
use std::sync::{ Arc, Weak };
+use std::panic::*;
+use std::any::Any;
+use std::process::abort;
pub unsafe trait Callback {
const ID: i32;
@@ -12,6 +15,16 @@ pub unsafe trait Callback {
unsafe fn from_raw(raw: *mut c_void) -> Self;
}
+fn print_err(err: Box<Any>) {
+ if let Some(err) = err.downcast_ref::<&str>() {
+ println!("Steam callback paniced: {}", err);
+ } else if let Some(err) = err.downcast_ref::<String>() {
+ println!("Steam callback paniced: {}", err);
+ } else {
+ println!("Steam callback paniced");
+ }
+}
+
pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>>, f: F, game_server: bool)
where C: Callback,
F: FnMut(C) + Send + Sync + 'static
@@ -25,7 +38,7 @@ pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>
func(param);
}
- unsafe extern "C" fn run_extra<C, F>(cb: *mut c_void, userdata: *mut c_void, param: *mut c_void, _: bool, _: sys::SteamAPICall)
+ unsafe extern "C" fn run_extra<C, F>(cb: *mut c_void, userdata: *mut c_void, param: *mut c_void, _: u8, _: sys::SteamAPICall)
where C: Callback,
F: FnMut(C) + Send + Sync + 'static
{
@@ -72,18 +85,46 @@ pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manag
where F: for<'a> FnMut(&'a C, bool) + Send + Sync + 'static
{
let data: &mut CallData<F, Manager> = &mut *(userdata as *mut CallData<F, Manager>);
- (data.func)(&*(param as *const _), false);
-
+ #[cfg(debug_assertions)]
+ {
+ let res = catch_unwind(AssertUnwindSafe(||
+ (data.func)(&*(param as *const _), false)
+ ));
+ if let Err(err) = res {
+ print_err(err);
+ abort();
+ }
+
+ }
+ #[cfg(not(debug_assertions))]
+ {
+ (data.func)(&*(param as *const _), false);
+ }
+
sys::delete_rust_callback(cb);
}
- unsafe extern "C" fn run_extra<C, F, Manager>(cb: *mut c_void, userdata: *mut c_void, param: *mut c_void, io_error: bool, api_call: sys::SteamAPICall)
+ unsafe extern "C" fn run_extra<C, F, Manager>(cb: *mut c_void, userdata: *mut c_void, param: *mut c_void, io_error: u8, api_call: sys::SteamAPICall)
where F: for<'a> FnMut(&'a C, bool) + Send + Sync + 'static
{
let data: &mut CallData<F, Manager> = &mut *(userdata as *mut CallData<F, Manager>);
if api_call == data.api_call {
- (data.func)(&*(param as *const _), io_error);
+ #[cfg(debug_assertions)]
+ {
+ let res = catch_unwind(AssertUnwindSafe(||
+ (data.func)(&*(param as *const _), io_error != 0)
+ ));
+ if let Err(err) = res {
+ print_err(err);
+ abort();
+ }
+
+ }
+ #[cfg(not(debug_assertions))]
+ {
+ (data.func)(&*(param as *const _), io_error != 0);
+ }
sys::delete_rust_callback(cb);
}
}
@@ -94,8 +135,6 @@ pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manag
let data: Box<CallData<F, Manager>> = Box::from_raw(userdata as _);
if let Some(inner) = data.inner.upgrade() {
- sys::SteamAPI_UnregisterCallResult(cb, data.api_call);
-
let mut cbs = inner.callbacks.lock().unwrap();
cbs.call_results.remove(&data.api_call);
}
@@ -110,7 +149,7 @@ pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manag
};
let data = sys::CallbackData {
- param_size: mem::size_of::<C> as _,
+ param_size: mem::size_of::<C>() as _,
userdata: Box::into_raw(Box::new(userdata)) as _,
run: run::<C, F, Manager>,
run_extra: run_extra::<C, F, Manager>,