diff --git a/posix/Reanimate/FileWatch.hs b/posix/Reanimate/FileWatch.hs new file mode 100644 index 0000000..e259f06 --- /dev/null +++ b/posix/Reanimate/FileWatch.hs @@ -0,0 +1,18 @@ +module Reanimate.FileWatch + ( watchFile ) where + +import Control.Concurrent +import System.Directory + +watchFile :: FilePath -> IO () -> IO () +watchFile path handler = do + t0 <- getModificationTime path + forkIO $ loop t0 + return () + where + loop lastModTime = do + t1 <- getModificationTime path + if t1 /= lastModTime + then handler >> loop t1 + else threadDelay (10^3 * delay) >> loop lastModTime + delay = 1000 -- pool delay in ms. diff --git a/reanimate.cabal b/reanimate.cabal index e43d9c7..9a96b6d 100644 --- a/reanimate.cabal +++ b/reanimate.cabal @@ -32,6 +32,10 @@ Source-Repository head Type: git Location: git://github.com/lemmih/reanimate.git +Flag inotify + Description: Enable file watching using linux's inotify + Default: True + library hs-source-dirs: src default-language: Haskell2010 @@ -48,14 +52,21 @@ library Reanimate.Misc other-modules: Reanimate.Svg.NamedColors Reanimate.Cache + Reanimate.FileWatch Paths_reanimate build-depends: base >=4.10 && <4.13, time, text, unix, filepath, process, directory, containers, reanimate-svg >= 0.7.0.0, xml, bytestring, lens, linear, mtl, matrix, JuicyPixels, attoparsec, parallel, diagrams, diagrams-svg, diagrams-core, diagrams-lib, diagrams-contrib, - svg-builder, matrices, cubicbezier, palette, hinotify, websockets, + svg-builder, matrices, cubicbezier, palette, websockets, hashable + if flag(inotify) + hs-source-dirs: unix + build-depends: hinotify + else + hs-source-dirs: posix + Flag server Description: Enable rendering server diff --git a/src/Reanimate/Driver.hs b/src/Reanimate/Driver.hs index 5a2464f..5e459a1 100644 --- a/src/Reanimate/Driver.hs +++ b/src/Reanimate/Driver.hs @@ -7,7 +7,7 @@ import qualified Data.Text as T import Network.WebSockets import System.Directory (findFile, listDirectory) import System.Environment (getArgs, getProgName) -import System.INotify (EventVariety (..), addWatch, withINotify) +import Reanimate.FileWatch (watchFile) import System.IO (BufferMode (..), hPutStrLn, hSetBuffering, stderr, stdin) @@ -38,7 +38,7 @@ reanimate animation = do case mbSelf of Nothing -> do hPutStrLn stderr "Failed to find own source code." - Just self -> withINotify $ \notify -> do + Just self -> do conn <- acceptRequest pending slave <- newEmptyMVar let handler = modifyMVar_ slave $ \tid -> do @@ -66,7 +66,7 @@ reanimate animation = do loop (frame : acc) return tid putStrLn "Found self. Listening." - addWatch notify [Modify] self (const handler) + watchFile self handler putMVar slave =<< forkIO (return ()) let loop = do fps <- receiveData conn :: IO T.Text diff --git a/unix/Reanimate/FileWatch.hs b/unix/Reanimate/FileWatch.hs new file mode 100644 index 0000000..b9ba747 --- /dev/null +++ b/unix/Reanimate/FileWatch.hs @@ -0,0 +1,10 @@ +module Reanimate.FileWatch + ( watchFile ) where + +import System.INotify + +watchFile :: FilePath -> IO () -> IO () +watchFile path handler = do + notify <- initINotify + addWatch notify [Modify] path (const handler) + return ()