diff options
author | Andrew Cady <d@cryptonomic.net> | 2022-09-15 23:33:47 -0400 |
---|---|---|
committer | Andrew Cady <d@cryptonomic.net> | 2022-09-15 23:36:49 -0400 |
commit | f5645f4fa3b00c68bacd7f8ddd8da71e1430d667 (patch) | |
tree | f51319bc54b4286c99042856975c960b97f2e063 | |
parent | fab434598d0958c9cdc339822017748cc5bd2461 (diff) |
fix clock
Now we use the queued time as the time to display (regardless of the
clock time when it triggers).
This helps prevent dropping seconds from the display when time warp is
used.
-rwxr-xr-x | countdown.hs | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/countdown.hs b/countdown.hs index b53a3a4..a7d1377 100755 --- a/countdown.hs +++ b/countdown.hs | |||
@@ -12,6 +12,7 @@ | |||
12 | {-# language TemplateHaskell #-} | 12 | {-# language TemplateHaskell #-} |
13 | {-# language ViewPatterns #-} | 13 | {-# language ViewPatterns #-} |
14 | import Rebase.Prelude hiding (toList, on, (<+>)) | 14 | import Rebase.Prelude hiding (toList, on, (<+>)) |
15 | import qualified Rebase.Prelude as Prelude | ||
15 | import Control.Lens hiding ((<|)) | 16 | import Control.Lens hiding ((<|)) |
16 | import Data.Foldable (toList) | 17 | import Data.Foldable (toList) |
17 | import Data.Ratio | 18 | import Data.Ratio |
@@ -266,21 +267,23 @@ commasF precision = prettyF cfg | |||
266 | commas :: Integral i => i -> Text | 267 | commas :: Integral i => i -> Text |
267 | commas = prettyI (Just ',') . fromIntegral | 268 | commas = prettyI (Just ',') . fromIntegral |
268 | 269 | ||
269 | microsecondsUntil :: Integral i => UTCTime -> UTCTime -> i | 270 | nextWholeSecond :: ZonedTime -> ZonedTime |
270 | microsecondsUntil now later = floor $ nominalDiffTimeToSeconds $ (later `diffUTCTime` now) * 1000 * 1000 | 271 | nextWholeSecond (ZonedTime (LocalTime day (TimeOfDay h m s)) z) = (ZonedTime (LocalTime day (TimeOfDay h m s')) z) |
271 | |||
272 | nextWholeSecond :: UTCTime -> UTCTime | ||
273 | nextWholeSecond (UTCTime day dayTime) = (UTCTime day dayTime') | ||
274 | where | 272 | where |
275 | dayTime' = secondsToDiffTime $ floor dayTime + 1 | 273 | s' = fromIntegral $ (floor s + 1 :: Int) |
276 | 274 | ||
277 | threadDelayUntil :: UTCTime -> UTCTime -> IO () | 275 | diffZonedTime :: ZonedTime -> ZonedTime -> NominalDiffTime |
278 | threadDelayUntil now t = threadDelay $ microsecondsUntil now t | 276 | diffZonedTime = diffLocalTime `Prelude.on` zonedTimeToLocalTime |
279 | 277 | ||
280 | queueNextEvent :: MonadIO m => BChan CustomEvent -> ZonedTime -> m () | 278 | queueNextEvent :: MonadIO m => BChan CustomEvent -> m ZonedTime |
281 | queueNextEvent chan (zonedTimeToUTC -> now) = liftIO . void . forkIO $ do | 279 | queueNextEvent chan = liftIO $ do |
282 | threadDelayUntil now (nextWholeSecond now) | 280 | now <- getZonedTime |
283 | getZonedTime >>= writeBChan chan . TimeChanged | 281 | void . forkIO $ do |
282 | let next = nextWholeSecond now | ||
283 | let delay = next `diffZonedTime` now | ||
284 | threadDelay $ floor $ delay * 1000 * 1000 | ||
285 | writeBChan chan $ TimeChanged next | ||
286 | return now | ||
284 | 287 | ||
285 | isSimulatedTime :: St -> Bool | 288 | isSimulatedTime :: St -> Bool |
286 | isSimulatedTime st = st ^. stDisplayTime /= st ^. stClockTime | 289 | isSimulatedTime st = st ^. stDisplayTime /= st ^. stClockTime |
@@ -307,7 +310,7 @@ handleEvent chan st e = | |||
307 | VtyEvent (V.EvKey (V.KChar 'p') []) -> cont $ st & stPaused %~ not | 310 | VtyEvent (V.EvKey (V.KChar 'p') []) -> cont $ st & stPaused %~ not |
308 | VtyEvent _ -> cont st | 311 | VtyEvent _ -> cont st |
309 | AppEvent (TimeChanged now) -> do | 312 | AppEvent (TimeChanged now) -> do |
310 | queueNextEvent chan now | 313 | void $ queueNextEvent chan |
311 | let oldTime = st ^. stClockTime | 314 | let oldTime = st ^. stClockTime |
312 | cont $ st & stClockTime .~ (zonedTimeToLocalTime now) | 315 | cont $ st & stClockTime .~ (zonedTimeToLocalTime now) |
313 | & stDisplayTime %~ if st ^. stPaused then id else (addLocalTime ((zonedTimeToLocalTime now) `diffLocalTime` oldTime)) | 316 | & stDisplayTime %~ if st ^. stPaused then id else (addLocalTime ((zonedTimeToLocalTime now) `diffLocalTime` oldTime)) |
@@ -383,6 +386,5 @@ main = do | |||
383 | 386 | ||
384 | let buildVty = V.mkVty V.defaultConfig | 387 | let buildVty = V.mkVty V.defaultConfig |
385 | initialVty <- buildVty | 388 | initialVty <- buildVty |
386 | now <- getZonedTime | 389 | now <- queueNextEvent chan |
387 | queueNextEvent chan now | ||
388 | void $ customMain initialVty buildVty (Just chan) (theApp chan) (initialState $ zonedTimeToLocalTime now) | 390 | void $ customMain initialVty buildVty (Just chan) (theApp chan) (initialState $ zonedTimeToLocalTime now) |