summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Benjamin Barenblat <bbaren@mit.edu>2015-05-27 22:04:48 -0400
committerGravatar Benjamin Barenblat <bbaren@mit.edu>2015-05-27 22:04:48 -0400
commit9ca0fcc6e90fef6f7adece3db7f168c9307e2864 (patch)
tree6c42ae9a93394f86ff985e3e4b55876027c49b13
parent545c4cbcde31596e64a03f49f2ad64e619d91e5b (diff)
Simple demonstration of multiple producers
This doesn’t work the way it should, though – something is wrong with my threading.
-rw-r--r--jarvis.cabal4
-rw-r--r--src/Main.hs65
2 files changed, 58 insertions, 11 deletions
diff --git a/jarvis.cabal b/jarvis.cabal
index 9f201e7..8695548 100644
--- a/jarvis.cabal
+++ b/jarvis.cabal
@@ -30,6 +30,8 @@ executable jarvis
main-is: Main.hs
-- other-modules:
build-depends: base >=4.6 && <4.7
+ , data-default-class >=0.0.1 && <0.1
+ , vty >=5.2.3 && <5.3
hs-source-dirs: src
default-language: Haskell2010
-- extensions:
@@ -40,3 +42,5 @@ executable jarvis
-fwarn-missing-signatures
-fwarn-orphans
-fwarn-unused-do-bind
+ -threaded
+ -with-rtsopts=-N
diff --git a/src/Main.hs b/src/Main.hs
index 3edefe2..9d3906c 100644
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -14,18 +14,61 @@
module Main (main) where
-import Control.Monad (forever)
-import System.IO (hFlush, stdout)
+import Control.Concurrent (forkIO, threadDelay)
+import Control.Concurrent.SampleVar
+import Control.Monad (forever, void)
+import Data.Default.Class (def)
+import Graphics.Vty (Vty, (<->), (<|>))
+import qualified Graphics.Vty as Vty
main :: IO ()
-main = forever $
- readCommand >>= evaluate
+main = do
+ terminal <- Vty.mkVty def
+ initialize terminal
+ jarvis terminal
+ Vty.shutdown terminal
-readCommand :: IO String
-readCommand = do
- putStr "> " >> hFlush stdout
- getLine
+initialize :: Vty -> IO ()
+initialize _ = return ()
-evaluate :: String -> IO ()
-evaluate command =
- putStrLn $ "Got command ‘" ++ command ++ "’"
+jarvis :: Vty -> IO ()
+jarvis terminal = do
+ log <- newSampleVar Vty.emptyImage
+ prompt <- newSampleVar Vty.emptyImage
+ ready <- newEmptySampleVar
+ void $ forkIO $ redrawer ready log prompt terminal
+ void $ forkIO $ prompter prompt ready
+ void $ forkIO $ logger log ready
+ void $ Vty.nextEvent terminal
+
+prompter :: SampleVar Vty.Image -> SampleVar () -> IO ()
+prompter output redraw = prompt' 0
+ where prompt' n = do
+ writeSampleVar output $ Vty.string def ("jarvis " ++ show n ++ " >")
+ writeSampleVar redraw ()
+ threadDelay 1000000
+ prompt' (n + 1)
+
+logger :: SampleVar Vty.Image -> SampleVar () -> IO ()
+logger output redraw = log 0 []
+ where log n lines = do
+ let lines' = lines ++ ["<" ++ show n ++ ">"]
+ writeSampleVar output $ Vty.vertCat $ map (Vty.string def) lines'
+ writeSampleVar redraw ()
+ threadDelay 200000
+ log (n + 1) lines'
+
+redrawer :: SampleVar () -> SampleVar Vty.Image -> SampleVar Vty.Image -> Vty -> IO ()
+redrawer ready log prompt terminal = forever $ do
+ void $ readSampleVar ready
+ (_maxX, maxY) <- Vty.displayBounds $ Vty.outputIface terminal
+ images <- sequence $ map readSampleVar [log, prompt]
+ let stack = resizeHeight' maxY $ Vty.vertCat images
+ Vty.update terminal $ Vty.picForImage stack
+ Vty.refresh terminal
+
+resizeHeight' :: Int -> Vty.Image -> Vty.Image
+resizeHeight' h i = case h `compare` Vty.imageHeight i of
+ LT -> Vty.cropTop h i
+ EQ -> i
+ GT -> Vty.translateY (h - Vty.imageHeight i) i