hbro-1.2.0.0: library/Hbro/IPC/Hooks.hs
{-# LANGUAGE TemplateHaskell #-}
module Hbro.IPC.Hooks where
-- {{{ Imports
import Hbro.Error
import Hbro.IPC.Signals
import Hbro.Prelude
import Control.Lens hiding(Action)
import Control.Monad.Reader
import Data.Map as M
-- }}}
-- {{{ Types
type Action m = [Argument] -> (m Response) -- ^ Actions may depend on arguments
newtype Hooks m = Hooks (Map Command (Action m)) -- ^ Map commands to actions
-- }}}
-- | Bind a new command to an action
bind :: Command -> Action m -> Hooks m -> Hooks m
bind command f (Hooks hooks) = Hooks $ M.insert command f hooks
-- |
dequeue :: (BaseIO m) => a -> Signals -> TVar (Hooks (ExceptT Text (ReaderT a m))) -> m ()
dequeue globalContext signals bindings = forever $ do
(Command c, arguments) <- atomically . takeTMVar $ nextCommand
(Hooks theBindings) <- atomically $ readTVar bindings
-- result <- (`runReaderT` globalContext) . handleAll (return . Left . show) $ do
result <- (`runReaderT` globalContext) . runExceptT $ do
f <- return (M.lookup (Command c) theBindings) <!> ("Unknown command: " ++ c)
f arguments
atomically . putTMVar response $ join result
where
nextCommand = signals^.nextCommandL
response = signals^.responseL