diff options
| author | Alex Parrill <[email protected]> | 2019-06-05 22:26:21 -0400 |
|---|---|---|
| committer | Matthew Collins <[email protected]> | 2019-06-09 23:50:11 +0100 |
| commit | 99051706e18f66f2e63494242dda41e7a7256971 (patch) | |
| tree | 13024d70399eb3fa57b106cec85d85874a8f629a /src | |
| parent | 0.5.1 (and 0.5.0 for sys) (diff) | |
| download | steamworks-rs-99051706e18f66f2e63494242dda41e7a7256971.tar.xz steamworks-rs-99051706e18f66f2e63494242dda41e7a7256971.zip | |
Add Utils::set_warning_callback for logging Steam warnings
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib.rs | 2 | ||||
| -rw-r--r-- | src/utils.rs | 54 |
2 files changed, 55 insertions, 1 deletions
@@ -5,6 +5,8 @@ extern crate steamworks_sys as sys; extern crate failure; #[macro_use] extern crate bitflags; +#[macro_use] +extern crate lazy_static; mod error; pub use crate::error::*; diff --git a/src/utils.rs b/src/utils.rs index 34ba6c9..3d569b3 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,6 +1,12 @@ use super::*; +use libc::c_char; +use std::ffi::CStr; +use std::panic; +use std::process::abort; +use std::sync::RwLock; + /// Access to the steam utils interface pub struct Utils<Manager> { pub(crate) utils: *mut sys::ISteamUtils, @@ -14,6 +20,36 @@ pub enum NotificationPosition { BottomRight, } +lazy_static!{ + /// Global rust warning callback + static ref WARNING_CALLBACK: RwLock<Option<Box<Fn(i32, &CStr) + Send + Sync>>> = RwLock::new(None); +} + +/// C function to pass as the real callback, which forwards to the `WARNING_CALLBACK` if any +unsafe extern "cdecl" fn c_warning_callback(level: i32, msg: *const c_char) { + let lock = WARNING_CALLBACK.read().expect("warning func lock poisoned"); + let cb = match lock.as_ref() { + Some(cb) => cb, + None => { return; } + }; + + let s = CStr::from_ptr(msg); + + let res = panic::catch_unwind(panic::AssertUnwindSafe(|| + cb(level, s) + )); + if let Err(err) = res { + if let Some(err) = err.downcast_ref::<&str>() { + println!("Steam warning callback paniced: {}", err); + } else if let Some(err) = err.downcast_ref::<String>() { + println!("Steam warning callback paniced: {}", err); + } else { + println!("Steam warning callback paniced"); + } + abort(); + } +} + impl <Manager> Utils<Manager> { /// Returns the app ID of the current process pub fn app_id(&self) -> AppId { @@ -47,4 +83,20 @@ impl <Manager> Utils<Manager> { sys::SteamAPI_ISteamUtils_SetOverlayNotificationPosition(self.utils, position); } } -}
\ No newline at end of file + + /// Sets the Steam warning callback, which is called to emit warning messages. + /// + /// The passed-in function takes two arguments: a severity level (0 = info, 1 = warning) and + /// the message itself. + /// + /// See [Steamwork's debugging page](https://partner.steamgames.com/doc/sdk/api/debugging) for more info. + pub fn set_warning_callback<F>(&self, cb: F) + where F: Fn(i32, &CStr) + Send + Sync + 'static + { + let mut lock = WARNING_CALLBACK.write().expect("warning func lock poisoned"); + *lock = Some(Box::new(cb)); + unsafe { + sys::SteamAPI_ISteamUtils_SetWarningMessageHook(self.utils, c_warning_callback); + } + } +} |