@@ -32,6 +32,7 @@ import Data.Dependent.Map (DMap, GCompare (..), Some)
3232import qualified Data.Dependent.Map as DMap
3333import Data.Dependent.Sum
3434import Data.Functor.Misc
35+import qualified Data.List.NonEmpty as NonEmpty
3536import Data.Maybe
3637import Data.Semigroup
3738import qualified Data.Some as Some
@@ -64,6 +65,12 @@ instance (ReflexHost t, Ref m ~ Ref IO, PrimMonad (HostFrame t)) => PerformEvent
6465 performEvent = PerformEventT . fmap (fmap runIdentity) . requesting
6566
6667instance (ReflexHost t, PrimMonad (HostFrame t)) => MonadAdjust t (PerformEventT t m) where
68+ runWithReplace outerA0 outerA' = PerformEventT $ runWithReplaceRequestTWith f (coerce outerA0) (coerceEvent outerA')
69+ where f :: HostFrame t a -> Event t (HostFrame t b) -> RequestT t (HostFrame t) Identity (HostFrame t) (a, Event t b)
70+ f a0 a' = do
71+ result0 <- lift a0
72+ result' <- requesting a'
73+ return (result0, fmap runIdentity result')
6774 sequenceDMapWithAdjust (outerDm0 :: DMap k (PerformEventT t m)) outerDm' = PerformEventT $ sequenceDMapWithAdjustRequestTWith f (coerce outerDm0) (coerceEvent outerDm')
6875 where f :: DMap k' (HostFrame t) -> Event t (PatchDMap k' (HostFrame t)) -> RequestT t (HostFrame t) Identity (HostFrame t) (DMap k' Identity, Event t (PatchDMap k' Identity))
6976 f dm0 dm' = do
@@ -185,9 +192,30 @@ instance MonadHold t m => MonadHold t (RequestT t request response m) where
185192 holdIncremental v0 = lift . holdIncremental v0
186193
187194instance (Reflex t, MonadAdjust t m, MonadHold t m) => MonadAdjust t (RequestT t request response m) where
195+ runWithReplace = runWithReplaceRequestTWith $ \dm0 dm' -> lift $ runWithReplace dm0 dm'
188196 sequenceDMapWithAdjust = sequenceDMapWithAdjustRequestTWith $ \dm0 dm' -> lift $ sequenceDMapWithAdjust dm0 dm'
189197
190−sequenceDMapWithAdjustRequestTWith :: (GCompare k, Monad m, Reflex t, MonadHold t m)
198+runWithReplaceRequestTWith :: forall m t request response a b. (Reflex t, MonadHold t m)
199+ => (forall a' b'.
200+ m a'
201+ -> Event t (m b')
202+ -> RequestT t request response m (a', Event t b')
203+ )
204+ -> RequestT t request response m a
205+ -> Event t (RequestT t request response m b)
206+ -> RequestT t request response m (a, Event t b)
207+runWithReplaceRequestTWith f a0 a' = do
208+ response <- RequestT ask
209+ let g :: RequestT t request response m c -> m (c, [Event t (DMap (Tag (PrimState m)) request)])
210+ g (RequestT r) = runReaderT (runStateT r mempty) response
211+ (result0, result') <- f (g a0) $ g <$> a'
212+ request <- holdDyn (fmap (mconcat . NonEmpty.toList) $ mergeList $ snd result0) $ fmap (mconcat . NonEmpty.toList) . mergeList . snd <$> result'
213+ -- We add these two separately to take advantage of the free merge being done later. The coincidence case must come first so that it has precedence if both fire simultaneously. (Really, we should probably block the 'switch' whenever 'updated' fires, but switchPromptlyDyn has the same issue.)
214+ RequestT $ modify $ (:) $ coincidence $ updated request
215+ RequestT $ modify $ (:) $ switch $ current request
216+ return (fst result0, fst <$> result')
217+
218+sequenceDMapWithAdjustRequestTWith :: (GCompare k, Reflex t, MonadHold t m)
191219 => (forall k'. GCompare k'
192220 => DMap k' m
193221 -> Event t (PatchDMap k' m)
@@ -210,9 +238,10 @@ sequenceDMapWithAdjustRequestTWith f (dm0 :: DMap k (RequestT t request response
210238 requests' = ffor children' $ \(PatchDMap p) -> PatchDMap $
211239 mapKeyValuePairsMonotonic (\(WrapArg k :=> ComposeMaybe mv) -> Const2 (Some.This k) :=> ComposeMaybe (fmap (mergeWith DMap.union . fst . runIdentity) mv)) p
212240 childRequestMap <- holdIncremental requests0 requests'
241+ -- We add these two separately to take advantage of the free merge being done later. The coincidence case must come first so that it has precedence if both fire simultaneously. (Really, we should probably block the 'switch' whenever 'updated' fires, but switchPromptlyDyn has the same issue.)
242+ RequestT $ modify $ (:) $ coincidence $ ffor requests' $ \(PatchDMap p) -> mergeWith DMap.union $ catMaybes $ ffor (DMap.toList p) $ \(Const2 _ :=> ComposeMaybe me) -> me
213243 RequestT $ modify $ (:) $ ffor (mergeIncremental childRequestMap) $ \m ->
214244 mconcat $ (\(Const2 _ :=> Identity reqs) -> reqs) <$> DMap.toList m
215− RequestT $ modify $ (:) $ coincidence $ ffor requests' $ \(PatchDMap p) -> mergeWith DMap.union $ catMaybes $ ffor (DMap.toList p) $ \(Const2 _ :=> ComposeMaybe me) -> me
216245 return (result0, result')
217246
218247instance PerformEvent t m => PerformEvent t (RequestT t request response m) where