{-| This module provides a clean way to load assets that will later be used in the spice-based program. -} module FRP.Spice.Assets where -------------------- -- Global Imports -- import qualified Data.Map.Strict as Map import Control.Monad import Data.Default ------------------- -- Local Imports -- import FRP.Spice.Graphics.Sprite import FRP.Spice.Utils.DoList ---------- -- Code -- {-| A single call to load an asset. -} data LoadAsset = LoadSprite FilePath {-| A list of @'LoadAssets'@ that may be composed in do-notation. -} type LoadAssets = DoList [LoadAsset] {-| The data structure that contains the loaded assets. -} data Assets = Assets { sprites :: Map.Map FilePath Sprite } {-| The default state for the @'Assets'@ data type. Used as the initial state for @'performAssetLoads'@. -} defaultAssets :: Assets defaultAssets = Assets { sprites = Map.fromList [] } {-| A synonym for @'defaultAssets'@ to fit within the data-default library. -} instance Default Assets where def = defaultAssets {-| Appending a @'Sprite'@ to an @'Assets'@. -} appendSprite :: Assets -> FilePath -> Sprite -> Assets appendSprite assets path sprite = assets { sprites = Map.insert path sprite $ sprites assets } {-| Performing the actual loading upon a @'LoadAssets'@. -} performAssetLoads :: LoadAssets -> IO Assets performAssetLoads la = performAssetLoads' (values la) defaultAssets where performAssetLoads' :: [LoadAsset] -> Assets -> IO Assets performAssetLoads' [] assets = return assets performAssetLoads' (LoadSprite path:xs) assets = (liftM (appendSprite assets path) $ loadSprite path) >>= performAssetLoads' xs {-| Loading a @'Sprite'@ asset. -} loadSpriteAsset :: FilePath -> LoadAssets loadSpriteAsset = fromValues . return . LoadSprite