-- | A Peakachu backend to write output to the console module FRP.Peakachu.Backend.StdIO ( stdoutB, interactB ) where import FRP.Peakachu.Backend (Backend(..)) import FRP.Peakachu.Backend.Internal (Sink(..), MainLoop(..), ParallelIO(..)) import Control.Concurrent.MVar.YC (writeMVar) import Control.Concurrent.MVar (newMVar, putMVar, readMVar, takeMVar) import Control.Monad (when) import Data.Monoid (mempty) import System.IO (hFlush, hReady, stdin, stdout) stdoutB :: Backend String () stdoutB = Backend . return . return $ mempty { sinkConsume = (>> hFlush stdout) . putStr } whileM :: Monad m => m Bool -> m () -> m () whileM cond iter = do resume <- cond when resume $ do iter whileM cond iter -- | The Peakachu equivalent to 'interact'. -- Prints all output lines from the program, and feeds -- input lines from the user to the program. interactB :: Backend String String interactB = Backend f where f handler = do resumeVar <- newMVar True lineVar <- newMVar "" return Sink { sinkConsume = putStrLn , sinkMainLoop = mempty { mlQuit = writeMVar resumeVar False , mlRun = Just . ParIO . whileM (readMVar resumeVar) $ do isReady <- hReady stdin when isReady $ do c <- getChar prevLine <- takeMVar lineVar case c of '\n' -> do _ <- handler prevLine putMVar lineVar "" _ -> putMVar lineVar $ prevLine ++ [c] } }