aboutsummaryrefslogtreecommitdiff
path: root/src/callback.rs
diff options
context:
space:
mode:
authorMatthew Collins <[email protected]>2018-05-05 15:46:12 +0100
committerMatthew Collins <[email protected]>2018-05-05 15:46:12 +0100
commit5ef3f6e17cd14d452cfcdbb8a30abf61e513e84d (patch)
treee667ed1dccc3d3ac0df83e8c66b76dd5dc0771e8 /src/callback.rs
parentMinor bump due to slight mistake with last publish (diff)
downloadsteamworks-rs-5ef3f6e17cd14d452cfcdbb8a30abf61e513e84d.tar.xz
steamworks-rs-5ef3f6e17cd14d452cfcdbb8a30abf61e513e84d.zip
Rework how the sys crate is generated
Due to packing issues with steam's structs we use wrapper methods to access the fields and create the structs.
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>,