#[serde(transparent)]
pub struct RawToken (pub String);
-// ---------- data structure ----------
+// ---------- public data structure ----------
#[derive(Debug,Serialize,Deserialize)]
#[derive(Eq,PartialEq,Ord,PartialOrd,Hash)]
#[derive(Debug,Clone)]
pub struct InstanceRef (Arc<Mutex<InstanceContainer>>);
-#[derive(Debug)]
-pub struct InstanceContainer {
- live : bool,
- g : Instance,
-}
-
#[derive(Debug)]
pub struct Instance {
pub name : Arc<InstanceName>,
pub gref : InstanceRef,
}
-#[derive(Default)]
-struct Global {
- // lock hierarchy: this is the innermost lock
- games : RwLock<HashMap<Arc<InstanceName>,InstanceRef>>,
- players : RwLock<TokenTable<PlayerId>>,
- clients : RwLock<TokenTable<ClientId>>,
- // xxx delete instances at some point!
-}
-
#[derive(Debug,Default)]
pub struct TokenRegistry<Id: AccessId> {
tr : HashSet<RawToken>,
id : PhantomData<Id>,
}
-#[derive(Debug,Serialize,Deserialize)]
-struct InstanceSaveAccesses<RawTokenStr> {
- tokens_players : Vec<(RawTokenStr, PlayerId)>,
-}
-
-display_as_debug!{InstanceLockError}
-impl<X> From<PoisonError<X>> for InstanceLockError {
- fn from(_: PoisonError<X>) -> Self { Self::GameCorrupted }
-}
-
-// ---------- API ----------
+// ---------- Token Table API ----------
#[derive(Clone,Debug)]
pub struct InstanceAccessDetails<Id> {
// workaround for inability to have private trait methods
const PRIVATE_Y : PrivateCaller = PrivateCaller(());
-// ========== implementations ==========
+// ========== internal data structures ==========
-// ---------- newtypes and type aliases ----------
+lazy_static! {
+ static ref GLOBAL : Global = Default::default();
+}
-impl Borrow<str> for RawToken {
- fn borrow(&self) -> &str { &self.0 }
+#[derive(Default)]
+struct Global {
+ // lock hierarchy: this is the innermost lock
+ games : RwLock<HashMap<Arc<InstanceName>,InstanceRef>>,
+ players : RwLock<TokenTable<PlayerId>>,
+ clients : RwLock<TokenTable<ClientId>>,
+ // xxx delete instances at some point!
}
-// ---------- data structure ----------
+#[derive(Debug)]
+pub struct InstanceContainer {
+ live : bool,
+ g : Instance,
+}
-lazy_static! {
- static ref GLOBAL : Global = Default::default();
+#[derive(Debug,Serialize,Deserialize)]
+struct InstanceSaveAccesses<RawTokenStr> {
+ tokens_players : Vec<(RawTokenStr, PlayerId)>,
+}
+
+display_as_debug!{InstanceLockError}
+impl<X> From<PoisonError<X>> for InstanceLockError {
+ fn from(_: PoisonError<X>) -> Self { Self::GameCorrupted }
}
-// ---------- Player and instance API ----------
+// ========== implementations ==========
+
+impl Borrow<str> for RawToken {
+ fn borrow(&self) -> &str { &self.0 }
+}
+
+// ---------- Main instance API ----------
impl InstanceRef {
#[throws(InstanceLockError)]
InstanceGuard::forget_all_tokens(&mut g.tokens_players);
InstanceGuard::forget_all_tokens(&mut g.tokens_clients);
}
+
+ pub fn list_names(scope: Option<&ManagementScope>)
+ -> Vec<Arc<InstanceName>> {
+ let games = GLOBAL.games.read().unwrap();
+ let out : Vec<Arc<InstanceName>> =
+ games.keys()
+ .filter(|k| scope == None || scope == Some(&k.scope))
+ .map(|k| k.clone())
+ .collect();
+ out
+ }
}
+// ---------- Simple trait implementations ----------
+
impl Deref for InstanceGuard<'_> {
type Target = Instance;
fn deref(&self) -> &Instance { &self.c.g }
fn deref_mut(&mut self) -> &mut Instance { &mut self.c.g }
}
+// ---------- Player and token functionality ----------
+
impl InstanceGuard<'_> {
#[throws(OE)]
pub fn player_new(&mut self, newplayer: PlayerState) -> PlayerId {
let mut global = global.write().unwrap();
for t in tokens.tr.drain() { global.remove(&t); }
}
+}
+// ---------- save/load ----------
+
+impl InstanceGuard<'_> {
fn savefile(name: &InstanceName, prefix: &str, suffix: &str) -> String {
let scope_prefix = { use ManagementScope::*; match &name.scope {
Server => format!(""),
}
}
-pub fn list_games(scope: Option<&ManagementScope>)
- -> Vec<Arc<InstanceName>> {
- let games = GLOBAL.games.read().unwrap();
- let out : Vec<Arc<InstanceName>> =
- games.keys()
- .filter(|k| scope == None || scope == Some(&k.scope))
- .map(|k| k.clone())
- .collect();
- out
-}
-
// ---------- Lookup and token API ----------
impl AccessId for PlayerId {