conways-game-of-life/Graphics/Engine.hs

48 lines
1.4 KiB
Haskell

{-# LANGUAGE AllowAmbiguousTypes #-}
{-# LANGUAGE Arrows #-}
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Graphics.Engine where
import Control.Arrow
import Control.Monad.Representable.Reader
import FRP.Yampa
import GOL.Engine
import GOL.Rule
import GOL.Space
import Graphics.Config
import Graphics.Display (drawGrid)
import Graphics.Gloss
import Graphics.Gloss.Interface.IO.Game hiding (Event)
import qualified Graphics.Gloss.Interface.IO.Game as G
import Graphics.GlossUtils (InputEvent)
type TickEvent = Event ()
initialSpace :: Space f => f Bool
initialSpace = tabulate $ const False
engine :: Space f => GOL f Bool -> SF TickEvent (GOL f Bool)
engine = accumHoldBy (\s _ -> tick s)
repeatTick :: Time -> SF a TickEvent
repeatTick t = repeatedly t ()
tickSignal :: SF (Event Time) TickEvent
tickSignal =
arr (\ev -> ((), fmap repeatTick ev))
>>> drSwitch (repeatTick 0.2)
processEvent :: G.Event -> Config -> Config
processEvent (EventKey (Char '-') Down _ _) c = c {tickPeriod = tickPeriod c * 0.8}
processEvent (EventResize s) c = c {windowSize = s}
processEvent _ c = c
run :: forall f. DisplayableSpace f => f Bool -> SF InputEvent Picture
run st = proc ev -> do
c <- accum defaultConfig -< fmap processEvent ev
c' <- hold defaultConfig -< c
t <- tickSignal -< fmap tickPeriod c
s <- engine (gol' standardRule st) -< t
identity -< drawGrid c' (getSpace s)