Refactor concurrent side effects

This commit is contained in:
2022-10-30 14:55:30 +00:00
parent 11e873ea48
commit 624a4c3bcd
10 changed files with 56 additions and 47 deletions
+1 -1
View File
@@ -89,7 +89,7 @@ firstWorldLoad theConfig = do
, _uvScreenLayers = [splashMenu] , _uvScreenLayers = [splashMenu]
, _uvIOEffects = return , _uvIOEffects = return
, _uvTestString = testStringInit , _uvTestString = testStringInit
, _uvConcEffects = NoConcEffect , _uvSideEffects = mempty
, _uvCanContinue = cancontinue , _uvCanContinue = cancontinue
, _uvMSeed = mseed , _uvMSeed = mseed
} }
+27 -14
View File
@@ -3,25 +3,38 @@ module Dodge.Concurrent where
--import qualified Data.Set as S --import qualified Data.Set as S
import Control.Lens import Control.Lens
import Dodge.Data.Universe import Dodge.Data.Universe
import Data.Sequence (Seq (..))
--import Control.Concurrent --import Control.Concurrent
--import SDL.Input.Keyboard.Codes --import SDL.Input.Keyboard.Codes
conEffects :: Universe -> ConcurrentEffect Universe conEffects :: Universe -> ConcurrentEffect Universe
conEffects u = case u ^. uvConcEffects of conEffects u = case u ^? uvSideEffects . _head of
NewConcEffect{_ceFunction = eff} -> eff Just NewSideEffect{_ceSideEffect = eff} -> ConcurrentEffect (u & uvSideEffects . _head %~ g)
(dopop eff)
_ -> NoConcurrentEffect _ -> NoConcurrentEffect
tryConcEffect :: Bool -> String -> IO (Universe -> Maybe Universe) -> Universe -> Universe
tryConcEffect bl str eff u = case u ^. uvConcEffects of
NoConcEffect -> u & uvConcEffects .~ NewConcEffect (ConcurrentEffect setstr (clearConcEff eff)) str bl
_ -> u
where where
setstr g seff = RunningSideEffect (_ceString seff)
| bl = uvConcEffects .~ BlockingConcEffect str dopop :: IO (Universe -> Maybe Universe) -> IO (Universe -> Maybe Universe)
| otherwise = uvConcEffects .~ BackgroundConcEffect str dopop mf = do
f <- mf
return $ f . (uvSideEffects %~ taker)
taker (_ :<| xs) = xs
taker _ = mempty
clearConcEff :: IO (Universe -> Maybe Universe) -> IO (Universe -> Maybe Universe) addSideEffect :: IO (Universe -> Maybe Universe) -> String -> Universe -> Universe
clearConcEff eff = do addSideEffect f s = uvSideEffects %~ (|> NewSideEffect f s)
f <- eff
return (f . (uvConcEffects .~ NoConcEffect)) --tryConcEffect :: Bool -> String -> IO (Universe -> Maybe Universe) -> Universe -> Universe
--tryConcEffect bl str eff u = case u ^. uvConcEffects of
-- NoConcEffect -> u & uvConcEffects .~ NewConcEffect (ConcurrentEffect setstr (clearConcEff eff)) str bl
-- _ -> u
-- where
-- setstr
-- | bl = uvConcEffects .~ BlockingConcEffect str
-- | otherwise = uvConcEffects .~ BackgroundConcEffect str
--clearConcEff :: IO (Universe -> Maybe Universe) -> IO (Universe -> Maybe Universe)
--clearConcEff eff = do
-- f <- eff
-- return (f . (uvConcEffects .~ NoConcEffect))
+17 -13
View File
@@ -1,5 +1,5 @@
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE StrictData #-} {-# LANGUAGE StrictData #-}
{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TemplateHaskell #-}
@@ -9,16 +9,17 @@ module Dodge.Data.Universe (
module Dodge.Data.World, module Dodge.Data.World,
module Data.Preload, module Data.Preload,
module Picture.Data, module Picture.Data,
module Loop.Data module Loop.Data,
) where ) where
import Loop.Data
import Control.Lens import Control.Lens
--import qualified Data.Map.Strict as M --import qualified Data.Map.Strict as M
import Data.Preload import Data.Preload
import Data.Sequence (Seq (..))
import qualified Data.Text as T import qualified Data.Text as T
import Dodge.Data.Config import Dodge.Data.Config
import Dodge.Data.World import Dodge.Data.World
import Loop.Data
import Picture.Data import Picture.Data
import SDL (Scancode) import SDL (Scancode)
@@ -27,18 +28,19 @@ data Universe = Universe
, _preloadData :: PreloadData , _preloadData :: PreloadData
, _uvScreenLayers :: [ScreenLayer] , _uvScreenLayers :: [ScreenLayer]
, _uvIOEffects :: Universe -> IO Universe , _uvIOEffects :: Universe -> IO Universe
, _uvConcEffects :: ConcEffect , _uvSideEffects :: Seq SideEffect
, _uvConfig :: Configuration , _uvConfig :: Configuration
, _uvTestString :: Universe -> [String] , _uvTestString :: Universe -> [String]
, _uvCanContinue :: Bool , _uvCanContinue :: Bool
, _uvMSeed :: Maybe Int , _uvMSeed :: Maybe Int
} }
data ConcEffect = NoConcEffect data SideEffect
| NewConcEffect {_ceFunction :: ConcurrentEffect Universe = NewSideEffect
, _ceString :: String, _ceIsBlocking :: Bool} { _ceSideEffect :: IO (Universe -> Maybe Universe)
| BlockingConcEffect {_ceString :: String} , _ceString :: String
| BackgroundConcEffect {_ceString :: String} }
| RunningSideEffect {_ceString :: String}
data OptionScreenFlag = NormalOptions | GameOverOptions | SplashOptions data OptionScreenFlag = NormalOptions | GameOverOptions | SplashOptions
deriving (Eq, Ord, Show, Read) --Generic, Flat) deriving (Eq, Ord, Show, Read) --Generic, Flat)
@@ -59,6 +61,7 @@ data ScreenLayer
{ _scInput :: T.Text { _scInput :: T.Text
, _scFooter :: String , _scFooter :: String
} }
-- | WaitScreen -- | WaitScreen
-- { _scWaitMessage :: Universe -> String -- { _scWaitMessage :: Universe -> String
-- , _scWaitTime :: Int -- , _scWaitTime :: Int
@@ -67,9 +70,10 @@ data ScreenLayer
-- { _scDisplay :: Universe -> Picture -- { _scDisplay :: Universe -> Picture
-- } -- }
data MenuOptionDisplay = MODString {_modString :: String} data MenuOptionDisplay
| MODBlockedString {_modString :: String} = MODString {_modString :: String}
| MODStringOption {_modString :: String,_modOption :: String} | MODBlockedString {_modString :: String}
| MODStringOption {_modString :: String, _modOption :: String}
data MenuOption data MenuOption
= Toggle = Toggle
@@ -93,5 +97,5 @@ data IntID a = IntID Int a
makeLenses ''Universe makeLenses ''Universe
makeLenses ''ScreenLayer makeLenses ''ScreenLayer
makeLenses ''ConcEffect makeLenses ''SideEffect
makeLenses ''MenuOptionDisplay makeLenses ''MenuOptionDisplay
+1 -1
View File
@@ -71,7 +71,7 @@ saveQuit :: Universe -> IO (Maybe Universe)
saveQuit u = saveQuit u =
return $ return $
Just $ Just $
u & tryConcEffect True "SAVING" (saveQuitConc u) u & addSideEffect (saveQuitConc u) "SAVING"
saveQuitConc :: Universe -> IO (Universe -> Maybe Universe) saveQuitConc :: Universe -> IO (Universe -> Maybe Universe)
saveQuitConc u = do saveQuitConc u = do
+3 -8
View File
@@ -26,14 +26,9 @@ fixedCoordPictures u =
cfig = _uvConfig u cfig = _uvConfig u
drawConcurrentMessage :: Universe -> Picture drawConcurrentMessage :: Universe -> Picture
drawConcurrentMessage u = case u ^. uvConcEffects of drawConcurrentMessage u = case u ^? uvSideEffects . _head of
BlockingConcEffect str -> fillWidthText cfig str --Just (BlockingConcEffect str) -> fillWidthText cfig str
--listPicturesAt Just (RunningSideEffect str) ->
--(halfWidth cfig)
--(halfHeight cfig)
--cfig
--[centerText str]
BackgroundConcEffect str ->
listPicturesAt listPicturesAt
(halfWidth cfig) (halfWidth cfig)
(_windowY cfig - 50) (_windowY cfig - 50)
+4 -2
View File
@@ -18,6 +18,7 @@ import qualified Data.ByteString.Lazy as BS
import Dodge.Data.Universe import Dodge.Data.Universe
--import qualified Data.Set as S --import qualified Data.Set as S
import System.Directory import System.Directory
--import Data.Sequence ((|>))
writeSaveSlot :: SaveSlot -> Universe -> IO (Universe -> Maybe Universe) writeSaveSlot :: SaveSlot -> Universe -> IO (Universe -> Maybe Universe)
@@ -52,13 +53,14 @@ saveSlotPath QuicksaveSlot = "saveSlot/QuickSave"
saveSlotPath (LevelStartSlot i) = "saveSlot/LevelStart" ++ show i saveSlotPath (LevelStartSlot i) = "saveSlot/LevelStart" ++ show i
saveWorldInSlot :: SaveSlot -> Universe -> Universe saveWorldInSlot :: SaveSlot -> Universe -> Universe
saveWorldInSlot slot u = tryConcEffect False "SAVING" (writeSaveSlot slot u) u --saveWorldInSlot slot u = u & uvSideEffects %~ (|> NewSideEffect (writeSaveSlot slot u) "SAVING")
saveWorldInSlot slot u = u & addSideEffect (writeSaveSlot slot u) "SAVING"
reloadLevelStart :: Universe -> Universe reloadLevelStart :: Universe -> Universe
reloadLevelStart = loadSaveSlot (LevelStartSlot 0) reloadLevelStart = loadSaveSlot (LevelStartSlot 0)
loadSaveSlot :: SaveSlot -> Universe -> Universe loadSaveSlot :: SaveSlot -> Universe -> Universe
loadSaveSlot slot = tryConcEffect True "LOADING" (readSaveSlot slot) loadSaveSlot slot = addSideEffect (readSaveSlot slot) "LOADING"
doQuicksave :: Universe -> Universe doQuicksave :: Universe -> Universe
doQuicksave = saveWorldInSlot QuicksaveSlot doQuicksave = saveWorldInSlot QuicksaveSlot
+1 -1
View File
@@ -17,7 +17,7 @@ startNewGameInSlot slot u = startSeedGame slot i u
i = fst $ randomR (0, maxBound) (_randGen (_uvWorld u)) i = fst $ randomR (0, maxBound) (_randGen (_uvWorld u))
startSeedGame :: Int -> Int -> Universe -> Universe startSeedGame :: Int -> Int -> Universe -> Universe
startSeedGame _ i = tryConcEffect True "GENERATING" (startSeedGameConc i) startSeedGame _ i = addSideEffect (startSeedGameConc i) "GENERATING"
startSeedGameConc :: Int -> IO (Universe -> Maybe Universe) startSeedGameConc :: Int -> IO (Universe -> Maybe Universe)
startSeedGameConc seed = do startSeedGameConc seed = do
-5
View File
@@ -93,7 +93,6 @@ updateUniverseLast = over uvWorld (input . mouseButtons . each .~ True) -- to de
{- For most menus the only way to change the world is using event handling. -} {- For most menus the only way to change the world is using event handling. -}
updateUniverseMid :: Universe -> Universe updateUniverseMid :: Universe -> Universe
updateUniverseMid u updateUniverseMid u
| concurrentblocking = u
| otherwise = case _uvScreenLayers u of | otherwise = case _uvScreenLayers u of
(OptionScreen{_scOptionFlag = GameOverOptions} : _) -> (OptionScreen{_scOptionFlag = GameOverOptions} : _) ->
u & uvWorld u & uvWorld
@@ -106,10 +105,6 @@ updateUniverseMid u
) )
(_ : _) -> u (_ : _) -> u
[] -> functionalUpdate'' u [] -> functionalUpdate'' u
where
concurrentblocking = case u ^. uvConcEffects of
BlockingConcEffect{} -> True
_ -> False
functionalUpdate'' :: Universe -> Universe functionalUpdate'' :: Universe -> Universe
functionalUpdate'' = advanceScrollAmount . functionalUpdate' functionalUpdate'' = advanceScrollAmount . functionalUpdate'
+1 -1
View File
@@ -161,7 +161,7 @@ doConLoop themvar spf window coneffs worldSideEffects eventFn !startWorld = go s
return () return ()
let startWorld'' = case mconeff of let startWorld'' = case mconeff of
NoConcurrentEffect -> sw NoConcurrentEffect -> sw
ConcurrentEffect immediatef _ -> immediatef sw ConcurrentEffect immediatef _ -> immediatef
mconupdate <- tryTakeMVar themvar mconupdate <- tryTakeMVar themvar
let mstartWorld' = case mconupdate of let mstartWorld' = case mconupdate of
Just conupdate -> conupdate startWorld'' Just conupdate -> conupdate startWorld''
+1 -1
View File
@@ -6,6 +6,6 @@ module Loop.Data where
data ConcurrentEffect world data ConcurrentEffect world
= NoConcurrentEffect = NoConcurrentEffect
| ConcurrentEffect | ConcurrentEffect
{ _immediateEffect :: world -> world { _immediateUpdate :: world
, _sideEffect :: IO (world -> Maybe world) , _sideEffect :: IO (world -> Maybe world)
} }