module Graphics.Gloss.Internals.Interface.Animate.Timing
( animateBegin
, animateEnd )
where
import Graphics.Gloss.Internals.Interface.Animate.State
import Control.Monad
import Control.Concurrent
import Data.IORef
import qualified Graphics.UI.GLUT as GLUT
import Graphics.UI.GLUT (get)
animateBegin :: IORef State -> IO ()
animateBegin stateRef
= do
displayTime <- get GLUT.elapsedTime
displayTimeLast <- stateRef `getsIORef` stateDisplayTime
let displayTimeElapsed = displayTime displayTimeLast
stateRef `modifyIORef` \s -> s
{ stateDisplayTime = displayTime
, stateDisplayTimeLast = displayTimeLast }
animate <- stateRef `getsIORef` stateAnimate
animateTime <- stateRef `getsIORef` stateAnimateTime
animateStart <- stateRef `getsIORef` stateAnimateStart
when (animate && not animateStart)
$ do stateRef `modifyIORef` \s -> s
{ stateAnimateTime = animateTime + displayTimeElapsed }
when animate
$ do stateRef `modifyIORef` \s -> s
{ stateAnimateStart = False }
animateEnd :: IORef State -> IO ()
animateEnd stateRef
= do
timeClamp <- stateRef `getsIORef` stateDisplayTimeClamp
gateTimeStart <- get GLUT.elapsedTime
gateTimeEnd <- stateRef `getsIORef` stateGateTimeEnd
let gateTimeElapsed
= gateTimeStart gateTimeEnd
when (gateTimeElapsed < timeClamp)
$ do threadDelay ((timeClamp gateTimeElapsed) * 1000)
gateTimeFinal <- get GLUT.elapsedTime
stateRef `modifyIORef` \s -> s
{ stateGateTimeEnd = gateTimeFinal
, stateGateTimeElapsed = gateTimeElapsed }
getsIORef :: IORef a -> (a -> r) -> IO r
getsIORef ref fun
= liftM fun $ readIORef ref