gameServer/RoomsAndClients.hs
author koda
Sat, 05 Jun 2010 14:07:58 +0000
changeset 3495 a6b4f351d400
parent 3458 11cd56019f00
child 3501 a3159a410e5c
permissions -rw-r--r--
now engine can be optionally built as library, there's an example wrapper of how to use it building server is now disabled by default, saves users some headaches
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     1
module RoomsAndClients(
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     2
    RoomIndex(),
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     3
    ClientIndex(),
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     4
    MRoomsAndClients(),
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     5
    IRoomsAndClients(),
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     6
    newRoomsAndClients,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     7
    addRoom,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     8
    addClient,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
     9
    removeRoom,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    10
    removeClient,
3436
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
    11
    modifyRoom,
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
    12
    modifyClient,
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    13
    lobbyId,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    14
    moveClientToLobby,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    15
    moveClientToRoom,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    16
    clientRoom,
3436
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
    17
    clientRoomM,
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    18
    client,
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3436
diff changeset
    19
    clientsM,
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    20
    allClients,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    21
    withRoomsAndClients,
3435
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
    22
    showRooms,
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
    23
    roomClients
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    24
    ) where
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    25
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    26
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    27
import Store
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    28
import Control.Monad
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    29
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    30
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    31
data Room r = Room {
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    32
    roomClients' :: [ClientIndex],
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    33
    room' :: r
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    34
    }
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    35
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    36
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    37
data Client c = Client {
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    38
    clientRoom' :: RoomIndex,
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    39
    client' :: c
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    40
    }
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    41
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    42
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    43
newtype RoomIndex = RoomIndex ElemIndex
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    44
    deriving (Eq)
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    45
newtype ClientIndex = ClientIndex ElemIndex
3435
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
    46
    deriving (Eq, Show, Read)
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    47
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    48
instance Show RoomIndex where
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    49
    show (RoomIndex i) = 'r' : show i
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    50
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    51
unRoomIndex :: RoomIndex -> ElemIndex
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    52
unRoomIndex (RoomIndex r) = r
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    53
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    54
unClientIndex :: ClientIndex -> ElemIndex
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    55
unClientIndex (ClientIndex c) = c
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    56
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    57
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    58
newtype MRoomsAndClients r c = MRoomsAndClients (MStore (Room r), MStore (Client c))
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    59
newtype IRoomsAndClients r c = IRoomsAndClients (IStore (Room r), IStore (Client c))
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    60
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    61
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    62
lobbyId :: RoomIndex
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    63
lobbyId = RoomIndex firstIndex
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    64
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    65
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    66
newRoomsAndClients :: r -> IO (MRoomsAndClients r c)
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    67
newRoomsAndClients r = do
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    68
    rooms <- newStore
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    69
    clients <- newStore
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    70
    let rnc = MRoomsAndClients (rooms, clients)
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    71
    ri <- addRoom rnc r
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    72
    when (ri /= lobbyId) $ error "Empty struct inserts not at firstIndex index"
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    73
    return rnc
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    74
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    75
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    76
roomAddClient :: ClientIndex -> Room r -> Room r
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    77
roomAddClient cl room = room{roomClients' = cl : roomClients' room}
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    78
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    79
roomRemoveClient :: ClientIndex -> Room r -> Room r
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    80
roomRemoveClient cl room = room{roomClients' = filter (/= cl) $ roomClients' room}
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    81
3435
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
    82
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    83
addRoom :: MRoomsAndClients r c -> r -> IO RoomIndex
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    84
addRoom (MRoomsAndClients (rooms, _)) room = do
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    85
    i <- addElem rooms (Room  [] room)
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    86
    return $ RoomIndex i
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    87
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    88
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    89
addClient :: MRoomsAndClients r c -> c -> IO ClientIndex
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    90
addClient (MRoomsAndClients (rooms, clients)) client = do
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    91
    i <- addElem clients (Client lobbyId client)
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    92
    modifyElem rooms (roomAddClient (ClientIndex i)) rid
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    93
    return $ ClientIndex i
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    94
    where
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    95
        rid = (\(RoomIndex i) -> i) lobbyId
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    96
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    97
removeRoom :: MRoomsAndClients r c -> RoomIndex -> IO ()
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    98
removeRoom rnc@(MRoomsAndClients (rooms, _)) room@(RoomIndex ri) 
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
    99
    | room == lobbyId = error "Cannot delete lobby"
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   100
    | otherwise = do
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   101
        clIds <- liftM roomClients' $ readElem rooms ri
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   102
        forM_ clIds (moveClientToLobby rnc)
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   103
        removeElem rooms ri
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   104
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   105
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   106
removeClient :: MRoomsAndClients r c -> ClientIndex -> IO ()
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   107
removeClient (MRoomsAndClients (rooms, clients)) cl@(ClientIndex ci) = do
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   108
    RoomIndex ri <- liftM clientRoom' $ readElem clients ci
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   109
    modifyElem rooms (roomRemoveClient cl) ri
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   110
    removeElem clients ci
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   111
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   112
3436
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   113
modifyRoom :: MRoomsAndClients r c -> (r -> r) -> RoomIndex -> IO ()
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   114
modifyRoom (MRoomsAndClients (rooms, _)) f (RoomIndex ri) = modifyElem rooms (\r -> r{room' = f $ room' r}) ri
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   115
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   116
modifyClient :: MRoomsAndClients r c -> (c -> c) -> ClientIndex -> IO ()
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   117
modifyClient (MRoomsAndClients (_, clients)) f (ClientIndex ci) = modifyElem clients (\c -> c{client' = f $ client' c}) ci
288fcbdb77b6 Make server build again (it's still useless though)
unc0rr
parents: 3435
diff changeset
   118
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   119
moveClientInRooms :: MRoomsAndClients r c -> RoomIndex -> RoomIndex -> ClientIndex -> IO ()
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   120
moveClientInRooms (MRoomsAndClients (rooms, clients)) (RoomIndex riFrom) rt@(RoomIndex riTo) cl@(ClientIndex ci) = do
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   121
    modifyElem rooms (roomRemoveClient cl) riFrom
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   122
    modifyElem rooms (roomAddClient cl) riTo
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   123
    modifyElem clients (\c -> c{clientRoom' = rt}) ci
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   124
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   125
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   126
moveClientToLobby :: MRoomsAndClients r c -> ClientIndex -> IO ()
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   127
moveClientToLobby rnc ci = do
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   128
    room <- clientRoomM rnc ci
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   129
    moveClientInRooms rnc room lobbyId ci
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   130
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   131
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   132
moveClientToRoom :: MRoomsAndClients r c -> RoomIndex -> ClientIndex -> IO ()
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   133
moveClientToRoom rnc ri ci = moveClientInRooms rnc lobbyId ri ci
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   134
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   135
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   136
clientRoomM :: MRoomsAndClients r c -> ClientIndex -> IO RoomIndex
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   137
clientRoomM (MRoomsAndClients (_, clients)) (ClientIndex ci) = liftM clientRoom' (clients `readElem` ci)
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   138
3458
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3436
diff changeset
   139
clientsM :: MRoomsAndClients r c -> (c -> a) -> ClientIndex -> IO a
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3436
diff changeset
   140
clientsM (MRoomsAndClients (_, clients)) f (ClientIndex ci) = liftM (f . client') (clients `readElem` ci)
11cd56019f00 Make some more protocol commands work
unc0rr
parents: 3436
diff changeset
   141
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   142
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   143
withRoomsAndClients :: MRoomsAndClients r c -> (IRoomsAndClients r c -> a) -> IO a
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   144
withRoomsAndClients (MRoomsAndClients (rooms, clients)) f =
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   145
    withIStore2 rooms clients (\r c -> f $ IRoomsAndClients (r, c))
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   146
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   147
----------------------------------------
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   148
----------- IRoomsAndClients -----------
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   149
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   150
showRooms :: (Show r, Show c) => IRoomsAndClients r c -> String
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   151
showRooms rnc@(IRoomsAndClients (rooms, clients)) = concatMap showRoom (allRooms rnc)
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   152
    where
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   153
    showRoom r = unlines $ ((show r) ++ ": " ++ (show $ room' $ rooms ! (unRoomIndex r))) : (map showClient (roomClients' $ rooms ! (unRoomIndex r)))
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   154
    showClient c = "    " ++ (show c) ++ ": " ++ (show $ client' $ clients ! (unClientIndex c))
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   155
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   156
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   157
allRooms :: IRoomsAndClients r c -> [RoomIndex]
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   158
allRooms (IRoomsAndClients (rooms, _)) = map RoomIndex $ indices rooms
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   159
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   160
allClients :: IRoomsAndClients r c -> [ClientIndex]
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   161
allClients (IRoomsAndClients (_, clients)) = map ClientIndex $ indices clients
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   162
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   163
3435
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
   164
clientRoom :: IRoomsAndClients r c -> ClientIndex -> RoomIndex
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
   165
clientRoom (IRoomsAndClients (_, clients)) (ClientIndex ci) = clientRoom' (clients ! ci)
3425
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   166
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   167
client :: IRoomsAndClients r c -> ClientIndex -> c
ead2ed20dfd4 Start the server refactoring
unc0rr
parents:
diff changeset
   168
client (IRoomsAndClients (_, clients)) (ClientIndex ci) = client' (clients ! ci)
3435
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
   169
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
   170
roomClients :: IRoomsAndClients r c -> RoomIndex -> [ClientIndex]
4e4f88a7bdf2 Some more steps in refactoring
unc0rr
parents: 3425
diff changeset
   171
roomClients (IRoomsAndClients (rooms, _)) (RoomIndex ri) = roomClients' $ (rooms ! ri)