spice-0.5.0.0: src/FRP/Spice/Internal/Types.hs
{-|
This module provides every single type defined within the spice framework.
This allows people to write functions on data structures without being
concerned about recursive imports (and thereby being unable to compile) due
to the fact that this file does not and WILL NEVER import any other local libraries.
-}
module FRP.Spice.Internal.Types where
--------------------
-- Global Imports --
import qualified Data.Map.Strict as Map
import Graphics.Rendering.OpenGL
import Graphics.UI.GLFW as GLFW
import Control.Applicative
import FRP.Elerea.Param
import Data.Default
import Data.Monoid
----------
-- Code --
{-|
A data type that can be composed (so long as the data stored is a Monoid) in
do-notation.
-}
data DoListT a b = DoListT a b
{-|
A type synonym for the @'DoListT'@ that should be used.
-}
type DoList a = DoListT a ()
{-|
A Functor instance to satisfy the Applicative's requirements.
-}
instance Functor (DoListT a) where
fmap fn (DoListT a b) = DoListT a $ fn b
{-|
An Applicative instance to satisfy the Monad's requirements in the future.
-}
instance Monoid a => Applicative (DoListT a) where
pure b = DoListT mempty b
(DoListT a' bfn) <*> (DoListT a b) =
DoListT (a `mappend` a') $ bfn b
{-|
The Monad instance to allow the DoList to compose through do-notation.
-}
instance Monoid a => Monad (DoListT a) where
return = pure
(DoListT a b) >>= fn =
let (DoListT a' b') = fn b in
DoListT (mappend a a') b'
{-|
The config that is used to define the GLFW window's properties.
-}
data WindowConfig = WindowConfig { getWindowWidth :: Int
, getWindowHeight :: Int
, getWindowFullscreen :: Bool
, getWindowTitle :: String
}
{-|
The default state for a @'WindowConfig'@.
-}
instance Default WindowConfig where
def = WindowConfig { getWindowWidth = 640
, getWindowHeight = 480
, getWindowFullscreen = False
, getWindowTitle = "Spice Application"
}
{-|
A data type representing a color as 4 floats (r, g, b, a) representing red,
green, blue, and the alpha channel respectively. The floats should range from
0 to 1, representing 0 to 255 in more classical representations.
-}
data Color = Color { colorRed :: Float
, colorGreen :: Float
, colorBlue :: Float
, colorAlpha :: Float
}
{-|
A data type that stores two values. It can be used to perform basic vector
logic. It should be noted that the @'Vector'@ logic provided in this library
is not linear-algebra style vector logic.
-}
data Vector a = Vector a a
{-|
The default state for a @'Vector'@.
-}
instance Default a => Default (Vector a) where
def = Vector def def
{-|
A functor instance to apply a function onto both values stored in a
@'Vector'@.
-}
instance Functor Vector where
fmap fn (Vector x y) = Vector (fn x) (fn y)
{-|
An applicative instance to allow one to write functions on @'Vector'@s that
have separate functions for both values.
-}
instance Applicative Vector where
pure a = Vector a a
(Vector fnx fny) <*> (Vector x y) =
Vector (fnx x) (fny y)
{-|
A wrapper around the sinks for the mouse position, mouse buttons, and
keyboard keys.
-}
data Sinks = Sinks { mousePosSink :: Vector Float -> IO ()
, mouseButtonSink :: Map.Map MouseButton (Bool -> IO ())
, keySink :: Map.Map Key (Bool -> IO ())
}
{-|
A data structure that represents the current state of the input. Used in the
@'InputContainer'@ along with the @'Sink'@ to handle all input -- updating
and referencing.
-}
data Input = Input { mousePos :: Vector Float
, mouseButton :: Map.Map MouseButton Bool
, key :: Map.Map Key Bool
}
{-|
The container for both @'Sink'@ and @'Input'@. The @'Input'@ is stored within
a @'Signal'@ so it may be used within the FRP/Elerea part of the framework.
-}
data InputContainer = InputContainer { getSinks :: Sinks
, getInput :: Signal Input
}
{-|
Containing all of the necessary information for rendering an image on screen
(aside from the position where the sprite should be rendered.)
-}
data Sprite = Sprite { spriteTex :: TextureObject
, spriteSize :: Vector Float
}
{-|
Representing the loading of an asset into the game framework.
-}
data LoadAsset = LoadSprite FilePath
{-|
A @'DoList'@ synonym for @'LoadAsset'@.
-}
type LoadAssets = DoList [LoadAsset]
{-|
Storing the loaded assets in a single data structure.
-}
data Assets = Assets { sprites :: Map.Map FilePath Sprite }
{-|
The default state for an @'Assets'@.
-}
instance Default Assets where
def = Assets { sprites = Map.fromList [] }
{-|
A type synonym to imply that functions performed in this function should
solely render.
-}
type Scene = IO ()
{-|
A type synonym to make the delta time (in the @'Game'@ definition) more self
documenting.
-}
type DeltaTime = Float
{-|
The requirements for a given data structure to be used as a game within the
framework.
-}
class Game a where
update :: DeltaTime -> Input -> a -> a
render :: Assets -> a -> Scene
loadAssets :: a -> LoadAssets