{-# LANGUAGE Arrows #-}
module LiveCoding.Gloss
( module X
, module LiveCoding.Gloss
) where
import Control.Concurrent
import Data.IORef
import Control.Monad.Trans.Writer
import Graphics.Gloss as X
import Graphics.Gloss.Interface.IO.Game as X
import LiveCoding
import LiveCoding.Gloss.Debugger as X
import LiveCoding.Gloss.PictureM as X
type GlossCellWorldForeground = (GlossCell, [Event], Picture)
playCellForeground :: GlossCell -> IO ()
playCellForeground cell = playIO (InWindow "Gears" (600, 800) (20, 20)) black stepRate (initialWorld cell) toPicture handleEvent playStep
type GlossCellWorld = (MVar GlossCell, [Event], Picture)
playCell :: GlossCell -> IO (MVar GlossCell)
playCell glossCell = do
var <- newMVar glossCell
forkIO $ playIO (InWindow "Gears" (600, 800) (20, 20)) black stepRate (initialWorld var) toPicture handleEvent playStepMVar
return var
updateGloss :: MVar GlossCell -> GlossCell -> IO ()
updateGloss var newGlossCell = do
oldGlossCell <- takeMVar var
putMVar var $ hotCodeSwapCell newGlossCell oldGlossCell
initialWorld cell = (cell, [], blank)
toPicture (_, _, picture) = do
threadDelay 10000
return picture
handleEvent event (cell, events, picture) = do
threadDelay 10000
return (cell, event : events, picture)
playStep _ (cell, events, _) = do
(picture, cell') <- fmap massageWriterOutput $ runWriterT $ step cell events
threadDelay 10000
return (cell', [], picture)
playStepMVar _ (var, events, _) = do
cell <- takeMVar var
(picture, cell') <- fmap massageWriterOutput $ runWriterT $ step cell events
putMVar var cell'
threadDelay 10000
return (var, [], picture)
glossWrap :: GlossCell -> IO (LiveProgram IO)
glossWrap cell = do
pictureVar <- newMVar blank
eventRef <- newIORef []
stepVar <- newMVar 0
let
getPicture () = takeMVar pictureVar
putEvent event () = modifyIORef eventRef $ (event :)
putStep _ () = putMVar stepVar $ 1 / stepRate
forkIO $ playIO (InWindow "Gears" (600, 800) (20, 20)) black stepRate () getPicture putEvent putStep
let
putPicture = putMVar pictureVar
getEvents = atomicModifyIORef eventRef $ \events -> ([], events)
getStep = takeMVar stepVar
return $ liveCell $ proc _ -> do
_ <- constM getStep -< ()
events <- constM getEvents -< ()
picture <- runPictureM cell -< events
arrM putPicture -< picture