aboutsummaryrefslogtreecommitdiff
path: root/src/callback.rs
diff options
context:
space:
mode:
authorMatthew Collins <[email protected]>2018-05-07 01:02:44 +0100
committerMatthew Collins <[email protected]>2018-05-07 01:02:44 +0100
commit63f96e3eb579cd53b4a7bee84ef173add5f888e8 (patch)
tree8badd7acdc85a70f141f3750bbf047c586cffd44 /src/callback.rs
parentFix building with older steam sdks (diff)
downloadsteamworks-rs-63f96e3eb579cd53b4a7bee84ef173add5f888e8.tar.xz
steamworks-rs-63f96e3eb579cd53b4a7bee84ef173add5f888e8.zip
Steam networking support + other improvements
Diffstat (limited to 'src/callback.rs')
-rw-r--r--src/callback.rs33
1 files changed, 32 insertions, 1 deletions
diff --git a/src/callback.rs b/src/callback.rs
index 18c1db0..d8e186d 100644
--- a/src/callback.rs
+++ b/src/callback.rs
@@ -5,8 +5,11 @@ use sys;
use std::mem;
use std::sync::{ Arc, Weak };
+#[cfg(debug_assertions)]
use std::panic::*;
+#[cfg(debug_assertions)]
use std::any::Any;
+#[cfg(debug_assertions)]
use std::process::abort;
pub unsafe trait Callback {
@@ -15,6 +18,29 @@ pub unsafe trait Callback {
unsafe fn from_raw(raw: *mut c_void) -> Self;
}
+/// A handled that can be used to remove a callback
+/// at a later point.
+///
+/// Removes the callback when dropped
+pub struct CallbackHandle<Manager = ClientManager> {
+ handle: *mut c_void,
+ inner: Weak<Inner<Manager>>,
+}
+unsafe impl <Manager> Send for CallbackHandle<Manager> {}
+
+impl <Manager> Drop for CallbackHandle<Manager> {
+ fn drop(&mut self) {
+ if let Some(inner) = self.inner.upgrade() {
+ let mut cb = inner.callbacks.lock().unwrap();
+ if let Some(pos) = cb.callbacks.iter().position(|v| *v == self.handle) {
+ cb.callbacks.swap_remove(pos);
+ unsafe { sys::delete_rust_callback(self.handle); }
+ }
+ }
+ }
+}
+
+#[cfg(debug_assertions)]
fn print_err(err: Box<Any>) {
if let Some(err) = err.downcast_ref::<&str>() {
println!("Steam callback paniced: {}", err);
@@ -25,7 +51,7 @@ fn print_err(err: Box<Any>) {
}
}
-pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>>, f: F, game_server: bool)
+pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>>, f: F, game_server: bool) -> CallbackHandle<Manager>
where C: Callback,
F: FnMut(C) + Send + 'static
{
@@ -70,6 +96,11 @@ pub(crate) unsafe fn register_callback<C, F, Manager>(inner: &Arc<Inner<Manager>
let mut cbs = inner.callbacks.lock().unwrap();
cbs.callbacks.push(ptr);
+
+ CallbackHandle {
+ handle: ptr,
+ inner: Arc::downgrade(inner),
+ }
}
pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manager>>, api_call: sys::SteamAPICall, callback_id: i32, f: F)