module Gamgine.Engine where import Graphics.UI.GLFW (getTime) import Control.Monad.State (MonadIO, liftIO) import Control.Applicative ((<$>)) import Data.Maybe (fromMaybe) mkUpdateLoop :: (MonadIO m) => Int -> Int -> m a -> (Double -> m (Double, Double)) mkUpdateLoop :: forall (m :: * -> *) a. MonadIO m => Int -> Int -> m a -> Double -> m (Double, Double) mkUpdateLoop Int ticksPerSecond Int maxFrameSkip m a update = \Double nextFrame -> Double -> Int -> m (Double, Double) loop Double nextFrame Int 0 where loop :: Double -> Int -> m (Double, Double) loop Double nextFrame Int skippedFrames = do Double time <- IO Double -> m Double forall a. IO a -> m a forall (m :: * -> *) a. MonadIO m => IO a -> m a liftIO (Double -> Maybe Double -> Double forall a. a -> Maybe a -> a fromMaybe Double nextFrame (Maybe Double -> Double) -> IO (Maybe Double) -> IO Double forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> IO (Maybe Double) getTime) if Double time Double -> Double -> Bool forall a. Ord a => a -> a -> Bool > Double nextFrame Bool -> Bool -> Bool && Int skippedFrames Int -> Int -> Bool forall a. Ord a => a -> a -> Bool < Int maxFrameSkip then do m a update Double -> Int -> m (Double, Double) loop (Double nextFrame Double -> Double -> Double forall a. Num a => a -> a -> a + Double skipTicks) (Int skippedFrames Int -> Int -> Int forall a. Num a => a -> a -> a + Int 1) else do let interpol :: Double interpol = Double -> Double -> Double -> Double forall {a}. Fractional a => a -> a -> a -> a interpolation Double time Double nextFrame Double skipTicks (Double, Double) -> m (Double, Double) forall a. a -> m a forall (m :: * -> *) a. Monad m => a -> m a return (Double nextFrame, Double interpol) interpolation :: a -> a -> a -> a interpolation a time a nextFrame a skipTicks = (a time a -> a -> a forall a. Num a => a -> a -> a - a skipTicks a -> a -> a forall a. Num a => a -> a -> a - a nextFrame) a -> a -> a forall a. Fractional a => a -> a -> a / a skipTicks skipTicks :: Double skipTicks = Double 1 Double -> Double -> Double forall a. Fractional a => a -> a -> a / (Int -> Double forall a b. (Integral a, Num b) => a -> b fromIntegral Int ticksPerSecond :: Double)