@@ -71,6 +71,7 @@ import Data.Tree (Forest, Tree (..), drawForest)
71import Data.WeakBag (WeakBag, WeakBagTicket)
71import Data.WeakBag (WeakBag, WeakBagTicket)
72import qualified Data.WeakBag as WeakBag
72import qualified Data.WeakBag as WeakBag
73import qualified Reflex.Class as R
73import qualified Reflex.Class as R
74import qualified Reflex.Host.Class as R
75import qualified Reflex.Host.Class as R
76-- Note: must come last to silence warnings due to AMP on GHC < 7.10
77-- Note: must come last to silence warnings due to AMP on GHC < 7.10
@@ -296,7 +297,7 @@ eventCoincidence !c = Event $ wrap eventSubscribedCoincidence $ getCoincidenceSu
296eventHold :: HasSpiderTimeline x => Hold x p -> Event x p
297eventHold :: HasSpiderTimeline x => Hold x p -> Event x p
297eventHold !h = Event $ subscribeHoldEvent h
298eventHold !h = Event $ subscribeHoldEvent h
299−eventDyn :: (HasSpiderTimeline x, R.Patch p) => Dyn x p -> Event x p
300+eventDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> Event x p
300eventDyn !j = Event $ \sub -> getDynHold j >>= \h -> subscribeHoldEvent h sub
301eventDyn !j = Event $ \sub -> getDynHold j >>= \h -> subscribeHoldEvent h sub
302{-# INLINE subscribeCoincidenceInner #-}
303{-# INLINE subscribeCoincidenceInner #-}
@@ -329,7 +330,7 @@ data Subscriber x a = Subscriber
329-- The result is also evaluated to WHNF, since forcing a thunk invalidates
330-- The result is also evaluated to WHNF, since forcing a thunk invalidates
330-- the weak pointer to it in some cases.
331-- the weak pointer to it in some cases.
332−newSubscriberHold :: (HasSpiderTimeline x, R.Patch p) => Hold x p -> IO (Subscriber x p)
333+newSubscriberHold :: (HasSpiderTimeline x, Patch p) => Hold x p -> IO (Subscriber x p)
333newSubscriberHold h = return $ Subscriber
334newSubscriberHold h = return $ Subscriber
334 { subscriberPropagate = {-# SCC "traverseHold" #-} propagateSubscriberHold h
335 { subscriberPropagate = {-# SCC "traverseHold" #-} propagateSubscriberHold h
335 , subscriberInvalidateHeight = \_ -> return ()
336 , subscriberInvalidateHeight = \_ -> return ()
@@ -564,7 +565,7 @@ unsubscribe (EventSubscription u _) = u
565newtype Behavior x a = Behavior { readBehaviorTracked :: BehaviorM x a }
566newtype Behavior x a = Behavior { readBehaviorTracked :: BehaviorM x a }
567−behaviorHold :: Hold x p -> Behavior x (R.PatchTarget p)
568+behaviorHold :: Hold x p -> Behavior x (PatchTarget p)
568behaviorHold !h = Behavior $ readHoldTracked h
569behaviorHold !h = Behavior $ readHoldTracked h
570behaviorHoldIdentity :: Hold x (Identity a) -> Behavior x a
571behaviorHoldIdentity :: Hold x (Identity a) -> Behavior x a
@@ -600,11 +601,11 @@ behaviorPull !p = Behavior $ do
600 askParentsRef >>= mapM_ (\r -> liftIO $ modifyIORef' r (SomeBehaviorSubscribed (BehaviorSubscribedPull subscribed) :))
601 askParentsRef >>= mapM_ (\r -> liftIO $ modifyIORef' r (SomeBehaviorSubscribed (BehaviorSubscribedPull subscribed) :))
603−behaviorDyn :: R.Patch p => Dyn x p -> Behavior x (R.PatchTarget p)
604+behaviorDyn :: Patch p => Dyn x p -> Behavior x (PatchTarget p)
604behaviorDyn !d = Behavior $ readHoldTracked =<< getDynHold d
605behaviorDyn !d = Behavior $ readHoldTracked =<< getDynHold d
606{-# INLINE readHoldTracked #-}
607{-# INLINE readHoldTracked #-}
607−readHoldTracked :: Hold x p -> BehaviorM x (R.PatchTarget p)
608+readHoldTracked :: Hold x p -> BehaviorM x (PatchTarget p)
608readHoldTracked h = do
609readHoldTracked h = do
609 result <- liftIO $ readIORef $ holdValue h
610 result <- liftIO $ readIORef $ holdValue h
610 askInvalidator >>= mapM_ (\wi -> liftIO $ modifyIORef' (holdInvalidators h) (wi:))
611 askInvalidator >>= mapM_ (\wi -> liftIO $ modifyIORef' (holdInvalidators h) (wi:))
@@ -623,7 +624,7 @@ readBehaviorUntracked b = do
623--------------------------------------------------------------------------------
624--------------------------------------------------------------------------------
625data Dynamic x p = Dynamic
626data Dynamic x p = Dynamic
626− { dynamicCurrent :: !(Behavior x (R.PatchTarget p))
627+ { dynamicCurrent :: !(Behavior x (PatchTarget p))
627 , dynamicUpdated :: !(Event x p)
628 , dynamicUpdated :: !(Event x p)
@@ -636,13 +637,13 @@ dynamicHold !h = Dynamic
636dynamicHoldIdentity :: HasSpiderTimeline x => Hold x (Identity a) -> Dynamic x (Identity a)
637dynamicHoldIdentity :: HasSpiderTimeline x => Hold x (Identity a) -> Dynamic x (Identity a)
637dynamicHoldIdentity = dynamicHold
638dynamicHoldIdentity = dynamicHold
639−dynamicConst :: R.PatchTarget p -> Dynamic x p
640+dynamicConst :: PatchTarget p -> Dynamic x p
640dynamicConst !a = Dynamic
641dynamicConst !a = Dynamic
641 { dynamicCurrent = behaviorConst a
642 { dynamicCurrent = behaviorConst a
642 , dynamicUpdated = eventNever
643 , dynamicUpdated = eventNever
645−dynamicDyn :: (HasSpiderTimeline x, R.Patch p) => Dyn x p -> Dynamic x p
646+dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> Dynamic x p
646dynamicDyn !d = Dynamic
647dynamicDyn !d = Dynamic
647 { dynamicCurrent = behaviorDyn d
648 { dynamicCurrent = behaviorDyn d
648 , dynamicUpdated = eventDyn d
649 , dynamicUpdated = eventDyn d
@@ -660,7 +661,7 @@ dynamicDynIdentity = dynamicDyn
661--type role Hold representational
662--type role Hold representational
662data Hold x p
663data Hold x p
663− = Hold { holdValue :: !(IORef (R.PatchTarget p))
664+ = Hold { holdValue :: !(IORef (PatchTarget p))
664 , holdInvalidators :: !(IORef [Weak (Invalidator x)])
665 , holdInvalidators :: !(IORef [Weak (Invalidator x)])
665 , holdEvent :: Event x p -- This must be lazy, or holds cannot be defined before their input Events
666 , holdEvent :: Event x p -- This must be lazy, or holds cannot be defined before their input Events
666 , holdParent :: !(IORef (Maybe (EventSubscription x))) -- Keeps its parent alive (will be undefined until the hold is initialized) --TODO: Probably shouldn't be an IORef
667 , holdParent :: !(IORef (Maybe (EventSubscription x))) -- Keeps its parent alive (will be undefined until the hold is initialized) --TODO: Probably shouldn't be an IORef
@@ -764,9 +765,9 @@ instance HasSpiderTimeline x => Defer (SomeResetCoincidence x) (EventM x) where
764 getDeferralQueue = asksEventEnv eventEnvResetCoincidences
765 getDeferralQueue = asksEventEnv eventEnvResetCoincidences
766-- Note: hold cannot examine its event until after the phase is over
767-- Note: hold cannot examine its event until after the phase is over
767−{- SPECIALIZE hold :: (HasSpiderTimeline x, R.Patch p) => R.PatchTarget p -> Event x p -> EventM x (Hold x p) #-}
768+{- SPECIALIZE hold :: (HasSpiderTimeline x, Patch p) => PatchTarget p -> Event x p -> EventM x (Hold x p) #-}
768{-# INLINE [1] hold #-}
769{-# INLINE [1] hold #-}
769−hold :: (R.Patch p, Defer (SomeHoldInit x) m) => R.PatchTarget p -> Event x p -> m (Hold x p)
770+hold :: (Patch p, Defer (SomeHoldInit x) m) => PatchTarget p -> Event x p -> m (Hold x p)
770hold v0 e = do
771hold v0 e = do
771 valRef <- liftIO $ newIORef v0
772 valRef <- liftIO $ newIORef v0
772 invsRef <- liftIO $ newIORef []
773 invsRef <- liftIO $ newIORef []
@@ -787,7 +788,7 @@ hold v0 e = do
789{-# INLINE getHoldEventSubscription #-}
790{-# INLINE getHoldEventSubscription #-}
790−getHoldEventSubscription :: forall m p x. (Defer (SomeAssignment x) m, Defer (SomeHoldInit x) m, Defer SomeClear m, R.Patch p, HasCurrentHeight x m, Defer (SomeMergeInit x) m, Defer (SomeResetCoincidence x) m, HasSpiderTimeline x, m ~ EventM x) => Hold x p -> m (EventSubscription x)
791+getHoldEventSubscription :: forall m p x. (Defer (SomeAssignment x) m, Defer (SomeHoldInit x) m, Defer SomeClear m, Patch p, HasCurrentHeight x m, Defer (SomeMergeInit x) m, Defer (SomeResetCoincidence x) m, HasSpiderTimeline x, m ~ EventM x) => Hold x p -> m (EventSubscription x)
791getHoldEventSubscription h = do
792getHoldEventSubscription h = do
792 ep <- liftIO $ readIORef $ holdParent h
793 ep <- liftIO $ readIORef $ holdParent h
793 case ep of
794 case ep of
@@ -801,7 +802,7 @@ getHoldEventSubscription h = do
801 Nothing -> return ()
802 Nothing -> return ()
802 Just o -> do
803 Just o -> do
803 old <- liftIO $ readIORef $ holdValue h
804 old <- liftIO $ readIORef $ holdValue h
804− case R.apply o old of
805+ case apply o old of
805 Nothing -> return ()
806 Nothing -> return ()
806 Just new -> do
807 Just new -> do
807 -- Need to evaluate these so that we don't retain the Hold itself
808 -- Need to evaluate these so that we don't retain the Hold itself
@@ -872,7 +873,7 @@ data Root x (k :: * -> *)
872 , rootInit :: !(forall a. k a -> RootTrigger x a -> IO (IO ()))
873 , rootInit :: !(forall a. k a -> RootTrigger x a -> IO (IO ()))
875−data SomeHoldInit x = forall p. R.Patch p => SomeHoldInit !(Hold x p)
876+data SomeHoldInit x = forall p. Patch p => SomeHoldInit !(Hold x p)
877data SomeMergeUpdate x = SomeMergeUpdate
878data SomeMergeUpdate x = SomeMergeUpdate
878 { _someMergeUpdate_update :: !(EventM x [EventSubscription x])
879 { _someMergeUpdate_update :: !(EventM x [EventSubscription x])
@@ -1015,7 +1016,7 @@ instance HasSpiderTimeline x => Align (Event x) where
1015 nil = eventNever
1016 nil = eventNever
1016 align ea eb = R.fmapMaybe R.dmapToThese $ merge $ dynamicConst $ DMap.fromList [R.LeftTag :=> ea, R.RightTag :=> eb]
1017 align ea eb = R.fmapMaybe R.dmapToThese $ merge $ dynamicConst $ DMap.fromList [R.LeftTag :=> ea, R.RightTag :=> eb]
1018−newtype Dyn x p = Dyn { unDyn :: IORef (Either (BehaviorM x (R.PatchTarget p), Event x p) (Hold x p)) }
1019+newtype Dyn x p = Dyn { unDyn :: IORef (Either (BehaviorM x (PatchTarget p), Event x p) (Hold x p)) }
1020newMapDyn :: HasSpiderTimeline x => (a -> b) -> Dynamic x (Identity a) -> Dynamic x (Identity b)
1021newMapDyn :: HasSpiderTimeline x => (a -> b) -> Dynamic x (Identity a) -> Dynamic x (Identity b)
1021newMapDyn f d = dynamicDynIdentity $ unsafeDyn (fmap f $ readBehaviorTracked $ dynamicCurrent d) (Identity . f . runIdentity <$> dynamicUpdated d)
1022newMapDyn f d = dynamicDynIdentity $ unsafeDyn (fmap f $ readBehaviorTracked $ dynamicCurrent d) (Identity . f . runIdentity <$> dynamicUpdated d)
@@ -1036,7 +1037,7 @@ zipDynWith f da db =
1036 return $ Just $ Identity $ f a b
1037 return $ Just $ Identity $ f a b
1037 in dynamicDynIdentity $ unsafeDyn (f <$> readBehaviorUntracked (dynamicCurrent da) <*> readBehaviorUntracked (dynamicCurrent db)) ec
1038 in dynamicDynIdentity $ unsafeDyn (f <$> readBehaviorUntracked (dynamicCurrent da) <*> readBehaviorUntracked (dynamicCurrent db)) ec
1039−unsafeDyn :: BehaviorM x (R.PatchTarget p) -> Event x p -> Dyn x p
1040+unsafeDyn :: BehaviorM x (PatchTarget p) -> Event x p -> Dyn x p
1040unsafeDyn readV0 v' = Dyn $ unsafeNewIORef x $ Left x
1041unsafeDyn readV0 v' = Dyn $ unsafeNewIORef x $ Left x
1041 where x = (readV0, v')
1042 where x = (readV0, v')
@@ -1209,13 +1210,13 @@ listsToForest l = fmap (\(a, l') -> Node a $ listsToForest $ toList l') $ groupB
1211{-# INLINE propagateSubscriberHold #-}
1212{-# INLINE propagateSubscriberHold #-}
1212−propagateSubscriberHold :: forall x p. (HasSpiderTimeline x, R.Patch p) => Hold x p -> p -> EventM x ()
1213+propagateSubscriberHold :: forall x p. (HasSpiderTimeline x, Patch p) => Hold x p -> p -> EventM x ()
1213propagateSubscriberHold h a = do
1214propagateSubscriberHold h a = do
1214 {-# SCC "trace" #-} traceMWhen (Proxy :: Proxy x) debugPropagate $ liftIO $ do
1215 {-# SCC "trace" #-} traceMWhen (Proxy :: Proxy x) debugPropagate $ liftIO $ do
1215 invalidators <- liftIO $ readIORef $ holdInvalidators h
1216 invalidators <- liftIO $ readIORef $ holdInvalidators h
1216 return $ "SubscriberHold" <> showNodeId h <> ": " ++ show (length invalidators)
1217 return $ "SubscriberHold" <> showNodeId h <> ": " ++ show (length invalidators)
1217 v <- {-# SCC "read" #-} liftIO $ readIORef $ holdValue h
1218 v <- {-# SCC "read" #-} liftIO $ readIORef $ holdValue h
1218− case {-# SCC "apply" #-} R.apply a v of
1219+ case {-# SCC "apply" #-} apply a v of
1219 Nothing -> return ()
1220 Nothing -> return ()
1220 Just v' -> do
1221 Just v' -> do
1221 {-# SCC "trace2" #-} withIncreasedDepth $ tracePropagate (Proxy :: Proxy x) $ "propagateSubscriberHold: assigning Hold" <> showNodeId h
1222 {-# SCC "trace2" #-} withIncreasedDepth $ tracePropagate (Proxy :: Proxy x) $ "propagateSubscriberHold: assigning Hold" <> showNodeId h
@@ -1248,7 +1249,7 @@ askBehaviorHoldInits = do
1248 return his
1249 return his
1250{-# INLINE getDynHold #-}
1251{-# INLINE getDynHold #-}
1251−getDynHold :: (Defer (SomeHoldInit x) m, R.Patch p) => Dyn x p -> m (Hold x p)
1252+getDynHold :: (Defer (SomeHoldInit x) m, Patch p) => Dyn x p -> m (Hold x p)
1252getDynHold d = do
1253getDynHold d = do
1253 mh <- liftIO $ readIORef $ unDyn d
1254 mh <- liftIO $ readIORef $ unDyn d
1254 case mh of
1255 case mh of
@@ -1488,11 +1489,11 @@ subscribeCoincidenceSubscribed :: CoincidenceSubscribed x a -> Subscriber x a ->
1488subscribeCoincidenceSubscribed subscribed sub = WeakBag.insert sub (coincidenceSubscribedSubscribers subscribed) (coincidenceSubscribedWeakSelf subscribed) cleanupCoincidenceSubscribed
1489subscribeCoincidenceSubscribed subscribed sub = WeakBag.insert sub (coincidenceSubscribedSubscribers subscribed) (coincidenceSubscribedWeakSelf subscribed) cleanupCoincidenceSubscribed
1490{-# INLINE merge #-}
1491{-# INLINE merge #-}
1491−merge :: forall k x. (HasSpiderTimeline x, GCompare k) => Dynamic x (R.PatchDMap k (Event x)) -> Event x (DMap k Identity)
1492+merge :: forall k x. (HasSpiderTimeline x, GCompare k) => Dynamic x (PatchDMap k (Event x)) -> Event x (DMap k Identity)
1492merge d = cacheEvent (mergeCheap d)
1493merge d = cacheEvent (mergeCheap d)
1494{-# INLINE [1] mergeCheap #-}
1495{-# INLINE [1] mergeCheap #-}
1495−mergeCheap :: forall k x. (HasSpiderTimeline x, GCompare k) => Dynamic x (R.PatchDMap k (Event x)) -> Event x (DMap k Identity)
1496+mergeCheap :: forall k x. (HasSpiderTimeline x, GCompare k) => Dynamic x (PatchDMap k (Event x)) -> Event x (DMap k Identity)
1496mergeCheap d = Event $ \sub -> do
1497mergeCheap d = Event $ \sub -> do
1497 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1498 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1498 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
1499 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
@@ -1580,9 +1581,9 @@ mergeCheap d = Event $ \sub -> do
1580 liftIO $ writeIORef heightBagRef $! myHeightBag
1581 liftIO $ writeIORef heightBagRef $! myHeightBag
1581 changeSubdRef <- liftIO $ newIORef $ error "getMergeSubscribed: changeSubdRef not yet initialized"
1582 changeSubdRef <- liftIO $ newIORef $ error "getMergeSubscribed: changeSubdRef not yet initialized"
1582 liftIO $ writeIORef parentsRef $! DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
1583 liftIO $ writeIORef parentsRef $! DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
1583− let updateMe (R.PatchDMap p) = do
1584+ let updateMe (PatchDMap p) = do
1584 oldParents <- liftIO $ readIORef parentsRef
1585 oldParents <- liftIO $ readIORef parentsRef
1585− let f (subscriptionsToKill, ps) (k :=> R.ComposeMaybe me) = do
1586+ let f (subscriptionsToKill, ps) (k :=> ComposeMaybe me) = do
1586 (mOldSubd, newPs) <- case me of
1587 (mOldSubd, newPs) <- case me of
1587 Nothing -> return $ DMap.updateLookupWithKey (\_ _ -> Nothing) k ps
1588 Nothing -> return $ DMap.updateLookupWithKey (\_ _ -> Nothing) k ps
1588 Just e -> do
1589 Just e -> do
@@ -1927,7 +1928,7 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
1927 {-# INLINABLE unsafeBuildIncremental #-}
1928 {-# INLINABLE unsafeBuildIncremental #-}
1928 unsafeBuildIncremental readV0 dv = SpiderIncremental $ dynamicDyn $ unsafeDyn (coerce readV0) $ unSpiderEvent dv
1929 unsafeBuildIncremental readV0 dv = SpiderIncremental $ dynamicDyn $ unsafeDyn (coerce readV0) $ unSpiderEvent dv
1929 {-# INLINABLE mergeIncremental #-}
1930 {-# INLINABLE mergeIncremental #-}
1930− mergeIncremental = SpiderEvent . merge . (unsafeCoerce :: Dynamic x (R.PatchDMap k (R.Event (SpiderTimeline x))) -> Dynamic x (R.PatchDMap k (Event x))) . unSpiderIncremental
1931+ mergeIncremental = SpiderEvent . merge . (unsafeCoerce :: Dynamic x (PatchDMap k (R.Event (SpiderTimeline x))) -> Dynamic x (PatchDMap k (Event x))) . unSpiderIncremental
1931 {-# INLINABLE currentIncremental #-}
1932 {-# INLINABLE currentIncremental #-}
1932 currentIncremental = SpiderBehavior . dynamicCurrent . unSpiderIncremental
1933 currentIncremental = SpiderBehavior . dynamicCurrent . unSpiderIncremental
1933 {-# INLINABLE updatedIncremental #-}
1934 {-# INLINABLE updatedIncremental #-}
@@ -1935,7 +1936,7 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
1935 {-# INLINABLE incrementalToDynamic #-}
1936 {-# INLINABLE incrementalToDynamic #-}
1936 incrementalToDynamic (SpiderIncremental i) = SpiderDynamic $ dynamicDynIdentity $ unsafeDyn (readBehaviorUntracked $ dynamicCurrent i) $ flip push (dynamicUpdated i) $ \p -> do
1937 incrementalToDynamic (SpiderIncremental i) = SpiderDynamic $ dynamicDynIdentity $ unsafeDyn (readBehaviorUntracked $ dynamicCurrent i) $ flip push (dynamicUpdated i) $ \p -> do
1937 c <- readBehaviorUntracked $ dynamicCurrent i
1938 c <- readBehaviorUntracked $ dynamicCurrent i
1938− return $ Identity <$> R.apply p c --TODO: Avoid the redundant 'apply'
1939+ return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
1939 eventCoercion Coercion = Coercion
1940 eventCoercion Coercion = Coercion
1940 behaviorCoercion Coercion = Coercion
1941 behaviorCoercion Coercion = Coercion
1941 dynamicCoercion = unsafeCoerce --TODO: How can we avoid this unsafeCoerce? This is safe only because we know how Identity works as a Patch instance
1942 dynamicCoercion = unsafeCoerce --TODO: How can we avoid this unsafeCoerce? This is safe only because we know how Identity works as a Patch instance
@@ -1958,7 +1959,7 @@ holdSpiderEventM v0 e = fmap (SpiderBehavior . behaviorHoldIdentity) $ hold v0 $
1958holdDynSpiderEventM :: HasSpiderTimeline x => a -> R.Event (SpiderTimeline x) a -> EventM x (R.Dynamic (SpiderTimeline x) a)
1959holdDynSpiderEventM :: HasSpiderTimeline x => a -> R.Event (SpiderTimeline x) a -> EventM x (R.Dynamic (SpiderTimeline x) a)
1959holdDynSpiderEventM v0 e = fmap (SpiderDynamic . dynamicHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
1960holdDynSpiderEventM v0 e = fmap (SpiderDynamic . dynamicHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
1961−holdIncrementalSpiderEventM :: (HasSpiderTimeline x, R.Patch p) => R.PatchTarget p -> R.Event (SpiderTimeline x) p -> EventM x (R.Incremental (SpiderTimeline x) p)
1962+holdIncrementalSpiderEventM :: (HasSpiderTimeline x, Patch p) => PatchTarget p -> R.Event (SpiderTimeline x) p -> EventM x (R.Incremental (SpiderTimeline x) p)
1962holdIncrementalSpiderEventM v0 e = fmap (SpiderIncremental . dynamicHold) $ hold v0 $ unSpiderEvent e
1963holdIncrementalSpiderEventM v0 e = fmap (SpiderIncremental . dynamicHold) $ hold v0 $ unSpiderEvent e
1964instance HasSpiderTimeline x => R.MonadHold (SpiderTimeline x) (SpiderHost x) where
1965instance HasSpiderTimeline x => R.MonadHold (SpiderTimeline x) (SpiderHost x) where