Shpadoinkle-html-0.2.0.0: Shpadoinkle/Html/Event/Throttle.hs
{-# LANGUAGE FlexibleContexts #-}
module Shpadoinkle.Html.Event.Throttle
( throttle
, Throttle
, runThrottle
) where
import Control.Monad
import Control.Monad.IO.Class
import Data.Text
import Data.Time.Clock
import GHC.Conc
import Shpadoinkle hiding (newTVarIO)
newtype Throttle m a b = Throttle { runThrottle
:: (a -> (Text, Prop m b))
-> a -> (Text, Prop m b) }
throttleRaw :: MonadIO n
=> NominalDiffTime
-> n ( (RawNode -> RawEvent -> JSM (Continuation m a))
-> RawNode -> RawEvent -> JSM (Continuation m a) )
throttleRaw duration = do
lastTriggered <- liftIO $ newTVarIO Nothing
return $ \handler rn re -> do
t1 <- liftIO getCurrentTime
continue <- liftIO . atomically $ do
t0m <- readTVar lastTriggered
case t0m of
Nothing -> do
writeTVar lastTriggered (Just t1)
return True
Just t0 -> do
let continue = diffUTCTime t1 t0 > duration
when continue $ writeTVar lastTriggered (Just t1)
return continue
if continue then handler rn re else return done
throttle :: MonadIO n
=> NominalDiffTime
-> n (Throttle m a b)
throttle duration = do
f <- throttleRaw duration
return . Throttle $ \g x ->
let (attr, p) = g x
in (attr, cataProp textProp (listenerProp . f) flagProp p)