packages feed

eventloop-0.5.0.0: src/Eventloop/Module/Websocket/Canvas/Canvas.hs

module Eventloop.Module.Websocket.Canvas.Canvas
    ( setupCanvasModuleConfiguration
    , canvasModuleIdentifier
    , canvasInitializer
    , canvasEventRetriever
    , canvasEventSender
    , canvasTeardown
    ) where

    
import Control.Concurrent
import Control.Concurrent.MVar
import Control.Concurrent.Thread
import Data.Aeson
import qualified Data.ByteString.Lazy.Char8 as LBS

import Eventloop.Module.Websocket.Canvas.Types
import Eventloop.Module.Websocket.Canvas.JSONEncoding
import Eventloop.Types.Common
import Eventloop.Types.Events
import Eventloop.Types.System
import Eventloop.Utility.Config
import qualified Eventloop.Utility.Websockets as WS


setupCanvasModuleConfiguration :: EventloopSetupModuleConfiguration
setupCanvasModuleConfiguration = ( EventloopSetupModuleConfiguration 
                                        canvasModuleIdentifier
                                        (Just canvasInitializer)
                                        (Just canvasEventRetriever)
                                        Nothing
                                        Nothing
                                        (Just canvasEventSender)
                                        (Just canvasTeardown)
                                      )
                                      
                                      
canvasModuleIdentifier :: EventloopModuleIdentifier
canvasModuleIdentifier = "canvas"


canvasInitializer :: Initializer
canvasInitializer sharedIO
    = do
        (comRecvBuffer, clientSocket, clientConn, serverSock, unbufferedReaderThread) <- WS.setupWebsocketConnection ipAddress canvasPort
        putStrLn "Canvas connection successfull!"
        userRecvBuffer <- newMVar []
        sysRecvBuffer <- newEmptyMVar
        routerThread <- forkThread (router comRecvBuffer userRecvBuffer sysRecvBuffer)
        --TODO Add measuretext to sharedIO
        return (sharedIO, CanvasState comRecvBuffer userRecvBuffer sysRecvBuffer clientSocket clientConn serverSock unbufferedReaderThread routerThread)


canvasEventRetriever :: EventRetriever
canvasEventRetriever sharedIO canvasState = do
                                                let
                                                    userRecvBuffer = canvasUserReceiveBuffer canvasState
                                                messages <- takeMVar userRecvBuffer
                                                putMVar userRecvBuffer []
                                                return (sharedIO, canvasState, (map InCanvas messages))

                                    
canvasEventSender :: EventSender
canvasEventSender sharedIO canvasState (OutCanvas canvasOut) = do
                                                        let
                                                          conn = clientConnection canvasState  
                                                        sendRoutedMessageOut conn (OutUserCanvas canvasOut)
                                                        return (sharedIO, canvasState)
                                    

                                    
canvasTeardown :: Teardown
canvasTeardown sharedIO canvasState
    = do
        WS.closeWebsocketConnection (serverSocket canvasState) (clientSocket canvasState) (clientConnection canvasState) (unbufferedReaderThread canvasState)
        terminateThread (routerThread canvasState)
        joinThread (routerThread canvasState)
        -- Todo teardown measureText websocket connection
        return sharedIO
    
    
sendRoutedMessageOut :: WS.Connection -> RoutedMessageOut -> IO ()
sendRoutedMessageOut conn out = WS.writeMessage conn $ LBS.unpack $ encode out


router :: WS.ReceiveBuffer -> CanvasUserReceiveBuffer -> CanvasSystemReceiveBuffer -> IO ()
router comRecvBuffer userRecvBuffer sysRecvBuffer = do
                                                        encodedRoutedIn <- takeMVar comRecvBuffer
                                                        let
                                                            Just routedIn = decode $ LBS.pack encodedRoutedIn :: Maybe RoutedMessageIn
                                                        case routedIn of
                                                            (InUserCanvas canvasIn)   -> do
                                                                                            ins <- takeMVar userRecvBuffer
                                                                                            putMVar userRecvBuffer (ins ++ [canvasIn])
                                                                                            nextStep
                                                            (InSystemCanvas canvasIn) -> do
                                                                                            putMVar sysRecvBuffer canvasIn
                                                                                            nextStep
                                                  where
                                                    nextStep = router comRecvBuffer userRecvBuffer sysRecvBuffer

                                                    
--TODO
measureText :: IOState -> CanvasId -> CanvasText -> IO ScreenDimensions
measureText canvasState canvasId canvasText = return (4,4)