From a68f4c76fd4bfd7e14c6d278d9ca65646789701b Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Sat, 18 Jul 2020 00:02:41 +0100 Subject: [PATCH] reorganise token registries nfc --- src/bin/server.rs | 2 +- src/global.rs | 114 ++++++++++++++++++++++++++++++++++++++-------- src/imports.rs | 6 ++- src/session.rs | 6 +-- 4 files changed, 103 insertions(+), 25 deletions(-) diff --git a/src/bin/server.rs b/src/bin/server.rs index 0c9609f5..46181ebb 100644 --- a/src/bin/server.rs +++ b/src/bin/server.rs @@ -69,7 +69,7 @@ fn resource(leaf : CheckedResourceLeaf) -> io::Result { } fn main() { - xxx_global_setup(); + xxx_global_setup().expect("global setup failed"); let helmet = SpaceHelmet::default() .enable(NoSniff::Enable) diff --git a/src/global.rs b/src/global.rs index e57e2ce9..2e751434 100644 --- a/src/global.rs +++ b/src/global.rs @@ -16,6 +16,8 @@ pub struct Instance { pub gs : GameState, pub clients : DenseSlotMap, pub updates : SecondarySlotMap, + pub tokens_players : TokenRegistry, + pub tokens_clients : TokenRegistry, } #[derive(Debug)] @@ -23,6 +25,12 @@ pub struct Client { pub player : PlayerId, } +#[derive(Debug)] +pub struct InstanceGuard<'g> { + ig : MutexGuard<'g,Instance>, + amu : Arc>, +} + #[derive(Default)] struct Global { // lock hierarchy: this is the innermost lock @@ -31,6 +39,12 @@ struct Global { // xxx delete instances at some point! } +#[derive(Debug,Default)] +pub struct TokenRegistry { + tr : HashSet, + id : PhantomData, +} + // ---------- API ---------- #[derive(Clone,Debug)] @@ -49,6 +63,7 @@ pub type TokenTable = HashMap>; pub trait AccessId : Copy + Clone + 'static { fn global_tokens() -> &'static RwLock>; + fn tokens_registry(ig: &mut Instance) -> &mut TokenRegistry; const ERROR : OnlineError; } @@ -66,15 +81,81 @@ lazy_static! { static ref GLOBAL : Global = Default::default(); } -// ---------- API ---------- +// ---------- Player and instance API ---------- + +impl Instance { + #[throws(OE)] + pub fn new(gs: GameState) -> Instance { + Instance { + gs, + clients : Default::default(), + updates : Default::default(), + tokens_players : Default::default(), + tokens_clients : Default::default(), + } + } + + #[throws(OE)] + pub fn lock<'g>(amu : &'g Arc>) -> InstanceGuard<'g> { + let ig = amu.lock()?; + InstanceGuard { ig, amu: amu.clone() } + } +} + +impl Deref for InstanceGuard<'_> { + type Target = Instance; + fn deref(&self) -> &Instance { &self.ig } +} +impl DerefMut for InstanceGuard<'_> { + fn deref_mut(&mut self) -> &mut Instance { &mut self.ig } +} + +impl InstanceGuard<'_> { + #[throws(OE)] + pub fn player_new(&mut self, newplayer: PlayerState) -> PlayerId { + let player = self.ig.gs.players.insert(newplayer); + self.ig.updates.insert(player, Default::default()); + self.save_game_now()?; + player + } + + #[throws(OE)] + pub fn player_access_register(&mut self, token: RawToken, player: PlayerId) { + let iad = InstanceAccessDetails { g : self.amu.clone(), ident : player }; + self.token_register(token, iad); + self.save_access_now()?; + } + + fn token_register( + &mut self, + token: RawToken, + iad: InstanceAccessDetails + ) { + Id::tokens_registry(&mut *self.ig).tr.insert(token.clone()); + Id::global_tokens().write().unwrap().insert(token, iad); + } + + #[throws(OE)] + fn save_game_now(&mut self) { eprintln!("xxx would save!"); } + #[throws(OE)] + fn save_access_now(&mut self) { eprintln!("xxx would save!"); } +} + +// ---------- Lookup and token API ---------- impl AccessId for PlayerId { const ERROR : OnlineError = NoPlayer; fn global_tokens() -> &'static RwLock> { &GLOBAL.players } + fn tokens_registry(ig: &mut Instance) -> &mut TokenRegistry { + &mut ig.tokens_players + } } impl AccessId for ClientId { const ERROR : OnlineError = NoClient; fn global_tokens() -> &'static RwLock> { &GLOBAL.clients } + fn tokens_registry(ig: &mut Instance) -> &mut TokenRegistry { + &mut ig.tokens_clients + } } pub fn lookup_token(s : &str) @@ -95,15 +176,17 @@ impl<'r, Id> FromParam<'r> for InstanceAccess<'r, Id> InstanceAccess { raw_token : token, i : i.clone() } } } - -pub fn record_token(iad : InstanceAccessDetails) - -> RawToken { + +pub fn record_token( + ig : &mut InstanceGuard, + iad : InstanceAccessDetails +) -> RawToken { let mut rng = thread_rng(); let token = RawToken ( repeat_with(|| rng.sample(Alphanumeric)) .take(64).collect() ); - Id::global_tokens().write().unwrap().insert(token.clone(), iad); + ig.token_register(token.clone(), iad); token } @@ -114,23 +197,16 @@ const XXX_PLAYERS_TOKENS : &[(&str, &str)] = &[ ("ccg9kzoTh758QrVE1xMY7BQWB36dNJTx", "bob"), ]; +#[throws(OE)] pub fn xxx_global_setup() { - let gi = Instance { - gs : xxx_gamestate_init(), - clients : Default::default(), - updates : Default::default(), - }; + let gs = xxx_gamestate_init(); + let gi = Instance::new(gs)?; let amu = Arc::new(Mutex::new(gi)); - let mut ig = amu.lock().unwrap(); + let mut ig = Instance::lock(&amu)?; for (token, nick) in XXX_PLAYERS_TOKENS { - let np = PlayerState { + let player = ig.player_new(PlayerState { nick : nick.to_string(), - }; - let player = ig.gs.players.insert(np); - let ia = InstanceAccessDetails { g : amu.clone(), ident : player }; - GLOBAL.players.write().unwrap().insert( - RawToken(token.to_string()), ia - ); - ig.updates.insert(player, Default::default()); + })?; + ig.player_access_register(RawToken(token.to_string()), player)?; } } diff --git a/src/imports.rs b/src/imports.rs index 717464c5..472d02ae 100644 --- a/src/imports.rs +++ b/src/imports.rs @@ -6,8 +6,8 @@ pub use std::fmt::Formatter; pub use std::fmt::{self,Display,Debug}; pub use std::thread; pub use std::time::Duration; -pub use std::sync::{Arc,Mutex,RwLock,Condvar}; -pub use std::collections::HashMap; +pub use std::sync::{Arc,Mutex,MutexGuard,RwLock,Condvar}; +pub use std::collections::{HashMap,HashSet}; pub use std::borrow::Borrow; pub use std::convert::{TryFrom,TryInto}; pub use std::str; @@ -18,6 +18,8 @@ pub use std::collections::VecDeque; pub use std::num::Wrapping; pub use std::cmp; pub use std::error::Error; +pub use std::marker::PhantomData; +pub use std::ops::{Deref,DerefMut}; pub use thiserror::Error; pub use anyhow::{Context,anyhow}; diff --git a/src/session.rs b/src/session.rs index 5ae52ac4..2253c2a5 100644 --- a/src/session.rs +++ b/src/session.rs @@ -47,8 +47,7 @@ fn session(form : Json) -> Result { let iad = lookup_token(&form.ptoken)?; let player = iad.ident; let c = { - let mut ig = iad.g.lock()?; - let ig = &mut *ig; + let mut ig = Instance::lock(&iad.g)?; let cl = Client { player }; let client = ig.clients.insert(cl); @@ -56,7 +55,8 @@ fn session(form : Json) -> Result { g : iad.g.clone(), ident : client, }; - let ctoken = record_token(ciad); + let ctoken = record_token(&mut ig, ciad); + let ig = &mut *ig; let mut uses = vec![]; let mut alldefs = vec![]; -- 2.30.2