{-# LANGUAGE RankNTypes #-}
{-# OPTIONS_HADDOCK hide #-}
module Graphics.Gloss.Internals.Interface.Animate.Timing
( animateBegin
, animateEnd )
where
import Graphics.Gloss.Internals.Interface.Backend
import Graphics.Gloss.Internals.Interface.Animate.State
import Control.Monad
import Data.IORef
animateBegin :: IORef State -> DisplayCallback
animateBegin :: IORef State -> DisplayCallback
animateBegin IORef State
stateRef IORef a
backendRef
= do
displayTime <- IORef a -> IO Double
forall a. Backend a => IORef a -> IO Double
elapsedTime IORef a
backendRef
displayTimeLast <- stateRef `getsIORef` stateDisplayTime
let displayTimeElapsed = Double
displayTime Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
displayTimeLast
modifyIORef' stateRef $ \State
s -> State
s
{ stateDisplayTime = displayTime
, stateDisplayTimeLast = displayTimeLast }
animate <- stateRef `getsIORef` stateAnimate
animateCount <- stateRef `getsIORef` stateAnimateCount
animateTime <- stateRef `getsIORef` stateAnimateTime
animateStart <- stateRef `getsIORef` stateAnimateStart
when (animate && not animateStart)
$ modifyIORef' stateRef $ \State
s -> State
s
{ stateAnimateTime = animateTime + displayTimeElapsed }
when animate
$ modifyIORef' stateRef $ \State
s -> State
s
{ stateAnimateCount = animateCount + 1
, stateAnimateStart = False }
animateEnd :: IORef State -> DisplayCallback
animateEnd :: IORef State -> DisplayCallback
animateEnd IORef State
stateRef IORef a
backendRef
= do
timeClamp <- IORef State
stateRef IORef State -> (State -> Double) -> IO Double
forall a r. IORef a -> (a -> r) -> IO r
`getsIORef` State -> Double
stateDisplayTimeClamp
gateTimeStart <- elapsedTime backendRef
gateTimeEnd <- stateRef `getsIORef` stateGateTimeEnd
let gateTimeElapsed = Double
gateTimeStart Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
gateTimeEnd
when (gateTimeElapsed < timeClamp)
$ do sleep backendRef (timeClamp - gateTimeElapsed)
gateTimeFinal <- elapsedTime backendRef
modifyIORef' stateRef $ \State
s -> State
s
{ stateGateTimeEnd = gateTimeFinal
, stateGateTimeElapsed = gateTimeElapsed }
getsIORef :: IORef a -> (a -> r) -> IO r
getsIORef :: forall a r. IORef a -> (a -> r) -> IO r
getsIORef IORef a
ref a -> r
fun
= (a -> r) -> IO a -> IO r
forall (m :: * -> *) a1 r. Monad m => (a1 -> r) -> m a1 -> m r
liftM a -> r
fun (IO a -> IO r) -> IO a -> IO r
forall a b. (a -> b) -> a -> b
$ IORef a -> IO a
forall a. IORef a -> IO a
readIORef IORef a
ref