chiark / gitweb /
reorganise global.rs
authorIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 27 Jul 2020 00:12:41 +0000 (01:12 +0100)
committerIan Jackson <ijackson@chiark.greenend.org.uk>
Mon, 27 Jul 2020 00:12:41 +0000 (01:12 +0100)
src/cmdlistener.rs
src/global.rs

index 948986e6c33e38161c68a530913d3709ae71fcad..54ed415cefe7ae87ef4344972c944953847ae472 100644 (file)
@@ -246,7 +246,7 @@ fn execute(cs: &mut CommandStream, cmd: MgmtCommand) -> MgmtResponse {
         let scope = cs.get_scope()?;
         Some(scope)
       };
-      let mut games = list_games(scope);
+      let mut games = Instance::list_names(scope);
       games.sort_unstable();
       GamesList { games }
     },
index 06775ac0cb085080edfdf672cbf183349e6f83b3..d78a3fcec118863eff4818dc5dd5a5899afb8a98 100644 (file)
@@ -15,7 +15,7 @@ visible_slotmap_key!{ ClientId('C') }
 #[serde(transparent)]
 pub struct RawToken (pub String);
 
-// ---------- data structure ----------
+// ---------- public data structure ----------
 
 #[derive(Debug,Serialize,Deserialize)]
 #[derive(Eq,PartialEq,Ord,PartialOrd,Hash)]
@@ -27,12 +27,6 @@ pub struct InstanceName {
 #[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>,
@@ -61,32 +55,13 @@ pub struct InstanceGuard<'g> {
   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> {
@@ -114,21 +89,44 @@ pub struct PrivateCaller(());
 // 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)]
@@ -192,8 +190,21 @@ impl Instance {
     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 }
@@ -202,6 +213,8 @@ impl DerefMut for InstanceGuard<'_> {
   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 {
@@ -232,7 +245,11 @@ impl InstanceGuard<'_> {
     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!(""),
@@ -336,17 +353,6 @@ impl InstanceGuard<'_> {
   }
 }
 
-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 {