module Eventloop.System.InitializationThread ( startInitializing ) where import Control.Exception import Control.Concurrent.STM import Data.List import Eventloop.Types.Exception import Eventloop.Types.System startInitializing :: EventloopSystemConfiguration progstateT -> IO (EventloopSystemConfiguration progstateT) startInitializing systemConfig = do sharedIO <- readTVarIO sharedIOT_ (sharedConst', sharedIO', moduleConfigs_') <- initializeModules sharedConst sharedIO moduleConfigs_ atomically $ writeTVar sharedIOT_ sharedIO' return systemConfig{moduleConfigs = reverse $ moduleConfigs_', sharedIOConstants = sharedConst'} where sharedConst = sharedIOConstants systemConfig sharedIOT_ = sharedIOStateT systemConfig moduleConfigs_ = reverse $ moduleConfigs systemConfig initializeModules :: SharedIOConstants -> SharedIOState -> [EventloopModuleConfiguration] -> IO (SharedIOConstants, SharedIOState, [EventloopModuleConfiguration]) initializeModules sharedConst sharedIO [] = return (sharedConst, sharedIO, []) initializeModules sharedConst sharedIO (moduleConfig:configs) = do (sharedConst', sharedIO', moduleConfig') <- initializeModule sharedConst sharedIO moduleConfig (sharedConst'', sharedIO'', configs') <- initializeModules sharedConst' sharedIO' configs return (sharedConst'', sharedIO'', moduleConfig':configs') initializeModule :: SharedIOConstants -> SharedIOState -> EventloopModuleConfiguration -> IO (SharedIOConstants, SharedIOState, EventloopModuleConfiguration) initializeModule sharedConst sharedIO moduleConfig = case (initializerM moduleConfig) of Nothing -> return (sharedConst, sharedIO, moduleConfig) (Just initializer) -> handle ( \exception -> throwIO (InitializationException moduleId_ exception) ) ( do ioState <- readTVarIO ioStateT_ (sharedConst', sharedIO', ioConst', ioState') <- initializer sharedConst sharedIO atomically $ writeTVar ioStateT_ ioState' return (sharedConst', sharedIO', moduleConfig {ioConstants = ioConst'}) ) where moduleId_ = moduleId moduleConfig ioConst = ioConstants moduleConfig ioStateT_ = ioStateT moduleConfig