module Engine.StageSwitch ( StageSwitchVar , newStageSwitchVar , StageSwitch(..) , trySwitchStage , trySwitchStageSTM , getNextStage ) where import RIO import RIO.App (appEnv) import Engine.Types (NextStage, StageRIO, StageSwitch(..), StageSwitchVar) import Engine.Types qualified as Engine newStageSwitchVar :: MonadIO m => m StageSwitchVar newStageSwitchVar = newEmptyTMVarIO trySwitchStage :: NextStage -> StageRIO rs Bool trySwitchStage nextStage = do var <- asks $ Engine.ghStageSwitch . appEnv atomically $ trySwitchStageSTM var nextStage trySwitchStageSTM :: StageSwitchVar -> NextStage -> STM Bool trySwitchStageSTM switchVar = tryPutTMVar switchVar . StageSwitchPending getNextStage :: StageRIO rs (Maybe NextStage) getNextStage = do var <- asks $ Engine.ghStageSwitch . appEnv atomically do noSwitch <- isEmptyTMVar var if noSwitch then pure Nothing else takeTMVar var >>= \case StageSwitchPending nextStage -> do putTMVar var StageSwitchHandled pure $ Just nextStage StageSwitchHandled -> pure Nothing