module FRP.Spice.Input.Backend where
import Graphics.Rendering.OpenGL
import Graphics.UI.GLFW as GLFW
import FRP.Elerea.Param
import Data.Map.Strict
import Data.IORef
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
data Sinks = Sinks { mousePositionSinks :: Vector Float -> IO ()
, keyboardSinks :: Map Key (Bool -> IO ())
, mouseSinks :: Map MouseButton (Bool -> IO ())
}
data InputContainer = InputContainer { getSinks :: Sinks
, getInput :: Signal Input
}
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
}
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)
makeKeyboardCallback :: InputContainer -> KeyCallback
makeKeyboardCallback ic key state =
keyboardSinks (getSinks ic) ! key $ case state of
Press -> True
Release -> False
makeMouseCallback :: InputContainer -> MouseButtonCallback
makeMouseCallback ic button state =
mouseSinks (getSinks ic) ! button $ case state of
Press -> True
Release -> False