diff options
author | Andrew Cady <d@jerkface.net> | 2015-12-06 03:07:52 -0500 |
---|---|---|
committer | Andrew Cady <d@jerkface.net> | 2015-12-06 03:07:59 -0500 |
commit | 38b6cd686acd70b0d94271e8256cd573ecc52ced (patch) | |
tree | b8c87b4e23f7beaccbb79d06aef5044757fa0730 /rtq.hs | |
parent | 3f83abf93d0870f3420b6efe900949fc3f6f74ba (diff) |
Document/tweak RealTimeQueue & its example program
Diffstat (limited to 'rtq.hs')
-rw-r--r-- | rtq.hs | 66 |
1 files changed, 39 insertions, 27 deletions
@@ -1,46 +1,58 @@ | |||
1 | {-# LANGUAGE FlexibleContexts #-} | ||
2 | {-# LANGUAGE ExplicitForAll #-} | ||
3 | {-# LANGUAGE KindSignatures #-} | ||
4 | |||
5 | import BasePrelude hiding ((.)) | 1 | import BasePrelude hiding ((.)) |
6 | import RealTimeQueue | 2 | import RealTimeQueue as Q |
7 | import Control.Monad.IO.Class | 3 | import Control.Monad.IO.Class |
8 | import Control.Monad.State | 4 | import Control.Monad.State |
9 | import System.Clock | 5 | import System.Clock |
10 | 6 | ||
11 | data LoopState = LoopState { | 7 | data LoopState = LoopState { |
12 | _queue :: Queue String | 8 | _queue :: Queue String, |
9 | _lastAction :: TimeSpec, | ||
10 | _beforeActing :: TimeSpec | ||
13 | } | 11 | } |
14 | 12 | ||
13 | type Loop r = StateT LoopState IO r | ||
14 | |||
15 | main :: IO () | 15 | main :: IO () |
16 | main = void $ runStateT main' (LoopState createQueue) | 16 | main = void $ runStateT (queueSomeStuff >> mainLoop) (LoopState createQueue (TimeSpec 0 0) (TimeSpec 0 0)) |
17 | 17 | where | |
18 | main' :: StateT LoopState IO () | 18 | queueSomeStuff = do |
19 | main' = do | 19 | now <- liftIO $ getTime Monotonic |
20 | queueAction $ scheduleEventIO (TimeSpec 1 0, "hello world") | 20 | modify $ \s -> s { _beforeActing = now, _lastAction = now } |
21 | queueAction $ scheduleEventIO (TimeSpec 2 0, "hello world") | 21 | forM_ [1,2,4,8,9,10,11,12] $ \i -> queueAction $ scheduleEventIO (TimeSpec i 0, "hello world " ++ show i) |
22 | queueAction $ scheduleEventIO (TimeSpec 3 0, "hello world") | 22 | |
23 | queueAction $ scheduleEventIO (TimeSpec 4 0, "hello world") | 23 | mainLoop :: Loop () |
24 | mainLoop = do | ||
25 | queueAction $ runScheduledIO tickTime runner | ||
26 | unlessEmptyQueue $ do | ||
27 | liftIO $ threadDelay' tickTime | ||
24 | mainLoop | 28 | mainLoop |
25 | 29 | ||
26 | queueAction :: forall (m :: * -> *). MonadState LoopState m => (Queue String -> m (Queue String)) -> m () | 30 | queueAction :: (Queue String -> Loop (Queue String)) -> Loop () |
27 | queueAction act = do | 31 | queueAction act = do |
28 | q <- gets _queue | 32 | q <- gets _queue |
29 | act q >>= modify . const . LoopState | 33 | act q >>= \q' -> modify $ \s -> s { _queue = q' } |
30 | 34 | ||
31 | tickTime :: TimeSpec | 35 | tickTime :: TimeSpec |
32 | tickTime = TimeSpec 0 15000 | 36 | tickTime = TimeSpec 0 1000 |
33 | 37 | ||
34 | threadDelay' :: TimeSpec -> IO () | 38 | threadDelay' :: TimeSpec -> IO () |
35 | threadDelay' = threadDelay . fromIntegral . timeSpecAsNanoSecs | 39 | threadDelay' = threadDelay . fromIntegral . timeSpecAsNanoSecs |
36 | 40 | ||
37 | runner :: TimeSpec -> String -> StateT LoopState IO () | 41 | timeSpecAsDouble :: TimeSpec -> Double |
38 | runner delay str = liftIO $ do | 42 | timeSpecAsDouble ts = x / (10^(9::Int)) where x = fromIntegral $ timeSpecAsNanoSecs ts |
39 | threadDelay' delay | 43 | |
40 | putStrLn str | 44 | runner :: (TimeSpec, String) -> Loop () |
41 | 45 | runner (delay, str) = do | |
42 | mainLoop :: StateT LoopState IO () | 46 | before <- gets _lastAction |
43 | mainLoop = do | 47 | muchBefore <- gets _beforeActing |
44 | queueAction $ runScheduledIO tickTime runner | 48 | after <- liftIO $ do |
45 | liftIO $ threadDelay' tickTime | 49 | threadDelay' delay |
46 | mainLoop | 50 | now <- liftIO $ getTime Monotonic |
51 | print (now, str, timeSpecAsDouble $ now - before, timeSpecAsDouble $ now - muchBefore) | ||
52 | return now | ||
53 | modify $ \s -> s { _lastAction = after } | ||
54 | |||
55 | unlessEmptyQueue :: Loop () -> Loop () | ||
56 | unlessEmptyQueue f = do | ||
57 | q <- gets _queue | ||
58 | unless (Q.null q) f | ||