@@ -2,13 +2,17 @@
2{-# LANGUAGE FlexibleContexts #-}
2{-# LANGUAGE FlexibleContexts #-}
3{-# LANGUAGE GADTs #-}
3{-# LANGUAGE GADTs #-}
4{-# LANGUAGE RankNTypes #-}
4{-# LANGUAGE RankNTypes #-}
5+{-# LANGUAGE RecursiveDo #-}
5{-# LANGUAGE ScopedTypeVariables #-}
6{-# LANGUAGE ScopedTypeVariables #-}
6module Main where
7module Main where
8import Control.Lens
9import Control.Lens
9import Control.Monad
10import Control.Monad
11+import Control.Monad.Fix
10import qualified Data.Dependent.Map as DMap
12import qualified Data.Dependent.Map as DMap
11import Data.Dependent.Sum
13import Data.Dependent.Sum
14+import Data.Functor.Misc
15+import qualified Data.Map as M
12import Data.These
16import Data.These
14import Reflex
18import Reflex
@@ -25,7 +29,6 @@ main = do
28− let ![[Just [10,9,8,7,6,5,4,3,2,1]]] = os1
29 os2 <- runApp' (unwrapApp testSimultaneous) $ map Just $
32 os2 <- runApp' (unwrapApp testSimultaneous) $ map Just $
@@ -33,7 +36,20 @@ main = do
33 , These () ()
36 , These () ()
39+ os3 <- runApp' (unwrapApp testMoribundRequest) [Just ()]
41+ os4 <- runApp' (unwrapApp testMoribundRequestDMap) [Just ()]
43+ os5 <- runApp' (unwrapApp testLiveRequestDMap) [Just ()]
45+ os6 <- runApp' (unwrapApp delayedPulse) [Just ()]
47+ let ![[Just [10,9,8,7,6,5,4,3,2,1]]] = os1
36 let ![[Just [1,3,5,7,9]],[Nothing,Nothing],[Just [2,4,6,8,10]],[Just [2,4,6,8,10],Nothing]] = os2
48 let ![[Just [1,3,5,7,9]],[Nothing,Nothing],[Just [2,4,6,8,10]],[Just [2,4,6,8,10],Nothing]] = os2
49+ let ![[Nothing, Just [2]]] = os3
50+ let ![[Nothing, Just [2]]] = os4
51+ let ![[Nothing, Just [1, 2]]] = os5
52+ let ![[Nothing, Nothing]] = os6
39unwrapRequest :: DSum tag RequestInt -> Int
55unwrapRequest :: DSum tag RequestInt -> Int
@@ -67,3 +83,87 @@ testSimultaneous pulse = do
67 switchE = fmapMaybe (^? there) pulse
83 switchE = fmapMaybe (^? there) pulse
68 forM_ [1,3..9] $ \i -> runWithReplace (requestingIdentity (RequestInt i <$ tellE)) $ ffor switchE $ \_ ->
84 forM_ [1,3..9] $ \i -> runWithReplace (requestingIdentity (RequestInt i <$ tellE)) $ ffor switchE $ \_ ->
69 requestingIdentity (RequestInt (i+1) <$ tellE)
85 requestingIdentity (RequestInt (i+1) <$ tellE)
87+-- | Test that a widget requesting and event which fires at the same time it has been replaced
88+-- doesn't count along with the new widget.
95+ , Response m ~ Identity
96+ , Request m ~ RequestInt
101+testMoribundRequest pulse = do
102+ rec let requestIntOnReplace x = requestingIdentity $ RequestInt x <$ rwrFinished
103+ (_, rwrFinished) <- runWithReplace (requestIntOnReplace 1) $ requestIntOnReplace 2 <$ pulse
106+-- | The equivalent of 'testMoribundRequest' for 'traverseDMapWithKeyWithAdjust'.
107+testMoribundRequestDMap
113+ , Response m ~ Identity
114+ , Request m ~ RequestInt
119+testMoribundRequestDMap pulse = do
120+ rec let requestIntOnReplace :: Int -> m ()
121+ requestIntOnReplace x = void $ requestingIdentity $ RequestInt x <$ rwrFinished
122+ (_, rwrFinished :: Event t (PatchDMap (Const2 () Int) Identity)) <-
123+ traverseDMapWithKeyWithAdjust
124+ (\(Const2 ()) (Identity v) -> Identity . const v <$> requestIntOnReplace v)
125+ (mapToDMap $ M.singleton () 1)
126+ ((PatchDMap $ DMap.map (ComposeMaybe . Just) $ mapToDMap $ M.singleton () 2) <$ pulse)
129+-- | Ensures that elements which are _not_ removed can still fire requests
130+-- during the same frame as other elements are updated.
137+ , Response m ~ Identity
138+ , Request m ~ RequestInt
143+testLiveRequestDMap pulse = do
144+ rec let requestIntOnReplace :: Int -> m ()
145+ requestIntOnReplace x = void $ requestingIdentity $ RequestInt x <$ rwrFinished
146+ (_, rwrFinished :: Event t (PatchDMap (Const2 Int ()) Identity)) <-
147+ traverseDMapWithKeyWithAdjust
148+ (\(Const2 k) (Identity ()) -> Identity <$> requestIntOnReplace k)
149+ (mapToDMap $ M.singleton 1 ())
150+ ((PatchDMap $ DMap.map (ComposeMaybe . Just) $ mapToDMap $ M.singleton 2 ()) <$ pulse)
159+ , Response m ~ Identity
160+ , Request m ~ RequestInt
166+delayedPulse pulse = void $ flip runWithReplace (pure () <$ pulse) $ do
167+ -- This has the effect of delaying pulse' from pulse
168+ (_, pulse') <- runWithReplace (pure ()) $ pure (RequestInt 1) <$ pulse
169+ requestingIdentity pulse'