summaryrefslogtreecommitdiff
path: root/TimeKeeper.hs
diff options
context:
space:
mode:
Diffstat (limited to 'TimeKeeper.hs')
-rw-r--r--TimeKeeper.hs40
1 files changed, 40 insertions, 0 deletions
diff --git a/TimeKeeper.hs b/TimeKeeper.hs
new file mode 100644
index 0000000..d85f61f
--- /dev/null
+++ b/TimeKeeper.hs
@@ -0,0 +1,40 @@
1{-# LANGUAGE LambdaCase #-}
2{-# LANGUAGE PatternSynonyms #-}
3module TimeKeeper where
4
5import Data.Int
6import Data.Word
7import GI.Gtk as Gtk
8import GI.Gdk.Objects
9import GI.GLib.Constants (pattern SOURCE_CONTINUE,pattern SOURCE_REMOVE)
10
11import Control.Concurrent
12
13-- | Type alias to mark a value returned by 'widgetAddTickCallback'.
14type TickCallbackHandle = Word32
15
16data TimeKeeper = TimeKeeper
17 { tmSeconds :: MVar Double
18 , tmFirstFrame :: MVar Int64
19 }
20
21newTimeKeeper :: IO TimeKeeper
22newTimeKeeper = do
23 s <- newMVar 0.0
24 ff <- newMVar 0
25 return $ TimeKeeper s ff
26
27tick :: TimeKeeper -> Widget -> FrameClock -> IO Bool
28tick tm widget clock = widgetGetWindow widget >>= \case
29 Nothing -> return SOURCE_REMOVE
30 Just win -> do
31 windowInvalidateRect win Nothing False
32 micros <- frameClockGetFrameTime clock
33 ff <- modifyMVar (tmFirstFrame tm) $ \prev ->
34 if prev == 0 then return (micros, micros)
35 else return (prev, prev)
36 secs <- modifyMVar (tmSeconds tm) $ \_ -> do
37 let secs = fromIntegral (micros - ff) / 1000000.0
38 return (secs,secs)
39 return SOURCE_CONTINUE
40