on master help sign in
use threaded runtime and forkOS to resolve issues with VMIN and VTIME
commitc9155d7dec43928b1edcf94d2c05ad3d92074584 authorCorey O'Connor <corey@ooyala.com> dateWed 22 Jan 2014, 15:26 (13 years ago) parenteb15f26
4 files changed+21−12
CHANGELOG+1 src/Graphics/Vty/Input.hs+5−3 src/Graphics/Vty/Input/Internal.hs+11−9 test/vty-examples.cabal+4
CHANGELOG+1
@@ -1,4 +1,5 @@
115.0.0
2+ * all projects using vty must be compiled with -threaded.
23 * input handling changes
34 * KASCII is now KChar
45 * KPN5 is now KCenter
src/Graphics/Vty/Input.hs+5−3
@@ -28,9 +28,11 @@
2828-- 3. ESC used as meta in a key combination: ESC byte, no other bytes read within
2929-- control-seq-period. Bytes up until next valid input block are the input events plus meta.
3030--
31−-- This, as best I can figure, is what VMIN and VTIME are supposed to be for. For some reason vty
32−-- implements the timing in the library. I'm not sure if this is an advantage or not. Getting this
33−-- right has provided a strangely interesting task so I haven't cared to determine.
31+-- If the current runtime is the threaded runtime then the terminal's VMIN and VTIME parameters can
32+-- be applied to implement the above rules.
33+-- If the current runtime does not support forkOS then there is currently no implementation. Vty
34+-- used to implement a parser which did tricky things with non-blocking reads and timers. This could
35+-- be revived.
3436module Graphics.Vty.Input ( Key(..)
3537 , Modifier(..)
3638 , Button(..)
src/Graphics/Vty/Input/Internal.hs+11−9
@@ -86,6 +86,8 @@ makeLenses ''InputState
8686
8787type InputM a = StateT InputState (ReaderT Input IO) a
8888
89+-- this must be run on an OS thread dedicated to this input handling.
90+-- otherwise the terminal timing read behavior will block the execution of the lightweight threads.
8991loop_input_processor :: InputM ()
9092loop_input_processor = do
9193 read_from_device >>= add_bytes_to_process
@@ -117,7 +119,7 @@ read_from_device = do
117119apply_timing_config :: Fd -> Config -> IO ()
118120apply_timing_config fd config =
119121 let vtime = min 255 $ singleEscPeriod config `div` 100000
120− in set_term_timing fd 0 vtime
122+ in set_term_timing fd 1 vtime
121123
122124parse_event :: InputM Event
123125parse_event = do
@@ -152,16 +154,16 @@ compile table = cl' where
152154 -- create a map from strings to event
153155 event_for_input = flip M.lookup (M.fromList table)
154156 cl' [] = Prefix
155− cl' input_block = case S.member input_block prefix_set of
156− True -> Prefix
157− -- if the input_block is exactly what is expected for an event then consume the whole
158− -- block and return the event
159− False -> case event_for_input input_block of
160− Just (EvKey k m) -> Valid k m []
157+ cl' input_block = case event_for_input input_block of
158+ Just (EvKey k m) -> Valid k m []
159+ Nothing -> case S.member input_block prefix_set of
160+ True -> Prefix
161+ -- if the input_block is exactly what is expected for an event then consume the whole
162+ -- block and return the event
161163 -- look up progressively large prefixes of the input block until an event is found
162164 -- H: There will always be one match. The prefix_set contains, by definition, all
163165 -- prefixes of an event.
164− Nothing ->
166+ False ->
165167 let input_prefixes = init $ inits input_block
166168 in case mapMaybe (\s -> (,) s `fmap` event_for_input s) input_prefixes of
167169 (s,EvKey k m) : _ -> Valid k m (drop (length s) input_block)
@@ -218,7 +220,7 @@ initInputForFd config_ref classify_table input_fd = do
218220 <*> pure (writeIORef stop_flag True)
219221 <*> pure config_ref
220222 <*> pure input_fd
221− _ <- forkIO $ run_input_processor_loop classify_table input stop_flag
223+ _ <- forkOS $ run_input_processor_loop classify_table input stop_flag
222224 return input
223225
224226foreign import ccall "vty_set_term_timing" set_term_timing :: Fd -> Int -> Int -> IO ()
test/vty-examples.cabal+4
@@ -25,6 +25,7 @@ executable vty-interactive-terminal-test
2525
2626 default-language: Haskell2010
2727 default-extensions: ScopedTypeVariables
28+ ghc-options: -threaded
2829
2930 build-depends: vty,
3031 base >= 4 && < 5,
@@ -48,6 +49,7 @@ executable vty-event-echo
4849
4950 default-language: Haskell2010
5051 default-extensions: ScopedTypeVariables
52+ ghc-options: -threaded
5153
5254 build-depends: vty,
5355 base >= 4 && < 5,
@@ -66,6 +68,7 @@ executable vty-rouge
6668
6769 default-language: Haskell2010
6870 default-extensions: ScopedTypeVariables
71+ ghc-options: -threaded
6972
7073 build-depends: vty,
7174 base >= 4 && < 5,
@@ -85,6 +88,7 @@ executable vty-benchmark
8588
8689 default-language: Haskell2010
8790 default-extensions: ScopedTypeVariables
91+ ghc-options: -threaded
8892
8993 build-depends: vty,
9094 base >= 4 && < 5,