gloss-banana-0.1.0.0: Graphics/Gloss/Interface/FRP/ReactiveBanana.hs
module Graphics.Gloss.Interface.FRP.ReactiveBanana (playBanana, InputEvent) where
import Graphics.Gloss
import Graphics.Gloss.Interface.IO.Game (playIO)
import qualified Graphics.Gloss.Interface.IO.Game as G
import Reactive.Banana
import Reactive.Banana.Frameworks
import Data.IORef (IORef, newIORef, readIORef, writeIORef)
-- | A useful type synonym for Gloss event values, to avoid confusion between
-- Gloss and ReactiveBanana.
type InputEvent = G.Event
-- | Play the game in a window, updating when the value of the provided
-- Behavior t Picture changes.
playBanana ∷ Display -- ^ The display method
→ Color -- ^ The background colour
→ Int -- ^ The refresh rate, in Hertz
→ (∀ t. Frameworks t
⇒ Event t Float
→ Event t InputEvent
→ Moment t (Behavior t Picture))
-- ^ A Moment t action to generate the Picture Behavior, taking
-- the refresh and input Events with respect to which to build it.
-- The refresh event generates a Float indicating the time delta
-- since the last refresh.
→ IO ()
playBanana display colour frequency mPicture = do
pictureref ← newIORef blank
(tickHandler, tick) ← newAddHandler
(eventHandler, event) ← newAddHandler
compile (makeNetwork tickHandler eventHandler $ change pictureref) >>= actuate
playIO display colour frequency ()
(\ _ → readIORef pictureref)
(\ ev _ → () <$ event ev)
(\ time _ → () <$ tick time)
where
change ∷ IORef Picture → Picture → IO ()
change pictureref picture = do
writeIORef pictureref picture
makeNetwork tickHandler eventHandler change = do
eTick ← fromAddHandler tickHandler
eEvent ← fromAddHandler eventHandler
bPicture ← mPicture eTick eEvent
changes bPicture >>= reactimate . fmap change
initial bPicture >>= liftIO . change