@@ -9,7 +9,6 @@
9{-# LANGUAGE GADTs #-}
9{-# LANGUAGE GADTs #-}
10{-# LANGUAGE GeneralizedNewtypeDeriving #-}
10{-# LANGUAGE GeneralizedNewtypeDeriving #-}
11{-# LANGUAGE LambdaCase #-}
11{-# LANGUAGE LambdaCase #-}
12−{-# LANGUAGE MultiParamTypeClasses #-}
13{-# LANGUAGE MultiWayIf #-}
12{-# LANGUAGE MultiWayIf #-}
14{-# LANGUAGE RankNTypes #-}
13{-# LANGUAGE RankNTypes #-}
15{-# LANGUAGE RoleAnnotations #-}
14{-# LANGUAGE RoleAnnotations #-}
@@ -18,6 +17,8 @@
18{-# LANGUAGE TypeOperators #-}
17{-# LANGUAGE TypeOperators #-}
19{-# LANGUAGE UndecidableInstances #-}
18{-# LANGUAGE UndecidableInstances #-}
20{-# LANGUAGE PolyKinds #-}
19{-# LANGUAGE PolyKinds #-}
20+{-# LANGUAGE DeriveFunctor #-}
21+{-# LANGUAGE StandaloneDeriving #-}
21{-# LANGUAGE InstanceSigs #-}
22{-# LANGUAGE InstanceSigs #-}
23#ifdef USE_REFLEX_OPTIMIZER
24#ifdef USE_REFLEX_OPTIMIZER
@@ -37,7 +38,10 @@ import Control.Monad hiding (forM, forM_, mapM, mapM_)
37import Control.Monad.Exception
38import Control.Monad.Exception
38import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
39import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
39import Control.Monad.Primitive
40import Control.Monad.Primitive
40−import Control.Monad.Reader hiding (forM, forM_, mapM, mapM_)
41+--import Control.Monad.Reader hiding (forM, forM_, mapM, mapM_)
42+import Control.Monad.Reader.Class
43+import Control.Monad.IO.Class
44+import Control.Monad.ReaderIO
41import Control.Monad.Ref
45import Control.Monad.Ref
42import Data.Align
46import Data.Align
43import Data.Coerce
47import Data.Coerce
@@ -68,6 +72,12 @@ import System.IO.Unsafe
68import System.Mem.Weak
72import System.Mem.Weak
69import Unsafe.Coerce
73import Unsafe.Coerce
75+#if defined(MIN_VERSION_semialign)
76+#if MIN_VERSION_these(0,8,0)
77+import Data.These.Combinators (justThese)
71#ifdef DEBUG_CYCLES
81#ifdef DEBUG_CYCLES
72import Control.Monad.State hiding (forM, forM_, mapM, mapM_, sequence)
82import Control.Monad.State hiding (forM, forM_, mapM, mapM_, sequence)
73import Data.List.NonEmpty (NonEmpty (..), nonEmpty)
83import Data.List.NonEmpty (NonEmpty (..), nonEmpty)
@@ -545,6 +555,11 @@ propagateFast a subscribers = withIncreasedDepth $ do
545toAny :: a -> Any
555toAny :: a -> Any
546toAny = unsafeCoerce
556toAny = unsafeCoerce
558+-- Why do we use Any here, instead of just giving eventSubscribedRetained an
559+-- existential type? Sadly, GHC does not currently know how to unbox types
560+-- with existentially quantified fields. So instead we just coerce values
561+-- to type Any on the way in. Since we never coerce them back, this is
548data EventSubscribed x = EventSubscribed
563data EventSubscribed x = EventSubscribed
549 { eventSubscribedHeightRef :: {-# UNPACK #-} !(IORef Height)
564 { eventSubscribedHeightRef :: {-# UNPACK #-} !(IORef Height)
550 , eventSubscribedRetained :: {-# NOUNPACK #-} !Any
565 , eventSubscribedRetained :: {-# NOUNPACK #-} !Any
@@ -668,7 +683,7 @@ behaviorPull !p = Behavior $ do
668 wi <- liftIO $ mkWeakPtrWithDebug i "InvalidatorPull"
683 wi <- liftIO $ mkWeakPtrWithDebug i "InvalidatorPull"
669 parentsRef <- liftIO $ newIORef []
684 parentsRef <- liftIO $ newIORef []
670 holdInits <- askBehaviorHoldInits
685 holdInits <- askBehaviorHoldInits
671− a <- liftIO $ runReaderT (unBehaviorM $ pullCompute p) (Just (wi, parentsRef), holdInits)
686+ a <- liftIO $ runReaderIO (unBehaviorM $ pullCompute p) (Just (wi, parentsRef), holdInits)
672 invsRef <- liftIO . newIORef . maybeToList =<< askInvalidator
687 invsRef <- liftIO . newIORef . maybeToList =<< askInvalidator
673 parents <- liftIO $ readIORef parentsRef
688 parents <- liftIO $ readIORef parentsRef
674 let subscribed = PullSubscribed
689 let subscribed = PullSubscribed
@@ -703,42 +718,46 @@ readBehaviorUntracked b = do
703-- Dynamic
718-- Dynamic
704--------------------------------------------------------------------------------
719--------------------------------------------------------------------------------
721+type DynamicS x p = Dynamic x (PatchTarget p) p
706−data Dynamic x p = Dynamic
723+data Dynamic x target p = Dynamic
707− { dynamicCurrent :: !(Behavior x (PatchTarget p))
724+ { dynamicCurrent :: !(Behavior x target)
708 , dynamicUpdated :: Event x p -- This must be lazy; see the comment on holdEvent --TODO: Would this let us eliminate `Dyn`?
725 , dynamicUpdated :: Event x p -- This must be lazy; see the comment on holdEvent --TODO: Would this let us eliminate `Dyn`?
728+deriving instance (HasSpiderTimeline x) => Functor (Dynamic x target)
711−dynamicHold :: Hold x p -> Dynamic x p
733+dynamicHold :: Hold x p -> DynamicS x p
712dynamicHold !h = Dynamic
734dynamicHold !h = Dynamic
713 { dynamicCurrent = behaviorHold h
735 { dynamicCurrent = behaviorHold h
714 , dynamicUpdated = eventHold h
736 , dynamicUpdated = eventHold h
717−dynamicHoldIdentity :: Hold x (Identity a) -> Dynamic x (Identity a)
739+dynamicHoldIdentity :: Hold x (Identity a) -> DynamicS x (Identity a)
718dynamicHoldIdentity = dynamicHold
740dynamicHoldIdentity = dynamicHold
720−dynamicConst :: PatchTarget p -> Dynamic x p
742+dynamicConst :: PatchTarget p -> DynamicS x p
721dynamicConst !a = Dynamic
743dynamicConst !a = Dynamic
722 { dynamicCurrent = behaviorConst a
744 { dynamicCurrent = behaviorConst a
723 , dynamicUpdated = eventNever
745 , dynamicUpdated = eventNever
726−dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> Dynamic x p
748+dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> DynamicS x p
727dynamicDyn !d = Dynamic
749dynamicDyn !d = Dynamic
728 { dynamicCurrent = behaviorDyn d
750 { dynamicCurrent = behaviorDyn d
729 , dynamicUpdated = eventDyn d
751 , dynamicUpdated = eventDyn d
732−dynamicDynIdentity :: HasSpiderTimeline x => Dyn x (Identity a) -> Dynamic x (Identity a)
754+dynamicDynIdentity :: HasSpiderTimeline x => Dyn x (Identity a) -> DynamicS x (Identity a)
733dynamicDynIdentity = dynamicDyn
755dynamicDynIdentity = dynamicDyn
735--------------------------------------------------------------------------------
757--------------------------------------------------------------------------------
736-- Combinators
758-- Combinators
737--------------------------------------------------------------------------------
759--------------------------------------------------------------------------------
739−--TODO: Figure out why certain things are not 'representational', then make them
740−--representational so we can use coerce
742--type role Hold representational
761--type role Hold representational
743data Hold x p
762data Hold x p
744 = Hold { holdValue :: !(IORef (PatchTarget p))
763 = Hold { holdValue :: !(IORef (PatchTarget p))
@@ -759,20 +778,25 @@ globalSpiderTimelineEnv = unsafePerformIO unsafeNewSpiderTimelineEnv
760-- | Stores all global data relevant to a particular Spider timeline; only one
779-- | Stores all global data relevant to a particular Spider timeline; only one
761-- value should exist for each type @x@
780-- value should exist for each type @x@
781+newtype SpiderTimelineEnv x = STE {unSTE :: SpiderTimelineEnv' x}
782+-- We implement SpiderTimelineEnv with a newtype wrapper so
783+-- we can get the coercions we want safely.
784+type role SpiderTimelineEnv nominal
762−data SpiderTimelineEnv x = SpiderTimelineEnv
786+data SpiderTimelineEnv' x = SpiderTimelineEnv
763 { _spiderTimeline_lock :: {-# UNPACK #-} !(MVar ())
787 { _spiderTimeline_lock :: {-# UNPACK #-} !(MVar ())
764 , _spiderTimeline_eventEnv :: {-# UNPACK #-} !(EventEnv x)
788 , _spiderTimeline_eventEnv :: {-# UNPACK #-} !(EventEnv x)
765#ifdef DEBUG
789#ifdef DEBUG
766 , _spiderTimeline_depth :: {-# UNPACK #-} !(IORef Int)
790 , _spiderTimeline_depth :: {-# UNPACK #-} !(IORef Int)
769−type role SpiderTimelineEnv nominal
793+type role SpiderTimelineEnv' phantom
771instance Eq (SpiderTimelineEnv x) where
795instance Eq (SpiderTimelineEnv x) where
772 _ == _ = True -- Since only one exists of each type
796 _ == _ = True -- Since only one exists of each type
774instance GEq SpiderTimelineEnv where
798instance GEq SpiderTimelineEnv where
775− a `geq` b = if _spiderTimeline_lock a == _spiderTimeline_lock b
799+ a `geq` b = if _spiderTimeline_lock (unSTE a) == _spiderTimeline_lock (unSTE b)
776 then Just $ unsafeCoerce Refl -- This unsafeCoerce is safe because the same SpiderTimelineEnv can't have two different 'x' arguments
800 then Just $ unsafeCoerce Refl -- This unsafeCoerce is safe because the same SpiderTimelineEnv can't have two different 'x' arguments
777 else Nothing
801 else Nothing
@@ -795,7 +819,7 @@ runEventM :: EventM x a -> IO a
795runEventM = unEventM
819runEventM = unEventM
797asksEventEnv :: forall x a. HasSpiderTimeline x => (EventEnv x -> a) -> EventM x a
821asksEventEnv :: forall x a. HasSpiderTimeline x => (EventEnv x -> a) -> EventM x a
798−asksEventEnv f = return $ f $ _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
822+asksEventEnv f = return $ f $ _spiderTimeline_eventEnv (unSTE (spiderTimeline :: SpiderTimelineEnv x))
800class MonadIO m => Defer a m where
824class MonadIO m => Defer a m where
801 getDeferralQueue :: m (IORef [a])
825 getDeferralQueue :: m (IORef [a])
@@ -933,9 +957,9 @@ getHoldEventSubscription h = do
934type BehaviorEnv x = (Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]), IORef [SomeHoldInit x])
958type BehaviorEnv x = (Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]), IORef [SomeHoldInit x])
936−--type role BehaviorM representational
937-- BehaviorM can sample behaviors
960-- BehaviorM can sample behaviors
938−newtype BehaviorM x a = BehaviorM { unBehaviorM :: ReaderT (BehaviorEnv x) IO a } deriving (Functor, Applicative, MonadIO, MonadFix)
961+newtype BehaviorM x a = BehaviorM { unBehaviorM :: ReaderIO (BehaviorEnv x) a }
962+ deriving (Functor, Applicative, MonadIO, MonadFix, MonadReader (BehaviorEnv x))
940instance Monad (BehaviorM x) where
964instance Monad (BehaviorM x) where
941 {-# INLINE (>>=) #-}
965 {-# INLINE (>>=) #-}
@@ -1139,17 +1163,21 @@ instance HasSpiderTimeline x => Semialign (Event x) where
1139 align ea eb = mapMaybe dmapToThese $ mergeG coerce $ dynamicConst $
1163 align ea eb = mapMaybe dmapToThese $ mergeG coerce $ dynamicConst $
1140 DMap.fromDistinctAscList [LeftTag :=> ea, RightTag :=> eb]
1164 DMap.fromDistinctAscList [LeftTag :=> ea, RightTag :=> eb]
1166+#if defined(MIN_VERSION_semialign)
1167+ zip x y = mapMaybe justThese $ align x y
1142data DynType x p = UnsafeDyn !(BehaviorM x (PatchTarget p), Event x p)
1170data DynType x p = UnsafeDyn !(BehaviorM x (PatchTarget p), Event x p)
1143 | BuildDyn !(EventM x (PatchTarget p), Event x p)
1171 | BuildDyn !(EventM x (PatchTarget p), Event x p)
1144 | HoldDyn !(Hold x p)
1172 | HoldDyn !(Hold x p)
1146newtype Dyn (x :: Type) p = Dyn { unDyn :: IORef (DynType x p) }
1174newtype Dyn (x :: Type) p = Dyn { unDyn :: IORef (DynType x p) }
1148−newMapDyn :: HasSpiderTimeline x => (a -> b) -> Dynamic x (Identity a) -> Dynamic x (Identity b)
1176+newMapDyn :: HasSpiderTimeline x => (a -> b) -> DynamicS x (Identity a) -> DynamicS x (Identity b)
1149newMapDyn f d = dynamicDynIdentity $ unsafeBuildDynamic (fmap f $ readBehaviorTracked $ dynamicCurrent d) (Identity . f . runIdentity <$> dynamicUpdated d)
1177newMapDyn f d = dynamicDynIdentity $ unsafeBuildDynamic (fmap f $ readBehaviorTracked $ dynamicCurrent d) (Identity . f . runIdentity <$> dynamicUpdated d)
1151--TODO: Avoid the duplication between this and R.zipDynWith
1179--TODO: Avoid the duplication between this and R.zipDynWith
1152−zipDynWith :: HasSpiderTimeline x => (a -> b -> c) -> Dynamic x (Identity a) -> Dynamic x (Identity b) -> Dynamic x (Identity c)
1180+zipDynWith :: HasSpiderTimeline x => (a -> b -> c) -> DynamicS x (Identity a) -> DynamicS x (Identity b) -> DynamicS x (Identity c)
1153zipDynWith f da db =
1181zipDynWith f da db =
1154 let eab = align (dynamicUpdated da) (dynamicUpdated db)
1182 let eab = align (dynamicUpdated da) (dynamicUpdated db)
1155 ec = flip push eab $ \o -> do
1183 ec = flip push eab $ \o -> do
@@ -1225,7 +1253,7 @@ run :: forall x b. HasSpiderTimeline x => [DSum (RootTrigger x) Identity] -> Res
1225run roots after = do
1253run roots after = do
1226 tracePropagate (Proxy :: Proxy x) $ "Running an event frame with " <> show (length roots) <> " events"
1254 tracePropagate (Proxy :: Proxy x) $ "Running an event frame with " <> show (length roots) <> " events"
1227 let t = spiderTimeline :: SpiderTimelineEnv x
1255 let t = spiderTimeline :: SpiderTimelineEnv x
1228− result <- SpiderHost $ withMVar (_spiderTimeline_lock t) $ \_ -> unSpiderHost $ runFrame $ do
1256+ result <- SpiderHost $ withMVar (_spiderTimeline_lock (unSTE t)) $ \_ -> unSpiderHost $ runFrame $ do
1229 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
1257 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
1230 occBefore <- liftIO $ do
1258 occBefore <- liftIO $ do
1231 occBefore <- readIORef occRef
1259 occBefore <- readIORef occRef
@@ -1289,9 +1317,9 @@ type WeakList a = [Weak a]
1289withIncreasedDepth :: CanTrace x m => m a -> m a
1317withIncreasedDepth :: CanTrace x m => m a -> m a
1290withIncreasedDepth a = do
1318withIncreasedDepth a = do
1291 spiderTimeline <- askSpiderTimelineEnv
1319 spiderTimeline <- askSpiderTimelineEnv
1292− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) succ
1320+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) succ
1293 result <- a
1321 result <- a
1294− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) pred
1322+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) pred
1295 return result
1323 return result
1297withIncreasedDepth :: m a -> m a
1325withIncreasedDepth :: m a -> m a
@@ -1318,7 +1346,7 @@ traceMWhen _ b getMessage = when b $ do
1318 message <- getMessage
1346 message <- getMessage
1319#ifdef DEBUG
1347#ifdef DEBUG
1320 spiderTimeline <- askSpiderTimelineEnv
1348 spiderTimeline <- askSpiderTimelineEnv
1321− d <- liftIO $ readIORef $ _spiderTimeline_depth spiderTimeline
1349+ d <- liftIO $ readIORef $ _spiderTimeline_depth $ unSTE spiderTimeline
1323 let d = 0
1351 let d = 0
@@ -1359,25 +1387,25 @@ propagateSubscriberHold h a = do
1359data SomeResetCoincidence x = forall a. SomeResetCoincidence !(EventSubscription x) !(Maybe (CoincidenceSubscribed x a)) -- The CoincidenceSubscriber will be present only if heights need to be reset
1387data SomeResetCoincidence x = forall a. SomeResetCoincidence !(EventSubscription x) !(Maybe (CoincidenceSubscribed x a)) -- The CoincidenceSubscriber will be present only if heights need to be reset
1361runBehaviorM :: BehaviorM x a -> Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]) -> IORef [SomeHoldInit x] -> IO a
1389runBehaviorM :: BehaviorM x a -> Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]) -> IORef [SomeHoldInit x] -> IO a
1362−runBehaviorM a mwi holdInits = runReaderT (unBehaviorM a) (mwi, holdInits)
1390+runBehaviorM a mwi holdInits = runReaderIO (unBehaviorM a) (mwi, holdInits)
1364askInvalidator :: BehaviorM x (Maybe (Weak (Invalidator x)))
1392askInvalidator :: BehaviorM x (Maybe (Weak (Invalidator x)))
1365askInvalidator = do
1393askInvalidator = do
1366− (!m, _) <- BehaviorM ask
1394+ (!m, _) <- ask
1367 case m of
1395 case m of
1368 Nothing -> return Nothing
1396 Nothing -> return Nothing
1369 Just (!wi, _) -> return $ Just wi
1397 Just (!wi, _) -> return $ Just wi
1371askParentsRef :: BehaviorM x (Maybe (IORef [SomeBehaviorSubscribed x]))
1399askParentsRef :: BehaviorM x (Maybe (IORef [SomeBehaviorSubscribed x]))
1372askParentsRef = do
1400askParentsRef = do
1373− (!m, _) <- BehaviorM ask
1401+ (!m, _) <- ask
1374 case m of
1402 case m of
1375 Nothing -> return Nothing
1403 Nothing -> return Nothing
1376 Just (_, !p) -> return $ Just p
1404 Just (_, !p) -> return $ Just p
1378askBehaviorHoldInits :: BehaviorM x (IORef [SomeHoldInit x])
1406askBehaviorHoldInits :: BehaviorM x (IORef [SomeHoldInit x])
1379askBehaviorHoldInits = do
1407askBehaviorHoldInits = do
1380− (_, !his) <- BehaviorM ask
1408+ (_, !his) <- ask
1381 return his
1409 return his
1383{-# INLINE getDynHold #-}
1411{-# INLINE getDynHold #-}
@@ -1701,20 +1729,20 @@ subscribeCoincidenceSubscribed subscribed sub = WeakBag.insert sub (coincidenceS
1701{-# INLINE mergeG #-}
1729{-# INLINE mergeG #-}
1702mergeG :: forall k q x v. (HasSpiderTimeline x, GCompare k)
1730mergeG :: forall k q x v. (HasSpiderTimeline x, GCompare k)
1703 => (forall a. q a -> Event x (v a))
1731 => (forall a. q a -> Event x (v a))
1704− -> Dynamic x (PatchDMap k q) -> Event x (DMap k v)
1732+ -> DynamicS x (PatchDMap k q) -> Event x (DMap k v)
1705mergeG nt d = cacheEvent (mergeCheap nt d)
1733mergeG nt d = cacheEvent (mergeCheap nt d)
1707{-# INLINE mergeWithMove #-}
1735{-# INLINE mergeWithMove #-}
1708mergeWithMove :: forall k v q x. (HasSpiderTimeline x, GCompare k)
1736mergeWithMove :: forall k v q x. (HasSpiderTimeline x, GCompare k)
1709 => (forall a. q a -> Event x (v a))
1737 => (forall a. q a -> Event x (v a))
1710− -> Dynamic x (PatchDMapWithMove k q) -> Event x (DMap k v)
1738+ -> DynamicS x (PatchDMapWithMove k q) -> Event x (DMap k v)
1711mergeWithMove nt d = cacheEvent (mergeCheapWithMove nt d)
1739mergeWithMove nt d = cacheEvent (mergeCheapWithMove nt d)
1713{-# INLINE [1] mergeCheap #-}
1741{-# INLINE [1] mergeCheap #-}
1714mergeCheap
1742mergeCheap
1715 :: forall k x q v. (HasSpiderTimeline x, GCompare k)
1743 :: forall k x q v. (HasSpiderTimeline x, GCompare k)
1716 => (forall a. q a -> Event x (v a))
1744 => (forall a. q a -> Event x (v a))
1717− -> Dynamic x (PatchDMap k q)
1745+ -> DynamicS x (PatchDMap k q)
1718 -> Event x (DMap k v)
1746 -> Event x (DMap k v)
1719mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
1747mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
@@ -1742,7 +1770,7 @@ mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
1742 let s = subscriber $ return k
1770 let s = subscriber $ return k
1743 (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead (nt e) s
1771 (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead (nt e) s
1744 height <- liftIO $ getEventSubscribedHeight parentSubd
1772 height <- liftIO $ getEventSubscribedHeight parentSubd
1745− return (fmap (\x -> k :=> x) parentOcc, height, k :=> MergeSubscribedParent subscription)
1773+ return (fmap (k :=>) parentOcc, height, k :=> MergeSubscribedParent subscription)
1746 return ( DMap.fromDistinctAscList $ mapMaybe (\(x, _, _) -> x) subscribers
1774 return ( DMap.fromDistinctAscList $ mapMaybe (\(x, _, _) -> x) subscribers
1747 , fmap (\(_, h, _) -> h) subscribers --TODO: Assert that there's no invalidHeight in here
1775 , fmap (\(_, h, _) -> h) subscribers --TODO: Assert that there's no invalidHeight in here
1748 , DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
1776 , DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
@@ -1754,7 +1782,7 @@ mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
1754{-# INLINE [1] mergeCheapWithMove #-}
1782{-# INLINE [1] mergeCheapWithMove #-}
1755mergeCheapWithMove :: forall k x v q. (HasSpiderTimeline x, GCompare k)
1783mergeCheapWithMove :: forall k x v q. (HasSpiderTimeline x, GCompare k)
1756 => (forall a. q a -> Event x (v a))
1784 => (forall a. q a -> Event x (v a))
1757− -> Dynamic x (PatchDMapWithMove k q)
1785+ -> DynamicS x (PatchDMapWithMove k q)
1758 -> Event x (DMap k v)
1786 -> Event x (DMap k v)
1759mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
1787mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
@@ -1790,7 +1818,7 @@ mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
1790 let s = subscriber $ liftIO $ readIORef keyRef
1818 let s = subscriber $ liftIO $ readIORef keyRef
1791 (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead (nt e) s
1819 (subscription@(EventSubscription _ parentSubd), parentOcc) <- subscribeAndRead (nt e) s
1792 height <- liftIO $ getEventSubscribedHeight parentSubd
1820 height <- liftIO $ getEventSubscribedHeight parentSubd
1793− return (fmap (\x -> k :=> x) parentOcc, height, k :=> MergeSubscribedParentWithMove subscription keyRef)
1821+ return (fmap (k :=>) parentOcc, height, k :=> MergeSubscribedParentWithMove subscription keyRef)
1794 return ( DMap.fromDistinctAscList $ mapMaybe (\(x, _, _) -> x) subscribers
1822 return ( DMap.fromDistinctAscList $ mapMaybe (\(x, _, _) -> x) subscribers
1795 , fmap (\(_, h, _) -> h) subscribers --TODO: Assert that there's no invalidHeight in here
1823 , fmap (\(_, h, _) -> h) subscribers --TODO: Assert that there's no invalidHeight in here
1796 , DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
1824 , DMap.fromDistinctAscList $ map (\(_, _, x) -> x) subscribers
@@ -1902,7 +1930,7 @@ updateMerge m updateFunc p = SomeMergeUpdate updateMe (invalidateMergeHeight m)
1903{-# INLINE mergeGCheap' #-}
1931{-# INLINE mergeGCheap' #-}
1904mergeGCheap' :: forall k v x p s q. (HasSpiderTimeline x, GCompare k, PatchTarget p ~ DMap k q)
1932mergeGCheap' :: forall k v x p s q. (HasSpiderTimeline x, GCompare k, PatchTarget p ~ DMap k q)
1905− => MergeInitFunc k v q x s -> MergeUpdateFunc k v x p s -> MergeDestroyFunc k s -> Dynamic x p -> Event x (DMap k v)
1933+ => MergeInitFunc k v q x s -> MergeUpdateFunc k v x p s -> MergeDestroyFunc k s -> DynamicS x p -> Event x (DMap k v)
1906mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
1934mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
1907 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1935 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1908 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
1936 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
@@ -1951,11 +1979,11 @@ mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
1954−mergeInt :: forall x a. (HasSpiderTimeline x) => Dynamic x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1982+mergeInt :: forall x a. (HasSpiderTimeline x) => DynamicS x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1955mergeInt = cacheEvent . mergeIntCheap
1983mergeInt = cacheEvent . mergeIntCheap
1957{-# INLINABLE mergeIntCheap #-}
1985{-# INLINABLE mergeIntCheap #-}
1958−mergeIntCheap :: forall x a. (HasSpiderTimeline x) => Dynamic x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1986+mergeIntCheap :: forall x a. (HasSpiderTimeline x) => DynamicS x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1959mergeIntCheap d = Event $ \sub -> do
1987mergeIntCheap d = Event $ \sub -> do
1960 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1988 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1961 accum <- liftIO $ FastMutableIntMap.newEmpty
1989 accum <- liftIO $ FastMutableIntMap.newEmpty
@@ -2115,7 +2143,7 @@ clearEventEnv (EventEnv toAssignRef holdInitRef dynInitRef mergeUpdateRef mergeI
2115-- | Run an event action outside of a frame
2143-- | Run an event action outside of a frame
2116runFrame :: forall x a. HasSpiderTimeline x => EventM x a -> SpiderHost x a --TODO: This function also needs to hold the mutex
2144runFrame :: forall x a. HasSpiderTimeline x => EventM x a -> SpiderHost x a --TODO: This function also needs to hold the mutex
2117runFrame a = SpiderHost $ do
2145runFrame a = SpiderHost $ do
2118− let env = _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
2146+ let env = _spiderTimeline_eventEnv $ unSTE (spiderTimeline :: SpiderTimelineEnv x)
2119 let go = do
2147 let go = do
2120 result <- a
2148 result <- a
2121 runHoldInits (eventEnvHoldInits env) (eventEnvDynInits env) (eventEnvMergeInits env) -- This must happen before doing the assignments, in case subscribing a Hold causes existing Holds to be read by the newly-propagated events
2149 runHoldInits (eventEnvHoldInits env) (eventEnvDynInits env) (eventEnvMergeInits env) -- This must happen before doing the assignments, in case subscribing a Hold causes existing Holds to be read by the newly-propagated events
@@ -2326,7 +2354,7 @@ instance HasSpiderTimeline x => Monad (Reflex.Class.Dynamic (SpiderTimeline x))
2326 fail _ = error "Dynamic does not support 'fail'"
2354 fail _ = error "Dynamic does not support 'fail'"
2328{-# INLINABLE newJoinDyn #-}
2356{-# INLINABLE newJoinDyn #-}
2329−newJoinDyn :: HasSpiderTimeline x => Reflex.Spider.Internal.Dynamic x (Identity (Reflex.Spider.Internal.Dynamic x (Identity a))) -> Reflex.Spider.Internal.Dyn x (Identity a)
2357+newJoinDyn :: HasSpiderTimeline x => DynamicS x (Identity (DynamicS x (Identity a))) -> Reflex.Spider.Internal.Dyn x (Identity a)
2330newJoinDyn d =
2358newJoinDyn d =
2331 let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
2359 let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
2332 eOuter = Reflex.Spider.Internal.push (fmap (Just . Identity) . readBehaviorUntracked . dynamicCurrent . runIdentity) $ dynamicUpdated d
2360 eOuter = Reflex.Spider.Internal.push (fmap (Just . Identity) . readBehaviorUntracked . dynamicCurrent . runIdentity) $ dynamicUpdated d
@@ -2476,7 +2504,7 @@ unsafeNewSpiderTimelineEnv = do
2476#ifdef DEBUG
2504#ifdef DEBUG
2477 depthRef <- newIORef 0
2505 depthRef <- newIORef 0
2479− return $ SpiderTimelineEnv
2507+ return $ STE $ SpiderTimelineEnv
2480 { _spiderTimeline_lock = lock
2508 { _spiderTimeline_lock = lock
2481 , _spiderTimeline_eventEnv = env
2509 , _spiderTimeline_eventEnv = env
2482#ifdef DEBUG
2510#ifdef DEBUG
@@ -2492,13 +2520,13 @@ data LocalSpiderTimeline (x :: Type) s
2493instance Reifies s (SpiderTimelineEnv x) =>
2521instance Reifies s (SpiderTimelineEnv x) =>
2494 HasSpiderTimeline (LocalSpiderTimeline x s) where
2522 HasSpiderTimeline (LocalSpiderTimeline x s) where
2495− spiderTimeline = localSpiderTimeline (Proxy :: Proxy s) $ reflect (Proxy :: Proxy s)
2523+ spiderTimeline = localSpiderTimeline Proxy $ reflect (Proxy :: Proxy s)
2497localSpiderTimeline
2525localSpiderTimeline
2498− :: Proxy s
2526+ :: proxy s
2499 -> SpiderTimelineEnv x
2527 -> SpiderTimelineEnv x
2500 -> SpiderTimelineEnv (LocalSpiderTimeline x s)
2528 -> SpiderTimelineEnv (LocalSpiderTimeline x s)
2501−localSpiderTimeline _ = unsafeCoerce
2529+localSpiderTimeline _ = coerce
2503-- | Pass a new timeline to the given function.
2531-- | Pass a new timeline to the given function.
2504withSpiderTimeline :: (forall x. HasSpiderTimeline x => SpiderTimelineEnv x -> IO r) -> IO r
2532withSpiderTimeline :: (forall x. HasSpiderTimeline x => SpiderTimelineEnv x -> IO r) -> IO r
@@ -2516,8 +2544,8 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2516 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
2544 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
2517 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
2545 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
2518 newtype Event (SpiderTimeline x) a = SpiderEvent { unSpiderEvent :: Event x a }
2546 newtype Event (SpiderTimeline x) a = SpiderEvent { unSpiderEvent :: Event x a }
2519− newtype Dynamic (SpiderTimeline x) a = SpiderDynamic { unSpiderDynamic :: Dynamic x (Identity a) } -- deriving (Functor, Applicative, Monad)
2547+ newtype Dynamic (SpiderTimeline x) a = SpiderDynamic { unSpiderDynamic :: DynamicS x (Identity a) } -- deriving (Functor, Applicative, Monad)
2520− newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: Dynamic x p }
2548+ newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: DynamicS x p }
2521 type PullM (SpiderTimeline x) = SpiderPullM x
2549 type PullM (SpiderTimeline x) = SpiderPullM x
2522 type PushM (SpiderTimeline x) = SpiderPushM x
2550 type PushM (SpiderTimeline x) = SpiderPushM x
2523 {-# INLINABLE never #-}
2551 {-# INLINABLE never #-}
@@ -2546,7 +2574,7 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2546 {-# INLINABLE current #-}
2574 {-# INLINABLE current #-}
2547 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
2575 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
2548 {-# INLINABLE updated #-}
2576 {-# INLINABLE updated #-}
2549− updated = coerce $ SpiderEvent . dynamicUpdated . unSpiderDynamic
2577+ updated = SpiderEvent #. dynamicUpdated .# fmap coerce . unSpiderDynamic
2550 {-# INLINABLE unsafeBuildDynamic #-}
2578 {-# INLINABLE unsafeBuildDynamic #-}
2551 unsafeBuildDynamic readV0 v' = SpiderDynamic $ dynamicDynIdentity $ unsafeBuildDynamic (coerce readV0) $ coerce $ unSpiderEvent v'
2579 unsafeBuildDynamic readV0 v' = SpiderDynamic $ dynamicDynIdentity $ unsafeBuildDynamic (coerce readV0) $ coerce $ unSpiderEvent v'
2552 {-# INLINABLE unsafeBuildIncremental #-}
2580 {-# INLINABLE unsafeBuildIncremental #-}
@@ -2565,9 +2593,10 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2565 return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
2593 return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
2566 eventCoercion Coercion = Coercion
2594 eventCoercion Coercion = Coercion
2567 behaviorCoercion Coercion = Coercion
2595 behaviorCoercion Coercion = Coercion
2568− dynamicCoercion = unsafeCoerce --TODO: How can we avoid this unsafeCoerce? This is safe only because we know how Identity works as a Patch instance
2596+ dynamicCoercion Coercion = Coercion
2597+ incrementalCoercion Coercion Coercion = Coercion
2569 {-# INLINABLE mergeIntIncremental #-}
2598 {-# INLINABLE mergeIntIncremental #-}
2570− mergeIntIncremental = SpiderEvent . mergeInt . (unsafeCoerce :: Dynamic x (PatchIntMap (R.Event (SpiderTimeline x) a)) -> Dynamic x (PatchIntMap (Event x a))) . unSpiderIncremental
2599+ mergeIntIncremental = SpiderEvent . mergeInt . coerce
2571 {-# INLINABLE fanInt #-}
2600 {-# INLINABLE fanInt #-}
2572 fanInt e = R.EventSelectorInt $ SpiderEvent . selectInt (fanInt (unSpiderEvent e))
2601 fanInt e = R.EventSelectorInt $ SpiderEvent . selectInt (fanInt (unSpiderEvent e))