aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authorMatthew Collins <[email protected]>2018-02-27 20:30:40 +0000
committerMatthew Collins <[email protected]>2018-02-27 20:30:40 +0000
commite99c0e0adc490b94b037838757bfa6647f3c3568 (patch)
tree1ab022877d951a111820b5c0a1d35facac3ef6ee /src/lib.rs
parentAdd accessors for `SteamId`'s inner values (diff)
downloadsteamworks-rs-e99c0e0adc490b94b037838757bfa6647f3c3568.tar.xz
steamworks-rs-e99c0e0adc490b94b037838757bfa6647f3c3568.zip
Try and make the accessors generic over the client and server
Diffstat (limited to 'src/lib.rs')
-rw-r--r--src/lib.rs152
1 files changed, 85 insertions, 67 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 01a5b24..e3d310c 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -40,11 +40,12 @@ pub type SResult<T> = Result<T, SteamError>;
///
/// This provides access to all of the steamworks api.
#[derive(Clone)]
-pub struct Client {
- inner: Arc<ClientInner>,
+pub struct Client<Manager = ClientManager> {
+ inner: Arc<Inner<Manager>>,
}
-struct ClientInner {
+struct Inner<Manager> {
+ _manager: Manager,
_client: *mut sys::ISteamClient,
callbacks: Mutex<ClientCallbacks>,
}
@@ -54,10 +55,10 @@ struct ClientCallbacks {
call_results: HashMap<sys::SteamAPICall, *mut libc::c_void>,
}
-unsafe impl Send for ClientInner {}
-unsafe impl Sync for ClientInner {}
+unsafe impl <Manager: Send + Sync> Send for Inner<Manager> {}
+unsafe impl <Manager: Send + Sync> Sync for Inner<Manager> {}
-impl Client {
+impl Client<ClientManager> {
/// Attempts to initialize the steamworks api and returns
/// a client to access the rest of the api.
///
@@ -75,13 +76,14 @@ impl Client {
/// * The game isn't running on the same user/level as the steam client
/// * The user doesn't own a license for the game.
/// * The app ID isn't completely set up.
- pub fn init() -> SResult<Client> {
+ pub fn init() -> SResult<Client<ClientManager>> {
unsafe {
if sys::SteamAPI_Init() == 0 {
return Err(SteamError::InitFailed);
}
let client = sys::steam_rust_get_client();
- let client = Arc::new(ClientInner {
+ let client = Arc::new(Inner {
+ _manager: ClientManager { _priv: () },
_client: client,
callbacks: Mutex::new(ClientCallbacks {
callbacks: Vec::new(),
@@ -93,7 +95,9 @@ impl Client {
})
}
}
+}
+impl <Manager> Client<Manager> {
/// Runs any currently pending callbacks
///
/// This runs all currently pending callbacks on the current
@@ -149,118 +153,70 @@ impl Client {
}
}
- pub(crate) unsafe fn register_call_result<C, F>(inner: &Arc<ClientInner>, api_call: sys::SteamAPICall, callback_id: i32, f: F)
- where F: for <'a> FnMut(&'a C, bool) + 'static + Send + Sync
- {
- use std::mem;
-
- struct Info<F> {
- func: F,
- api_call: sys::SteamAPICall,
- client: Weak<ClientInner>,
- }
-
- let userdata = Box::into_raw(Box::new(Info {
- func: f,
- api_call,
- client: Arc::downgrade(&inner),
- }));
-
- extern "C" fn run_func<C, F>(userdata: *mut libc::c_void, param: *mut libc::c_void, io_error: bool)
- where F: for <'a> FnMut(&'a C, bool) + 'static + Send + Sync
- {
- unsafe {
- let func: &mut Info<F> = &mut *(userdata as *mut Info<F>);
- (func.func)(&*(param as *const _), io_error);
- }
- }
- extern "C" fn dealloc<C, F>(userdata: *mut libc::c_void)
- where F: for <'a> FnMut(&'a C, bool) + 'static + Send + Sync
- {
- let func: Box<Info<F>> = unsafe { Box::from_raw(userdata as _) };
- if let Some(inner) = func.client.upgrade() {
- let mut cbs = inner.callbacks.lock().unwrap();
- cbs.call_results.remove(&func.api_call);
- }
- drop(func);
- }
-
- let ptr = sys::register_rust_steam_call_result(
- mem::size_of::<C>() as _,
- userdata as _,
- run_func::<C, F>,
- dealloc::<C, F>,
- api_call,
- callback_id as _,
- );
- let mut cbs = inner.callbacks.lock().unwrap();
- cbs.call_results.insert(api_call, ptr);
- }
-
/// Returns an accessor to the steam utils interface
- pub fn utils(&self) -> Utils {
+ pub fn utils(&self) -> Utils<Manager> {
unsafe {
let utils = sys::steam_rust_get_utils();
debug_assert!(!utils.is_null());
Utils {
utils: utils,
- _client: self.inner.clone(),
+ _inner: self.inner.clone(),
}
}
}
/// Returns an accessor to the steam matchmaking interface
- pub fn matchmaking(&self) -> Matchmaking {
+ pub fn matchmaking(&self) -> Matchmaking<Manager> {
unsafe {
let mm = sys::steam_rust_get_matchmaking();
debug_assert!(!mm.is_null());
Matchmaking {
mm: mm,
- client: self.inner.clone(),
+ inner: self.inner.clone(),
}
}
}
/// Returns an accessor to the steam apps interface
- pub fn apps(&self) -> Apps {
+ pub fn apps(&self) -> Apps<Manager> {
unsafe {
let apps = sys::steam_rust_get_apps();
debug_assert!(!apps.is_null());
Apps {
apps: apps,
- _client: self.inner.clone(),
+ _inner: self.inner.clone(),
}
}
}
/// Returns an accessor to the steam friends interface
- pub fn friends(&self) -> Friends {
+ pub fn friends(&self) -> Friends<Manager> {
unsafe {
let friends = sys::steam_rust_get_friends();
debug_assert!(!friends.is_null());
Friends {
friends: friends,
- _client: self.inner.clone(),
+ inner: self.inner.clone(),
}
}
}
/// Returns an accessor to the steam user interface
- pub fn user(&self) -> User {
+ pub fn user(&self) -> User<Manager> {
unsafe {
let user = sys::steam_rust_get_user();
debug_assert!(!user.is_null());
User {
user,
- _client: self.inner.clone(),
+ _inner: self.inner.clone(),
}
}
}
}
-impl Drop for ClientInner {
+impl <Manager> Drop for Inner<Manager> {
fn drop(&mut self) {
unsafe {
{
@@ -272,6 +228,68 @@ impl Drop for ClientInner {
sys::unregister_rust_steam_call_result(*cb);
}
}
+ }
+ }
+}
+
+
+
+pub(crate) unsafe fn register_call_result<C, F, Manager>(inner: &Arc<Inner<Manager>>, api_call: sys::SteamAPICall, callback_id: i32, f: F)
+ where F: for <'a> FnMut(&'a C, bool) + 'static + Send + Sync
+{
+ use std::mem;
+
+ struct Info<F, Manager> {
+ func: F,
+ api_call: sys::SteamAPICall,
+ inner: Weak<Inner<Manager>>,
+ }
+
+ let userdata = Box::into_raw(Box::new(Info {
+ func: f,
+ api_call,
+ inner: Arc::downgrade(&inner),
+ }));
+
+ extern "C" fn run_func<C, F, Manager>(userdata: *mut libc::c_void, param: *mut libc::c_void, io_error: bool)
+ where F: for <'a> FnMut(&'a C, bool) + 'static + Send + Sync
+ {
+ unsafe {
+ let func: &mut Info<F, Manager> = &mut *(userdata as *mut Info<F, Manager>);
+ (func.func)(&*(param as *const _), io_error);
+ }
+ }
+ extern "C" fn dealloc<C, F, Manager>(userdata: *mut libc::c_void)
+ where F: for <'a> FnMut(&'a C, bool) + 'static + Send + Sync
+ {
+ let func: Box<Info<F, Manager>> = unsafe { Box::from_raw(userdata as _) };
+ if let Some(inner) = func.inner.upgrade() {
+ let mut cbs = inner.callbacks.lock().unwrap();
+ cbs.call_results.remove(&func.api_call);
+ }
+ drop(func);
+ }
+
+ let ptr = sys::register_rust_steam_call_result(
+ mem::size_of::<C>() as _,
+ userdata as _,
+ run_func::<C, F, Manager>,
+ dealloc::<C, F, Manager>,
+ api_call,
+ callback_id as _,
+ );
+ let mut cbs = inner.callbacks.lock().unwrap();
+ cbs.call_results.insert(api_call, ptr);
+}
+
+/// Manages keeping the steam api active for clients
+pub struct ClientManager {
+ _priv: (),
+}
+
+impl Drop for ClientManager {
+ fn drop(&mut self) {
+ unsafe {
sys::SteamAPI_Shutdown();
}
}