Refactor, remove dependency of Loop on Preload

This commit is contained in:
2021-03-24 16:29:48 +01:00
parent 3cce959d00
commit f45ca2dd24
3 changed files with 68 additions and 86 deletions
+6 -2
View File
@@ -38,13 +38,17 @@ main :: IO ()
main = do main = do
(sizex,sizey) <- loadConfig (sizex,sizey) <- loadConfig
setupLoop setupLoop
"windowName" (sizex,sizey)
sizex sizey
(doPreload >>= resizeSpareFBO sizex sizey) (doPreload >>= resizeSpareFBO sizex sizey)
cleanUpPreload cleanUpPreload
(fmap (setWindowSize sizex sizey) firstWorld) (fmap (setWindowSize sizex sizey) firstWorld)
( \preData w -> do ( \preData w -> do
startTicks <- SDL.ticks startTicks <- SDL.ticks
errs <- errors
if length errs > 0
then putStrLn $ "GLerror during doLoop: " ++ (unwords $ map show errs)
else return ()
clear [ColorBuffer,DepthBuffer]
(lightTicks,timeSpentPoking) <- renderPicture' (_renderData preData) (lightTicks,timeSpentPoking) <- renderPicture' (_renderData preData)
(_cameraRot w) (_cameraZoom w) (_cameraRot w) (_cameraZoom w)
(_cameraPos w) (_cameraPos w)
+40 -72
View File
@@ -1,6 +1,5 @@
module Loop module Loop
( setupLoop ( setupLoop
-- , withExits
) where ) where
import SDL import SDL
import qualified Data.Text as T import qualified Data.Text as T
@@ -11,8 +10,6 @@ import Control.Monad
import System.Mem import System.Mem
import Foreign.C import Foreign.C
import Preload
import Control.Lens ((.~),(&),(+~)) import Control.Lens ((.~),(&),(+~))
winConfig :: Int -> Int -> WindowConfig winConfig :: Int -> Int -> WindowConfig
@@ -26,101 +23,72 @@ winConfig x y = defaultWindow
, windowResizable =True , windowResizable =True
} }
setupLoop :: String setupLoop
-> Int :: (Int,Int)
-> Int -> IO params
-> IO (PreloadData a) -> (params -> IO ())
-> (PreloadData a -> IO ())
-> IO world -> IO world
-> (PreloadData a -> world -> IO (PreloadData a)) -> (params -> world -> IO params)
-> (world -> Event -> Maybe world) -> (world -> Event -> Maybe world)
-> (world -> Maybe world) -> (world -> Maybe world)
-> IO () -> IO ()
setupLoop wName xSize ySize setupLoop
customInit initCleanup ioStartWorld sideEffects eventFn worldFn = do (xSize,ySize)
initParams
paramCleanup
ioStartWorld
sideEffects
eventFn
worldFn = do
startWorld <- ioStartWorld startWorld <- ioStartWorld
initializeAll initializeAll
bracket (createWindow (T.pack wName) (winConfig xSize ySize)) destroyWindow bracket
(\window -> (createWindow (T.pack "A Minimal Game Loop") (winConfig xSize ySize))
do bracket (glCreateContext window) (\con -> GL.finish >> glDeleteContext con) destroyWindow
(\_ -> bracket customInit initCleanup $ \setup -> do -- setup <- customInit $ \window -> bracket
-- swapInterval $= ImmediateUpdates (glCreateContext window)
GL.blend $= GL.Enabled (\con -> GL.finish >> glDeleteContext con)
-- GL.depthMask $= GL.Enabled $ \_ -> bracket
GL.blendEquation $= GL.FuncAdd initParams
GL.blendFunc $= (GL.SrcAlpha,GL.OneMinusSrcAlpha) paramCleanup
GL.clearColor $= GL.Color4 0 0.5 0 1 $ \setup -> doLoop setup window startWorld sideEffects eventFn worldFn
GL.clearDepth $= (200)
swapInterval $= ImmediateUpdates
GL.lineSmooth $= GL.Enabled
doLoop setup window startWorld
sideEffects eventFn worldFn
)
)
doLoop
--doLoop :: setupParams -> Window -> WorldView world0 :: params
-- -> (setupParams -> WorldView world0 -> IO ()) -> Window
-- -> (world0 -> Event -> Maybe world0) -> world
-- -> (world0 -> Maybe world0) -> (params -> world -> IO params)
-- -> IO () -> (world -> Event -> Maybe world)
doLoop setup window startWorld -> (world -> Maybe world)
-> IO ()
doLoop
setup
window
startWorld
worldSideEffects worldSideEffects
eventFn eventFn
worldUpdate worldUpdate
= do = do
errs <- GL.errors
if length errs > 0 then putStrLn $ "GLerror during doLoop: " ++ (unwords $ map show errs)
else return ()
startLoopTicks <- ticks startLoopTicks <- ticks
GL.clear [GL.ColorBuffer,GL.DepthBuffer] newParams <- worldSideEffects setup startWorld
newParams <- worldSideEffects (setup & currentTime .~ startLoopTicks) startWorld
glSwapWindow window glSwapWindow window
endSideTicks <- ticks
events <- pollEvents events <- pollEvents
maybeUpdatedWorld <- applyEventsIO eventFn startWorld events maybeUpdatedWorld <- foldM (applyEventIO eventFn) (Just startWorld) events
case maybeUpdatedWorld >>= worldUpdate of case maybeUpdatedWorld >>= worldUpdate of
Just updatedWorld -> do Just updatedWorld -> do
endSimTicks <- ticks
performGC performGC
endLoopTicks <- ticks -- it might be better to use System.Clock (monotonic) endLoopTicks <- ticks -- it might be better to use System.Clock (monotonic)
let delay = max 0 (20 + fromIntegral startLoopTicks - fromIntegral endLoopTicks) let delay = max 0 (20 + fromIntegral startLoopTicks - fromIntegral endLoopTicks)
threadDelay (delay * 1000 ) threadDelay (delay * 1000 )
endTime <- ticks endTime <- ticks
let newNewParams = newParams & idleTime +~ (endTime - endLoopTicks) doLoop newParams window updatedWorld worldSideEffects eventFn worldUpdate
& gcTime +~ (endLoopTicks - endSimTicks) Nothing -> return ()
& simTime +~ (endSimTicks - endSideTicks)
doLoop newNewParams window updatedWorld worldSideEffects eventFn worldUpdate
Nothing -> showTiming setup
applyEvents :: (world0 -> Event -> Maybe world0)
-> world0
-> [Event]
-> (world0 -> Maybe world0)
-> Maybe world0
applyEvents eventFn startWorld events worldUpdate =
case foldM (applyH eventFn) startWorld events of
Just w -> fmap (\w' -> w') $ worldUpdate w
Nothing -> Nothing
where
applyH :: (world0 -> Event -> Maybe world0) -> world0 -> Event -> Maybe world0
applyH f w e
= case eventPayload e of
QuitEvent -> Nothing
WindowClosedEvent _ -> Nothing
_ -> f w e
applyEventIO :: (world -> Event -> Maybe world) -> Maybe world -> Event -> IO (Maybe world) applyEventIO :: (world -> Event -> Maybe world) -> Maybe world -> Event -> IO (Maybe world)
applyEventIO fn mw e = case eventPayload e of applyEventIO fn mw e = case eventPayload e of
QuitEvent -> return Nothing QuitEvent -> return Nothing
WindowClosedEvent _ -> return Nothing WindowClosedEvent _ -> return Nothing
WindowSizeChangedEvent WindowSizeChangedEvent (WindowSizeChangedEventData {windowSizeChangedEventSize = V2 x y})
(WindowSizeChangedEventData {windowSizeChangedEventSize = V2 x y})
-> GL.viewport $= (GL.Position 0 0,GL.Size x y) >> return (mw >>= \w -> fn w e) -> GL.viewport $= (GL.Position 0 0,GL.Size x y) >> return (mw >>= \w -> fn w e)
_ -> return $ mw >>= flip fn e _ -> return $ mw >>= flip fn e
applyEventsIO :: (world0 -> Event -> Maybe world0)
-> world0
-> [Event]
-> IO (Maybe world0)
applyEventsIO fn w es = foldM (applyEventIO fn) (Just w) es
+10
View File
@@ -92,6 +92,16 @@ preloadRender = do
, _fboRenderbufferObject = fboRBO , _fboRenderbufferObject = fboRBO
} }
-- potential drawing setup
---- swapInterval $= ImmediateUpdates
-- GL.blend $= GL.Enabled
---- GL.depthMask $= GL.Enabled
-- GL.blendEquation $= GL.FuncAdd
-- GL.blendFunc $= (GL.SrcAlpha,GL.OneMinusSrcAlpha)
-- GL.clearColor $= GL.Color4 0 0.5 0 1
-- GL.clearDepth $= (200)
-- swapInterval $= ImmediateUpdates
-- GL.lineSmooth $= GL.Enabled
--------------------end preloadRender --------------------end preloadRender