packages feed

eventloop-0.5.1.0: src/Eventloop/Types/System.hs

module Eventloop.Types.System where

import Control.Concurrent
import Control.Concurrent.ExceptionCollection
import Control.Concurrent.MVar
import Control.Concurrent.Thread
import Control.Concurrent.SafePrint
import Control.Concurrent.Datastructures.BlockingConcurrentQueue
import Data.Maybe

import Eventloop.Module.Websocket.Keyboard.Types
import Eventloop.Module.Websocket.Mouse.Types
import Eventloop.Module.Websocket.Canvas.Types
import Eventloop.Module.File.Types
import Eventloop.Module.StatefulGraphics.Types
import Eventloop.Module.StdIn.Types
import Eventloop.Module.StdOut.Types
import Eventloop.Module.Timer.Types

import Eventloop.Types.Common
import Eventloop.Types.Events
import Eventloop.Types.Exception
import qualified Eventloop.Utility.Websockets as WS
import qualified Eventloop.Utility.BufferedWebsockets as BWS


type Initializer = SharedIOState -> IO (SharedIOState, IOState)
type EventRetriever = SharedIOState -> IOState -> IO (SharedIOState, IOState, [In])
type PreProcessor = SharedIOState -> IOState -> In -> IO (SharedIOState, IOState, [In])
type PostProcessor = SharedIOState -> IOState -> Out -> IO (SharedIOState, IOState, [Out])
type EventSender = SharedIOState -> IOState -> Out -> IO (SharedIOState, IOState)
type Teardown = SharedIOState -> IOState -> IO SharedIOState

type OutEventRouter = Out -> EventloopModuleIdentifier

type InEventQueue = BlockingConcurrentQueue In
type OutEventQueue = BlockingConcurrentQueue Out
type SenderEventQueue = BlockingConcurrentQueue Out

-- System Configurations
data EventloopModuleConfiguration
    = EventloopModuleConfiguration { moduleId :: EventloopModuleIdentifier
                                   , iostateM :: MVar IOState
                                   , initializerM :: Maybe Initializer
                                   , retrieverM :: Maybe EventRetriever
                                   , preprocessorM :: Maybe PreProcessor
                                   , postprocessorM :: Maybe PostProcessor
                                   , senderConfigM :: Maybe EventloopModuleSenderConfiguration
                                   , teardownM :: Maybe Teardown
                                   }
    
    
data EventloopModuleSenderConfiguration 
    = EventloopModuleSenderConfiguration { sender :: EventSender
                                         , senderEventQueue :: BlockingConcurrentQueue Out
                                         }

                                         
data EventloopConfiguration progstateT
    = EventloopConfiguration { progstateM :: MVar progstateT
                             , eventloopFunc :: progstateT -> In -> (progstateT, [Out])
                             , inEventQueue :: InEventQueue
                             , outEventQueue :: OutEventQueue
                             }
                               

data EventloopSystemConfiguration progstateT
    = EventloopSystemConfiguration { eventloopConfig :: EventloopConfiguration progstateT
                                   , moduleConfigs :: [EventloopModuleConfiguration]
                                   , sharedIOStateM :: MVar SharedIOState
                                   , systemThreadId :: ThreadId
                                   , retrieverThreadsM :: MVar [Thread]
                                   , outRouterThreadM :: MVar Thread
                                   , senderThreadsM :: MVar [Thread]
                                   , exceptions :: ExceptionCollection EventloopException
                                   , isStoppingM :: MVar Bool
                                   }
                        
-- Setup Configurations
data EventloopSetupConfiguration progstateT
    = EventloopSetupConfiguration { beginProgstate :: progstateT
                                  , eventloopF :: progstateT -> In -> (progstateT, [Out])
                                  , setupModuleConfigurations :: [EventloopSetupModuleConfiguration]
                                  }
         
         
data EventloopSetupModuleConfiguration
    = EventloopSetupModuleConfiguration { moduleIdentifier :: EventloopModuleIdentifier
                                        , initializerF :: Maybe Initializer
                                        , eventRetrieverF :: Maybe EventRetriever
                                        , preprocessorF :: Maybe PreProcessor
                                        , postprocessorF :: Maybe PostProcessor
                                        , eventSenderF :: Maybe EventSender
                                        , teardownF :: Maybe Teardown
                                        }
         
         
-- Shared IO State
data SharedIOState = SharedIOState { safePrintToken :: SafePrintToken
                                   , measureText :: CanvasText -> IO ScreenDimensions
                                   }
         
-- Modules IO State
data IOState = MouseState { receiveBuffer        :: BWS.BufferedReceiveBuffer
                          , clientSocket         :: BWS.ClientSocket
                          , clientConnection     :: BWS.Connection
                          , serverSocket         :: BWS.ServerSocket
                          , bufferedReaderThread :: BWS.BufferedReaderThread
                          }
             | KeyboardState { receiveBuffer    :: BWS.BufferedReceiveBuffer
                             , clientSocket     :: BWS.ClientSocket
                             , clientConnection :: BWS.Connection
                             , serverSocket     :: BWS.ServerSocket
                             , bufferedReaderThread :: BWS.BufferedReaderThread
                             }
             | CanvasState { commonReceiveBuffer       :: WS.ReceiveBuffer
                           , canvasUserReceiveBuffer   :: CanvasUserReceiveBuffer
                           , canvasSystemReceiveBuffer :: CanvasSystemReceiveBuffer
                           , clientSocket              :: WS.ClientSocket
                           , clientConnection          :: WS.Connection
                           , serverSocket              :: WS.ServerSocket
                           , unbufferedReaderThread    :: WS.UnbufferedReaderThread
                           , routerThread              :: Thread
                           }
             | StdInState { newStdInInEvents :: [StdInIn] 
                          }
             | TimerState { startedIntervalTimers      :: [StartedTimer]
                          , startedTimers              :: [StartedTimer]
                          , incomingIntervalTickBuffer :: IncomingTickBuffer
                          , incomingTickBuffer         :: IncomingTickBuffer
                          }
             | FileState { newFileInEvents :: [FileIn]
                         , opened          :: [OpenFile]
                         }
             | StatefulGraphicsState { states :: GraphicsStates
                                     }
             | NoState