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
Double
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
Double -> Eff (State Double : es) b -> Eff es b
forall s (es :: [Effect]) a.
HasCallStack =>
s -> Eff (State s : es) a -> Eff es a
evalState Double
a do
Eff (State Double : es) () -> Eff (State Double : es) b
forall (f :: * -> *) a b. Applicative f => f a -> f b
forever do
Eff es () -> Eff (State Double : es) ()
forall (es :: [Effect]) a (e :: Effect). Eff es a -> Eff (e : es) a
raise Eff es ()
f
Double
t0 <- Eff (State Double : es) Double
forall s (es :: [Effect]).
(HasCallStack, State s :> es) =>
Eff es s
get
Double
t1 <- IO Double -> Eff (State Double : es) Double
forall a. IO a -> Eff (State Double : es) a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO IO Double
getMonotonicTime
Double
wa <- TVar Double -> Eff (State Double : es) Double
forall (es :: [Effect]) a. (Concurrent :> es) => TVar a -> Eff es a
readTVarIO TVar Double
tr Eff (State Double : es) Double
-> (Double -> Double) -> Eff (State Double : es) Double
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \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))
Int -> Eff (State Double : es) ()
forall (es :: [Effect]). (Concurrent :> es) => Int -> Eff es ()
threadDelay (Double -> Int
forall b. Integral b => Double -> b
forall a b. (RealFrac a, Integral b) => a -> b
ceiling (Double
1e6 Double -> Double -> Double
forall a. Num a => a -> a -> a
* Double
wa))