on develop help sign in
Cleanup trailing whitespace
fa5c17fleon.smith@obsidian.systems
reflex.cabal+2−2
@@ -185,7 +185,7 @@ library
185 if impl(ghcjs)
185 if impl(ghcjs)
186 build-depends: ghcjs-base
186 build-depends: ghcjs-base
187
187
188−
188+
189
189
190test-suite semantics
190test-suite semantics
191 type: exitcode-stdio-1.0
191 type: exitcode-stdio-1.0
@@ -292,7 +292,7 @@ test-suite DebugCycles
292 build-depends: these-lens, semialign
292 build-depends: these-lens, semialign
293
293
294 other-modules:
294 other-modules:
295− Test.Run
295+ Test.Run
296
296
297
297
298test-suite RequesterT
298test-suite RequesterT
src/Reflex/Spider/Internal.hs+61−61
@@ -129,7 +129,7 @@ class HasNodeId a where
129
129
130instance HasNodeId (CacheSubscribed x a) where
130instance HasNodeId (CacheSubscribed x a) where
131 getNodeId = _cacheSubscribed_nodeId
131 getNodeId = _cacheSubscribed_nodeId
132−
132+
133instance HasNodeId (FanInt x a) where
133instance HasNodeId (FanInt x a) where
134 getNodeId = _fanInt_nodeId
134 getNodeId = _fanInt_nodeId
135
135
@@ -156,7 +156,7 @@ showNodeId :: HasNodeId a => a -> String
156showNodeId = showNodeId' . getNodeId
156showNodeId = showNodeId' . getNodeId
157
157
158showNodeId' :: Int -> String
158showNodeId' :: Int -> String
159−showNodeId' = ("#"<>) . show
159+showNodeId' = ("#"<>) . show
160
160
161
161
162#else
162#else
@@ -253,9 +253,9 @@ headE originalE = do
253 let clearParent = liftIO $ writeIORef parent Nothing
253 let clearParent = liftIO $ writeIORef parent Nothing
254 (_, occ) <- subscribeAndReadHead originalE $ terminalSubscriber $ const clearParent
254 (_, occ) <- subscribeAndReadHead originalE $ terminalSubscriber $ const clearParent
255 when (isJust occ) clearParent
255 when (isJust occ) clearParent
256− return $ Event $ \sub ->
256+ return $ Event $ \sub ->
257 liftIO (readIORef parent) >>= \case
257 liftIO (readIORef parent) >>= \case
258− Nothing -> subscribeAndReadNever
258+ Nothing -> subscribeAndReadNever
259 Just e -> subscribeAndReadHead e sub
259 Just e -> subscribeAndReadHead e sub
260
260
261data CacheSubscribed x a
261data CacheSubscribed x a
@@ -305,8 +305,8 @@ cacheEvent e =
305 liftIO $ writeIORef occRef (Just a)
305 liftIO $ writeIORef occRef (Just a)
306 scheduleClear occRef
306 scheduleClear occRef
307 propagateFast a subscribers
307 propagateFast a subscribers
308− , subscriberInvalidateHeight = FastWeakBag.traverse subscribers . invalidateSubscriberHeight
308+ , subscriberInvalidateHeight = FastWeakBag.traverse subscribers . invalidateSubscriberHeight
309− , subscriberRecalculateHeight = FastWeakBag.traverse subscribers . recalculateSubscriberHeight
309+ , subscriberRecalculateHeight = FastWeakBag.traverse subscribers . recalculateSubscriberHeight
310 }
310 }
311||||||| merged common ancestors
311||||||| merged common ancestors
312 (parentSub, occ) <- subscribeAndRead e $ Subscriber
312 (parentSub, occ) <- subscribeAndRead e $ Subscriber
@@ -340,20 +340,20 @@ cacheEvent e =
340 , _cacheSubscribed_occurrence = occRef
340 , _cacheSubscribed_occurrence = occRef
341#ifdef DEBUG_NODEIDS
341#ifdef DEBUG_NODEIDS
342 , _cacheSubscribed_nodeId = nodeId
342 , _cacheSubscribed_nodeId = nodeId
343−#endif
343+#endif
344 }
344 }
345 subscribedTicket <- liftIO $ mkFastWeakTicket subscribed
345 subscribedTicket <- liftIO $ mkFastWeakTicket subscribed
346 liftIO $ writeIORef mSubscribedRef =<< getFastWeakTicketWeak subscribedTicket
346 liftIO $ writeIORef mSubscribedRef =<< getFastWeakTicketWeak subscribedTicket
347 return subscribedTicket
347 return subscribedTicket
348 liftIO $ cacheSubscription sub mSubscribedRef subscribedTicket
348 liftIO $ cacheSubscription sub mSubscribedRef subscribedTicket
349
349
350−cacheSubscription :: Subscriber x a -> IORef (FastWeak (CacheSubscribed x a))
350+cacheSubscription :: Subscriber x a -> IORef (FastWeak (CacheSubscribed x a))
351 -> FastWeakTicket (CacheSubscribed x a) -> IO (EventSubscription x, Maybe a)
351 -> FastWeakTicket (CacheSubscribed x a) -> IO (EventSubscription x, Maybe a)
352−cacheSubscription sub mSubscribedRef subscribedTicket = do
352+cacheSubscription sub mSubscribedRef subscribedTicket = do
353 subscribed <- getFastWeakTicketValue subscribedTicket
353 subscribed <- getFastWeakTicketValue subscribedTicket
354 ticket <- FastWeakBag.insert sub $ _cacheSubscribed_subscribers subscribed
354 ticket <- FastWeakBag.insert sub $ _cacheSubscribed_subscribers subscribed
355 occ <- readIORef $ _cacheSubscribed_occurrence subscribed
355 occ <- readIORef $ _cacheSubscribed_occurrence subscribed
356−
356+
357 let parentSub = _cacheSubscribed_parent subscribed
357 let parentSub = _cacheSubscribed_parent subscribed
358 es = EventSubscription
358 es = EventSubscription
359 { _eventSubscription_unsubscribe = do
359 { _eventSubscription_unsubscribe = do
@@ -372,9 +372,9 @@ cacheSubscription sub mSubscribedRef subscribedTicket = do
372 , eventSubscribedGetParents = return [_eventSubscription_subscribed parentSub]
372 , eventSubscribedGetParents = return [_eventSubscription_subscribed parentSub]
373 , eventSubscribedHasOwnHeightRef = False
373 , eventSubscribedHasOwnHeightRef = False
374 , eventSubscribedWhoCreated = whoCreatedIORef mSubscribedRef
374 , eventSubscribedWhoCreated = whoCreatedIORef mSubscribedRef
375−#endif
375+#endif
376 }
376 }
377− }
377+ }
378 return (es, occ)
378 return (es, occ)
379
379
380
380
@@ -495,7 +495,7 @@ newSubscriberCoincidenceOuter subscribed = debugSubscriber ("SubscriberCoinciden
495 liftIO $ writeIORef (coincidenceSubscribedInnerParent subscribed) $ Just innerSubd
495 liftIO $ writeIORef (coincidenceSubscribedInnerParent subscribed) $ Just innerSubd
496 scheduleClear $ coincidenceSubscribedInnerParent subscribed
496 scheduleClear $ coincidenceSubscribedInnerParent subscribed
497 case occ of
497 case occ of
498− Nothing ->
498+ Nothing ->
499 when (innerHeight > outerHeight) $ liftIO $ do -- If the event fires, it will fire at a later height
499 when (innerHeight > outerHeight) $ liftIO $ do -- If the event fires, it will fire at a later height
500 writeIORef (coincidenceSubscribedHeight subscribed) $! innerHeight
500 writeIORef (coincidenceSubscribedHeight subscribed) $! innerHeight
501 WeakBag.traverse_ (coincidenceSubscribedSubscribers subscribed) $ invalidateSubscriberHeight outerHeight
501 WeakBag.traverse_ (coincidenceSubscribedSubscribers subscribed) $ invalidateSubscriberHeight outerHeight
@@ -505,7 +505,7 @@ newSubscriberCoincidenceOuter subscribed = debugSubscriber ("SubscriberCoinciden
505 scheduleClear $ coincidenceSubscribedOccurrence subscribed
505 scheduleClear $ coincidenceSubscribedOccurrence subscribed
506 propagate o $ coincidenceSubscribedSubscribers subscribed
506 propagate o $ coincidenceSubscribedSubscribers subscribed
507 , subscriberInvalidateHeight = \_ -> invalidateCoincidenceHeight subscribed
507 , subscriberInvalidateHeight = \_ -> invalidateCoincidenceHeight subscribed
508− , subscriberRecalculateHeight = \_ -> recalculateCoincidenceHeight subscribed
508+ , subscriberRecalculateHeight = \_ -> recalculateCoincidenceHeight subscribed
509 }
509 }
510
510
511newSubscriberCoincidenceInner :: forall x a. HasSpiderTimeline x => CoincidenceSubscribed x a -> IO (Subscriber x a)
511newSubscriberCoincidenceInner :: forall x a. HasSpiderTimeline x => CoincidenceSubscribed x a -> IO (Subscriber x a)
@@ -526,18 +526,18 @@ invalidateSubscriberHeight :: Height -> Subscriber x a -> IO ()
526invalidateSubscriberHeight = flip subscriberInvalidateHeight
526invalidateSubscriberHeight = flip subscriberInvalidateHeight
527
527
528recalculateSubscriberHeight :: Height -> Subscriber x a -> IO ()
528recalculateSubscriberHeight :: Height -> Subscriber x a -> IO ()
529−recalculateSubscriberHeight = flip subscriberRecalculateHeight
529+recalculateSubscriberHeight = flip subscriberRecalculateHeight
530
530
531-- | Propagate everything at the current height
531-- | Propagate everything at the current height
532propagate :: forall x a. HasSpiderTimeline x => a -> WeakBag (Subscriber x a) -> EventM x ()
532propagate :: forall x a. HasSpiderTimeline x => a -> WeakBag (Subscriber x a) -> EventM x ()
533−propagate a subscribers = withIncreasedDepth (Proxy::Proxy x) $
533+propagate a subscribers = withIncreasedDepth (Proxy::Proxy x) $
534 -- Note: in the following traversal, we do not visit nodes that are added to the list during our traversal; they are new events, which will necessarily have full information already, so there is no need to traverse them
534 -- Note: in the following traversal, we do not visit nodes that are added to the list during our traversal; they are new events, which will necessarily have full information already, so there is no need to traverse them
535 --TODO: Should we check if nodes already have their values before propagating? Maybe we're re-doing work
535 --TODO: Should we check if nodes already have their values before propagating? Maybe we're re-doing work
536 WeakBag.traverse_ subscribers $ \s -> subscriberPropagate s a
536 WeakBag.traverse_ subscribers $ \s -> subscriberPropagate s a
537
537
538-- | Propagate everything at the current height
538-- | Propagate everything at the current height
539propagateFast :: forall x a. HasSpiderTimeline x => a -> FastWeakBag (Subscriber x a) -> EventM x ()
539propagateFast :: forall x a. HasSpiderTimeline x => a -> FastWeakBag (Subscriber x a) -> EventM x ()
540−propagateFast a subscribers = withIncreasedDepth (Proxy::Proxy x) $
540+propagateFast a subscribers = withIncreasedDepth (Proxy::Proxy x) $
541 -- Note: in the following traversal, we do not visit nodes that are added to the list during our traversal; they are new events, which will necessarily have full information already, so there is no need to traverse them
541 -- Note: in the following traversal, we do not visit nodes that are added to the list during our traversal; they are new events, which will necessarily have full information already, so there is no need to traverse them
542 --TODO: Should we check if nodes already have their values before propagating? Maybe we're re-doing work
542 --TODO: Should we check if nodes already have their values before propagating? Maybe we're re-doing work
543 FastWeakBag.traverse_ subscribers $ \s -> subscriberPropagate s a
543 FastWeakBag.traverse_ subscribers $ \s -> subscriberPropagate s a
@@ -1023,7 +1023,7 @@ data SomeMergeUpdate x = SomeMergeUpdate
1023newtype SomeMergeInit x = SomeMergeInit { unSomeMergeInit :: EventM x () }
1023newtype SomeMergeInit x = SomeMergeInit { unSomeMergeInit :: EventM x () }
1024
1024
1025-- EventM can do everything BehaviorM can, plus create holds
1025-- EventM can do everything BehaviorM can, plus create holds
1026−newtype EventM x a = EventM { unEventM :: IO a } deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadException, MonadAsyncException)
1026+newtype EventM x a = EventM { unEventM :: IO a } deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadException, MonadAsyncException)
1027
1027
1028newtype MergeSubscribedParent x a = MergeSubscribedParent { unMergeSubscribedParent :: EventSubscription x }
1028newtype MergeSubscribedParent x a = MergeSubscribedParent { unMergeSubscribedParent :: EventSubscription x }
1029
1029
@@ -1048,7 +1048,7 @@ heightBagFromList :: [Height] -> HeightBag
1048heightBagFromList heights = heightBagVerify $ foldl' (flip heightBagAdd) heightBagEmpty heights
1048heightBagFromList heights = heightBagVerify $ foldl' (flip heightBagAdd) heightBagEmpty heights
1049
1049
1050heightBagAdd :: Height -> HeightBag -> HeightBag
1050heightBagAdd :: Height -> HeightBag -> HeightBag
1051−heightBagAdd (Height h) (HeightBag s c) = heightBagVerify $ HeightBag (succ s) $
1051+heightBagAdd (Height h) (HeightBag s c) = heightBagVerify $ HeightBag (succ s) $
1052 IntMap.insertWithKey (\_ _ old -> succ old) h 0 c
1052 IntMap.insertWithKey (\_ _ old -> succ old) h 0 c
1053
1053
1054heightBagRemove :: Height -> HeightBag -> HeightBag
1054heightBagRemove :: Height -> HeightBag -> HeightBag
@@ -1059,11 +1059,11 @@ heightBagRemove (Height h) b@(HeightBag s c) = heightBagVerify $ case IntMap.loo
1059 _ -> IntMap.insert h (pred old) c
1059 _ -> IntMap.insert h (pred old) c
1060
1060
1061heightBagRemoveMaybe :: Height -> HeightBag -> Maybe HeightBag
1061heightBagRemoveMaybe :: Height -> HeightBag -> Maybe HeightBag
1062−heightBagRemoveMaybe (Height h) b@(HeightBag s c) = heightBagVerify . removed <$> IntMap.lookup h c where
1062+heightBagRemoveMaybe (Height h) b@(HeightBag s c) = heightBagVerify . removed <$> IntMap.lookup h c where
1063 removed old = HeightBag (pred s) $ case old of
1063 removed old = HeightBag (pred s) $ case old of
1064 0 -> IntMap.delete h c
1064 0 -> IntMap.delete h c
1065 _ -> IntMap.insert h (pred old) c
1065 _ -> IntMap.insert h (pred old) c
1066−
1066+
1067
1067
1068heightBagMax :: HeightBag -> Height
1068heightBagMax :: HeightBag -> Height
1069heightBagMax (HeightBag _ c) = case IntMap.maxViewWithKey c of
1069heightBagMax (HeightBag _ c) = case IntMap.maxViewWithKey c of
@@ -1328,7 +1328,7 @@ debugSubscriber :: forall x a. HasSpiderTimeline x => String -> Subscriber x a -
1328debugSubscriber description = return . debugSubscriber' description
1328debugSubscriber description = return . debugSubscriber' description
1329
1329
1330debugSubscriber' :: forall x a. HasSpiderTimeline x => String -> Subscriber x a -> Subscriber x a
1330debugSubscriber' :: forall x a. HasSpiderTimeline x => String -> Subscriber x a -> Subscriber x a
1331−debugSubscriber' description subscribed = Subscriber
1331+debugSubscriber' description subscribed = Subscriber
1332 {
1332 {
1333 subscriberPropagate = \m -> do
1333 subscriberPropagate = \m -> do
1334 tracePropagate (Proxy :: Proxy x) ("subscriberPropagate: " <> description)
1334 tracePropagate (Proxy :: Proxy x) ("subscriberPropagate: " <> description)
@@ -1430,12 +1430,12 @@ filterStack prefix = filter (not . (prefix `isPrefixOf`))
1430
1430
1431#ifdef DEBUG_CYCLES
1431#ifdef DEBUG_CYCLES
1432
1432
1433−data EventLoopException = EventLoopException [[String]]
1433+data EventLoopException = EventLoopException [[String]]
1434instance Exception EventLoopException
1434instance Exception EventLoopException
1435
1435
1436instance Show EventLoopException where
1436instance Show EventLoopException where
1437− show (EventLoopException stacks) = "causality loop detected:\n" <> if null stacks
1437+ show (EventLoopException stacks) = "causality loop detected:\n" <> if null stacks
1438− then "no location information, compile with profiling enabled for stack tree"
1438+ then "no location information, compile with profiling enabled for stack tree"
1439 else showStacks stacks
1439 else showStacks stacks
1440
1440
1441#else
1441#else
@@ -1461,7 +1461,7 @@ propagateSubscriberHold h a = do
1461 case {-# SCC "apply" #-} apply a v of
1461 case {-# SCC "apply" #-} apply a v of
1462 Nothing -> return ()
1462 Nothing -> return ()
1463 Just v' -> do
1463 Just v' -> do
1464− withIncreasedDepth (Proxy :: Proxy x) $
1464+ withIncreasedDepth (Proxy :: Proxy x) $
1465 tracePropagate (Proxy :: Proxy x) ("propagateSubscriberHold: assigning Hold" <> showNodeId h)
1465 tracePropagate (Proxy :: Proxy x) ("propagateSubscriberHold: assigning Hold" <> showNodeId h)
1466 vRef <- {-# SCC "vRef" #-} liftIO $ evaluate $ holdValue h
1466 vRef <- {-# SCC "vRef" #-} liftIO $ evaluate $ holdValue h
1467 iRef <- {-# SCC "iRef" #-} liftIO $ evaluate $ holdInvalidators h
1467 iRef <- {-# SCC "iRef" #-} liftIO $ evaluate $ holdInvalidators h
@@ -1582,7 +1582,7 @@ data FanInt x a = FanInt
1582 { _fanInt_subscribers :: {-# UNPACK #-} !(FastMutableIntMap (FastWeakBag (Subscriber x a))) --TODO: Clean up the keys in here when their child weak bags get empty --TODO: Remove our own subscription when the subscribers list is completely empty
1582 { _fanInt_subscribers :: {-# UNPACK #-} !(FastMutableIntMap (FastWeakBag (Subscriber x a))) --TODO: Clean up the keys in here when their child weak bags get empty --TODO: Remove our own subscription when the subscribers list is completely empty
1583 , _fanInt_subscriptionRef :: {-# UNPACK #-} !(IORef (EventSubscription x)) -- This should have a valid subscription iff subscribers is non-empty
1583 , _fanInt_subscriptionRef :: {-# UNPACK #-} !(IORef (EventSubscription x)) -- This should have a valid subscription iff subscribers is non-empty
1584 , _fanInt_occRef :: {-# UNPACK #-} !(IORef (IntMap a))
1584 , _fanInt_occRef :: {-# UNPACK #-} !(IORef (IntMap a))
1585−#ifdef DEBUG_NODEIDS
1585+#ifdef DEBUG_NODEIDS
1586 , _fanInt_nodeId :: {-# UNPACK #-} !Int
1586 , _fanInt_nodeId :: {-# UNPACK #-} !Int
1587#endif
1587#endif
1588 }
1588 }
@@ -1592,15 +1592,15 @@ newFanInt = do
1592 subscribers <- FastMutableIntMap.newEmpty --TODO: Clean up the keys in here when their child weak bags get empty --TODO: Remove our own subscription when the subscribers list is completely empty
1592 subscribers <- FastMutableIntMap.newEmpty --TODO: Clean up the keys in here when their child weak bags get empty --TODO: Remove our own subscription when the subscribers list is completely empty
1593 subscriptionRef <- newIORef $ error "fanInt: no subscription"
1593 subscriptionRef <- newIORef $ error "fanInt: no subscription"
1594 occRef <- newIORef $ error "fanInt: no occurrence"
1594 occRef <- newIORef $ error "fanInt: no occurrence"
1595−#ifdef DEBUG_NODEIDS
1595+#ifdef DEBUG_NODEIDS
1596 nodeId <- newNodeId
1596 nodeId <- newNodeId
1597#endif
1597#endif
1598 return $ FanInt
1598 return $ FanInt
1599 { _fanInt_subscribers = subscribers
1599 { _fanInt_subscribers = subscribers
1600 , _fanInt_subscriptionRef = subscriptionRef
1600 , _fanInt_subscriptionRef = subscriptionRef
1601 , _fanInt_occRef = occRef
1601 , _fanInt_occRef = occRef
1602−#ifdef DEBUG_NODEIDS
1602+#ifdef DEBUG_NODEIDS
1603− , _fanInt_nodeId = nodeId
1603+ , _fanInt_nodeId = nodeId
1604#endif
1604#endif
1605 }
1605 }
1606
1606
@@ -1616,15 +1616,15 @@ fanInt p = unsafePerformIO $ do
1616 liftIO $ writeIORef (_fanInt_occRef self) m
1616 liftIO $ writeIORef (_fanInt_occRef self) m
1617 scheduleIntClear $ _fanInt_occRef self
1617 scheduleIntClear $ _fanInt_occRef self
1618 FastMutableIntMap.forIntersectionWithImmutable_ (_fanInt_subscribers self) m $ \b v -> --TODO: Do we need to know that no subscribers are being added as we traverse?
1618 FastMutableIntMap.forIntersectionWithImmutable_ (_fanInt_subscribers self) m $ \b v -> --TODO: Do we need to know that no subscribers are being added as we traverse?
1619− FastWeakBag.traverse_ b $ \s ->
1619+ FastWeakBag.traverse_ b $ \s ->
1620 subscriberPropagate s v
1620 subscriberPropagate s v
1621− , subscriberInvalidateHeight = \old ->
1621+ , subscriberInvalidateHeight = \old ->
1622− FastMutableIntMap.for_ (_fanInt_subscribers self) $ \b ->
1622+ FastMutableIntMap.for_ (_fanInt_subscribers self) $ \b ->
1623− FastWeakBag.traverse_ b $ \s ->
1623+ FastWeakBag.traverse_ b $ \s ->
1624 subscriberInvalidateHeight s old
1624 subscriberInvalidateHeight s old
1625 , subscriberRecalculateHeight = \new ->
1625 , subscriberRecalculateHeight = \new ->
1626− FastMutableIntMap.for_ (_fanInt_subscribers self) $ \b ->
1626+ FastMutableIntMap.for_ (_fanInt_subscribers self) $ \b ->
1627− FastWeakBag.traverse_ b $ \s ->
1627+ FastWeakBag.traverse_ b $ \s ->
1628 subscriberRecalculateHeight s new
1628 subscriberRecalculateHeight s new
1629 }
1629 }
1630 liftIO $ do
1630 liftIO $ do
@@ -1640,14 +1640,14 @@ fanInt p = unsafePerformIO $ do
1640 Just b -> return b
1640 Just b -> return b
1641 ticket <- liftIO $ FastWeakBag.insert sub b
1641 ticket <- liftIO $ FastWeakBag.insert sub b
1642 currentOcc <- readIORef (_fanInt_occRef self)
1642 currentOcc <- readIORef (_fanInt_occRef self)
1643−
1643+
1644 subscribed <- fanIntSubscribed ticket self
1644 subscribed <- fanIntSubscribed ticket self
1645 return (EventSubscription (FastWeakBag.remove ticket) subscribed, IntMap.lookup k currentOcc)
1645 return (EventSubscription (FastWeakBag.remove ticket) subscribed, IntMap.lookup k currentOcc)
1646
1646
1647fanIntSubscribed :: FastWeakBagTicket k -> FanInt x a -> IO (EventSubscribed x)
1647fanIntSubscribed :: FastWeakBagTicket k -> FanInt x a -> IO (EventSubscribed x)
1648−fanIntSubscribed ticket self = do
1648+fanIntSubscribed ticket self = do
1649 subscribedParent <- _eventSubscription_subscribed <$> readIORef (_fanInt_subscriptionRef self)
1649 subscribedParent <- _eventSubscription_subscribed <$> readIORef (_fanInt_subscriptionRef self)
1650− return $ EventSubscribed
1650+ return $ EventSubscribed
1651 { eventSubscribedHeightRef = eventSubscribedHeightRef subscribedParent
1651 { eventSubscribedHeightRef = eventSubscribedHeightRef subscribedParent
1652 , eventSubscribedRetained = toAny (_fanInt_subscriptionRef self, ticket)
1652 , eventSubscribedRetained = toAny (_fanInt_subscriptionRef self, ticket)
1653#ifdef DEBUG_CYCLES
1653#ifdef DEBUG_CYCLES
@@ -1656,7 +1656,7 @@ fanIntSubscribed ticket self = do
1656 , eventSubscribedWhoCreated = whoCreatedIORef $ _fanInt_subscriptionRef self
1656 , eventSubscribedWhoCreated = whoCreatedIORef $ _fanInt_subscriptionRef self
1657#endif
1657#endif
1658 }
1658 }
1659−
1659+
1660
1660
1661{-# INLINABLE getFanSubscribed #-}
1661{-# INLINABLE getFanSubscribed #-}
1662getFanSubscribed :: (HasSpiderTimeline x, GCompare k) => k a -> Fan x k v -> Subscriber x (v a) -> EventM x (WeakBagTicket, FanSubscribed x k v, Maybe (v a))
1662getFanSubscribed :: (HasSpiderTimeline x, GCompare k) => k a -> Fan x k v -> Subscriber x (v a) -> EventM x (WeakBagTicket, FanSubscribed x k v, Maybe (v a))
@@ -1869,7 +1869,7 @@ mergeCheap nt = mergeGCheap' unMergeSubscribedParent getInitialSubscribers updat
1869 liftIO $ modifyIORef' heightBagRef $ heightBagAdd newParentHeight
1869 liftIO $ modifyIORef' heightBagRef $ heightBagAdd newParentHeight
1870 return $ DMap.insertLookupWithKey' (\_ new _ -> new) k newParent ps
1870 return $ DMap.insertLookupWithKey' (\_ new _ -> new) k newParent ps
1871 forM_ mOldSubd $ \oldSubd -> do
1871 forM_ mOldSubd $ \oldSubd -> do
1872− oldHeight <- liftIO $ getEventSubscribedHeight $
1872+ oldHeight <- liftIO $ getEventSubscribedHeight $
1873 _eventSubscription_subscribed $ unMergeSubscribedParent oldSubd
1873 _eventSubscription_subscribed $ unMergeSubscribedParent oldSubd
1874
1874
1875 liftIO $ modifyIORef heightBagRef $ heightBagRemove oldHeight
1875 liftIO $ modifyIORef heightBagRef $ heightBagRemove oldHeight
@@ -1915,7 +1915,7 @@ mergeCheapWithMove nt = mergeGCheap' _mergeSubscribedParentWithMove_subscription
1915 let moveOrDelete :: forall a. k a -> PatchDMapWithMove.NodeInfo k q a -> MergeSubscribedParentWithMove x k a -> Constant (EventM x (Maybe (EventSubscription x))) a
1915 let moveOrDelete :: forall a. k a -> PatchDMapWithMove.NodeInfo k q a -> MergeSubscribedParentWithMove x k a -> Constant (EventM x (Maybe (EventSubscription x))) a
1916 moveOrDelete _ ni parent = Constant $ case getComposeMaybe $ PatchDMapWithMove._nodeInfo_to ni of
1916 moveOrDelete _ ni parent = Constant $ case getComposeMaybe $ PatchDMapWithMove._nodeInfo_to ni of
1917 Nothing -> do
1917 Nothing -> do
1918− oldHeight <- liftIO $ getEventSubscribedHeight $ _eventSubscription_subscribed $
1918+ oldHeight <- liftIO $ getEventSubscribedHeight $ _eventSubscription_subscribed $
1919 _mergeSubscribedParentWithMove_subscription parent
1919 _mergeSubscribedParentWithMove_subscription parent
1920
1920
1921 liftIO $ modifyIORef heightBagRef $ heightBagRemove oldHeight
1921 liftIO $ modifyIORef heightBagRef $ heightBagRemove oldHeight
@@ -1923,7 +1923,7 @@ mergeCheapWithMove nt = mergeGCheap' _mergeSubscribedParentWithMove_subscription
1923 Just toKey -> do
1923 Just toKey -> do
1924 liftIO $ writeIORef (_mergeSubscribedParentWithMove_key parent) $! toKey
1924 liftIO $ writeIORef (_mergeSubscribedParentWithMove_key parent) $! toKey
1925 return Nothing
1925 return Nothing
1926− toDelete <- fmap catMaybes $ mapM (\(_ :=> v) -> getConstant v) $ DMap.toList $
1926+ toDelete <- fmap catMaybes $ mapM (\(_ :=> v) -> getConstant v) $ DMap.toList $
1927 DMap.intersectionWithKey moveOrDelete (unPatchDMapWithMove p) oldParents
1927 DMap.intersectionWithKey moveOrDelete (unPatchDMapWithMove p) oldParents
1928
1928
1929 return (toDelete, applyAlways p' oldParents)
1929 return (toDelete, applyAlways p' oldParents)
@@ -1976,16 +1976,16 @@ invalidateMergeHeight' :: IORef Height -> Subscriber x a -> IO ()
1976invalidateMergeHeight' heightRef sub = do
1976invalidateMergeHeight' heightRef sub = do
1977 oldHeight <- readIORef heightRef
1977 oldHeight <- readIORef heightRef
1978 -- If the height used to be valid, it must be invalid now; we should never have *more* heights than we have parents
1978 -- If the height used to be valid, it must be invalid now; we should never have *more* heights than we have parents
1979− when (oldHeight /= invalidHeight) $ do
1979+ when (oldHeight /= invalidHeight) $ do
1980 writeIORef heightRef $! invalidHeight
1980 writeIORef heightRef $! invalidHeight
1981 subscriberInvalidateHeight sub oldHeight
1981 subscriberInvalidateHeight sub oldHeight
1982
1982
1983revalidateMergeHeight :: Merge x k v s -> IO ()
1983revalidateMergeHeight :: Merge x k v s -> IO ()
1984revalidateMergeHeight m = do
1984revalidateMergeHeight m = do
1985 currentHeight <- readIORef $ _merge_heightRef m
1985 currentHeight <- readIORef $ _merge_heightRef m
1986−
1986+
1987 -- revalidateMergeHeight may be called multiple times; perhaps the's a way to finesse it to avoid this check
1987 -- revalidateMergeHeight may be called multiple times; perhaps the's a way to finesse it to avoid this check
1988− when (currentHeight == invalidHeight) $ do
1988+ when (currentHeight == invalidHeight) $ do
1989 heights <- readIORef $ _merge_heightBagRef m
1989 heights <- readIORef $ _merge_heightBagRef m
1990 parents <- readIORef $ _merge_parentsRef m
1990 parents <- readIORef $ _merge_parentsRef m
1991 -- When the number of heights in the bag reaches the number of parents, we should have a valid height
1991 -- When the number of heights in the bag reaches the number of parents, we should have a valid height
@@ -2001,22 +2001,22 @@ revalidateMergeHeight m = do
2001scheduleMergeSelf :: HasSpiderTimeline x => Merge x k v s -> Height -> EventM x ()
2001scheduleMergeSelf :: HasSpiderTimeline x => Merge x k v s -> Height -> EventM x ()
2002scheduleMergeSelf m height = scheduleMerge' height (_merge_heightRef m) $ do
2002scheduleMergeSelf m height = scheduleMerge' height (_merge_heightRef m) $ do
2003 vals <- liftIO $ readIORef $ _merge_accumRef m
2003 vals <- liftIO $ readIORef $ _merge_accumRef m
2004− -- Once we're done with this, we can clear it immediately, because if there's a cacheEvent in front of us,
2004+ -- Once we're done with this, we can clear it immediately, because if there's a cacheEvent in front of us,
2005 -- it'll handle subsequent subscribers, and if not, we won't get subsequent subscribers
2005 -- it'll handle subsequent subscribers, and if not, we won't get subsequent subscribers
2006− liftIO $ writeIORef (_merge_accumRef m) $! DMap.empty
2006+ liftIO $ writeIORef (_merge_accumRef m) $! DMap.empty
2007 --TODO: Assert that m is not empty
2007 --TODO: Assert that m is not empty
2008 subscriberPropagate (_merge_sub m) vals
2008 subscriberPropagate (_merge_sub m) vals
2009
2009
2010checkCycle :: HasSpiderTimeline x => EventSubscribed x -> EventM x ()
2010checkCycle :: HasSpiderTimeline x => EventSubscribed x -> EventM x ()
2011checkCycle subscribed = liftIO $ do
2011checkCycle subscribed = liftIO $ do
2012 height <- readIORef (eventSubscribedHeightRef subscribed)
2012 height <- readIORef (eventSubscribedHeightRef subscribed)
2013−
2013+
2014 -- currentHeight <- getCurrentHeight
2014 -- currentHeight <- getCurrentHeight
2015 -- when (height <= currentHeight) $ if height /= invalidHeight
2015 -- when (height <= currentHeight) $ if height /= invalidHeight
2016 -- then do
2016 -- then do
2017 -- myStack <- liftIO $ whoCreatedIORef undefined --TODO
2017 -- myStack <- liftIO $ whoCreatedIORef undefined --TODO
2018 -- error $ "Height (" ++ show height ++ ") is not greater than current height (" ++ show currentHeight ++ ")\n" ++ unlines (reverse myStack)
2018 -- error $ "Height (" ++ show height ++ ") is not greater than current height (" ++ show currentHeight ++ ")\n" ++ unlines (reverse myStack)
2019− -- else liftIO $
2019+ -- else liftIO $
2020 when (height == invalidHeight) $
2020 when (height == invalidHeight) $
2021#ifdef DEBUG_CYCLES
2021#ifdef DEBUG_CYCLES
2022 do
2022 do
@@ -2069,17 +2069,17 @@ mergeGCheap' getParent getInitialSubscribers updateFunc destroy d = Event $ \sub
2069 parentsRef :: IORef (DMap k s) <- liftIO $ newIORef $ error "merge: parentsRef not yet initialized"
2069 parentsRef :: IORef (DMap k s) <- liftIO $ newIORef $ error "merge: parentsRef not yet initialized"
2070 changeSubdRef <- liftIO $ newIORef $ error "getMergeSubscribed: changeSubdRef not yet initialized"
2070 changeSubdRef <- liftIO $ newIORef $ error "getMergeSubscribed: changeSubdRef not yet initialized"
2071
2071
2072− let subscribed = EventSubscribed
2072+ let subscribed = EventSubscribed
2073− { eventSubscribedHeightRef = heightRef
2073+ { eventSubscribedHeightRef = heightRef
2074 , eventSubscribedRetained = toAny (parentsRef, changeSubdRef)
2074 , eventSubscribedRetained = toAny (parentsRef, changeSubdRef)
2075#ifdef DEBUG_CYCLES
2075#ifdef DEBUG_CYCLES
2076 , eventSubscribedGetParents = do
2076 , eventSubscribedGetParents = do
2077 let getParent' (_ :=> v) = _eventSubscription_subscribed (getParent v)
2077 let getParent' (_ :=> v) = _eventSubscription_subscribed (getParent v)
2078− fmap getParent' . DMap.toList <$> readIORef parentsRef
2078+ fmap getParent' . DMap.toList <$> readIORef parentsRef
2079 , eventSubscribedHasOwnHeightRef = False
2079 , eventSubscribedHasOwnHeightRef = False
2080 , eventSubscribedWhoCreated = whoCreatedIORef heightRef
2080 , eventSubscribedWhoCreated = whoCreatedIORef heightRef
2081−#endif
2081+#endif
2082− }
2082+ }
2083
2083
2084 m = Merge
2084 m = Merge
2085 { _merge_parentsRef = parentsRef
2085 { _merge_parentsRef = parentsRef
@@ -2117,9 +2117,9 @@ mergeGCheap' getParent getInitialSubscribers updateFunc destroy d = Event $ \sub
2117 -- its subscription.
2117 -- its subscription.
2118 liftIO $ writeIORef changeSubdRef (changeSubscriber, changeSubscription)
2118 liftIO $ writeIORef changeSubdRef (changeSubscriber, changeSubscription)
2119 let unsubscribeAll = destroy =<< readIORef parentsRef
2119 let unsubscribeAll = destroy =<< readIORef parentsRef
2120−
2120+
2121 return (EventSubscription unsubscribeAll subscribed, occ)
2121 return (EventSubscription unsubscribeAll subscribed, occ)
2122−
2122+
2123
2123
2124mergeInt :: forall x a. (HasSpiderTimeline x) => DynamicS x (PatchIntMap (Event x a)) -> Event x (IntMap a)
2124mergeInt :: forall x a. (HasSpiderTimeline x) => DynamicS x (PatchIntMap (Event x a)) -> Event x (IntMap a)
2125mergeInt = cacheEvent . mergeIntCheap
2125mergeInt = cacheEvent . mergeIntCheap
@@ -2133,14 +2133,14 @@ mergeIntCheap d = Event $ \sub -> do
2133 heightBagRef <- liftIO $ newIORef heightBagEmpty
2133 heightBagRef <- liftIO $ newIORef heightBagEmpty
2134 parents <- liftIO $ FastMutableIntMap.newEmpty
2134 parents <- liftIO $ FastMutableIntMap.newEmpty
2135 changeSubdRef <- liftIO $ newIORef $ error "getMergeSubscribed: changeSubdRef not yet initialized"
2135 changeSubdRef <- liftIO $ newIORef $ error "getMergeSubscribed: changeSubdRef not yet initialized"
2136− let subscribed = EventSubscribed
2136+ let subscribed = EventSubscribed
2137− { eventSubscribedHeightRef = heightRef
2137+ { eventSubscribedHeightRef = heightRef
2138 , eventSubscribedRetained = toAny (parents, changeSubdRef)
2138 , eventSubscribedRetained = toAny (parents, changeSubdRef)
2139#ifdef DEBUG_CYCLES
2139#ifdef DEBUG_CYCLES
2140 , eventSubscribedGetParents = fmap (_eventSubscription_subscribed . snd) <$> FastMutableIntMap.toList parents
2140 , eventSubscribedGetParents = fmap (_eventSubscription_subscribed . snd) <$> FastMutableIntMap.toList parents
2141 , eventSubscribedHasOwnHeightRef = False
2141 , eventSubscribedHasOwnHeightRef = False
2142 , eventSubscribedWhoCreated = whoCreatedIORef heightRef
2142 , eventSubscribedWhoCreated = whoCreatedIORef heightRef
2143−#endif
2143+#endif
2144 }
2144 }
2145 let scheduleSelf = do
2145 let scheduleSelf = do
2146 height <- liftIO $ readIORef $ heightRef
2146 height <- liftIO $ readIORef $ heightRef
@@ -2229,7 +2229,7 @@ mergeIntCheap d = Event $ \sub -> do
2229 -- its subscription.
2229 -- its subscription.
2230 liftIO $ writeIORef changeSubdRef (changeSubscriber, changeSubscription)
2230 liftIO $ writeIORef changeSubdRef (changeSubscriber, changeSubscription)
2231 let unsubscribeAll = traverse_ unsubscribe =<< FastMutableIntMap.getFrozenAndClear parents
2231 let unsubscribeAll = traverse_ unsubscribe =<< FastMutableIntMap.getFrozenAndClear parents
2232−
2232+
2233
2233
2234 return (EventSubscription unsubscribeAll subscribed, occ)
2234 return (EventSubscription unsubscribeAll subscribed, occ)
2235
2235
test/DebugCycles.hs+25−25
@@ -43,11 +43,11 @@ import Data.Witherable (Filterable)
43import Data.These.Lens
43import Data.These.Lens
44#endif
44#endif
45
45
46−type Widget t m = (MonadHold t m, Reflex t, MonadFix m)
46+type Widget t m = (MonadHold t m, Reflex t, MonadFix m)
47
47
48
48
49connectDyn ::Widget t m => Event t () -> (Dynamic t a, Dynamic t a) -> m (Dynamic t a)
49connectDyn ::Widget t m => Event t () -> (Dynamic t a, Dynamic t a) -> m (Dynamic t a)
50−connectDyn e (d, d') = do
50+connectDyn e (d, d') = do
51 dd <- holdDyn d (d' <$ e)
51 dd <- holdDyn d (d' <$ e)
52 return $ join dd
52 return $ join dd
53
53
@@ -64,7 +64,7 @@ connectOnCoincidence :: Widget t m => Event t () -> Event t a -> m (Event t a)
64connectOnCoincidence click e = do
64connectOnCoincidence click e = do
65 d <- holdDyn never (e <$ click)
65 d <- holdDyn never (e <$ click)
66 return $ coincidence (updated d)
66 return $ coincidence (updated d)
67−
67+
68coincidenceLoop :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
68coincidenceLoop :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
69coincidenceLoop (e1, e2) = do
69coincidenceLoop (e1, e2) = do
70-- "heightBagRemove: Height 1 not present in bag HeightBag {_heightBag_size = 1, _heightBag_contents = fromList [(0,0)]}"
70-- "heightBagRemove: Height 1 not present in bag HeightBag {_heightBag_size = 1, _heightBag_contents = fromList [(0,0)]}"
@@ -83,11 +83,11 @@ addHeight e = leftmost [e4, e4] where
83 e4 = leftmost [e3, e3]
83 e4 = leftmost [e3, e3]
84
84
85
85
86−-- Take an existing test and build it inside a
86+-- Take an existing test and build it inside a
87buildLoop :: Widget t m => (forall t m. Widget t m => (Event t Int, Event t ()) -> m (Event t Int)) -> (Event t Int, Event t ()) -> m (Event t Int)
87buildLoop :: Widget t m => (forall t m. Widget t m => (Event t Int, Event t ()) -> m (Event t Int)) -> (Event t Int, Event t ()) -> m (Event t Int)
88buildLoop test (e1, e2) = switchHold never buildLoop
88buildLoop test (e1, e2) = switchHold never buildLoop
89− where buildLoop = pushAlways (const $ test (e1, e2)) e2
89+ where buildLoop = pushAlways (const $ test (e1, e2)) e2
90−
90+
91
91
92connectButtonPromptly :: Widget t m => Event t () -> Event t a -> m (Event t a)
92connectButtonPromptly :: Widget t m => Event t () -> Event t a -> m (Event t a)
93connectButtonPromptly click e = do
93connectButtonPromptly click e = do
@@ -110,13 +110,13 @@ switchLoop (e1, e2) = do
110mergeLoop :: forall t m. (Adjustable t m, Widget t m) => (Event t Int, Event t ()) -> m (Event t Int)
110mergeLoop :: forall t m. (Adjustable t m, Widget t m) => (Event t Int, Event t ()) -> m (Event t Int)
111mergeLoop (e1, e2) = do
111mergeLoop (e1, e2) = do
112 rec
112 rec
113− (_, e) <- runEventWriterT $
113+ (_, e) <- runEventWriterT $
114 runWithReplace w (leftmost [w <$ e1])
114 runWithReplace w (leftmost [w <$ e1])
115
115
116 return (sum <$> e)
116 return (sum <$> e)
117−
117+
118 where
118 where
119− w = do
119+ w = do
120 c <- count e1
120 c <- count e1
121 tellEvent (updated ((pure <$> c) :: Dynamic t [Int]))
121 tellEvent (updated ((pure <$> c) :: Dynamic t [Int]))
122
122
@@ -128,7 +128,7 @@ switchLoop' (e1, e2) = do
128 rec
128 rec
129 e' <- connectButton e2 (updated d)
129 e' <- connectButton e2 (updated d)
130 d <- count (leftmost [e', e1])
130 d <- count (leftmost [e', e1])
131− return $ updated d
131+ return $ updated d
132
132
133
133
134switchLoop2 :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
134switchLoop2 :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
@@ -137,7 +137,7 @@ switchLoop2 (e1, e2) = do
137 e' <- connectButton e2 (addHeight $ updated d)
137 e' <- connectButton e2 (addHeight $ updated d)
138 d <- count (align e' e1)
138 d <- count (align e' e1)
139 return $ updated d
139 return $ updated d
140−
140+
141
141
142staticLoop :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
142staticLoop :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
143staticLoop (e1, e2) = do
143staticLoop (e1, e2) = do
@@ -149,12 +149,12 @@ staticLoop' :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
149staticLoop' (e1, e2) = do
149staticLoop' (e1, e2) = do
150 rec
150 rec
151 d <- foldDyn (+) (0 :: Int) (leftmost [e1, updated d])
151 d <- foldDyn (+) (0 :: Int) (leftmost [e1, updated d])
152− return $ updated d
152+ return $ updated d
153
153
154
154
155buildStaticLoop :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
155buildStaticLoop :: Widget t m => (Event t Int, Event t ()) -> m (Event t Int)
156buildStaticLoop (e1, e2) = switchHold never buildLoop
156buildStaticLoop (e1, e2) = switchHold never buildLoop
157− where buildLoop = pushAlways (const $ staticLoop (e1, e2)) e2
157+ where buildLoop = pushAlways (const $ staticLoop (e1, e2)) e2
158
158
159splitThese :: Filterable f => f (These a b) -> (f a, f b)
159splitThese :: Filterable f => f (These a b) -> (f a, f b)
160splitThese f = (mapMaybe (preview here) f, mapMaybe (preview there) f)
160splitThese f = (mapMaybe (preview here) f, mapMaybe (preview there) f)
@@ -166,31 +166,31 @@ runTest (name, TestCase test) = do
166 putStrLn ("Test: " <> name)
166 putStrLn ("Test: " <> name)
167 mError <- timeout (milliseconds 5) $
167 mError <- timeout (milliseconds 5) $
168 run `catch` \(e :: EventLoopException) -> pure (show e)
168 run `catch` \(e :: EventLoopException) -> pure (show e)
169−
169+
170− case mError of
170+ case mError of
171 Just err -> putStrLn err
171 Just err -> putStrLn err
172 Nothing -> error "timed out (loop not detected)"
172 Nothing -> error "timed out (loop not detected)"
173−
174− where
175
173
174+ where
175+
176− run = do
176+ run = do
177− r <- runApp' (test . splitThese) (Just <$> occs)
177+ r <- runApp' (test . splitThese) (Just <$> occs)
178 error (name <> ": unexpected success " <> show r)
178 error (name <> ": unexpected success " <> show r)
179
179
180 occs = [ This 1, This 2, That (), This 3, That (), This 1 ]
180 occs = [ This 1, This 2, That (), This 3, That (), This 1 ]
181−
181+
182 milliseconds = (*1000)
182 milliseconds = (*1000)
183−
183+
184
184
185newtype TestCase = TestCase { unTest :: forall t m. (Widget t m, Adjustable t m) => (Event t Int, Event t ()) -> m (Event t Int) }
185newtype TestCase = TestCase { unTest :: forall t m. (Widget t m, Adjustable t m) => (Event t Int, Event t ()) -> m (Event t Int) }
186
186
187tests :: [(String, TestCase)]
187tests :: [(String, TestCase)]
188−tests =
188+tests =
189 [ ("switchLoop'", TestCase switchLoop')
189 [ ("switchLoop'", TestCase switchLoop')
190 , ("switchLoop", TestCase switchLoop)
190 , ("switchLoop", TestCase switchLoop)
191−
191+
192 , ("mergeLoop", TestCase mergeLoop)
192 , ("mergeLoop", TestCase mergeLoop)
193−
193+
194
194
195 -- , ("switchLoop2", TestCase switchLoop2)
195 -- , ("switchLoop2", TestCase switchLoop2)
196
196
@@ -207,7 +207,7 @@ tests =
207main :: IO ()
207main :: IO ()
208main = traverse_ runTest tests
208main = traverse_ runTest tests
209
209
210−
210+
211
211
212
212
213
213