module EventQueue (
EventQueue
, newQueue
, emitTriggerAll
, emitModified
, emitDone
, processQueue
) where
import Prelude ()
import Prelude.Compat
import Control.Monad.Compat
import Control.Concurrent (threadDelay)
import Control.Concurrent.STM.TChan
import Control.Monad.STM
import Data.List.Compat
import Util
type EventQueue = TChan Event
data Event = TriggerAll | Modified FilePath | Done
deriving Eq
newQueue :: IO EventQueue
newQueue = atomically $ newTChan
emitTriggerAll :: EventQueue -> IO ()
emitTriggerAll chan = atomically $ writeTChan chan TriggerAll
emitModified :: FilePath -> EventQueue -> IO ()
emitModified path chan = atomically $ writeTChan chan (Modified path)
emitDone :: EventQueue -> IO ()
emitDone chan = atomically $ writeTChan chan Done
readEvents :: EventQueue -> IO [Event]
readEvents chan = do
e <- atomically $ readTChan chan
unless (isKeyboardInput e) $ do
threadDelay 100000
es <- atomically emptyQueue
return (e : es)
where
isKeyboardInput :: Event -> Bool
isKeyboardInput event = event == Done || event == TriggerAll
emptyQueue :: STM [Event]
emptyQueue = do
mEvent <- tryReadTChan chan
case mEvent of
Nothing -> return []
Just e -> (e :) <$> emptyQueue
processQueue :: EventQueue -> IO () -> IO () -> IO ()
processQueue chan triggerAll trigger = go
where
go = do
readEvents chan >>= \case
events | Done `elem` events -> return ()
events | TriggerAll `elem` events -> do
triggerAll
go
events -> do
let files = (nub . sort) [p | Modified p <- events]
withInfoColor $ do
mapM_ putStrLn (map ("--> " ++) files)
trigger
go