@@ -3,8 +3,9 @@
4module Development.IDE.Core.Debouncer
4module Development.IDE.Core.Debouncer
5 ( Debouncer
5 ( Debouncer
7 , registerEvent
6 , registerEvent
10import Control.Concurrent.Extra
11import Control.Concurrent.Extra
@@ -22,13 +23,14 @@ import System.Time.Extra
22-- by delaying each event for a given time. If another event
23-- by delaying each event for a given time. If another event
23-- is registered for the same key within that timeframe,
24-- is registered for the same key within that timeframe,
24-- only the new event will fire.
25-- only the new event will fire.
27+-- We abstract over the debouncer used so we an use a proper debouncer in the IDE but disable
28+-- debouncing in the DAML CLI compiler.
25−newtype Debouncer k = Debouncer (Var (HashMap k (Async ())))
29+newtype Debouncer k = Debouncer { registerEvent :: Seconds -> k -> IO () -> IO () }
27−-- | Create a new empty debouncer.
31+-- | Debouncer used in the IDE that delays events as expected.
28−newDebouncer :: IO (Debouncer k)
32+newAsyncDebouncer :: (Eq k, Hashable k) => IO (Debouncer k)
29−newDebouncer = do
33+newAsyncDebouncer = Debouncer . asyncRegisterEvent <$> newVar Map.empty
30− m <- newVar Map.empty
33-- | Register an event that will fire after the given delay if no other event
35-- | Register an event that will fire after the given delay if no other event
34-- for the same key gets registered until then.
36-- for the same key gets registered until then.
@@ -36,11 +38,15 @@ newDebouncer = do
36-- If there is a pending event for the same key, the pending event will be killed.
38-- If there is a pending event for the same key, the pending event will be killed.
37-- Events are run unmasked so it is up to the user of `registerEvent`
39-- Events are run unmasked so it is up to the user of `registerEvent`
38-- to mask if required.
40-- to mask if required.
39−registerEvent :: (Eq k, Hashable k) => Debouncer k -> Seconds -> k -> IO () -> IO ()
41+asyncRegisterEvent :: (Eq k, Hashable k) => Var (HashMap k (Async ())) -> Seconds -> k -> IO () -> IO ()
40−registerEvent (Debouncer d) delay k fire = modifyVar_ d $ \m -> mask_ $ do
42+asyncRegisterEvent d delay k fire = modifyVar_ d $ \m -> mask_ $ do
41 whenJust (Map.lookup k m) cancel
43 whenJust (Map.lookup k m) cancel
42 a <- asyncWithUnmask $ \unmask -> unmask $ do
44 a <- asyncWithUnmask $ \unmask -> unmask $ do
43 sleep delay
45 sleep delay
45 modifyVar_ d (pure . Map.delete k)
47 modifyVar_ d (pure . Map.delete k)
46 pure $ Map.insert k a m
48 pure $ Map.insert k a m
50+-- | Debouncer used in the DAML CLI compiler that emits events immediately.
51+noopDebouncer :: Debouncer k
52+noopDebouncer = Debouncer $ \_ _ a -> a