{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
module Main where
import Control.Monad (forM_, void)
import Reflex.SDL2
import System.Exit (exitSuccess)
data AABB = AABB InputMotion (V2 Int)
mouseButtonToAABB :: MouseButtonEventData -> AABB
mouseButtonToAABB dat = AABB (mouseButtonEventMotion dat) pos
where P pos32 = mouseButtonEventPos dat
pos = fromIntegral <$> pos32
motionToColor :: InputMotion -> V4 Int
motionToColor Released = V4 255 255 0 128
motionToColor Pressed = V4 255 0 255 128
renderAABBs :: MonadIO m => Maybe Renderer -> [AABB] -> Maybe (m ())
renderAABBs mayRenderer aabbs = ffor mayRenderer $ \r -> do
rendererDrawColor r $= V4 0 0 0 255
clear r
forM_ aabbs $ \(AABB motion pos) -> do
let color = motionToColor motion
rendererDrawColor r $= (fromIntegral <$> color)
fillRect r $ Just $ Rectangle (P $ fromIntegral <$> pos - 10) 20
present r
guest :: ReflexSDL2 t m => m ()
guest = do
-- Print some stuff after the network is built.
evPB <- asks sysPostBuildEvent
performEvent_ $ ffor evPB $ \() ->
liftIO $ putStrLn "starting up..."
-- Get the window shown event and use it to create a renderer event.
-- We use 'headE' because we only want to create one renderer, ever.
evWindow <- headE =<< asks (fmap windowShownEventWindow . sysWindowShownEvent)
evRenderer <- performEvent $ ffor evWindow $ \window -> do
liftIO $ putStrLn "creating renderer..."
r <- createRenderer window (-1) defaultRenderer
rendererDrawBlendMode r $= BlendAdditive
return r
-- Get any mouse button event and accumulate them as a list of
-- AABBs. Then combine the dynamic list of AABBs with the renderer
-- to perform a rendering event.
evMouseButton <- asks sysMouseButtonEvent
dAABBs <- foldDyn (:) [] $ mouseButtonToAABB <$> evMouseButton
dMayRenderer <- holdDyn Nothing $ Just <$> evRenderer
let dRendering = renderAABBs <$> dMayRenderer <*> dAABBs
evRendering = fmapMaybe id $ updated dRendering
performEvent_ evRendering
-- Quit on any quit event.
evQuit <- asks sysQuitEvent
performEvent_ $ ffor evQuit $ \() -> liftIO $ do
putStrLn "bye!"
exitSuccess
main :: IO ()
main = do
initializeAll
let ogl = defaultOpenGL{ glProfile = Core Debug 3 3 }
cfg = defaultWindow{ windowOpenGL = Just ogl
, windowResizable = True
, windowHighDPI = False
, windowInitialSize = V2 640 480
}
createWindow "reflex-sdl2-exe" cfg >>= void . glCreateContext
host guest