{-# LANGUAGE Arrows #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE NamedFieldPuns #-}
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE TypeFamilies #-}
module FRP.Rhine.Gloss.Internals where
import qualified Control.Category as Category
import Data.Functor.Identity (Identity)
import Control.Monad.Trans.MSF.Reader (readerS, runReaderS)
import Graphics.Gloss.Interface.Pure.Game
import FRP.Rhine hiding (readerS, runReaderS)
errMsg :: String
errMsg = unwords
[ "You cannot start pure rhine-gloss apps with FRP.Rhine.flow,"
, "since gloss has its own main loop."
, "Use FRP.Rhine.Gloss.flowGloss instead."
]
data GlossEventClock = GlossEventClock
instance Clock m GlossEventClock where
type Time GlossEventClock = ()
type Tag GlossEventClock = Event
initClock _ = error errMsg
data GlossSimulationClock_ = GlossSimulationClock_
instance Clock m GlossSimulationClock_ where
type Time GlossSimulationClock_ = ()
type Tag GlossSimulationClock_ = Float
initClock _ = error errMsg
data GlossSimulationClock = GlossSimulationClock
instance Clock m GlossSimulationClock where
type Time GlossSimulationClock = Float
type Tag GlossSimulationClock = ()
initClock _ = error errMsg
withProperSimClock
:: Monad m
=> ClSF m GlossSimulationClock a b
-> ClSF m GlossSimulationClock_ a b
withProperSimClock clsf = readerS
$ (intermingle *** Category.id) >>> runReaderS clsf
where
intermingle :: Monad m => MSF m (TimeInfo GlossSimulationClock_) (TimeInfo GlossSimulationClock)
intermingle = proc TimeInfo {tag} -> do
let sinceLast = tag
absolute <- sumS -< sinceLast
let sinceInit = absolute
returnA -< TimeInfo { tag = (), .. }
data GlossGraphicsClock = GlossGraphicsClock
instance Clock m GlossGraphicsClock where
type Time GlossGraphicsClock = ()
type Tag GlossGraphicsClock = ()
initClock _ = error errMsg
glossSchedule :: Schedule Identity (SelectClock GlossEventClock a) GlossSimulationClock_
glossSchedule = error errMsg