on develop help sign in
Fix Adjustable for EventWriterT with simultaneous replace and tell events

Previously if the widget being replaced has a `tellEvent` which fires at the same time as the resulting ('replace finished') event returned from `runWithReplace`, the moribund widget's `tellEvent` will still count, potentially even at the same time as a new widget's `tellEvent`.

commitca50bb4cf1e85e1c980b3ddad0e1b0c483542349 authorKen Micklas <ken.micklas@obsidian.systems> dateWed 18 Jul 2018, 15:09 (8 years ago) parent0b6ac99
1 file changed+6−9
src/Reflex/EventWriter/Base.hs+6−9
src/Reflex/EventWriter/Base.hs+6−9
@@ -154,10 +154,7 @@ runWithReplaceEventWriterTWith :: forall m t w a b. (Reflex t, MonadHold t m, Se
154154 -> EventWriterT t w m (a, Event t b)
155155runWithReplaceEventWriterTWith f a0 a' = do
156156 (result0, result') <- f (runEventWriterT a0) $ fmapCheap runEventWriterT a'
157− request <- holdDyn (snd result0) $ fmapCheap snd result'
158− -- 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.)
159− tellEvent $ coincidence $ updated request
160− tellEvent $ switch $ current request
157+ tellEvent =<< switchHoldPromptOnly (snd result0) (fmapCheap snd result')
161158 return (fst result0, fmapCheap fst result')
162159
163160-- | Like 'runWithReplaceEventWriterTWith', but for 'sequenceIntMapWithAdjust'.
@@ -219,6 +216,7 @@ sequenceDMapWithAdjustEventWriterTWith base mapPatch weakenPatchWith patchNewEle
219216tellEventsPromptly
220217 :: ( Foldable f
221218 , Reflex t
219+ , MonadHold t m
222220 , EventWriter t w m
223221 )
224222 => Event t a
@@ -226,11 +224,10 @@ tellEventsPromptly
226224 -> Event t (f w)
227225 -> m ()
228226tellEventsPromptly requests' patchNewElements mergedChildRequestMap = do
229− -- 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.)
230− tellEvent $ coincidence $ fmapCheap (mconcat . patchNewElements) requests' --TODO: Create a mergeIncrementalPromptly, and use that to eliminate this 'coincidence'
231− tellEvent $ fforMaybeCheap mergedChildRequestMap $ \m -> case toList m of
232− [] -> Nothing
233− h : t -> Just $ sconcat $ h :| t
227+ let patch0 = fforMaybeCheap mergedChildRequestMap $ \m -> case toList m of
228+ [] -> Nothing
229+ h : t -> Just $ sconcat $ h :| t
230+ tellEvent =<< switchHoldPromptOnly patch0 (fmapCheap (mconcat . patchNewElements) requests')
234231
235232instance PerformEvent t m => PerformEvent t (EventWriterT t w m) where
236233 type Performable (EventWriterT t w m) = Performable m