summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cady <d@cryptonomic.net>2022-09-15 11:10:29 -0400
committerAndrew Cady <d@cryptonomic.net>2022-09-15 11:10:29 -0400
commitf818e356797da77b9bdc8167f6828d9362d44834 (patch)
tree4dafbe62c0a5c55427abe7b80be2e50a4e31f9fa
parent6e10d8246eabad813b45a2e444250985a6dd79f8 (diff)
implement time warp
-rwxr-xr-xcountdown.hs42
1 files changed, 26 insertions, 16 deletions
diff --git a/countdown.hs b/countdown.hs
index ffe7af0..57788c5 100755
--- a/countdown.hs
+++ b/countdown.hs
@@ -75,8 +75,9 @@ data CustomEvent = TimeChanged UTCTime deriving Show
75 75
76data St = 76data St =
77 St { _stLastBrickEvent :: Maybe (BrickEvent () CustomEvent) 77 St { _stLastBrickEvent :: Maybe (BrickEvent () CustomEvent)
78 , _stCurrentTime :: UTCTime 78 , _stClockTime :: UTCTime
79 , _stNextEvent :: Maybe UTCTime 79 , _stDisplayTime :: UTCTime
80 , _stNextEvent :: Maybe UTCTime
80 } 81 }
81 82
82makeLenses ''St 83makeLenses ''St
@@ -117,7 +118,7 @@ drawUI st = [a]
117 <=> 118 <=>
118 (str "\n") 119 (str "\n")
119 <=> 120 <=>
120 (countdownWidget $ utcToZonedTime zone $ st ^. stCurrentTime) 121 (countdownWidget $ utcToZonedTime zone $ st ^. stDisplayTime)
121 122
122countdownWidget :: ZonedTime -> Widget n 123countdownWidget :: ZonedTime -> Widget n
123countdownWidget t = 124countdownWidget t =
@@ -158,27 +159,41 @@ countdownWidget t =
158 yearElapsed = (zonedTimeToLocalTime t) `diffLocalTime` (zonedTimeToLocalTime $ yearStart t) 159 yearElapsed = (zonedTimeToLocalTime t) `diffLocalTime` (zonedTimeToLocalTime $ yearStart t)
159 160
160 daysLeft = numDays - dayNum 161 daysLeft = numDays - dayNum
161 secondsLeft = toSeconds $ yearLength - yearElapsed 162 secondsLeft = toSeconds $ yearLength - yearElapsed :: Int
162 toSeconds dt = nominalDiffTimeToSeconds dt `div'` 1 :: Int 163 toSeconds = floor . nominalDiffTimeToSeconds
163 x // y = fromRational $ toRational x / toRational y :: Double 164 x // y = fromRational $ toRational x / toRational y :: Double
164 progressLabel = printf "%.6F%%" (100 * (yearElapsed // yearLength)) 165 progressLabel = printf "%.6F%%" (100 * (yearElapsed // yearLength))
165 166
166commas :: Integral i => i -> Text 167commas :: Integral i => i -> Text
167commas = prettyI (Just ',') . fromIntegral 168commas = prettyI (Just ',') . fromIntegral
168 169
170microsecondsUntil :: Integral i => UTCTime -> UTCTime -> i
171microsecondsUntil now later = floor $ nominalDiffTimeToSeconds $ (later `diffUTCTime` now) * 1000 * 1000
172
173nextWholeSecond :: UTCTime -> UTCTime
174nextWholeSecond (UTCTime day dayTime) = (UTCTime day dayTime')
175 where
176 dayTime' = secondsToDiffTime $ floor dayTime + 1
177
178threadDelayUntil :: UTCTime -> UTCTime -> IO ()
179threadDelayUntil now t = threadDelay $ microsecondsUntil now t
180
169queueNextEvent :: MonadIO m => BChan CustomEvent -> UTCTime -> m () 181queueNextEvent :: MonadIO m => BChan CustomEvent -> UTCTime -> m ()
170queueNextEvent chan now = liftIO . void . forkIO $ do 182queueNextEvent chan now = liftIO . void . forkIO $ do
171 threadDelay $ microsecondsUntilNextSecond now 183 threadDelayUntil now (nextWholeSecond now)
172 getCurrentTime >>= writeBChan chan . TimeChanged 184 getCurrentTime >>= writeBChan chan . TimeChanged
173 185
174handleEvent :: BChan CustomEvent -> St -> BrickEvent () CustomEvent -> EventM () (Next St) 186handleEvent :: BChan CustomEvent -> St -> BrickEvent () CustomEvent -> EventM () (Next St)
175handleEvent chan st e = 187handleEvent chan st e =
176 case e of 188 case e of
177 VtyEvent (V.EvKey V.KEsc []) -> halt st 189 VtyEvent (V.EvKey V.KEsc []) -> halt st
178 VtyEvent _ -> cont st 190 VtyEvent (V.EvKey V.KPageUp []) -> cont $ st & stDisplayTime %~ (addUTCTime lengthOfDay)
191 VtyEvent (V.EvKey V.KPageDown []) -> cont $ st & stDisplayTime %~ (addUTCTime (-lengthOfDay))
192 VtyEvent _ -> cont st
179 AppEvent (TimeChanged now) -> do 193 AppEvent (TimeChanged now) -> do
180 queueNextEvent chan now 194 queueNextEvent chan now
181 cont $ st & stCurrentTime .~ now 195 let oldTime = st ^. stClockTime
196 cont $ st & stClockTime .~ now & stDisplayTime %~ (addUTCTime (now `diffUTCTime` oldTime))
182 _ -> cont st 197 _ -> cont st
183 where 198 where
184 cont s = do 199 cont s = do
@@ -187,7 +202,8 @@ handleEvent chan st e =
187initialState :: UTCTime -> St 202initialState :: UTCTime -> St
188initialState t = 203initialState t =
189 St { _stLastBrickEvent = Nothing 204 St { _stLastBrickEvent = Nothing
190 , _stCurrentTime = t 205 , _stClockTime = t
206 , _stDisplayTime = t
191 , _stNextEvent = Nothing 207 , _stNextEvent = Nothing
192 } 208 }
193 209
@@ -232,12 +248,6 @@ theApp chan =
232zone :: TimeZone 248zone :: TimeZone
233zone = unsafePerformIO getCurrentTimeZone 249zone = unsafePerformIO getCurrentTimeZone
234 250
235microsecondsUntilNextSecond :: Integral i => UTCTime -> i
236microsecondsUntilNextSecond now = (1000 * 1000 * remainingInCurrentSecond) `div'` 1
237 where
238 todSecNow = todSec $ localTimeOfDay $ utcToLocalTime zone now
239 remainingInCurrentSecond = 1 - (todSecNow `mod'` 1)
240
241main :: IO () 251main :: IO ()
242main = do 252main = do
243 chan <- newBChan 10 253 chan <- newBChan 10