{-# LANGUAGE OverloadedStrings #-}
module Discord.Internal.Gateway
( GatewayHandle(..)
, CacheHandle(..)
, GatewayException(..)
, Cache(..)
, startCacheThread
, startGatewayThread
, module Discord.Internal.Types
) where
import Prelude hiding (log)
import Control.Concurrent.Chan (newChan, dupChan, Chan)
import Control.Concurrent (forkIO, ThreadId, newEmptyMVar, MVar)
import Data.IORef (newIORef)
import qualified Data.Text as T
import Discord.Internal.Types (Auth, EventInternalParse, GatewayIntent)
import Discord.Internal.Gateway.EventLoop (connectionLoop, GatewayHandle(..), GatewayException(..))
import Discord.Internal.Gateway.Cache (cacheLoop, Cache(..), CacheHandle(..))
startCacheThread :: Chan T.Text -> IO (CacheHandle, ThreadId)
startCacheThread :: Chan Text -> IO (CacheHandle, ThreadId)
startCacheThread Chan Text
log = do
Chan (Either GatewayException EventInternalParse)
events <- forall a. IO (Chan a)
newChan :: IO (Chan (Either GatewayException EventInternalParse))
MVar (Either (Cache, GatewayException) Cache)
cache <- forall a. IO (MVar a)
newEmptyMVar :: IO (MVar (Either (Cache, GatewayException) Cache))
let cacheHandle :: CacheHandle
cacheHandle = Chan (Either GatewayException EventInternalParse)
-> MVar (Either (Cache, GatewayException) Cache) -> CacheHandle
CacheHandle Chan (Either GatewayException EventInternalParse)
events MVar (Either (Cache, GatewayException) Cache)
cache
ThreadId
tid <- IO () -> IO ThreadId
forkIO forall a b. (a -> b) -> a -> b
$ CacheHandle -> Chan Text -> IO ()
cacheLoop CacheHandle
cacheHandle Chan Text
log
forall (f :: * -> *) a. Applicative f => a -> f a
pure (CacheHandle
cacheHandle, ThreadId
tid)
startGatewayThread :: Auth -> GatewayIntent -> CacheHandle -> Chan T.Text -> IO (GatewayHandle, ThreadId)
startGatewayThread :: Auth
-> GatewayIntent
-> CacheHandle
-> Chan Text
-> IO (GatewayHandle, ThreadId)
startGatewayThread Auth
auth GatewayIntent
intent CacheHandle
cacheHandle Chan Text
log = do
Chan (Either GatewayException EventInternalParse)
events <- forall a. Chan a -> IO (Chan a)
dupChan (CacheHandle -> Chan (Either GatewayException EventInternalParse)
cacheHandleEvents CacheHandle
cacheHandle)
Chan GatewaySendable
sends <- forall a. IO (Chan a)
newChan
IORef (Maybe UpdateStatusOpts)
status <- forall a. a -> IO (IORef a)
newIORef forall a. Maybe a
Nothing
IORef Integer
seqid <- forall a. a -> IO (IORef a)
newIORef Integer
0
IORef Text
seshid <- forall a. a -> IO (IORef a)
newIORef Text
""
IORef HostName
host <- forall a. a -> IO (IORef a)
newIORef forall a b. (a -> b) -> a -> b
$ HostName
"gateway.discord.gg"
let gatewayHandle :: GatewayHandle
gatewayHandle = Chan (Either GatewayException EventInternalParse)
-> Chan GatewaySendable
-> IORef (Maybe UpdateStatusOpts)
-> IORef Integer
-> IORef Text
-> IORef HostName
-> GatewayHandle
GatewayHandle Chan (Either GatewayException EventInternalParse)
events Chan GatewaySendable
sends IORef (Maybe UpdateStatusOpts)
status IORef Integer
seqid IORef Text
seshid IORef HostName
host
ThreadId
tid <- IO () -> IO ThreadId
forkIO forall a b. (a -> b) -> a -> b
$ Auth -> GatewayIntent -> GatewayHandle -> Chan Text -> IO ()
connectionLoop Auth
auth GatewayIntent
intent GatewayHandle
gatewayHandle Chan Text
log
forall (f :: * -> *) a. Applicative f => a -> f a
pure (GatewayHandle
gatewayHandle, ThreadId
tid)