spice 0.3.2.2 → 0.3.2.4
raw patch · 24 files changed
+955/−941 lines, 24 filessetup-changed
Files
- LICENSE +20/−20
- Setup.hs +2/−2
- spice.cabal +50/−50
- src/FRP/Spice.hs +22/−22
- src/FRP/Spice/Config.hs +44/−44
- src/FRP/Spice/Engine.hs +86/−86
- src/FRP/Spice/Engine/Driver.hs +26/−26
- src/FRP/Spice/Engine/Network.hs +31/−31
- src/FRP/Spice/Engine/RenderWrapper.hs +31/−31
- src/FRP/Spice/Engine/RunInput.hs +31/−31
- src/FRP/Spice/Game.hs +27/−27
- src/FRP/Spice/Graphics.hs +15/−15
- src/FRP/Spice/Graphics/Color.hs +92/−92
- src/FRP/Spice/Graphics/Element.hs +34/−34
- src/FRP/Spice/Graphics/Geometry.hs +46/−46
- src/FRP/Spice/Graphics/Scene.hs +61/−61
- src/FRP/Spice/Graphics/Utils.hs +18/−18
- src/FRP/Spice/Input.hs +26/−26
- src/FRP/Spice/Input/Backend.hs +97/−97
- src/FRP/Spice/Input/Keyboard.hs +40/−40
- src/FRP/Spice/Input/Mouse.hs +52/−52
- src/FRP/Spice/Input/MousePosition.hs +31/−31
- src/FRP/Spice/Math.hs +9/−9
- src/FRP/Spice/Math/Vector.hs +64/−50
LICENSE view
@@ -1,20 +1,20 @@-Copyright (c) 2014 Cerek Hillen - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be included -in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. -IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, -TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE -SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +Copyright (c) 2014 Cerek Hillen++Permission is hereby granted, free of charge, to any person obtaining+a copy of this software and associated documentation files (the+"Software"), to deal in the Software without restriction, including+without limitation the rights to use, copy, modify, merge, publish,+distribute, sublicense, and/or sell copies of the Software, and to+permit persons to whom the Software is furnished to do so, subject to+the following conditions:++The above copyright notice and this permission notice shall be included+in all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.+IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,+TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE+SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple -main = defaultMain +import Distribution.Simple+main = defaultMain
spice.cabal view
@@ -1,50 +1,50 @@-name: spice -version: 0.3.2.2 -synopsis: An FRP-based game engine written in Haskell. -description: An FRP-based game engine written in Haskell. - See the homepage for more information. -homepage: http://github.com/crockeo/spice -license: MIT -license-file: LICENSE -author: Cerek Hillen -maintainer: Cerek Hillen <cerekh@gmail.com> -copyright: (c) 2014, Cerek Hillen -category: FRP -build-type: Simple -cabal-version: >=1.10 - -library - ghc-options: -Wall -fno-warn-unused-do-bind - - exposed-modules: FRP.Spice - FRP.Spice.Graphics - FRP.Spice.Math - - other-modules: FRP.Spice.Config - FRP.Spice.Engine - FRP.Spice.Engine.Driver - FRP.Spice.Engine.Network - FRP.Spice.Engine.RenderWrapper - FRP.Spice.Engine.RunInput - FRP.Spice.Game - FRP.Spice.Graphics.Color - FRP.Spice.Graphics.Element - FRP.Spice.Graphics.Geometry - FRP.Spice.Graphics.Scene - FRP.Spice.Graphics.Utils - FRP.Spice.Input - FRP.Spice.Input.Backend - FRP.Spice.Input.Keyboard - FRP.Spice.Input.Mouse - FRP.Spice.Input.MousePosition - FRP.Spice.Math.Vector - - hs-source-dirs: src/ - - build-depends: base == 4.7.* - , elerea == 2.7.* - , GLFW == 0.5.* - , containers == 0.5.* - , data-default == 0.5.* - , OpenGL - - default-language: Haskell2010 +name: spice+version: 0.3.2.4+synopsis: An FRP-based game engine written in Haskell.+description: An FRP-based game engine written in Haskell. - See the homepage for more information.+homepage: http://github.com/crockeo/spice+license: MIT+license-file: LICENSE+author: Cerek Hillen+maintainer: Cerek Hillen <cerekh@gmail.com>+copyright: (c) 2014, Cerek Hillen+category: FRP+build-type: Simple+cabal-version: >=1.10++library+ ghc-options: -Wall -fno-warn-unused-do-bind++ exposed-modules: FRP.Spice+ FRP.Spice.Graphics+ FRP.Spice.Math++ other-modules: FRP.Spice.Config+ FRP.Spice.Engine+ FRP.Spice.Engine.Driver+ FRP.Spice.Engine.Network+ FRP.Spice.Engine.RenderWrapper+ FRP.Spice.Engine.RunInput+ FRP.Spice.Game+ FRP.Spice.Graphics.Color+ FRP.Spice.Graphics.Element+ FRP.Spice.Graphics.Geometry+ FRP.Spice.Graphics.Scene+ FRP.Spice.Graphics.Utils+ FRP.Spice.Input+ FRP.Spice.Input.Backend+ FRP.Spice.Input.Keyboard+ FRP.Spice.Input.Mouse+ FRP.Spice.Input.MousePosition+ FRP.Spice.Math.Vector++ hs-source-dirs: src/++ build-depends: base == 4.7.*+ , elerea == 2.7.*+ , GLFW == 0.5.*+ , containers == 0.5.*+ , data-default == 0.5.*+ , OpenGL++ default-language: Haskell2010
src/FRP/Spice.hs view
@@ -1,22 +1,22 @@-{-| - This module re-exports some other modules in the spice library so that you - needn't import all of them explicitly. --} -module FRP.Spice ( module Graphics.UI.GLFW - , module Data.Map.Strict - - , module FRP.Spice.Config - , module FRP.Spice.Engine - , module FRP.Spice.Input - , module FRP.Spice.Game - ) where - ------------------------ --- Rexported Imports -- -import Graphics.UI.GLFW (Key (..), SpecialKey (..), MouseButton (..)) -import Data.Map.Strict ((!)) - -import FRP.Spice.Config -import FRP.Spice.Engine -import FRP.Spice.Input -import FRP.Spice.Game +{-|+ This module re-exports some other modules in the spice library so that you+ needn't import all of them explicitly.+-}+module FRP.Spice ( module Graphics.UI.GLFW+ , module Data.Map.Strict++ , module FRP.Spice.Config+ , module FRP.Spice.Engine+ , module FRP.Spice.Input+ , module FRP.Spice.Game+ ) where++-----------------------+-- Rexported Imports --+import Graphics.UI.GLFW (Key (..), SpecialKey (..), MouseButton (..))+import Data.Map.Strict ((!))++import FRP.Spice.Config+import FRP.Spice.Engine+import FRP.Spice.Input+import FRP.Spice.Game
src/FRP/Spice/Config.hs view
@@ -1,44 +1,44 @@-{-| - This module handles the configuration for the project. --} -module FRP.Spice.Config where - --------------------- --- Global Imports -- -import Data.Default - ----------- --- Code -- - -{-| - A datatype to configure the window settings when creating an OpenGL context - using @'FRP.Spice.Engine.startEngine'@ in the engine. --} -data WindowConfig = WindowConfig { getWindowWidth :: Int - , getWindowHeight :: Int - , getWindowFullscreen :: Bool - , getWindowTitle :: String - } - deriving (Eq, Show, Read) - -{-| - The default for @'WindowConfig'@ - - > getWindowWidth = 640 - > getWindowHeight = 480 - > getWindowFullscreen = False - > getWindowTitle = "Spice Application" --} -defaultWindowConfig :: WindowConfig -defaultWindowConfig = WindowConfig { getWindowWidth = 640 - , getWindowHeight = 480 - , getWindowFullscreen = False - , getWindowTitle = "Spice Application" - } - -{-| - A default instance for @'WindowConfig'@. Equivalent to calling - @'defaultWindowConfig'@. --} -instance Default WindowConfig where - def = defaultWindowConfig +{-|+ This module handles the configuration for the project.+-}+module FRP.Spice.Config where++--------------------+-- Global Imports --+import Data.Default++----------+-- Code --++{-|+ A datatype to configure the window settings when creating an OpenGL context+ using @'FRP.Spice.Engine.startEngine'@ in the engine.+-}+data WindowConfig = WindowConfig { getWindowWidth :: Int+ , getWindowHeight :: Int+ , getWindowFullscreen :: Bool+ , getWindowTitle :: String+ }+ deriving (Eq, Show, Read)++{-|+ The default for @'WindowConfig'@++ > getWindowWidth = 640+ > getWindowHeight = 480+ > getWindowFullscreen = False+ > getWindowTitle = "Spice Application"+-}+defaultWindowConfig :: WindowConfig+defaultWindowConfig = WindowConfig { getWindowWidth = 640+ , getWindowHeight = 480+ , getWindowFullscreen = False+ , getWindowTitle = "Spice Application"+ }++{-|+ A default instance for @'WindowConfig'@. Equivalent to calling+ @'defaultWindowConfig'@.+-}+instance Default WindowConfig where+ def = defaultWindowConfig
src/FRP/Spice/Engine.hs view
@@ -1,86 +1,86 @@-{-| - This module handles starting the engine. This is done via the use of the - @'startEngine'@ function. --} -module FRP.Spice.Engine (startEngine) where - --------------------- --- Global Imports -- -import Graphics.Rendering.OpenGL -import Graphics.UI.GLFW as GLFW -import Data.IORef - -------------------- --- Local Imports -- -import FRP.Spice.Engine.RunInput -import FRP.Spice.Engine.Network -import FRP.Spice.Engine.Driver -import FRP.Spice.Input.Backend -import FRP.Spice.Config -import FRP.Spice.Game -import FRP.Spice.Math - ----------- --- Code -- - --- Making the size from a WindowConfig -makeSize :: WindowConfig -> Size -makeSize wc = Size (fromIntegral $ getWindowWidth wc) (fromIntegral $ getWindowHeight wc) - --- Making the displaybits from a WindowConfig -makeDisplayBits :: [DisplayBits] -makeDisplayBits = [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24] - --- Making the window mode from a WindowConfig -makeWindowMode :: WindowConfig -> WindowMode -makeWindowMode wc = - if getWindowFullscreen wc - then FullScreen - else Window - --- Resizing the window -resizeCallback :: IORef (Vector Int) -> WindowSizeCallback -resizeCallback wSize size@(Size w h) = do - writeIORef wSize $ Vector (fromIntegral w) (fromIntegral h) - viewport $= (Position 0 0, size) - -{-| - Starting the spice engine with the parameters prescribed in the - @'WindowConfig'@. It updates and renders the @'Game'@ automatically so all - you need to to is set up the @'WindowConfig'@ and make a datatype with an - instance of @'Game'@. --} -startEngine :: Game a => WindowConfig -> a -> IO () -startEngine wc game = do - -- Opening the window - initialize - openWindow (makeSize wc) makeDisplayBits (makeWindowMode wc) - windowTitle $= getWindowTitle wc - - -- Checking for the window being closed - closed <- newIORef False - windowCloseCallback $= do - writeIORef closed True - return True - - -- Function to run on window resize - wSizeRef <- newIORef $ Vector (getWindowWidth wc) (getWindowHeight wc) - windowSizeCallback $= resizeCallback wSizeRef - - -- Getting the input container - ic <- makeInputContainer - - -- Updating the input - mousePosCallback $= makeMousePositionCallback ic wSizeRef - keyCallback $= makeKeyboardCallback ic - mouseButtonCallback $= makeMouseCallback ic - - -- Creating the network - network <- makeNetwork (getInput ic) game - - -- Driving the network - GLFW.time $= 0 - driveNetwork network $ runInput closed - - -- Closing the window, after all is said and done - closeWindow +{-|+ This module handles starting the engine. This is done via the use of the+ @'startEngine'@ function.+-}+module FRP.Spice.Engine (startEngine) where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL+import Graphics.UI.GLFW as GLFW+import Data.IORef++-------------------+-- Local Imports --+import FRP.Spice.Engine.RunInput+import FRP.Spice.Engine.Network+import FRP.Spice.Engine.Driver+import FRP.Spice.Input.Backend+import FRP.Spice.Config+import FRP.Spice.Game+import FRP.Spice.Math++----------+-- Code --++-- Making the size from a WindowConfig+makeSize :: WindowConfig -> Size+makeSize wc = Size (fromIntegral $ getWindowWidth wc) (fromIntegral $ getWindowHeight wc)++-- Making the displaybits from a WindowConfig+makeDisplayBits :: [DisplayBits]+makeDisplayBits = [DisplayRGBBits 8 8 8, DisplayAlphaBits 8, DisplayDepthBits 24]++-- Making the window mode from a WindowConfig+makeWindowMode :: WindowConfig -> WindowMode+makeWindowMode wc =+ if getWindowFullscreen wc+ then FullScreen+ else Window++-- Resizing the window+resizeCallback :: IORef (Vector Int) -> WindowSizeCallback+resizeCallback wSize size@(Size w h) = do+ writeIORef wSize $ Vector (fromIntegral w) (fromIntegral h)+ viewport $= (Position 0 0, size)++{-|+ Starting the spice engine with the parameters prescribed in the+ @'WindowConfig'@. It updates and renders the @'Game'@ automatically so all+ you need to to is set up the @'WindowConfig'@ and make a datatype with an+ instance of @'Game'@.+-}+startEngine :: Game a => WindowConfig -> a -> IO ()+startEngine wc game = do+ -- Opening the window+ initialize+ openWindow (makeSize wc) makeDisplayBits (makeWindowMode wc)+ windowTitle $= getWindowTitle wc++ -- Checking for the window being closed+ closed <- newIORef False+ windowCloseCallback $= do+ writeIORef closed True+ return True++ -- Function to run on window resize+ wSizeRef <- newIORef $ Vector (getWindowWidth wc) (getWindowHeight wc)+ windowSizeCallback $= resizeCallback wSizeRef++ -- Getting the input container+ ic <- makeInputContainer++ -- Updating the input+ mousePosCallback $= makeMousePositionCallback ic wSizeRef+ keyCallback $= makeKeyboardCallback ic+ mouseButtonCallback $= makeMouseCallback ic++ -- Creating the network+ network <- makeNetwork (getInput ic) game++ -- Driving the network+ GLFW.time $= 0+ driveNetwork network $ runInput closed++ -- Closing the window, after all is said and done+ closeWindow
src/FRP/Spice/Engine/Driver.hs view
@@ -1,26 +1,26 @@-{-| - This module need not be used directly. Refer to @'FRP.Spice.Engine'@ instead. --} -module FRP.Spice.Engine.Driver where - --------------------- --- Global Imports -- -import FRP.Spice.Engine.RenderWrapper -import FRP.Spice.Game - ----------- --- Code -- - -{-| - Driving a network created with the @'FRP.Spice.Engine.Network.makeNetwork'@ - function and a function such as @'FRP.Spice.Engine.RunInput.runInput'@. --} -driveNetwork :: Game a => (Float -> IO a) -> IO (Maybe Float) -> IO () -driveNetwork network iomdriver = do - mdriver <- iomdriver - - case mdriver of - Just driver -> do state <- network driver - renderWrapper $ render state - driveNetwork network iomdriver - Nothing -> return () +{-|+ This module need not be used directly. Refer to @'FRP.Spice.Engine'@ instead.+-}+module FRP.Spice.Engine.Driver where++--------------------+-- Global Imports --+import FRP.Spice.Engine.RenderWrapper+import FRP.Spice.Game++----------+-- Code --++{-|+ Driving a network created with the @'FRP.Spice.Engine.Network.makeNetwork'@+ function and a function such as @'FRP.Spice.Engine.RunInput.runInput'@.+-}+driveNetwork :: Game a => (Float -> IO a) -> IO (Maybe Float) -> IO ()+driveNetwork network iomdriver = do+ mdriver <- iomdriver++ case mdriver of+ Just driver -> do state <- network driver+ renderWrapper $ render state+ driveNetwork network iomdriver+ Nothing -> return ()
src/FRP/Spice/Engine/Network.hs view
@@ -1,31 +1,31 @@-{-| - This module need not be used directly. Refer to - @'FRP.Spice.Engine.startEngine'@ instead. --} -module FRP.Spice.Engine.Network where - --------------------- --- Global Imports -- -import FRP.Elerea.Param - -------------------- --- Local Imports -- -import FRP.Spice.Input -import FRP.Spice.Game - ----------- --- Code -- - -{-| - The raw update function that @'makeNetwork'@ calls. --} -updateFn :: Game a => Float -> Input -> a -> a -updateFn = update - -{-| - Creating a network to be used with the - @'FRP.Spice.Engine.Driver.driveNetwork'@ function. --} -makeNetwork :: Game a => Signal Input -> a -> IO (Float -> IO a) -makeNetwork inputSignal game = - start $ transfer game updateFn inputSignal +{-|+ This module need not be used directly. Refer to+ @'FRP.Spice.Engine.startEngine'@ instead.+-}+module FRP.Spice.Engine.Network where++--------------------+-- Global Imports --+import FRP.Elerea.Param++-------------------+-- Local Imports --+import FRP.Spice.Input+import FRP.Spice.Game++----------+-- Code --++{-|+ The raw update function that @'makeNetwork'@ calls.+-}+updateFn :: Game a => Float -> Input -> a -> a+updateFn = update++{-|+ Creating a network to be used with the+ @'FRP.Spice.Engine.Driver.driveNetwork'@ function.+-}+makeNetwork :: Game a => Signal Input -> a -> IO (Float -> IO a)+makeNetwork inputSignal game =+ start $ transfer game updateFn inputSignal
src/FRP/Spice/Engine/RenderWrapper.hs view
@@ -1,31 +1,31 @@-{-| - This module provides a wrapper to use with a given @'FRP.Spice.Game.Game'@'s - render function. --} -module FRP.Spice.Engine.RenderWrapper where - --------------------- --- Global Imports -- -import Graphics.Rendering.OpenGL -import Graphics.UI.GLFW - --------------------- --- Global Imports -- -import FRP.Spice.Graphics.Scene - ----------- --- Code -- - -{-| - A function to be ran on a @'FRP.Spice.Game.Game'@'s render function to - provide a bit of a framework around it. It runs @'clear'@ before the render - function, and @'flush'@ / @'swapBuffers'@ afterwards. --} -renderWrapper :: Scene -> IO () -renderWrapper scene = do - clear [ColorBuffer] - - renderScene scene - - flush - swapBuffers +{-|+ This module provides a wrapper to use with a given @'FRP.Spice.Game.Game'@'s+ render function.+-}+module FRP.Spice.Engine.RenderWrapper where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL+import Graphics.UI.GLFW++--------------------+-- Global Imports --+import FRP.Spice.Graphics.Scene++----------+-- Code --++{-|+ A function to be ran on a @'FRP.Spice.Game.Game'@'s render function to+ provide a bit of a framework around it. It runs @'clear'@ before the render+ function, and @'flush'@ / @'swapBuffers'@ afterwards.+-}+renderWrapper :: Scene -> IO ()+renderWrapper scene = do+ clear [ColorBuffer]++ renderScene scene++ flush+ swapBuffers
src/FRP/Spice/Engine/RunInput.hs view
@@ -1,31 +1,31 @@-{-| - This module need not be used directly. Refer to @'FRP.Spice.Engine'@ instead. --} -module FRP.Spice.Engine.RunInput where - --------------------- --- Global Imports -- -import Graphics.Rendering.OpenGL -import Graphics.UI.GLFW as GLFW -import Data.IORef -import GHC.Float - ----------- --- Code -- - -{-| - Given an @'IORef'@ indicating whether or not the program should close, it - either returns the delta time since the last call, or a @'Nothing'@, - indicating that the program should close. --} -runInput :: IORef Bool -> IO (Maybe Float) -runInput closed = do - pollEvents - c <- readIORef closed - - if c - then return Nothing - else do - dt <- get GLFW.time - GLFW.time $= 0 - return $ Just $ double2Float dt +{-|+ This module need not be used directly. Refer to @'FRP.Spice.Engine'@ instead.+-}+module FRP.Spice.Engine.RunInput where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL+import Graphics.UI.GLFW as GLFW+import Data.IORef+import GHC.Float++----------+-- Code --++{-|+ Given an @'IORef'@ indicating whether or not the program should close, it+ either returns the delta time since the last call, or a @'Nothing'@,+ indicating that the program should close.+-}+runInput :: IORef Bool -> IO (Maybe Float)+runInput closed = do+ pollEvents+ c <- readIORef closed++ if c+ then return Nothing+ else do+ dt <- get GLFW.time+ GLFW.time $= 0+ return $ Just $ double2Float dt
src/FRP/Spice/Game.hs view
@@ -1,27 +1,27 @@-{-| - This module provides the API which people must use to define a game within - the scope of Spice. --} -module FRP.Spice.Game where - -------------------- --- Local Imports -- -import FRP.Spice.Graphics.Scene -import FRP.Spice.Input - ----------- --- Code -- - -{-| - A synonym to make the update function more self-documenting. --} -type DeltaTime = Float - -{-| - The class which is to be used in the @'FRP.Spice.Engine.startEngine'@ - function. @'update'@ provides the API to update on every tick (purely), an - @'render'@ provides the API to render every frame. --} -class Game a where - update :: DeltaTime -> Input -> a -> a - render :: a -> Scene +{-|+ This module provides the API which people must use to define a game within+ the scope of Spice.+-}+module FRP.Spice.Game where++-------------------+-- Local Imports --+import FRP.Spice.Graphics.Scene+import FRP.Spice.Input++----------+-- Code --++{-|+ A synonym to make the update function more self-documenting.+-}+type DeltaTime = Float++{-|+ The class which is to be used in the @'FRP.Spice.Engine.startEngine'@+ function. @'update'@ provides the API to update on every tick (purely), an+ @'render'@ provides the API to render every frame.+-}+class Game a where+ update :: DeltaTime -> Input -> a -> a+ render :: a -> Scene
src/FRP/Spice/Graphics.hs view
@@ -1,15 +1,15 @@-{-| - This module re-exports a number of modules having to do with graphics. --} -module FRP.Spice.Graphics ( module FRP.Spice.Graphics.Geometry - , module FRP.Spice.Graphics.Color - , module FRP.Spice.Graphics.Scene - , module FRP.Spice.Graphics.Utils - ) where - ------------------------ --- Rexported Imports -- -import FRP.Spice.Graphics.Geometry -import FRP.Spice.Graphics.Color -import FRP.Spice.Graphics.Scene -import FRP.Spice.Graphics.Utils +{-|+ This module re-exports a number of modules having to do with graphics.+-}+module FRP.Spice.Graphics ( module FRP.Spice.Graphics.Geometry+ , module FRP.Spice.Graphics.Color+ , module FRP.Spice.Graphics.Scene+ , module FRP.Spice.Graphics.Utils+ ) where++-----------------------+-- Rexported Imports --+import FRP.Spice.Graphics.Geometry+import FRP.Spice.Graphics.Color+import FRP.Spice.Graphics.Scene+import FRP.Spice.Graphics.Utils
src/FRP/Spice/Graphics/Color.hs view
@@ -1,92 +1,92 @@-{-| - This module provides an abstraction over the default representations of color - in the Haskell OpenGL bindings. --} -module FRP.Spice.Graphics.Color where - -------------------- --- Local Imports -- -import FRP.Spice.Graphics.Element -import FRP.Spice.Graphics.Scene - ----------- --- Code -- - -{-| - Representing a Color using four @'Float'@ representing reg, green, blue, and - the alpha mask respectively. The @'Float'@s are in a range from 0-1, - representing @'Int'@s from 0-255. --} -data Color = Color { getRed :: Float - , getGreen :: Float - , getBlue :: Float - , getAlpha :: Float - } - deriving (Eq, Show, Read) - -{-| - Converting a color to an action in a @'Scene'@. --} -bindColor :: Color -> Scene -bindColor (Color r g b a) = fromElements [SetColor r g b a] - -{-| - A synonym for the @'Color'@ constructor. --} -color4f :: Float -> Float -> Float -> Float -> Color -color4f = Color - -{-| - Constructing a @'Color'@ from 3 @'Float'@s, defaulting the alpha mask to 1.0. --} -color3f :: Float -> Float -> Float -> Color -color3f r g b = color4f r g b 1.0 - -{-| - Creating a @'Color'@ from 4 @'Int'@s. The ints, similarly to @'color4f'@ - represent red, green, blue, and the alpha mask respectively. The ints should - be in the range of 0-255. (Note: @'color4i'@ is functionally equivalent (and - also equivalent in source code) to calling color4f with each of its arguments - divided by 255.) --} -color4i :: Int -> Int -> Int -> Int -> Color -color4i r g b a = color4f (fromIntegral r / 255) - (fromIntegral g / 255) - (fromIntegral b / 255) - (fromIntegral a / 255) - -{-| - Constructing a @'Color'@ from 3 @'Int'@s, defaulting the alpha mask to 255. --} -color3i :: Int -> Int -> Int -> Color -color3i r g b = color4i r g b 255 - -{-| - The color black. --} -black :: Color -black = color3i 0 0 0 - -{-| - The color white. --} -white :: Color -white = color3i 255 255 255 - -{-| - The color red. --} -red :: Color -red = color3i 255 0 0 - -{-| - The color green. --} -green :: Color -green = color3i 0 255 0 - -{-| - The color blue. --} -blue :: Color -blue = color3i 0 0 255 +{-|+ This module provides an abstraction over the default representations of color+ in the Haskell OpenGL bindings.+-}+module FRP.Spice.Graphics.Color where++-------------------+-- Local Imports --+import FRP.Spice.Graphics.Element+import FRP.Spice.Graphics.Scene++----------+-- Code --++{-|+ Representing a Color using four @'Float'@ representing reg, green, blue, and+ the alpha mask respectively. The @'Float'@s are in a range from 0-1,+ representing @'Int'@s from 0-255.+-}+data Color = Color { getRed :: Float+ , getGreen :: Float+ , getBlue :: Float+ , getAlpha :: Float+ }+ deriving (Eq, Show, Read)++{-|+ Converting a color to an action in a @'Scene'@.+-}+bindColor :: Color -> Scene+bindColor (Color r g b a) = fromElements [SetColor r g b a]++{-|+ A synonym for the @'Color'@ constructor.+-}+color4f :: Float -> Float -> Float -> Float -> Color+color4f = Color++{-|+ Constructing a @'Color'@ from 3 @'Float'@s, defaulting the alpha mask to 1.0.+-}+color3f :: Float -> Float -> Float -> Color+color3f r g b = color4f r g b 1.0++{-|+ Creating a @'Color'@ from 4 @'Int'@s. The ints, similarly to @'color4f'@+ represent red, green, blue, and the alpha mask respectively. The ints should+ be in the range of 0-255. (Note: @'color4i'@ is functionally equivalent (and+ also equivalent in source code) to calling color4f with each of its arguments+ divided by 255.)+-}+color4i :: Int -> Int -> Int -> Int -> Color+color4i r g b a = color4f (fromIntegral r / 255)+ (fromIntegral g / 255)+ (fromIntegral b / 255)+ (fromIntegral a / 255)++{-|+ Constructing a @'Color'@ from 3 @'Int'@s, defaulting the alpha mask to 255.+-}+color3i :: Int -> Int -> Int -> Color+color3i r g b = color4i r g b 255++{-|+ The color black.+-}+black :: Color+black = color3i 0 0 0++{-|+ The color white.+-}+white :: Color+white = color3i 255 255 255++{-|+ The color red.+-}+red :: Color+red = color3i 255 0 0++{-|+ The color green.+-}+green :: Color+green = color3i 0 255 0++{-|+ The color blue.+-}+blue :: Color+blue = color3i 0 0 255
src/FRP/Spice/Graphics/Element.hs view
@@ -1,34 +1,34 @@-module FRP.Spice.Graphics.Element ( Element (..) - , renderElement - ) where - --------------------- --- Global Imports -- -import Graphics.Rendering.OpenGL -import Control.Monad - -------------------- --- Local Imports -- -import FRP.Spice.Graphics.Utils -import FRP.Spice.Math - ----------- --- Code -- - -{-| - A type to purely contain the information for any kind of render call (that - has been implemented so far.) --} -data Element = RenderPrimitive PrimitiveMode [Vector Float] - | SetColor Float Float Float Float - -{-| - Converting an @'Element'@ into its matching OpenGL call. --} -renderElement :: Element -> IO () -renderElement (RenderPrimitive mode vertecies) = - renderPrimitive mode $ - forM_ vertecies $ \(Vector x y) -> - vertex $ Vertex2 (togl x) (togl y) -renderElement (SetColor r g b a) = - color $ Color4 (togl r) (togl g) (togl b) (togl a) +module FRP.Spice.Graphics.Element ( Element (..)+ , renderElement+ ) where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL+import Control.Monad++-------------------+-- Local Imports --+import FRP.Spice.Graphics.Utils+import FRP.Spice.Math++----------+-- Code --++{-|+ A type to purely contain the information for any kind of render call (that+ has been implemented so far.)+-}+data Element = RenderPrimitive PrimitiveMode [Vector Float]+ | SetColor Float Float Float Float++{-|+ Converting an @'Element'@ into its matching OpenGL call.+-}+renderElement :: Element -> IO ()+renderElement (RenderPrimitive mode vertecies) =+ renderPrimitive mode $+ forM_ vertecies $ \(Vector x y) ->+ vertex $ Vertex2 (togl x) (togl y)+renderElement (SetColor r g b a) =+ color $ Color4 (togl r) (togl g) (togl b) (togl a)
src/FRP/Spice/Graphics/Geometry.hs view
@@ -1,46 +1,46 @@-{-| - This module provides a cleaner API to render a number of shapes in the - current OpenGL context. --} -module FRP.Spice.Graphics.Geometry ( renderPoint - , renderRectangle - , renderSquare - ) where - --------------------- --- Global Imports -- -import Graphics.Rendering.OpenGL - -------------------- --- Local Imports -- -import FRP.Spice.Graphics.Element -import FRP.Spice.Graphics.Scene -import FRP.Spice.Math.Vector - ----------- --- Code -- - -{-| - Rendering a point. --} -renderPoint :: Vector Float -> Scene -renderPoint pos = - fromElements [RenderPrimitive Points [pos]] - -{-| - Rendering a rectangle. --} -renderRectangle :: Vector Float -> Vector Float -> Scene -renderRectangle (Vector x y) (Vector w h) = do - fromElements [ RenderPrimitive Quads [ Vector (x ) (y ) - , Vector (x + w) (y ) - , Vector (x + w) (y + h) - , Vector (x ) (y + h) - ] - ] - -{-| - Rendering a square. --} -renderSquare :: Vector Float -> Float -> Scene -renderSquare pos size = renderRectangle pos $ Vector size size +{-|+ This module provides a cleaner API to render a number of shapes in the+ current OpenGL context.+-}+module FRP.Spice.Graphics.Geometry ( renderPoint+ , renderRectangle+ , renderSquare+ ) where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL++-------------------+-- Local Imports --+import FRP.Spice.Graphics.Element+import FRP.Spice.Graphics.Scene+import FRP.Spice.Math.Vector++----------+-- Code --++{-|+ Rendering a point.+-}+renderPoint :: Vector Float -> Scene+renderPoint pos =+ fromElements [RenderPrimitive Points [pos]]++{-|+ Rendering a rectangle.+-}+renderRectangle :: Vector Float -> Vector Float -> Scene+renderRectangle (Vector x y) (Vector w h) = do+ fromElements [ RenderPrimitive Quads [ Vector (x ) (y )+ , Vector (x + w) (y )+ , Vector (x + w) (y + h)+ , Vector (x ) (y + h)+ ]+ ]++{-|+ Rendering a square.+-}+renderSquare :: Vector Float -> Float -> Scene+renderSquare pos size = renderRectangle pos $ Vector size size
src/FRP/Spice/Graphics/Scene.hs view
@@ -1,61 +1,61 @@-module FRP.Spice.Graphics.Scene where - --------------------- --- Global Imports -- -import Control.Applicative -import Control.Monad - -------------------- --- Local Imports -- -import FRP.Spice.Graphics.Element - ----------- --- Code -- - -{-| - For composing a scene out of a set of elements. --} -data SceneT a = SceneT [Element] a - -{-| - The commonly used instance of SceneT --} -type Scene = SceneT () - -{-| - Functor instance to satisfy applicative instance. --} -instance Functor SceneT where - fmap fn (SceneT elements v) = SceneT elements $ fn v - -{-| - Applicative instance to satisfy the monad instance. Not advised to use --} -instance Applicative SceneT where - pure = return - (<*>) = ap - -{-| - Used for being able to compose Scenes in a do-notation. Not very useful - outside of that. --} -instance Monad SceneT where - return a = SceneT [] a - (SceneT elements v) >>= fn = - let (SceneT elements' v') = fn v in - SceneT (elements ++ elements') v' - -{-| - Constructing a SceneT from a list of elements. --} -fromElements :: [Element] -> Scene -fromElements elements = - SceneT elements () - -{-| - Rendering a whole @'Scene'@ (renders each @'Element'@ from first in list to last in - list.) --} -renderScene :: Scene -> IO () -renderScene (SceneT elements _) = - forM_ elements renderElement +module FRP.Spice.Graphics.Scene where++--------------------+-- Global Imports --+import Control.Applicative+import Control.Monad++-------------------+-- Local Imports --+import FRP.Spice.Graphics.Element++----------+-- Code --++{-|+ For composing a scene out of a set of elements.+-}+data SceneT a = SceneT [Element] a++{-|+ The commonly used instance of SceneT+-}+type Scene = SceneT ()++{-|+ Functor instance to satisfy applicative instance.+-}+instance Functor SceneT where+ fmap fn (SceneT elements v) = SceneT elements $ fn v++{-|+ Applicative instance to satisfy the monad instance. Not advised to use+-}+instance Applicative SceneT where+ pure = return+ (<*>) = ap++{-|+ Used for being able to compose Scenes in a do-notation. Not very useful+ outside of that.+-}+instance Monad SceneT where+ return a = SceneT [] a+ (SceneT elements v) >>= fn =+ let (SceneT elements' v') = fn v in+ SceneT (elements ++ elements') v'++{-|+ Constructing a SceneT from a list of elements.+-}+fromElements :: [Element] -> Scene+fromElements elements =+ SceneT elements ()++{-|+ Rendering a whole @'Scene'@ (renders each @'Element'@ from first in list to last in+ list.)+-}+renderScene :: Scene -> IO ()+renderScene (SceneT elements _) =+ forM_ elements renderElement
src/FRP/Spice/Graphics/Utils.hs view
@@ -1,18 +1,18 @@-{-| - This module provides a set of utilities to ease the burden of writing OpenGL - rendering functions. --} -module FRP.Spice.Graphics.Utils where - --------------------- --- Global Imports -- -import Graphics.Rendering.OpenGL - ----------- --- Code -- - -{-| - Converting a @'Float'@ to a @'GLfloat'@ --} -togl :: Float -> GLfloat -togl = realToFrac +{-|+ This module provides a set of utilities to ease the burden of writing OpenGL+ rendering functions.+-}+module FRP.Spice.Graphics.Utils where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL++----------+-- Code --++{-|+ Converting a @'Float'@ to a @'GLfloat'@+-}+togl :: Float -> GLfloat+togl = realToFrac
src/FRP/Spice/Input.hs view
@@ -1,26 +1,26 @@-{-| - This module provides everything relating to input in the scope of spice. --} -module FRP.Spice.Input where - --------------------- --- Global Imports -- -import Graphics.UI.GLFW -import Data.Map.Strict - -------------------- --- Local Imports -- -import FRP.Spice.Math - ----------- --- Code -- - -{-| - A container for all of the states themselves. It is used as a @'Signal'@ - @'Input'@ in the @'InputContainer'@ (which is necessary to use it within - Elerea's FRP network). --} -data Input = Input { mousePosition :: Vector Float - , keyboard :: Map Key Bool - , mouse :: Map MouseButton Bool - } +{-|+ This module provides everything relating to input in the scope of spice.+-}+module FRP.Spice.Input where++--------------------+-- Global Imports --+import Graphics.UI.GLFW+import Data.Map.Strict++-------------------+-- Local Imports --+import FRP.Spice.Math++----------+-- Code --++{-|+ A container for all of the states themselves. It is used as a @'Signal'@+ @'Input'@ in the @'InputContainer'@ (which is necessary to use it within+ Elerea's FRP network).+-}+data Input = Input { mousePosition :: Vector Float+ , keyboard :: Map Key Bool+ , mouse :: Map MouseButton Bool+ }
src/FRP/Spice/Input/Backend.hs view
@@ -1,97 +1,97 @@-{-| - The backend to be used with the input. --} -module FRP.Spice.Input.Backend where - --------------------- --- Global Imports -- -import Graphics.Rendering.OpenGL -import Graphics.UI.GLFW as GLFW -import FRP.Elerea.Param -import Data.Map.Strict -import Data.IORef - -------------------- --- Local Imports -- -import qualified FRP.Spice.Input.MousePosition as MousePosition -import qualified FRP.Spice.Input.Keyboard as Keyboard -import qualified FRP.Spice.Input.Mouse as Mouse -import FRP.Spice.Input -import FRP.Spice.Math - ----------- --- Code -- - -{-| - A wrapper around the sinks for the mouse position, the key states, and the - mouse button states. --} -data Sinks = Sinks { mousePositionSinks :: Vector Float -> IO () - , keyboardSinks :: Map Key (Bool -> IO ()) - , mouseSinks :: Map MouseButton (Bool -> IO ()) - } - - - -{-| - A container around @'Sinks'@ and @'Signal'@ @'Input'@ so that one needn't - pass around a tuple. --} -data InputContainer = InputContainer { getSinks :: Sinks - , getInput :: Signal Input - } - -{-| - Making an @'InputContainer'@ filled with all necessary externals. --} -makeInputContainer :: IO InputContainer -makeInputContainer = do - mousePositionExternals <- MousePosition.externals - keyboardExternals <- Keyboard.externals - mouseExternals <- Mouse.externals - - let sinks = Sinks { mousePositionSinks = MousePosition.sinks mousePositionExternals - , keyboardSinks = Keyboard.sinks keyboardExternals - , mouseSinks = Mouse.sinks mouseExternals - } - - let input = do mps <- fst mousePositionExternals - kbs <- Keyboard.signals keyboardExternals - ms <- Mouse.signals mouseExternals - - return Input { mousePosition = mps - , keyboard = kbs - , mouse = ms - } - - return InputContainer { getSinks = sinks - , getInput = input - } - -{-| - Creating a callback to update the mouse position's state. --} -makeMousePositionCallback :: InputContainer -> IORef (Vector Int) -> MousePosCallback -makeMousePositionCallback ic wSizeRef (Position x y) = do - (Vector w h) <- readIORef wSizeRef - mousePositionSinks (getSinks ic) $ - Vector ( fromIntegral x / ((fromIntegral $ w) / 2) - 1) - ((-fromIntegral y) / ((fromIntegral $ h) / 2) + 1) - -{-| - Creating a callback to update the keyboard's states. --} -makeKeyboardCallback :: InputContainer -> KeyCallback -makeKeyboardCallback ic key state = - keyboardSinks (getSinks ic) ! key $ case state of - Press -> True - Release -> False - -{-| - Creating a callback to update the mouse buttons' states. --} -makeMouseCallback :: InputContainer -> MouseButtonCallback -makeMouseCallback ic button state = - mouseSinks (getSinks ic) ! button $ case state of - Press -> True - Release -> False +{-|+ The backend to be used with the input.+-}+module FRP.Spice.Input.Backend where++--------------------+-- Global Imports --+import Graphics.Rendering.OpenGL+import Graphics.UI.GLFW as GLFW+import FRP.Elerea.Param+import Data.Map.Strict+import Data.IORef++-------------------+-- Local Imports --+import qualified FRP.Spice.Input.MousePosition as MousePosition+import qualified FRP.Spice.Input.Keyboard as Keyboard+import qualified FRP.Spice.Input.Mouse as Mouse+import FRP.Spice.Input+import FRP.Spice.Math++----------+-- Code --++{-|+ A wrapper around the sinks for the mouse position, the key states, and the+ mouse button states.+-}+data Sinks = Sinks { mousePositionSinks :: Vector Float -> IO ()+ , keyboardSinks :: Map Key (Bool -> IO ())+ , mouseSinks :: Map MouseButton (Bool -> IO ())+ }++++{-|+ A container around @'Sinks'@ and @'Signal'@ @'Input'@ so that one needn't+ pass around a tuple.+-}+data InputContainer = InputContainer { getSinks :: Sinks+ , getInput :: Signal Input+ }++{-|+ Making an @'InputContainer'@ filled with all necessary externals.+-}+makeInputContainer :: IO InputContainer+makeInputContainer = do+ mousePositionExternals <- MousePosition.externals+ keyboardExternals <- Keyboard.externals+ mouseExternals <- Mouse.externals++ let sinks = Sinks { mousePositionSinks = MousePosition.sinks mousePositionExternals+ , keyboardSinks = Keyboard.sinks keyboardExternals+ , mouseSinks = Mouse.sinks mouseExternals+ }++ let input = do mps <- fst mousePositionExternals+ kbs <- Keyboard.signals keyboardExternals+ ms <- Mouse.signals mouseExternals++ return Input { mousePosition = mps+ , keyboard = kbs+ , mouse = ms+ }++ return InputContainer { getSinks = sinks+ , getInput = input+ }++{-|+ Creating a callback to update the mouse position's state.+-}+makeMousePositionCallback :: InputContainer -> IORef (Vector Int) -> MousePosCallback+makeMousePositionCallback ic wSizeRef (Position x y) = do+ (Vector w h) <- readIORef wSizeRef+ mousePositionSinks (getSinks ic) $+ Vector ( fromIntegral x / ((fromIntegral $ w) / 2) - 1)+ ((-fromIntegral y) / ((fromIntegral $ h) / 2) + 1)++{-|+ Creating a callback to update the keyboard's states.+-}+makeKeyboardCallback :: InputContainer -> KeyCallback+makeKeyboardCallback ic key state =+ keyboardSinks (getSinks ic) ! key $ case state of+ Press -> True+ Release -> False++{-|+ Creating a callback to update the mouse buttons' states.+-}+makeMouseCallback :: InputContainer -> MouseButtonCallback+makeMouseCallback ic button state =+ mouseSinks (getSinks ic) ! button $ case state of+ Press -> True+ Release -> False
src/FRP/Spice/Input/Keyboard.hs view
@@ -1,40 +1,40 @@-{-| - The keyboard specific section of input. --} -module FRP.Spice.Input.Keyboard where - --------------------- --- Global Imports -- -import qualified Data.Traversable as T -import Data.Map.Strict hiding (keys, map) -import Graphics.UI.GLFW as GLFW -import FRP.Elerea.Param -import Control.Monad - ----------- --- Code -- - -{-| - A list of all possible keys used in the GLFW API. --} -keys :: [Key] -keys = map toEnum [0 .. 318] - -{-| - A Map from @'Key'@ to the externals created for every single key. --} -externals :: IO (Map Key (Signal Bool, Bool -> IO ())) -externals = liftM fromList $ mapM (\k -> liftM ((,) k) $ external False) keys - -{-| - Creating the @'Signal'@ of a @'Map'@ from @'Key'@ to @'Bool'@ from a @'Map'@ - of @'externals'@. --} -signals :: Map Key (Signal Bool, Bool -> IO ()) -> Signal (Map Key Bool) -signals = T.sequence . fmap fst - -{-| - Making a @'Map'@ from @'Key'@ to sink from a @'Map'@ of @'externals'@. --} -sinks :: Map Key (Signal Bool, Bool -> IO ()) -> Map Key (Bool -> IO ()) -sinks = fmap snd +{-|+ The keyboard specific section of input.+-}+module FRP.Spice.Input.Keyboard where++--------------------+-- Global Imports --+import qualified Data.Traversable as T+import Data.Map.Strict hiding (keys, map)+import Graphics.UI.GLFW as GLFW+import FRP.Elerea.Param+import Control.Monad++----------+-- Code --++{-|+ A list of all possible keys used in the GLFW API.+-}+keys :: [Key]+keys = map toEnum [0 .. 318]++{-|+ A Map from @'Key'@ to the externals created for every single key.+-}+externals :: IO (Map Key (Signal Bool, Bool -> IO ()))+externals = liftM fromList $ mapM (\k -> liftM ((,) k) $ external False) keys++{-|+ Creating the @'Signal'@ of a @'Map'@ from @'Key'@ to @'Bool'@ from a @'Map'@+ of @'externals'@.+-}+signals :: Map Key (Signal Bool, Bool -> IO ()) -> Signal (Map Key Bool)+signals = T.sequence . fmap fst++{-|+ Making a @'Map'@ from @'Key'@ to sink from a @'Map'@ of @'externals'@.+-}+sinks :: Map Key (Signal Bool, Bool -> IO ()) -> Map Key (Bool -> IO ())+sinks = fmap snd
src/FRP/Spice/Input/Mouse.hs view
@@ -1,52 +1,52 @@-{-| - The mouse (button) specific section of input. --} -module FRP.Spice.Input.Mouse where - --------------------- --- Global Imports -- -import qualified Data.Traversable as T (sequence) -import Data.Map.Strict hiding (keys, map) -import Graphics.UI.GLFW as GLFW -import FRP.Elerea.Param -import Control.Monad - ----------- --- Code -- - -{-| - Adding an instance of Ord to MouseButton so it can be used with the map. --} -instance Ord MouseButton where - mb1 <= mb2 = fromEnum mb1 < fromEnum mb2 - -{-| - A list of all mouse buttons available via the GLFW api. --} -buttons :: [MouseButton] -buttons = [ ButtonLeft - , ButtonRight - , ButtonMiddle - ] - ++ - map ButtonNo [0 .. 7] - -{-| - A map from @'MouseButton'@ to externals created for every button. --} -externals :: IO (Map MouseButton (Signal Bool, Bool -> IO ())) -externals = liftM fromList $ mapM (\b -> liftM ((,) b) $ external False) buttons - -{-| - Creating the @'Signal'@ of a @'Map'@ from @'MouseButton'@ to @'Bool'@ from a - @'Map'@ of @'externals'@. --} -signals :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Signal (Map MouseButton Bool) -signals = T.sequence . fmap fst - -{-| - Making a @'Map'@ from @'MouseButton'@ to sink from a @'Map'@ of - @'externals'@. --} -sinks :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Map MouseButton (Bool -> IO ()) -sinks = fmap snd +{-|+ The mouse (button) specific section of input.+-}+module FRP.Spice.Input.Mouse where++--------------------+-- Global Imports --+import qualified Data.Traversable as T (sequence)+import Data.Map.Strict hiding (keys, map)+import Graphics.UI.GLFW as GLFW+import FRP.Elerea.Param+import Control.Monad++----------+-- Code --++{-|+ Adding an instance of Ord to MouseButton so it can be used with the map.+-}+instance Ord MouseButton where+ mb1 <= mb2 = fromEnum mb1 < fromEnum mb2++{-|+ A list of all mouse buttons available via the GLFW api.+-}+buttons :: [MouseButton]+buttons = [ ButtonLeft+ , ButtonRight+ , ButtonMiddle+ ]+ +++ map ButtonNo [0 .. 7]++{-|+ A map from @'MouseButton'@ to externals created for every button.+-}+externals :: IO (Map MouseButton (Signal Bool, Bool -> IO ()))+externals = liftM fromList $ mapM (\b -> liftM ((,) b) $ external False) buttons++{-|+ Creating the @'Signal'@ of a @'Map'@ from @'MouseButton'@ to @'Bool'@ from a+ @'Map'@ of @'externals'@.+-}+signals :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Signal (Map MouseButton Bool)+signals = T.sequence . fmap fst++{-|+ Making a @'Map'@ from @'MouseButton'@ to sink from a @'Map'@ of+ @'externals'@.+-}+sinks :: Map MouseButton (Signal Bool, Bool -> IO ()) -> Map MouseButton (Bool -> IO ())+sinks = fmap snd
src/FRP/Spice/Input/MousePosition.hs view
@@ -1,31 +1,31 @@-{-| - The mouse (position) specific section of input. --} -module FRP.Spice.Input.MousePosition where - --------------------- --- Global Imports -- -import FRP.Elerea.Param -import Data.Default - -------------------- --- Local Imports -- -import FRP.Spice.Math.Vector - -{-| - Creating the external for the mouse position. --} -externals :: IO (Signal (Vector Float), Vector Float -> IO ()) -externals = external def - -{-| - Getting the signal from the mouse position external. --} -signals :: (Signal (Vector Float), Vector Float -> IO ()) -> Signal (Vector Float) -signals = fst - -{-| - Getting the sink from the mouse position external. --} -sinks :: (Signal (Vector Float), Vector Float -> IO ()) -> Vector Float -> IO () -sinks = snd +{-|+ The mouse (position) specific section of input.+-}+module FRP.Spice.Input.MousePosition where++--------------------+-- Global Imports --+import FRP.Elerea.Param+import Data.Default++-------------------+-- Local Imports --+import FRP.Spice.Math.Vector++{-|+ Creating the external for the mouse position.+-}+externals :: IO (Signal (Vector Float), Vector Float -> IO ())+externals = external def++{-|+ Getting the signal from the mouse position external.+-}+signals :: (Signal (Vector Float), Vector Float -> IO ()) -> Signal (Vector Float)+signals = fst++{-|+ Getting the sink from the mouse position external.+-}+sinks :: (Signal (Vector Float), Vector Float -> IO ()) -> Vector Float -> IO ()+sinks = snd
src/FRP/Spice/Math.hs view
@@ -1,9 +1,9 @@-{-| - This module re-exports a number of modules having to do with math. --} -module FRP.Spice.Math ( module FRP.Spice.Math.Vector - ) where - ------------------------ --- Rexported Imports -- -import FRP.Spice.Math.Vector +{-|+ This module re-exports a number of modules having to do with math.+-}+module FRP.Spice.Math ( module FRP.Spice.Math.Vector+ ) where++-----------------------+-- Rexported Imports --+import FRP.Spice.Math.Vector
src/FRP/Spice/Math/Vector.hs view
@@ -1,50 +1,64 @@-{-| - This module provides a @'Vector'@ datatype as described below. --} -module FRP.Spice.Math.Vector where - --------------------- --- Global Imports -- -import Data.Default -import Data.Monoid - ----------- --- Code -- - -{-| - A datatype that houses two values of a given type. It is provided with a - @'Num'@ instance so that, when used with number types it can function - similarly (though not exactly) to a mathematical vector. --} -data Vector a = Vector a a - -{-| - The default for the @'Vector'@. --} -instance Default a => Default (Vector a) where - def = Vector def def - -{-| - Displaying the @'Vector'@. --} -instance Show a => Show (Vector a) where - show (Vector x y) = mconcat ["Vector ", show x, " ", show y] - -{-| - Performs operations on the matching fields of the other @'Vector'@. --} -instance Num a => Num (Vector a) where - (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2) - (Vector x1 y1) * (Vector x2 y2) = Vector (x1 * x2) (y1 * y2) - - fromInteger n = Vector (fromInteger n) (fromInteger n) - - abs (Vector x y) = Vector (abs x) (abs y) - signum (Vector x y) = Vector (signum x) (signum y) - negate (Vector x y) = Vector (negate x) (negate y) - -{-| - Maps over both values in the @'Vector'@ --} -instance Functor Vector where - fmap fn (Vector x y) = Vector (fn x) (fn y) +{-|+ This module provides a @'Vector'@ datatype as described below.+-}+module FRP.Spice.Math.Vector where++--------------------+-- Global Imports --+import Control.Applicative+import Data.Default+import Data.Monoid++----------+-- Code --++{-|+ A datatype that houses two values of a given type. It is provided with a+ @'Num'@ instance so that, when used with number types it can function+ similarly (though not exactly) to a mathematical vector.+-}+data Vector a = Vector a a++{-|+ The default for the @'Vector'@.+-}+instance Default a => Default (Vector a) where+ def = Vector def def++{-|+ Displaying the @'Vector'@.+-}+instance Show a => Show (Vector a) where+ show (Vector x y) = mconcat ["Vector ", show x, " ", show y]++{-|+ Performs operations on the matching fields of the other @'Vector'@.+-}+instance Num a => Num (Vector a) where+ (Vector x1 y1) + (Vector x2 y2) = Vector (x1 + x2) (y1 + y2)+ (Vector x1 y1) * (Vector x2 y2) = Vector (x1 * x2) (y1 * y2)++ fromInteger n = Vector (fromInteger n) (fromInteger n)++ abs (Vector x y) = Vector (abs x) (abs y)+ signum (Vector x y) = Vector (signum x) (signum y)+ negate (Vector x y) = Vector (negate x) (negate y)++{-|+ Maps over both values in the @'Vector'@.+-}+instance Functor Vector where+ fmap fn (Vector x y) = Vector (fn x) (fn y)++{-|+ Applicative instance for @'Vector'@.+-}+instance Applicative Vector where+ pure a = Vector a a+ (Vector fn _) <*> (Vector x y) = Vector (fn x) (fn y)++{-|+ Multiplying @'Vector'@ by a scalar value.+-}+scalar :: Num a => Vector a -> a -> Vector a+scalar (Vector x y) n = Vector (x * n) (y * n)