module Graphics.Gloss.Interface.FRP.Yampa (playYampa, InputEvent) where import Control.Monad (when) import Data.IORef (newIORef, readIORef, writeIORef) import FRP.Yampa (Event (..), SF, react, reactInit) import Graphics.Gloss (Color, Display, Picture, blank) import qualified Graphics.Gloss import Graphics.Gloss.Interface.IO.Game (playIO) import qualified Graphics.Gloss.Interface.IO.Game as G type InputEvent = G.Event -- | Play the game in a window, updating when the value of the provided playYampa :: Display -- ^ The display method -> Color -- ^ The background color -> Int -- ^ The refresh rate, in Hertz -> SF (Event InputEvent) Picture -> IO () playYampa display color frequency mainSF = do picRef <- newIORef blank handle <- reactInit (return NoEvent) (\_ updated pic -> when updated (picRef `writeIORef` pic) >> return False) mainSF let delta = 0.01 / fromIntegral frequency -- An action to convert the world to a picture toPic = (const $ readIORef picRef) -- A function to handle input events handleInput = (\e t -> react handle (delta, Just (Event e)) >> return (t + delta)) -- A function to step the world one iteration. It is passed the period -- of time (in seconds) needing to be advanced stepWorld = (\d t -> let delta' = realToFrac d - t in if delta' > 0 then react handle (delta', Just NoEvent) >> return 0.0 else return (-delta')) playIO display color frequency 0 toPic handleInput stepWorld