packages feed

shaker-0.1: src/Shaker/Listener.hs

module Shaker.Listener(
  listen
  ,initialize
  ,schedule
  ,updateFileStat
  ,ListenState(ListenState,threadIds,modifiedFiles,currentFiles)
)
where

import Control.Monad
import Control.Concurrent.MVar
import Control.Concurrent
import Shaker.Type
import Shaker.Io

-- | MVar used to store currentFiles listed
type CurrentFiles = MVar [FileInfo]
-- | MVar used to store modifiedFiles since the last check
type ModifiedFiles = MVar [FileInfo]
-- | MVar used to pass action to the directory scanner
type Job = MVar [FileListenInfo]

-- | Agregate all information of listener
data ListenState = ListenState {
  currentFiles :: CurrentFiles  -- ^ Files found in the last check
  ,modifiedFiles :: ModifiedFiles -- ^ Differences between last and before last check
  ,threadIds :: [ThreadId] -- ^ List of all forks id initialized
}

-- | initialize the mvar and launch forks
initialize :: ListenerInput -> IO ListenState
initialize lstInput = do
  mC <- newMVar [] 
  mM <- newEmptyMVar
  mJ <- newEmptyMVar 
  idLst <- forkIO $ forever $ listen mC mM mJ
  idSch <- forkIO $ forever $ schedule lstInput mJ
  return $ ListenState mC mM [idLst,idSch]

-- | manage the job box. Fill it with a job every delay
schedule :: ListenerInput -> Job -> IO()
schedule lstInput mJ = do
  putMVar mJ $ fileListenInfo lstInput
  threadDelay $ delay lstInput
  return ()
     
-- | listen to the job box and process the job
listen :: CurrentFiles -> ModifiedFiles -> Job -> IO ()
listen mC mM mJ = do 
  job <- takeMVar mJ
  curFiles <- readMVar mC 
  (newFiles,modFiles) <- listModifiedAndCreatedFiles job curFiles
  updateFileStat mC mM newFiles modFiles 
  return ()

-- | Update the files status
updateFileStat :: CurrentFiles -> ModifiedFiles -> [FileInfo] -> [FileInfo] -> IO ()
updateFileStat _ _ _ [] = return ()
updateFileStat mC mM curFiles curMod = do
  _ <- swapMVar mC curFiles 
  putMVar mM curMod 
  return()