packages feed

spice 0.2.0.0 → 0.3.0.0

raw patch · 10 files changed

+200/−147 lines, 10 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- FRP.Spice: InputContainer :: Sinks -> Signal Input -> InputContainer
- FRP.Spice: Sinks :: (Vector Float -> IO ()) -> Map Key (Bool -> IO ()) -> Map MouseButton (Bool -> IO ()) -> Sinks
- FRP.Spice: data InputContainer
- FRP.Spice: data Sinks
- FRP.Spice: getInput :: InputContainer -> Signal Input
- FRP.Spice: getSinks :: InputContainer -> Sinks
- FRP.Spice: keyboardSinks :: Sinks -> Map Key (Bool -> IO ())
- FRP.Spice: makeInputContainer :: IO InputContainer
- FRP.Spice: makeKeyboardCallback :: InputContainer -> KeyCallback
- FRP.Spice: makeMouseCallback :: InputContainer -> MouseButtonCallback
- FRP.Spice: makeMousePositionCallback :: WindowConfig -> InputContainer -> MousePosCallback
- FRP.Spice: mousePositionSinks :: Sinks -> Vector Float -> IO ()
- FRP.Spice: mouseSinks :: Sinks -> Map MouseButton (Bool -> IO ())
- FRP.Spice.Graphics: Element :: PrimitiveMode -> [Vector Float] -> Element
- FRP.Spice.Graphics: SceneT :: [Element] -> a -> SceneT a
- FRP.Spice.Graphics: bindColor :: Color -> IO ()
- FRP.Spice.Graphics: data Element
- FRP.Spice.Graphics: data SceneT a
- FRP.Spice.Graphics: fromElements :: [Element] -> Scene
- FRP.Spice.Graphics: renderElement :: Element -> IO ()
+ FRP.Spice.Graphics: Render :: (IO ()) -> Render
+ FRP.Spice.Graphics: class Renderable a
+ FRP.Spice.Graphics: fromRenderables :: Renderable a => [a] -> Scene
+ FRP.Spice.Graphics: newtype Render
+ FRP.Spice.Graphics: runRender :: Render -> IO ()
+ FRP.Spice.Graphics: toRender :: Renderable a => a -> Render
- FRP.Spice.Graphics: black :: Color
+ FRP.Spice.Graphics: black :: Scene
- FRP.Spice.Graphics: blue :: Color
+ FRP.Spice.Graphics: blue :: Scene
- FRP.Spice.Graphics: color3f :: Float -> Float -> Float -> Color
+ FRP.Spice.Graphics: color3f :: Float -> Float -> Float -> Scene
- FRP.Spice.Graphics: color3i :: Int -> Int -> Int -> Color
+ FRP.Spice.Graphics: color3i :: Int -> Int -> Int -> Scene
- FRP.Spice.Graphics: color4f :: Float -> Float -> Float -> Float -> Color
+ FRP.Spice.Graphics: color4f :: Float -> Float -> Float -> Float -> Scene
- FRP.Spice.Graphics: color4i :: Int -> Int -> Int -> Int -> Color
+ FRP.Spice.Graphics: color4i :: Int -> Int -> Int -> Int -> Scene
- FRP.Spice.Graphics: green :: Color
+ FRP.Spice.Graphics: green :: Scene
- FRP.Spice.Graphics: red :: Color
+ FRP.Spice.Graphics: red :: Scene
- FRP.Spice.Graphics: white :: Color
+ FRP.Spice.Graphics: white :: Scene

Files

