module Graphics.UI.GLFW.Task
(
Event(..)
, onKey
, onChar
, onButton
, onPos
, onWheel
, onSize
, onClose
, onRefresh
, isKey
, isChar
, isButton
, isPress
, isRelease
, registerTaskCallbacks
) where
import Control.Concurrent
import Graphics.UI.GLFW
import qualified Graphics.Rendering.OpenGL as GL
import Graphics.Rendering.OpenGL (($=))
import Control.Monad.IO.Class
import Control.Monad.Task.Class
data Event
= KeyEvent Key KeyButtonState
| CharEvent Char KeyButtonState
| MouseButtonEvent MouseButton KeyButtonState
| MousePosEvent GL.Position
| MouseWheelEvent Int
| WindowSizeEvent GL.Size
| WindowCloseEvent
| WindowRefreshEvent
deriving (Eq, Show)
onKey :: Event -> Maybe (Key, KeyButtonState)
onKey (KeyEvent k s) = Just (k, s)
onKey _ = Nothing
onChar :: Event -> Maybe (Char, KeyButtonState)
onChar (CharEvent ch s) = Just (ch, s)
onChar _ = Nothing
onButton :: Event -> Maybe (MouseButton, KeyButtonState)
onButton (MouseButtonEvent b s) = Just (b, s)
onButton _ = Nothing
onPos :: Event -> Maybe GL.Position
onPos (MousePosEvent p) = Just p
onPos _ = Nothing
onWheel :: Event -> Maybe Int
onWheel (MouseWheelEvent w) = Just w
onWheel _ = Nothing
onSize :: Event -> Maybe GL.Size
onSize (WindowSizeEvent s) = Just s
onSize _ = Nothing
onClose :: Event -> Maybe ()
onClose WindowCloseEvent = Just ()
onClose _ = Nothing
onRefresh :: Event -> Maybe ()
onRefresh WindowRefreshEvent = Just ()
onRefresh _ = Nothing
isKey :: Enum a => a -> Key -> Maybe ()
isKey key k | fromEnum k == fromEnum key = Just ()
| otherwise = Nothing
isChar :: Char -> Char -> Maybe ()
isChar ch c | ch == c = Just ()
| otherwise = Nothing
isButton :: MouseButton -> MouseButton -> Maybe ()
isButton but b | b == but = Just ()
| otherwise = Nothing
isPress, isRelease :: (a, KeyButtonState) -> Maybe a
isPress (b, s) | s == Press = Just b
| otherwise = Nothing
isRelease (b, s) | s == Release = Just b
| otherwise = Nothing
registerTaskCallbacks :: (MonadIO m, MonadTask Event m) => IO (m ())
registerTaskCallbacks = do
q <- newMVar []
let enqueue = modifyMVar_ q . (return .) . (:)
dequeue = modifyMVar q $ return . ([],)
windowRefreshCallback $= enqueue WindowRefreshEvent
windowSizeCallback $= enqueue . WindowSizeEvent
windowCloseCallback $= (enqueue WindowCloseEvent >> return True)
keyCallback $= (enqueue .) . KeyEvent
charCallback $= (enqueue .) . CharEvent
mouseButtonCallback $= (enqueue .) . MouseButtonEvent
mousePosCallback $= enqueue . MousePosEvent
mouseWheelCallback $= enqueue . MouseWheelEvent
return (liftIO (waitEvents >> dequeue) >>= mapM_ signal . reverse)