Holumbus-Distribution-0.1.0: Examples/Distribution/ChatDFunction/InterfacesDFunction.hs
-- ----------------------------------------------------------------------------
{- |
Module : Holumbus
Copyright : Copyright (C) 2009 Stefan Schmidt
License : MIT
Maintainer : Stefan Schmidt (stefanschmidt@web.de)
Stability : experimental
Portability: portable
Version : 0.1
-}
-- ----------------------------------------------------------------------------
module InterfacesDFunction
(
RegisterClientFunction
, UnregisterClientFunction
, SendChatMessageFunction
, ServerInterfaceStub
, RemoteServerInterface(..)
, createLocalServerInterfaceStub
, closeLocalServerInterfaceStub
, createRemoveServerInterface
, ReceiveChatMessageFunction
, ClientInterfaceStub
, RemoteClientInterface(..)
, createLocalClientInterfaceStub
, closeLocalClientInterfaceStub
, createRemoteClientInterface
)
where
import Data.Binary
import Holumbus.Distribution.DNode
import Holumbus.Distribution.DFunction
-- ----------------------------------------------------------------------------
-- the servers' interface
-- ----------------------------------------------------------------------------
-- functions of the chat server
type RegisterClientFunction = String -> DNodeId -> ClientInterfaceStub -> IO (Maybe Int)
type UnregisterClientFunction = Int -> IO ()
type SendChatMessageFunction = Int -> String -> IO ()
-- in theory this could be made binary, but we don't need this
data ServerInterfaceStub = ServerInterfaceStub {
sifs_register :: DFunction RegisterClientFunction
, sifs_unregister :: DFunction UnregisterClientFunction
, sifs_send :: DFunction SendChatMessageFunction
}
-- this cannot be binary, but it is much nicer to call the real functions
data RemoteServerInterface = RemoteServerInterface {
sif_register :: RegisterClientFunction
, sif_unregister :: UnregisterClientFunction
, sif_send :: SendChatMessageFunction
}
createLocalServerInterfaceStub
:: RegisterClientFunction
-> UnregisterClientFunction
-> SendChatMessageFunction
-> IO ServerInterfaceStub
createLocalServerInterfaceStub f1 f2 f3
= do
df1 <- newDFunction "register" f1
df2 <- newDFunction "unregister" f2
df3 <- newDFunction "send" f3
return (ServerInterfaceStub df1 df2 df3)
closeLocalServerInterfaceStub :: ServerInterfaceStub -> IO ()
closeLocalServerInterfaceStub (ServerInterfaceStub df1 df2 df3)
= do
closeDFunction df1
closeDFunction df2
closeDFunction df3
createRemoveServerInterface :: String -> IO RemoteServerInterface
createRemoveServerInterface sn
= do
f1 <- mkNamedServerFunction "register" sn
f2 <- mkNamedServerFunction "unregister" sn
f3 <- mkNamedServerFunction "send" sn
return (RemoteServerInterface f1 f2 f3)
where
mkNamedServerFunction :: (BinaryFunction a) => String -> String -> IO a
mkNamedServerFunction fn sn
= do
df <- newRemoteDFunction fn sn
return (accessDFunction df)
-- ----------------------------------------------------------------------------
-- the client's interface
-- ----------------------------------------------------------------------------
-- functions of the client
type ReceiveChatMessageFunction = String -> String -> IO ()
-- this needs to be binary, because we send this to the server
data ClientInterfaceStub = ClientInterfaceStub {
cifs_receive :: DFunction ReceiveChatMessageFunction
}
instance Binary ClientInterfaceStub where
put (ClientInterfaceStub f1) = put f1
get = get >>= \f1 -> return (ClientInterfaceStub f1)
-- this cannot be binary, but it is much nicer to call the real functions
data RemoteClientInterface = RemoteClientInterface {
cif_receive :: ReceiveChatMessageFunction
}
createLocalClientInterfaceStub :: ReceiveChatMessageFunction -> IO ClientInterfaceStub
createLocalClientInterfaceStub f1
= do
df1 <- newDFunction "receive" f1
return (ClientInterfaceStub df1)
closeLocalClientInterfaceStub :: ClientInterfaceStub -> IO ()
closeLocalClientInterfaceStub (ClientInterfaceStub df1)
= do
closeDFunction df1
createRemoteClientInterface :: ClientInterfaceStub -> RemoteClientInterface
createRemoteClientInterface (ClientInterfaceStub df1)
= (RemoteClientInterface f1)
where
f1 = (accessDFunction df1)