typed-fsm-0.1.0.0: examples/motion/Handler.hs
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE NumericUnderscores #-}
{-# LANGUAGE QualifiedDo #-}
{-# LANGUAGE TypeFamilies #-}
{-# OPTIONS_GHC -Wall #-}
module Handler where
import Control.Concurrent.STM (atomically)
import Control.Concurrent.STM.TChan
import Control.Monad.State
import Data.IFunctor (At (..), returnAt)
import qualified Data.IFunctor as I
import GHC.Event
import Lens.Micro.Mtl
import SDL
import Type
import TypedFsm.Core
import TypedFsm.Driver
timeoutSize :: Int
timeoutSize = 400_000
myRegisterTimeout :: StateT MotionState IO (TimerManager, TimeoutKey)
myRegisterTimeout = do
chan <- use channel
liftIO $ do
tm <- getSystemTimerManager
tk <- registerTimeout tm timeoutSize (atomically $ writeTChan chan ())
pure (tm, tk)
idelHandler :: Op Motion MotionState IO () Exit Idle
idelHandler = I.do
msg <- getInput
case msg of
ExitMotion -> returnAt ()
MoveIn pos tms -> I.do
At tp <- liftm $ do
mousePos .= pos
(tm, tk) <- myRegisterTimeout
pure (tm, tk, tms)
overHandler tp
overHandler :: (TimerManager, TimeoutKey, Timestamp) -> Op Motion MotionState IO () Exit Over
overHandler (tm, tk, oldtms) = I.do
msg <- getInput
case msg of
ExitMotion -> returnAt ()
MoveOut -> I.do
liftm $ liftIO $ unregisterTimeout tm tk
idelHandler
InMove pos tms -> I.do
liftm $ do
mousePos .= pos
if tms - oldtms > 40
then I.do
liftm $ liftIO $ updateTimeout tm tk timeoutSize
overHandler (tm, tk, tms)
else overHandler (tm, tk, oldtms)
TimeoutH -> I.do
liftm $ do
liftIO $ unregisterTimeout tm tk
pos <- use mousePos
onHover .= Just (pos, [show oldtms, show pos])
hoverHandler
hoverHandler :: Op Motion MotionState IO () Exit Hover
hoverHandler = I.do
msg <- getInput
case msg of
ExitMotion -> returnAt ()
HInMove pos tms -> I.do
At tp <- liftm $ do
mousePos .= pos
onHover .= Nothing
(tm, tk) <- myRegisterTimeout
pure (tm, tk, tms)
overHandler tp
HMoveOut -> I.do
liftm $ onHover .= Nothing
idelHandler