{-# 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
Double
displayTime <- IORef a -> IO Double
forall a. Backend a => IORef a -> IO Double
elapsedTime IORef a
backendRef
Double
displayTimeLast <- IORef State
stateRef IORef State -> (State -> Double) -> IO Double
forall a r. IORef a -> (a -> r) -> IO r
`getsIORef` State -> Double
stateDisplayTime
let displayTimeElapsed :: Double
displayTimeElapsed = Double
displayTime Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
displayTimeLast
IORef State -> (State -> State) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef State
stateRef ((State -> State) -> IO ()) -> (State -> State) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State
s -> State
s
{ stateDisplayTime :: Double
stateDisplayTime = Double
displayTime
, stateDisplayTimeLast :: Double
stateDisplayTimeLast = Double
displayTimeLast }
Bool
animate <- IORef State
stateRef IORef State -> (State -> Bool) -> IO Bool
forall a r. IORef a -> (a -> r) -> IO r
`getsIORef` State -> Bool
stateAnimate
Integer
animateCount <- IORef State
stateRef IORef State -> (State -> Integer) -> IO Integer
forall a r. IORef a -> (a -> r) -> IO r
`getsIORef` State -> Integer
stateAnimateCount
Double
animateTime <- IORef State
stateRef IORef State -> (State -> Double) -> IO Double
forall a r. IORef a -> (a -> r) -> IO r
`getsIORef` State -> Double
stateAnimateTime
Bool
animateStart <- IORef State
stateRef IORef State -> (State -> Bool) -> IO Bool
forall a r. IORef a -> (a -> r) -> IO r
`getsIORef` State -> Bool
stateAnimateStart
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool
animate Bool -> Bool -> Bool
&& Bool -> Bool
not Bool
animateStart)
(IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ IORef State -> (State -> State) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef State
stateRef ((State -> State) -> IO ()) -> (State -> State) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State
s -> State
s
{ stateAnimateTime :: Double
stateAnimateTime = Double
animateTime Double -> Double -> Double
forall a. Num a => a -> a -> a
+ Double
displayTimeElapsed }
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
animate
(IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ IORef State -> (State -> State) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef State
stateRef ((State -> State) -> IO ()) -> (State -> State) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State
s -> State
s
{ stateAnimateCount :: Integer
stateAnimateCount = Integer
animateCount Integer -> Integer -> Integer
forall a. Num a => a -> a -> a
+ Integer
1
, stateAnimateStart :: Bool
stateAnimateStart = Bool
False }
animateEnd :: IORef State -> DisplayCallback
animateEnd :: IORef State -> DisplayCallback
animateEnd IORef State
stateRef IORef a
backendRef
= do
Double
timeClamp <- IORef State
stateRef IORef State -> (State -> Double) -> IO Double
forall a r. IORef a -> (a -> r) -> IO r
`getsIORef` State -> Double
stateDisplayTimeClamp
Double
gateTimeStart <- IORef a -> IO Double
forall a. Backend a => IORef a -> IO Double
elapsedTime IORef a
backendRef
Double
gateTimeEnd <- IORef State
stateRef IORef State -> (State -> Double) -> IO Double
forall a r. IORef a -> (a -> r) -> IO r
`getsIORef` State -> Double
stateGateTimeEnd
let gateTimeElapsed :: Double
gateTimeElapsed = Double
gateTimeStart Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
gateTimeEnd
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Double
gateTimeElapsed Double -> Double -> Bool
forall a. Ord a => a -> a -> Bool
< Double
timeClamp)
(IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do IORef a -> Double -> IO ()
forall a. Backend a => IORef a -> Double -> IO ()
sleep IORef a
backendRef (Double
timeClamp Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
gateTimeElapsed)
Double
gateTimeFinal <- IORef a -> IO Double
forall a. Backend a => IORef a -> IO Double
elapsedTime IORef a
backendRef
IORef State -> (State -> State) -> IO ()
forall a. IORef a -> (a -> a) -> IO ()
modifyIORef' IORef State
stateRef ((State -> State) -> IO ()) -> (State -> State) -> IO ()
forall a b. (a -> b) -> a -> b
$ \State
s -> State
s
{ stateGateTimeEnd :: Double
stateGateTimeEnd = Double
gateTimeFinal
, stateGateTimeElapsed :: Double
stateGateTimeElapsed = Double
gateTimeElapsed }
getsIORef :: IORef a -> (a -> r) -> IO r
getsIORef :: 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