on develop help sign in
Reflex.Time: Add throttle
commit5bb4430415a6d56f64199e03c08118b321188935 authorAli Abrar <aliabrar@gmail.com> dateTue 6 Mar 2018, 10:06 (9 years ago) parentdcd66cb
1 file changed+33
src/Reflex/Time.hs+33
src/Reflex/Time.hs+33
@@ -222,6 +222,39 @@ batchOccurrences t newValues = do
222222 delayed <- delay t toDelay
223223 return $ tag buffer delayed
224224
225+-- | Throttle an input event, ensuring that at least a given amount of time passes between occurrences of the output event. If the input event occurs too
226+-- frequently, the output event occurs with the most recently seen input value after the given delay passes since the last occurrence of the output.
227+-- If the output event has not occurred recently, occurrences of the input event will cause the output event to fire immediately.
228+throttle :: (MonadFix m, MonadHold t m, PerformEvent t m, TriggerEvent t m, MonadIO (Performable m)) => NominalDiffTime -> Event t a -> m (Event t a)
229+throttle t e = do
230+ let f (immediate, buffer) x = case x of -- (Just newState, out)
231+ This a -- If only the input event fires
232+ | immediate -> -- and we're in immediate mode
233+ -- * Immediate mode turns off, and the buffer is empty.
234+ -- * We fire the output event with the input event value immediately.
235+ (Just (False, Nothing), Just a)
236+ | otherwise -> -- and we're not in immediate mode
237+ -- * Immediate mode remains off, and we replace the contents of the buffer (if any) with the input value.
238+ -- * We don't fire the output event.
239+ (Just (False, Just a), Nothing)
240+ That _ -> -- If only the delayed output event fires,
241+ case buffer of
242+ Nothing -> -- and the buffer is empty:
243+ -- * Immediate mode turns back on, and the buffer remains empty.
244+ -- * We don't fire.
245+ (Just (True, Nothing), Nothing)
246+ Just b -> -- and the buffer is full:
247+ -- * Immediate mode remains off, and the buffer is cleared.
248+ -- * We fire with the buffered value.
249+ (Just (False, Nothing), Just b)
250+ These a _ -> -- If both the input and delayed output event fire simultaneously:
251+ -- * Immediate mode turns off, and the buffer is empty.
252+ -- * We fire with the input event's value, as it is the most recent we have seen at this moment.
253+ (Just (False, Nothing), Just a)
254+ rec (_, outE) <- mapAccumMaybeDyn f (True, Nothing) $ align e delayed -- We start in immediate mode with an empty buffer.
255+ delayed <- delay t outE
256+ return outE
257+
225258#ifdef USE_TEMPLATE_HASKELL
226259makeLensesWith (lensRules & simpleLenses .~ True) ''TickInfo
227260#else