Implement multi-sessions for players
This commit is contained in:
parent
09e6f6a5e9
commit
96424bfa2e
3 changed files with 24 additions and 12 deletions
|
@ -18,7 +18,7 @@ receive :: Message.FromClient -> Session.Status -> App.T ()
|
||||||
|
|
||||||
receive (Message.Hello {Message.name}) Nothing = do
|
receive (Message.Hello {Message.name}) Nothing = do
|
||||||
sessionID <- asks App.sessionID
|
sessionID <- asks App.sessionID
|
||||||
playerID <- App.exec (Server.register sessionID)
|
playerID <- App.exec (Server.register [sessionID])
|
||||||
room <- App.get Server.room
|
room <- App.get Server.room
|
||||||
Messaging.send $ Message.Welcome room playerID
|
Messaging.send $ Message.Welcome room playerID
|
||||||
App.update (Server.update sessionID $ Session.setPlayer playerID name)
|
App.update (Server.update sessionID $ Session.setPlayer playerID name)
|
||||||
|
|
|
@ -41,7 +41,7 @@ sendToSessions sessions obj = do
|
||||||
sendTo :: [KoiKoi.PlayerID] -> Message.T -> App.T ()
|
sendTo :: [KoiKoi.PlayerID] -> Message.T -> App.T ()
|
||||||
sendTo playerIDs obj = do
|
sendTo playerIDs obj = do
|
||||||
sessions <- App.get $ Server.sessionsWhere selectedPlayer
|
sessions <- App.get $ Server.sessionsWhere selectedPlayer
|
||||||
sendToSessions (elems sessions) obj
|
sendToSessions (foldl (++) [] sessions) obj
|
||||||
where
|
where
|
||||||
selectedPlayer playerID _ = Set.member playerID $ Set.fromList playerIDs
|
selectedPlayer playerID _ = Set.member playerID $ Set.fromList playerIDs
|
||||||
|
|
||||||
|
|
|
@ -16,8 +16,8 @@ module Server (
|
||||||
, update
|
, update
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Data.Map (Map, (!), (!?), adjust, delete, insert)
|
import Data.Map (Map, (!), (!?), adjust, delete, insert, mapMaybe)
|
||||||
import qualified Data.Map as Map (empty, lookup, mapMaybeWithKey)
|
import qualified Data.Map as Map (empty, foldlWithKey, lookup)
|
||||||
import Data.Text (Text)
|
import Data.Text (Text)
|
||||||
import Hanafuda.KoiKoi (PlayerID)
|
import Hanafuda.KoiKoi (PlayerID)
|
||||||
import Hanafuda.Message (Room)
|
import Hanafuda.Message (Room)
|
||||||
|
@ -28,7 +28,7 @@ import qualified RW (RW(..))
|
||||||
import qualified Session (ID, T(..), setPlayer)
|
import qualified Session (ID, T(..), setPlayer)
|
||||||
import System.Random (Random(..))
|
import System.Random (Random(..))
|
||||||
|
|
||||||
type SessionIDs = Map PlayerID Session.ID
|
type SessionIDs = Map PlayerID [Session.ID]
|
||||||
type Sessions = Map Session.ID Session.T
|
type Sessions = Map Session.ID Session.T
|
||||||
data T = T {
|
data T = T {
|
||||||
keys :: Keys.T
|
keys :: Keys.T
|
||||||
|
@ -52,15 +52,27 @@ new = getKeys >>= \keys -> return $ T {
|
||||||
}
|
}
|
||||||
|
|
||||||
room :: T -> Room
|
room :: T -> Room
|
||||||
room = fmap Player.name . select (\_ -> Session.player)
|
room = mapMaybe keepName . select (\_ -> Session.player)
|
||||||
|
where
|
||||||
|
keepName [] = Nothing
|
||||||
|
keepName (player:_) = Just $ Player.name player
|
||||||
|
|
||||||
select :: (PlayerID -> Session.T -> Maybe a) -> T -> Map PlayerID a
|
push :: Ord k => k -> v -> Map k [v] -> Map k [v]
|
||||||
|
push key value m =
|
||||||
|
(maybe (insert key [value]) (insert key . (value:)) $ Map.lookup key m) m
|
||||||
|
|
||||||
|
select :: (PlayerID -> Session.T -> Maybe a) -> T -> Map PlayerID [a]
|
||||||
select selector (T {sessionIDsByPlayerID, sessions}) =
|
select selector (T {sessionIDsByPlayerID, sessions}) =
|
||||||
Map.mapMaybeWithKey selected sessionIDsByPlayerID where
|
Map.foldlWithKey (\accumulator playerID sessionIDs ->
|
||||||
selected playerID sessionID =
|
foldl (\acc ->
|
||||||
Map.lookup sessionID sessions >>= selector playerID
|
maybe acc (\v -> push playerID v acc) . selected playerID
|
||||||
|
) accumulator sessionIDs
|
||||||
|
) Map.empty sessionIDsByPlayerID
|
||||||
|
where
|
||||||
|
selected playerID sessionID =
|
||||||
|
Map.lookup sessionID sessions >>= selector playerID
|
||||||
|
|
||||||
sessionsWhere :: (PlayerID -> Session.T -> Bool) -> T -> Map PlayerID Session.T
|
sessionsWhere :: (PlayerID -> Session.T -> Bool) -> T -> Map PlayerID [Session.T]
|
||||||
sessionsWhere predicate = select selectorOfPredicate where
|
sessionsWhere predicate = select selectorOfPredicate where
|
||||||
selectorOfPredicate playerID session =
|
selectorOfPredicate playerID session =
|
||||||
if predicate playerID session then Just session else Nothing
|
if predicate playerID session then Just session else Nothing
|
||||||
|
@ -79,7 +91,7 @@ update keyID updator =
|
||||||
|
|
||||||
logIn :: Text -> PlayerID -> Session.ID -> T -> T
|
logIn :: Text -> PlayerID -> Session.ID -> T -> T
|
||||||
logIn name playerID sessionID =
|
logIn name playerID sessionID =
|
||||||
RW.update (insert playerID sessionID) .
|
RW.update (push playerID sessionID) .
|
||||||
update sessionID (Session.setPlayer playerID name)
|
update sessionID (Session.setPlayer playerID name)
|
||||||
|
|
||||||
logOut :: Session.ID -> T -> T
|
logOut :: Session.ID -> T -> T
|
||||||
|
|
Loading…
Reference in a new issue