module M.IO.Tick
(
tick,
)
where
import Control.Monad
import Data.Functor
import Effectful
import Effectful.Concurrent
import Effectful.Concurrent.STM
import Effectful.State.Static.Local
import GHC.Clock
tick ::
(IOE :> es, Concurrent :> es) =>
TVar Double ->
Eff es () ->
Eff es b
tick :: forall (es :: [Effect]) b.
(IOE :> es, Concurrent :> es) =>
TVar Double -> Eff es () -> Eff es b
tick TVar Double
tr Eff es ()
f = do
a <- IO Double -> Eff es Double
forall a. IO a -> Eff es a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO Double
getMonotonicTime
evalState a do
forever do
raise f
t0 <- get
t1 <- liftIO getMonotonicTime
wa <- readTVarIO tr <&> \Double
t -> Double -> Double -> Double
forall a. Ord a => a -> a -> a
max Double
0 (Double -> Double
forall a. Fractional a => a -> a
recip Double
t Double -> Double -> Double
forall a. Num a => a -> a -> a
- (Double
t1 Double -> Double -> Double
forall a. Num a => a -> a -> a
- Double
t0))
threadDelay (ceiling (1e6 * wa))