meow
This commit is contained in:
parent
cd16ce7971
commit
65e0c5d272
5 changed files with 39 additions and 26 deletions
|
@ -16,6 +16,8 @@ import qualified Data.Aeson as A
|
||||||
import qualified Data.ByteString as B
|
import qualified Data.ByteString as B
|
||||||
import qualified Data.ByteString.Lazy.Char8 as B8
|
import qualified Data.ByteString.Lazy.Char8 as B8
|
||||||
|
|
||||||
|
import Data.IORef
|
||||||
|
|
||||||
import Data.UUID
|
import Data.UUID
|
||||||
|
|
||||||
import qualified Data.Vector.Storable as VS
|
import qualified Data.Vector.Storable as VS
|
||||||
|
@ -50,12 +52,10 @@ sendMessage
|
||||||
-> IO ()
|
-> IO ()
|
||||||
sendMessage st msg sock = do
|
sendMessage st msg sock = do
|
||||||
let msgJson = A.encode msg
|
let msgJson = A.encode msg
|
||||||
msgVector = VS.fromList $ B.unpack $ B.toStrict msgJson
|
msgList = B.unpack $ B.toStrict msgJson
|
||||||
VS.unsafeWith
|
ptr <- newArray msgList
|
||||||
msgVector
|
void $ sendBuf sock ptr (length msgList)
|
||||||
(\ptr -> do
|
free ptr
|
||||||
void $ sendBuf sock ptr (VS.length msgVector)
|
|
||||||
)
|
|
||||||
|
|
||||||
handleMessages
|
handleMessages
|
||||||
:: Game ()
|
:: Game ()
|
||||||
|
@ -141,24 +141,19 @@ receiveMessage sock queue st = do
|
||||||
mJsonMsg
|
mJsonMsg
|
||||||
)
|
)
|
||||||
msgs
|
msgs
|
||||||
|
free ptr
|
||||||
|
|
||||||
-- | Function that installs a handler on SIGINT to terminate game
|
-- | Function that installs a handler on SIGINT to terminate game
|
||||||
terminateGameOnSigint
|
terminateGameOnSigint
|
||||||
:: Game ()
|
:: IORef Bool
|
||||||
terminateGameOnSigint = do
|
-> Game ()
|
||||||
sock <- asks rcSocket
|
terminateGameOnSigint stopper = do
|
||||||
clientId <- asks rcClientUUID
|
|
||||||
clientState <- gets scClientState
|
|
||||||
st <- get
|
|
||||||
void $ liftIO $ installHandler
|
void $ liftIO $ installHandler
|
||||||
keyboardSignal
|
keyboardSignal
|
||||||
(CatchOnce $ do
|
(CatchOnce $ do
|
||||||
putStrLn "receiveMessage: SIGINT caught, terminating…"
|
putStrLn "receiveMessage: SIGINT caught, terminating…"
|
||||||
STM.atomically $ do
|
atomicWriteIORef stopper True
|
||||||
currentState <- STM.readTMVar clientState
|
|
||||||
void $ STM.swapTMVar clientState $ currentState { clientStop = True }
|
|
||||||
-- Vty.shutdown (clientVty currentState)
|
-- Vty.shutdown (clientVty currentState)
|
||||||
partingMessage st clientId sock
|
|
||||||
-- Raise SIGINT again so it does not get blocked
|
-- Raise SIGINT again so it does not get blocked
|
||||||
-- raiseSignal keyboardSignal
|
-- raiseSignal keyboardSignal
|
||||||
)
|
)
|
||||||
|
|
|
@ -10,6 +10,8 @@ import Control.Monad.Loops
|
||||||
|
|
||||||
import Control.Monad.RWS
|
import Control.Monad.RWS
|
||||||
|
|
||||||
|
import Data.IORef (IORef, readIORef)
|
||||||
|
|
||||||
import Graphics.Vty
|
import Graphics.Vty
|
||||||
|
|
||||||
-- internal imports
|
-- internal imports
|
||||||
|
@ -20,21 +22,25 @@ import Client.Types
|
||||||
|
|
||||||
import Library.Types
|
import Library.Types
|
||||||
|
|
||||||
runGame :: Game ()
|
runGame
|
||||||
runGame = do
|
:: IORef Bool
|
||||||
|
-> Game ()
|
||||||
|
runGame stopper = do
|
||||||
sock <- asks rcSocket
|
sock <- asks rcSocket
|
||||||
queue <- asks rcQueue
|
queue <- asks rcQueue
|
||||||
clientId <- asks rcClientUUID
|
clientId <- asks rcClientUUID
|
||||||
st <- get
|
st <- get
|
||||||
recvThread <- liftIO $ forkIO $ forever $ receiveMessage sock queue st
|
-- recvThread <- liftIO $ forkIO $ forever $ receiveMessage sock queue st
|
||||||
liftIO $ sendMessage st(ClientMessage clientId ClientReady) sock
|
liftIO $ sendMessage st(ClientMessage clientId ClientReady) sock
|
||||||
whileM_
|
whileM_
|
||||||
(not . clientStop <$> (liftIO . STM.atomically . STM.readTMVar =<< gets scClientState))
|
(liftIO (not <$> readIORef stopper))
|
||||||
(do
|
(do
|
||||||
|
liftIO $ receiveMessage sock queue st
|
||||||
handleMessages
|
handleMessages
|
||||||
-- draw
|
-- draw
|
||||||
)
|
)
|
||||||
liftIO $ killThread recvThread
|
liftIO $ partingMessage st clientId sock
|
||||||
|
-- liftIO $ killThread recvThread
|
||||||
|
|
||||||
handleEvent
|
handleEvent
|
||||||
:: Maybe Event
|
:: Maybe Event
|
||||||
|
|
|
@ -2,6 +2,8 @@ module Client.Types where
|
||||||
|
|
||||||
import qualified Control.Concurrent.STM as STM
|
import qualified Control.Concurrent.STM as STM
|
||||||
|
|
||||||
|
import Control.Exception (Exception)
|
||||||
|
|
||||||
import Control.Monad.RWS
|
import Control.Monad.RWS
|
||||||
|
|
||||||
import Data.UUID
|
import Data.UUID
|
||||||
|
@ -38,3 +40,8 @@ data StateContainer = StateContainer
|
||||||
}
|
}
|
||||||
|
|
||||||
type Game = RWST ReaderContainer String StateContainer IO
|
type Game = RWST ReaderContainer String StateContainer IO
|
||||||
|
|
||||||
|
data ClientTerminate = ClientTerminate
|
||||||
|
deriving (Show)
|
||||||
|
|
||||||
|
instance Exception ClientTerminate
|
||||||
|
|
|
@ -8,6 +8,8 @@ import Control.Monad
|
||||||
|
|
||||||
import Control.Monad.RWS
|
import Control.Monad.RWS
|
||||||
|
|
||||||
|
import Data.IORef
|
||||||
|
|
||||||
import qualified Data.Matrix as M
|
import qualified Data.Matrix as M
|
||||||
|
|
||||||
import Graphics.Vty
|
import Graphics.Vty
|
||||||
|
@ -71,17 +73,18 @@ main = do
|
||||||
initState = StateContainer (initWizard playerWizard) clientState initSlice
|
initState = StateContainer (initWizard playerWizard) clientState initSlice
|
||||||
-- putStrLn "sending quit message"
|
-- putStrLn "sending quit message"
|
||||||
-- sendMessage (ClientMessage clientId ClientQuit) sock
|
-- sendMessage (ClientMessage clientId ClientQuit) sock
|
||||||
|
stopper <- newIORef False
|
||||||
void $ execRWST
|
void $ execRWST
|
||||||
(do
|
(do
|
||||||
terminateGameOnSigint
|
terminateGameOnSigint stopper
|
||||||
runGame
|
runGame stopper
|
||||||
)
|
)
|
||||||
initRead
|
initRead
|
||||||
initState
|
initState
|
||||||
-- shutdown vty
|
-- shutdown vty
|
||||||
partingMessage initState clientId sock
|
putStrLn "Shutting down client…"
|
||||||
threadDelay 100
|
-- threadDelay 100
|
||||||
close sock
|
-- close sock
|
||||||
putStrLn "bye bye"
|
putStrLn "bye bye"
|
||||||
where
|
where
|
||||||
opts = info (options <**> helper)
|
opts = info (options <**> helper)
|
||||||
|
|
|
@ -252,11 +252,13 @@ handleMessage stateContainer readerContainer msg = do
|
||||||
ClientQuit -> do
|
ClientQuit -> do
|
||||||
putStrLn $ "removing client " <> show clientId
|
putStrLn $ "removing client " <> show clientId
|
||||||
let newClients = filter (\a -> ccUUID a /= Just clientId) clients
|
let newClients = filter (\a -> ccUUID a /= Just clientId) clients
|
||||||
|
client = find (\a -> ccUUID a == Just clientId) clients
|
||||||
STM.atomically $ do
|
STM.atomically $ do
|
||||||
currentPlayers <- STM.readTMVar (scPlayers stateContainer)
|
currentPlayers <- STM.readTMVar (scPlayers stateContainer)
|
||||||
let newPlayers = filter (\p -> playerId p /= clientId) currentPlayers
|
let newPlayers = filter (\p -> playerId p /= clientId) currentPlayers
|
||||||
void $ STM.swapTMVar (scPlayers stateContainer) newPlayers
|
void $ STM.swapTMVar (scPlayers stateContainer) newPlayers
|
||||||
void $ STM.swapTMVar clientList newClients
|
void $ STM.swapTMVar clientList newClients
|
||||||
|
close (ccSocket $ fromJust client)
|
||||||
ClientRequestWizard -> do
|
ClientRequestWizard -> do
|
||||||
putStrLn "initializing new wizard"
|
putStrLn "initializing new wizard"
|
||||||
let arena = rcMap readerContainer
|
let arena = rcMap readerContainer
|
||||||
|
|
Loading…
Reference in a new issue