aboutsummaryrefslogtreecommitdiff
path: root/src
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
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')
-rw-r--r--src/app.rs6
-rw-r--r--src/friends.rs20
-rw-r--r--src/lib.rs152
-rw-r--r--src/matchmaking.rs14
-rw-r--r--src/user.rs6
-rw-r--r--src/utils.rs6
6 files changed, 112 insertions, 92 deletions
diff --git a/src/app.rs b/src/app.rs
index 1a20caa..d6e787f 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -5,12 +5,12 @@ use super::*;
pub struct AppId(pub u32);
/// Access to the steam apps interface
-pub struct Apps {
+pub struct Apps<Manager> {
pub(crate) apps: *mut sys::ISteamApps,
- pub(crate) _client: Arc<ClientInner>,
+ pub(crate) _inner: Arc<Inner<Manager>>,
}
-impl Apps {
+impl <Manager> Apps<Manager> {
/// Returns whether the user currently has the app with the given
/// ID currently installed.
diff --git a/src/friends.rs b/src/friends.rs
index 5885e6f..c57d54d 100644
--- a/src/friends.rs
+++ b/src/friends.rs
@@ -41,13 +41,15 @@ bitflags! {
const STEAM_LEVEL = 0x2000;
}
}
-pub struct Friends {
+
+/// Access to the steam friends interface
+pub struct Friends<Manager> {
pub(crate) friends: *mut sys::ISteamFriends,
- pub(crate) _client: Arc<ClientInner>,
+ pub(crate) inner: Arc<Inner<Manager>>,
}
-impl Friends {
- pub fn get_friends(&self, flags: FriendFlags) -> Vec<Friend> {
+impl <Manager> Friends<Manager> {
+ pub fn get_friends(&self, flags: FriendFlags) -> Vec<Friend<Manager>> {
unsafe {
let count = sys::SteamAPI_ISteamFriends_GetFriendCount(self.friends, flags.bits() as _);
let mut friends = Vec::with_capacity(count as usize);
@@ -56,7 +58,7 @@ impl Friends {
friends.push(Friend {
id: friend,
friends: self.friends,
- _client: self._client.clone(),
+ _inner: self.inner.clone(),
});
}
@@ -102,19 +104,19 @@ unsafe impl Callback for PersonaStateChange {
}
}
-pub struct Friend {
+pub struct Friend<Manager> {
id: SteamId,
friends: *mut sys::ISteamFriends,
- _client: Arc<ClientInner>,
+ _inner: Arc<Inner<Manager>>,
}
-impl Debug for Friend {
+impl <Manager> Debug for Friend<Manager> {
fn fmt(&self, f: &mut Formatter) -> fmt::Result {
write!(f, "Friend({:?})", self.id)
}
}
-impl Friend {
+impl <Manager> Friend<Manager> {
pub fn id(&self) -> SteamId {
self.id
}
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();
}
}
diff --git a/src/matchmaking.rs b/src/matchmaking.rs
index 27cf9e5..9ed8f8f 100644
--- a/src/matchmaking.rs
+++ b/src/matchmaking.rs
@@ -2,9 +2,9 @@
use super::*;
/// Access to the steam matchmaking interface
-pub struct Matchmaking {
+pub struct Matchmaking<Manager> {
pub(crate) mm: *mut sys::ISteamMatchmaking,
- pub(crate) client: Arc<ClientInner>,
+ pub(crate) inner: Arc<Inner<Manager>>,
}
const CALLBACK_BASE_ID: i32 = 500;
@@ -19,15 +19,15 @@ pub enum LobbyType {
#[derive(Debug)]
pub struct LobbyId(u64);
-impl Matchmaking {
+impl <Manager> Matchmaking<Manager> {
pub fn request_lobby_list<F>(&self, mut cb: F)
where F: FnMut(Result<Vec<LobbyId>, SteamError>) + 'static + Send + Sync
{
unsafe {
let api_call = sys::SteamAPI_ISteamMatchmaking_RequestLobbyList(self.mm);
- Client::register_call_result::<sys::LobbyMatchList, _>(
- &self.client, api_call, CALLBACK_BASE_ID + 10,
+ register_call_result::<sys::LobbyMatchList, _, _>(
+ &self.inner, api_call, CALLBACK_BASE_ID + 10,
move |v, io_error| {
cb(if io_error {
Err(SteamError::IOFailure)
@@ -53,8 +53,8 @@ impl Matchmaking {
LobbyType::Invisible => sys::LobbyType::Invisible,
};
let api_call = sys::SteamAPI_ISteamMatchmaking_CreateLobby(self.mm, ty, max_members as _);
- Client::register_call_result::<sys::LobbyCreated, _>(
- &self.client, api_call, CALLBACK_BASE_ID + 13,
+ register_call_result::<sys::LobbyCreated, _, _>(
+ &self.inner, api_call, CALLBACK_BASE_ID + 13,
move |v, io_error| {
cb(if io_error {
Err(SteamError::IOFailure)
diff --git a/src/user.rs b/src/user.rs
index fcd3e40..f589c2b 100644
--- a/src/user.rs
+++ b/src/user.rs
@@ -2,12 +2,12 @@
use super::*;
/// Access to the steam user interface
-pub struct User {
+pub struct User<Manager> {
pub(crate) user: *mut sys::ISteamUser,
- pub(crate) _client: Arc<ClientInner>,
+ pub(crate) _inner: Arc<Inner<Manager>>,
}
-impl User {
+impl <Manager> User<Manager> {
/// Returns the steam id of the current user
pub fn steam_id(&self) -> SteamId {
unsafe {
diff --git a/src/utils.rs b/src/utils.rs
index aa19d46..eb10d8b 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -2,9 +2,9 @@
use super::*;
/// Access to the steam utils interface
-pub struct Utils {
+pub struct Utils<Manager> {
pub(crate) utils: *mut sys::ISteamUtils,
- pub(crate) _client: Arc<ClientInner>,
+ pub(crate) _inner: Arc<Inner<Manager>>,
}
pub enum NotificationPosition {
@@ -14,7 +14,7 @@ pub enum NotificationPosition {
BottomRight,
}
-impl Utils {
+impl <Manager> Utils<Manager> {
/// Returns the app ID of the current process
pub fn app_id(&self) -> AppId {
unsafe {