spice.cabal view
@@ -1,5 +1,5 @@ name:                spice-version:             0.2.0.0+version:             0.3.0.0 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@@ -28,9 +28,11 @@                        FRP.Spice.Game                        FRP.Spice.Graphics.Color                        FRP.Spice.Graphics.Geometry+                       FRP.Spice.Graphics.Renderable                        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
src/FRP/Spice.hs view
@@ -2,7 +2,10 @@   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 FRP.Spice.Config+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@@ -10,6 +13,9 @@  ----------------------- -- 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
src/FRP/Spice/Engine.hs view
@@ -16,8 +16,8 @@ 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.Input import FRP.Spice.Game  ----------
src/FRP/Spice/Graphics.hs view
@@ -1,7 +1,8 @@ {-|   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 ( module FRP.Spice.Graphics.Renderable+                          , module FRP.Spice.Graphics.Geometry                           , module FRP.Spice.Graphics.Color                           , module FRP.Spice.Graphics.Scene                           , module FRP.Spice.Graphics.Utils@@ -9,6 +10,7 @@  ----------------------- -- Rexported Imports --+import FRP.Spice.Graphics.Renderable import FRP.Spice.Graphics.Geometry import FRP.Spice.Graphics.Color import FRP.Spice.Graphics.Scene
src/FRP/Spice/Graphics/Color.hs view
@@ -10,6 +10,8 @@  ------------------- -- Local Imports --+import FRP.Spice.Graphics.Renderable+import FRP.Spice.Graphics.Scene import FRP.Spice.Graphics.Utils  ----------@@ -28,23 +30,24 @@   deriving (Eq, Show, Read)  {-|-  Changes the current OpenGL context's rendering color to the @'Color'@+  Changing the current OpenGL context's @'Color4'@ to whatever @'Color'@   specified. -}-bindColor :: Color -> IO ()-bindColor (Color r g b a) =-  color $ Color4 (togl r) (togl g) (togl b) (togl a)+instance Renderable Color where+  toRender (Color r g b a) =+    Render $+      color $ Color4 (togl r) (togl g) (togl b) (togl a)  {-|   A synonym for the @'Color'@ constructor. -}-color4f :: Float -> Float -> Float -> Float -> Color-color4f = Color+color4f :: Float -> Float -> Float -> Float -> Scene+color4f r g b a = fromRenderables [Color r g b a]  {-|   Constructing a @'Color'@ from 3 @'Float'@s, defaulting the alpha mask to 1.0. -}-color3f :: Float -> Float -> Float -> Color+color3f :: Float -> Float -> Float -> Scene color3f r g b = color4f r g b 1.0  {-|@@ -54,7 +57,7 @@   also equivalent in source code) to calling color4f with each of its arguments   divided by 255.) -}-color4i :: Int -> Int -> Int -> Int -> Color+color4i :: Int -> Int -> Int -> Int -> Scene color4i r g b a = color4f (fromIntegral r / 255)                           (fromIntegral g / 255)                           (fromIntegral b / 255)@@ -63,35 +66,35 @@ {-|   Constructing a @'Color'@ from 3 @'Int'@s, defaulting the alpha mask to 255. -}-color3i :: Int -> Int -> Int -> Color+color3i :: Int -> Int -> Int -> Scene color3i r g b = color4i r g b 255  {-|   The color black. -}-black :: Color+black :: Scene black = color3i 0 0 0  {-|   The color white. -}-white :: Color+white :: Scene white = color3i 255 255 255  {-|   The color red. -}-red :: Color+red :: Scene red = color3i 255 0 0  {-|   The color green. -}-green :: Color+green :: Scene green = color3i 0 255 0  {-|   The color blue. -}-blue :: Color+blue :: Scene blue = color3i 0 0 255
src/FRP/Spice/Graphics/Geometry.hs view
@@ -2,14 +2,23 @@   This module provides a cleaner API to render a number of shapes in the   current OpenGL context. -}-module FRP.Spice.Graphics.Geometry where+module FRP.Spice.Graphics.Geometry ( renderPoint+                                   , renderRectangle+                                   , renderSquare+                                   ) where  -------------------- -- Global Imports ---import Graphics.Rendering.OpenGL+import Graphics.Rendering.OpenGL ( PrimitiveMode (..)+                                 , Vertex2 (..)+                                 , renderPrimitive+                                 , vertex+                                 )+import Control.Monad  ------------------- -- Local Imports --+import FRP.Spice.Graphics.Renderable import FRP.Spice.Graphics.Scene import FRP.Spice.Graphics.Utils import FRP.Spice.Math.Vector@@ -18,18 +27,35 @@ -- Code --  {-|+  The information necessary to construct any given OpenGL primitive. The+  @'PrimitiveMode'@ represents -- of course -- the kind of GL primitive to+  render. The list of @'Vector'@s directly represents the vertecies to bind.+-}+data Primitive = Primitive PrimitiveMode [Vector Float]++{-|+  Rendering whatever OpenGL primitive is specified.+-}+instance Renderable Primitive where+  toRender (Primitive mode vertecies) =+    Render $+      renderPrimitive mode $+        forM_ vertecies $ \(Vector x y) ->+          vertex $ Vertex2 (togl x) (togl y)++{-|   Rendering a point. -} renderPoint :: Vector Float -> Scene renderPoint pos =-  fromElements [Element Points [pos]]+  fromRenderables [Primitive Points [pos]]  {-|   Rendering a rectangle. -} renderRectangle :: Vector Float -> Vector Float -> Scene renderRectangle (Vector x y) (Vector w h) = do-  fromElements [ Element Quads [ Vector (x    ) (y    )+  fromRenderables [ Primitive Quads [ Vector (x    ) (y    )                                , Vector (x + w) (y    )                                , Vector (x + w) (y + h)                                , Vector (x    ) (y + h)
+ src/FRP/Spice/Graphics/Renderable.hs view
@@ -0,0 +1,22 @@+module FRP.Spice.Graphics.Renderable where++----------+-- Code --++{-|+  A container around IO to suggest that one should perform rendering in a+  rendering function.+-}+newtype Render = Render (IO ())++{-|+  Performing the IO contained in a @'Render'@.+-}+runRender :: Render -> IO ()+runRender (Render action) = action++{-|+  A class that provides an API to convert a datatype into a @'Render'@.+-}+class Renderable a where+  toRender :: a -> Render
src/FRP/Spice/Graphics/Scene.hs view
@@ -1,29 +1,24 @@-module FRP.Spice.Graphics.Scene where+module FRP.Spice.Graphics.Scene ( Scene+                                , fromRenderables+                                , renderScene+                                ) where  -------------------- -- Global Imports ---import Graphics.Rendering.OpenGL import Control.Applicative import Control.Monad  ------------------- -- Local Imports ---import FRP.Spice.Graphics.Utils-import FRP.Spice.Math.Vector+import FRP.Spice.Graphics.Renderable  ---------- -- Code --  {-|-  Purely specifying the rendering behavior of a single element. To be composed-  into @'FRP.Spice.Graphics.Scene'@s for a full rendering effect.--}-data Element = Element PrimitiveMode [Vector Float]--{-|-  For composing a scene out of a set of elements.+  For composing a scene out of a set of renderables. -}-data SceneT a = SceneT [Element] a+data SceneT a = SceneT [Render] a  {-|   The commonly used instance of SceneT@@ -34,7 +29,7 @@   Functor instance to satisfy applicative instance. -} instance Functor SceneT where-  fmap fn (SceneT elements v) = SceneT elements $ fn v+  fmap fn (SceneT renderables v) = SceneT renderables $ fn v  {-|   Applicative instance to satisfy the monad instance. Not advised to use@@ -49,30 +44,21 @@ -} instance Monad SceneT where   return a = SceneT [] a-  (SceneT elements v) >>= fn =-    let (SceneT elements' v') = fn v in-      SceneT (elements ++ elements') v'--{-|-  Rendering a single @'Element'@.--}-renderElement :: Element -> IO ()-renderElement (Element pm vs) =-  renderPrimitive pm $-    forM_ vs $ \(Vector x y) ->-      vertex $ Vertex2 (togl x) (togl y)+  (SceneT renderables v) >>= fn =+    let (SceneT renderables' v') = fn v in+      SceneT (renderables ++ renderables') v'  {-|-  Constructing a SceneT from a list of elements.+  Constructing a SceneT from a list of renderables. -}-fromElements :: [Element] -> Scene-fromElements elements =-  SceneT elements ()+fromRenderables :: Renderable a => [a] -> Scene+fromRenderables renderables =+  SceneT (map toRender renderables) ()  {-|   Rendering a whole @'Scene'@ (renders each @'Element'@ from first in list to last in   list.) -} renderScene :: Scene -> IO ()-renderScene (SceneT elements _) =-  forM_ elements renderElement+renderScene (SceneT renderables _) =+  forM_ renderables runRender
src/FRP/Spice/Input.hs view
@@ -1,49 +1,21 @@ {-|   This module provides everything relating to input in the scope of spice. -}-module FRP.Spice.Input ( module Rexport-                       , Sinks (..)-                       , Input (..)-                       , InputContainer (..)-                       , makeInputContainer-                       , makeMousePositionCallback-                       , makeKeyboardCallback-                       , makeMouseCallback-                       ) where+module FRP.Spice.Input where  -------------------- -- Global Imports ---import Data.Map.Strict hiding (keys, map)-import Graphics.Rendering.OpenGL-import Graphics.UI.GLFW as GLFW-import FRP.Elerea.Param+import Graphics.UI.GLFW+import Data.Map.Strict  ------------------- -- 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.Math.Vector-import FRP.Spice.Config---------------------------- Rexported Imports ---import Data.Map.Strict  as Rexport ((!))-import Graphics.UI.GLFW as Rexport (Key (..), SpecialKey (..), MouseButton (..))+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 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).@@ -52,65 +24,3 @@                    , keyboard      :: Map Key Bool                    , mouse         :: Map MouseButton Bool                    }--{-|-  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 :: WindowConfig -> InputContainer -> MousePosCallback-makeMousePositionCallback wc ic (Position x y) =-  mousePositionSinks (getSinks ic) $-    Vector (  fromIntegral x  / ((fromIntegral $ getWindowWidth  wc) / 2) - 1)-           ((-fromIntegral y) / ((fromIntegral $ getWindowHeight wc) / 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/Backend.hs view
@@ -0,0 +1,96 @@+{-|+  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++-------------------+-- 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.Config+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 :: WindowConfig -> InputContainer -> MousePosCallback+makeMousePositionCallback wc ic (Position x y) =+  mousePositionSinks (getSinks ic) $+    Vector (  fromIntegral x  / ((fromIntegral $ getWindowWidth  wc) / 2) - 1)+           ((-fromIntegral y) / ((fromIntegral $ getWindowHeight wc) / 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