@@ -17,6 +17,8 @@
17{-# LANGUAGE TypeOperators #-}
17{-# LANGUAGE TypeOperators #-}
18{-# LANGUAGE UndecidableInstances #-}
18{-# LANGUAGE UndecidableInstances #-}
19{-# LANGUAGE PolyKinds #-}
19{-# LANGUAGE PolyKinds #-}
20+{-# LANGUAGE DeriveFunctor #-}
21+{-# LANGUAGE StandaloneDeriving #-}
20{-# LANGUAGE InstanceSigs #-}
22{-# LANGUAGE InstanceSigs #-}
22#ifdef USE_REFLEX_OPTIMIZER
24#ifdef USE_REFLEX_OPTIMIZER
@@ -36,7 +38,10 @@ import Control.Monad hiding (forM, forM_, mapM, mapM_)
36import Control.Monad.Exception
38import Control.Monad.Exception
37import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
39import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
38import Control.Monad.Primitive
40import Control.Monad.Primitive
39−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
40import Control.Monad.Ref
45import Control.Monad.Ref
41import Data.Align
46import Data.Align
42import Data.Coerce
47import Data.Coerce
@@ -550,6 +555,11 @@ propagateFast a subscribers = withIncreasedDepth $ do
550toAny :: a -> Any
555toAny :: a -> Any
551toAny = 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
553data EventSubscribed x = EventSubscribed
563data EventSubscribed x = EventSubscribed
554 { eventSubscribedHeightRef :: {-# UNPACK #-} !(IORef Height)
564 { eventSubscribedHeightRef :: {-# UNPACK #-} !(IORef Height)
555 , eventSubscribedRetained :: {-# NOUNPACK #-} !Any
565 , eventSubscribedRetained :: {-# NOUNPACK #-} !Any
@@ -673,7 +683,7 @@ behaviorPull !p = Behavior $ do
673 wi <- liftIO $ mkWeakPtrWithDebug i "InvalidatorPull"
683 wi <- liftIO $ mkWeakPtrWithDebug i "InvalidatorPull"
674 parentsRef <- liftIO $ newIORef []
684 parentsRef <- liftIO $ newIORef []
675 holdInits <- askBehaviorHoldInits
685 holdInits <- askBehaviorHoldInits
676− a <- liftIO $ runReaderT (unBehaviorM $ pullCompute p) (Just (wi, parentsRef), holdInits)
686+ a <- liftIO $ runReaderIO (unBehaviorM $ pullCompute p) (Just (wi, parentsRef), holdInits)
677 invsRef <- liftIO . newIORef . maybeToList =<< askInvalidator
687 invsRef <- liftIO . newIORef . maybeToList =<< askInvalidator
678 parents <- liftIO $ readIORef parentsRef
688 parents <- liftIO $ readIORef parentsRef
679 let subscribed = PullSubscribed
689 let subscribed = PullSubscribed
@@ -708,42 +718,46 @@ readBehaviorUntracked b = do
708-- Dynamic
718-- Dynamic
709--------------------------------------------------------------------------------
719--------------------------------------------------------------------------------
721+type DynamicS x p = Dynamic x (PatchTarget p) p
711−data Dynamic x p = Dynamic
723+data Dynamic x target p = Dynamic
712− { dynamicCurrent :: !(Behavior x (PatchTarget p))
724+ { dynamicCurrent :: !(Behavior x target)
713 , 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)
716−dynamicHold :: Hold x p -> Dynamic x p
733+dynamicHold :: Hold x p -> DynamicS x p
717dynamicHold !h = Dynamic
734dynamicHold !h = Dynamic
718 { dynamicCurrent = behaviorHold h
735 { dynamicCurrent = behaviorHold h
719 , dynamicUpdated = eventHold h
736 , dynamicUpdated = eventHold h
722−dynamicHoldIdentity :: Hold x (Identity a) -> Dynamic x (Identity a)
739+dynamicHoldIdentity :: Hold x (Identity a) -> DynamicS x (Identity a)
723dynamicHoldIdentity = dynamicHold
740dynamicHoldIdentity = dynamicHold
725−dynamicConst :: PatchTarget p -> Dynamic x p
742+dynamicConst :: PatchTarget p -> DynamicS x p
726dynamicConst !a = Dynamic
743dynamicConst !a = Dynamic
727 { dynamicCurrent = behaviorConst a
744 { dynamicCurrent = behaviorConst a
728 , dynamicUpdated = eventNever
745 , dynamicUpdated = eventNever
731−dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> Dynamic x p
748+dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> DynamicS x p
732dynamicDyn !d = Dynamic
749dynamicDyn !d = Dynamic
733 { dynamicCurrent = behaviorDyn d
750 { dynamicCurrent = behaviorDyn d
734 , dynamicUpdated = eventDyn d
751 , dynamicUpdated = eventDyn d
737−dynamicDynIdentity :: HasSpiderTimeline x => Dyn x (Identity a) -> Dynamic x (Identity a)
754+dynamicDynIdentity :: HasSpiderTimeline x => Dyn x (Identity a) -> DynamicS x (Identity a)
738dynamicDynIdentity = dynamicDyn
755dynamicDynIdentity = dynamicDyn
740--------------------------------------------------------------------------------
757--------------------------------------------------------------------------------
741-- Combinators
758-- Combinators
742--------------------------------------------------------------------------------
759--------------------------------------------------------------------------------
744−--TODO: Figure out why certain things are not 'representational', then make them
745−--representational so we can use coerce
747--type role Hold representational
761--type role Hold representational
748data Hold x p
762data Hold x p
749 = Hold { holdValue :: !(IORef (PatchTarget p))
763 = Hold { holdValue :: !(IORef (PatchTarget p))
@@ -764,20 +778,25 @@ globalSpiderTimelineEnv = unsafePerformIO unsafeNewSpiderTimelineEnv
765-- | 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
766-- 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
767−data SpiderTimelineEnv x = SpiderTimelineEnv
786+data SpiderTimelineEnv' x = SpiderTimelineEnv
768 { _spiderTimeline_lock :: {-# UNPACK #-} !(MVar ())
787 { _spiderTimeline_lock :: {-# UNPACK #-} !(MVar ())
769 , _spiderTimeline_eventEnv :: {-# UNPACK #-} !(EventEnv x)
788 , _spiderTimeline_eventEnv :: {-# UNPACK #-} !(EventEnv x)
770#ifdef DEBUG
789#ifdef DEBUG
771 , _spiderTimeline_depth :: {-# UNPACK #-} !(IORef Int)
790 , _spiderTimeline_depth :: {-# UNPACK #-} !(IORef Int)
774−type role SpiderTimelineEnv nominal
793+type role SpiderTimelineEnv' phantom
776instance Eq (SpiderTimelineEnv x) where
795instance Eq (SpiderTimelineEnv x) where
777 _ == _ = True -- Since only one exists of each type
796 _ == _ = True -- Since only one exists of each type
779instance GEq SpiderTimelineEnv where
798instance GEq SpiderTimelineEnv where
780− a `geq` b = if _spiderTimeline_lock a == _spiderTimeline_lock b
799+ a `geq` b = if _spiderTimeline_lock (unSTE a) == _spiderTimeline_lock (unSTE b)
781 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
782 else Nothing
801 else Nothing
@@ -800,7 +819,7 @@ runEventM :: EventM x a -> IO a
800runEventM = unEventM
819runEventM = unEventM
802asksEventEnv :: forall x a. HasSpiderTimeline x => (EventEnv x -> a) -> EventM x a
821asksEventEnv :: forall x a. HasSpiderTimeline x => (EventEnv x -> a) -> EventM x a
803−asksEventEnv f = return $ f $ _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
822+asksEventEnv f = return $ f $ _spiderTimeline_eventEnv (unSTE (spiderTimeline :: SpiderTimelineEnv x))
805class MonadIO m => Defer a m where
824class MonadIO m => Defer a m where
806 getDeferralQueue :: m (IORef [a])
825 getDeferralQueue :: m (IORef [a])
@@ -938,9 +957,9 @@ getHoldEventSubscription h = do
939type 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])
941−--type role BehaviorM representational
942-- BehaviorM can sample behaviors
960-- BehaviorM can sample behaviors
943−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))
945instance Monad (BehaviorM x) where
964instance Monad (BehaviorM x) where
946 {-# INLINE (>>=) #-}
965 {-# INLINE (>>=) #-}
@@ -1154,11 +1173,11 @@ data DynType x p = UnsafeDyn !(BehaviorM x (PatchTarget p), Event x p)
1155newtype Dyn (x :: Type) p = Dyn { unDyn :: IORef (DynType x p) }
1174newtype Dyn (x :: Type) p = Dyn { unDyn :: IORef (DynType x p) }
1157−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)
1158newMapDyn 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)
1160--TODO: Avoid the duplication between this and R.zipDynWith
1179--TODO: Avoid the duplication between this and R.zipDynWith
1161−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)
1162zipDynWith f da db =
1181zipDynWith f da db =
1163 let eab = align (dynamicUpdated da) (dynamicUpdated db)
1182 let eab = align (dynamicUpdated da) (dynamicUpdated db)
1164 ec = flip push eab $ \o -> do
1183 ec = flip push eab $ \o -> do
@@ -1234,7 +1253,7 @@ run :: forall x b. HasSpiderTimeline x => [DSum (RootTrigger x) Identity] -> Res
1234run roots after = do
1253run roots after = do
1235 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"
1236 let t = spiderTimeline :: SpiderTimelineEnv x
1255 let t = spiderTimeline :: SpiderTimelineEnv x
1237− result <- SpiderHost $ withMVar (_spiderTimeline_lock t) $ \_ -> unSpiderHost $ runFrame $ do
1256+ result <- SpiderHost $ withMVar (_spiderTimeline_lock (unSTE t)) $ \_ -> unSpiderHost $ runFrame $ do
1238 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
1257 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
1239 occBefore <- liftIO $ do
1258 occBefore <- liftIO $ do
1240 occBefore <- readIORef occRef
1259 occBefore <- readIORef occRef
@@ -1298,9 +1317,9 @@ type WeakList a = [Weak a]
1298withIncreasedDepth :: CanTrace x m => m a -> m a
1317withIncreasedDepth :: CanTrace x m => m a -> m a
1299withIncreasedDepth a = do
1318withIncreasedDepth a = do
1300 spiderTimeline <- askSpiderTimelineEnv
1319 spiderTimeline <- askSpiderTimelineEnv
1301− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) succ
1320+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) succ
1302 result <- a
1321 result <- a
1303− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) pred
1322+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) pred
1304 return result
1323 return result
1306withIncreasedDepth :: m a -> m a
1325withIncreasedDepth :: m a -> m a
@@ -1327,7 +1346,7 @@ traceMWhen _ b getMessage = when b $ do
1327 message <- getMessage
1346 message <- getMessage
1328#ifdef DEBUG
1347#ifdef DEBUG
1329 spiderTimeline <- askSpiderTimelineEnv
1348 spiderTimeline <- askSpiderTimelineEnv
1330− d <- liftIO $ readIORef $ _spiderTimeline_depth spiderTimeline
1349+ d <- liftIO $ readIORef $ _spiderTimeline_depth $ unSTE spiderTimeline
1332 let d = 0
1351 let d = 0
@@ -1368,25 +1387,25 @@ propagateSubscriberHold h a = do
1368data 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
1370runBehaviorM :: 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
1371−runBehaviorM a mwi holdInits = runReaderT (unBehaviorM a) (mwi, holdInits)
1390+runBehaviorM a mwi holdInits = runReaderIO (unBehaviorM a) (mwi, holdInits)
1373askInvalidator :: BehaviorM x (Maybe (Weak (Invalidator x)))
1392askInvalidator :: BehaviorM x (Maybe (Weak (Invalidator x)))
1374askInvalidator = do
1393askInvalidator = do
1375− (!m, _) <- BehaviorM ask
1394+ (!m, _) <- ask
1376 case m of
1395 case m of
1377 Nothing -> return Nothing
1396 Nothing -> return Nothing
1378 Just (!wi, _) -> return $ Just wi
1397 Just (!wi, _) -> return $ Just wi
1380askParentsRef :: BehaviorM x (Maybe (IORef [SomeBehaviorSubscribed x]))
1399askParentsRef :: BehaviorM x (Maybe (IORef [SomeBehaviorSubscribed x]))
1381askParentsRef = do
1400askParentsRef = do
1382− (!m, _) <- BehaviorM ask
1401+ (!m, _) <- ask
1383 case m of
1402 case m of
1384 Nothing -> return Nothing
1403 Nothing -> return Nothing
1385 Just (_, !p) -> return $ Just p
1404 Just (_, !p) -> return $ Just p
1387askBehaviorHoldInits :: BehaviorM x (IORef [SomeHoldInit x])
1406askBehaviorHoldInits :: BehaviorM x (IORef [SomeHoldInit x])
1388askBehaviorHoldInits = do
1407askBehaviorHoldInits = do
1389− (_, !his) <- BehaviorM ask
1408+ (_, !his) <- ask
1390 return his
1409 return his
1392{-# INLINE getDynHold #-}
1411{-# INLINE getDynHold #-}
@@ -1710,20 +1729,20 @@ subscribeCoincidenceSubscribed subscribed sub = WeakBag.insert sub (coincidenceS
1710{-# INLINE mergeG #-}
1729{-# INLINE mergeG #-}
1711mergeG :: forall k q x v. (HasSpiderTimeline x, GCompare k)
1730mergeG :: forall k q x v. (HasSpiderTimeline x, GCompare k)
1712 => (forall a. q a -> Event x (v a))
1731 => (forall a. q a -> Event x (v a))
1713− -> Dynamic x (PatchDMap k q) -> Event x (DMap k v)
1732+ -> DynamicS x (PatchDMap k q) -> Event x (DMap k v)
1714mergeG nt d = cacheEvent (mergeCheap nt d)
1733mergeG nt d = cacheEvent (mergeCheap nt d)
1716{-# INLINE mergeWithMove #-}
1735{-# INLINE mergeWithMove #-}
1717mergeWithMove :: forall k v q x. (HasSpiderTimeline x, GCompare k)
1736mergeWithMove :: forall k v q x. (HasSpiderTimeline x, GCompare k)
1718 => (forall a. q a -> Event x (v a))
1737 => (forall a. q a -> Event x (v a))
1719− -> Dynamic x (PatchDMapWithMove k q) -> Event x (DMap k v)
1738+ -> DynamicS x (PatchDMapWithMove k q) -> Event x (DMap k v)
1720mergeWithMove nt d = cacheEvent (mergeCheapWithMove nt d)
1739mergeWithMove nt d = cacheEvent (mergeCheapWithMove nt d)
1722{-# INLINE [1] mergeCheap #-}
1741{-# INLINE [1] mergeCheap #-}
1723mergeCheap
1742mergeCheap
1724 :: forall k x q v. (HasSpiderTimeline x, GCompare k)
1743 :: forall k x q v. (HasSpiderTimeline x, GCompare k)
1725 => (forall a. q a -> Event x (v a))
1744 => (forall a. q a -> Event x (v a))
1726− -> Dynamic x (PatchDMap k q)
1745+ -> DynamicS x (PatchDMap k q)
1727 -> Event x (DMap k v)
1746 -> Event x (DMap k v)
1728mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
1747mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
@@ -1763,7 +1782,7 @@ mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
1763{-# INLINE [1] mergeCheapWithMove #-}
1782{-# INLINE [1] mergeCheapWithMove #-}
1764mergeCheapWithMove :: forall k x v q. (HasSpiderTimeline x, GCompare k)
1783mergeCheapWithMove :: forall k x v q. (HasSpiderTimeline x, GCompare k)
1765 => (forall a. q a -> Event x (v a))
1784 => (forall a. q a -> Event x (v a))
1766− -> Dynamic x (PatchDMapWithMove k q)
1785+ -> DynamicS x (PatchDMapWithMove k q)
1767 -> Event x (DMap k v)
1786 -> Event x (DMap k v)
1768mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
1787mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
@@ -1911,7 +1930,7 @@ updateMerge m updateFunc p = SomeMergeUpdate updateMe (invalidateMergeHeight m)
1912{-# INLINE mergeGCheap' #-}
1931{-# INLINE mergeGCheap' #-}
1913mergeGCheap' :: 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)
1914− => 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)
1915mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
1934mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
1916 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1935 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1917 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
1936 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
@@ -1960,11 +1979,11 @@ mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
1963−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)
1964mergeInt = cacheEvent . mergeIntCheap
1983mergeInt = cacheEvent . mergeIntCheap
1966{-# INLINABLE mergeIntCheap #-}
1985{-# INLINABLE mergeIntCheap #-}
1967−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)
1968mergeIntCheap d = Event $ \sub -> do
1987mergeIntCheap d = Event $ \sub -> do
1969 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1988 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1970 accum <- liftIO $ FastMutableIntMap.newEmpty
1989 accum <- liftIO $ FastMutableIntMap.newEmpty
@@ -2124,7 +2143,7 @@ clearEventEnv (EventEnv toAssignRef holdInitRef dynInitRef mergeUpdateRef mergeI
2124-- | Run an event action outside of a frame
2143-- | Run an event action outside of a frame
2125runFrame :: 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
2126runFrame a = SpiderHost $ do
2145runFrame a = SpiderHost $ do
2127− let env = _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
2146+ let env = _spiderTimeline_eventEnv $ unSTE (spiderTimeline :: SpiderTimelineEnv x)
2128 let go = do
2147 let go = do
2129 result <- a
2148 result <- a
2130 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
@@ -2335,7 +2354,7 @@ instance HasSpiderTimeline x => Monad (Reflex.Class.Dynamic (SpiderTimeline x))
2335 fail _ = error "Dynamic does not support 'fail'"
2354 fail _ = error "Dynamic does not support 'fail'"
2337{-# INLINABLE newJoinDyn #-}
2356{-# INLINABLE newJoinDyn #-}
2338−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)
2339newJoinDyn d =
2358newJoinDyn d =
2340 let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
2359 let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
2341 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
@@ -2485,7 +2504,7 @@ unsafeNewSpiderTimelineEnv = do
2485#ifdef DEBUG
2504#ifdef DEBUG
2486 depthRef <- newIORef 0
2505 depthRef <- newIORef 0
2488− return $ SpiderTimelineEnv
2507+ return $ STE $ SpiderTimelineEnv
2489 { _spiderTimeline_lock = lock
2508 { _spiderTimeline_lock = lock
2490 , _spiderTimeline_eventEnv = env
2509 , _spiderTimeline_eventEnv = env
2491#ifdef DEBUG
2510#ifdef DEBUG
@@ -2501,13 +2520,13 @@ data LocalSpiderTimeline (x :: Type) s
2502instance Reifies s (SpiderTimelineEnv x) =>
2521instance Reifies s (SpiderTimelineEnv x) =>
2503 HasSpiderTimeline (LocalSpiderTimeline x s) where
2522 HasSpiderTimeline (LocalSpiderTimeline x s) where
2504− spiderTimeline = localSpiderTimeline (Proxy :: Proxy s) $ reflect (Proxy :: Proxy s)
2523+ spiderTimeline = localSpiderTimeline Proxy $ reflect (Proxy :: Proxy s)
2506localSpiderTimeline
2525localSpiderTimeline
2507− :: Proxy s
2526+ :: proxy s
2508 -> SpiderTimelineEnv x
2527 -> SpiderTimelineEnv x
2509 -> SpiderTimelineEnv (LocalSpiderTimeline x s)
2528 -> SpiderTimelineEnv (LocalSpiderTimeline x s)
2510−localSpiderTimeline _ = unsafeCoerce
2529+localSpiderTimeline _ = coerce
2512-- | Pass a new timeline to the given function.
2531-- | Pass a new timeline to the given function.
2513withSpiderTimeline :: (forall x. HasSpiderTimeline x => SpiderTimelineEnv x -> IO r) -> IO r
2532withSpiderTimeline :: (forall x. HasSpiderTimeline x => SpiderTimelineEnv x -> IO r) -> IO r
@@ -2525,8 +2544,8 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2525 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
2544 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
2526 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
2545 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
2527 newtype Event (SpiderTimeline x) a = SpiderEvent { unSpiderEvent :: Event x a }
2546 newtype Event (SpiderTimeline x) a = SpiderEvent { unSpiderEvent :: Event x a }
2528− 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)
2529− newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: Dynamic x p }
2548+ newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: DynamicS x p }
2530 type PullM (SpiderTimeline x) = SpiderPullM x
2549 type PullM (SpiderTimeline x) = SpiderPullM x
2531 type PushM (SpiderTimeline x) = SpiderPushM x
2550 type PushM (SpiderTimeline x) = SpiderPushM x
2532 {-# INLINABLE never #-}
2551 {-# INLINABLE never #-}
@@ -2555,7 +2574,7 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2555 {-# INLINABLE current #-}
2574 {-# INLINABLE current #-}
2556 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
2575 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
2557 {-# INLINABLE updated #-}
2576 {-# INLINABLE updated #-}
2558− updated = coerce $ SpiderEvent . dynamicUpdated . unSpiderDynamic
2577+ updated = SpiderEvent #. dynamicUpdated .# fmap coerce . unSpiderDynamic
2559 {-# INLINABLE unsafeBuildDynamic #-}
2578 {-# INLINABLE unsafeBuildDynamic #-}
2560 unsafeBuildDynamic readV0 v' = SpiderDynamic $ dynamicDynIdentity $ unsafeBuildDynamic (coerce readV0) $ coerce $ unSpiderEvent v'
2579 unsafeBuildDynamic readV0 v' = SpiderDynamic $ dynamicDynIdentity $ unsafeBuildDynamic (coerce readV0) $ coerce $ unSpiderEvent v'
2561 {-# INLINABLE unsafeBuildIncremental #-}
2580 {-# INLINABLE unsafeBuildIncremental #-}
@@ -2574,9 +2593,10 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2574 return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
2593 return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
2575 eventCoercion Coercion = Coercion
2594 eventCoercion Coercion = Coercion
2576 behaviorCoercion Coercion = Coercion
2595 behaviorCoercion Coercion = Coercion
2577− 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
2578 {-# INLINABLE mergeIntIncremental #-}
2598 {-# INLINABLE mergeIntIncremental #-}
2579− mergeIntIncremental = SpiderEvent . mergeInt . (unsafeCoerce :: Dynamic x (PatchIntMap (R.Event (SpiderTimeline x) a)) -> Dynamic x (PatchIntMap (Event x a))) . unSpiderIncremental
2599+ mergeIntIncremental = SpiderEvent . mergeInt . coerce
2580 {-# INLINABLE fanInt #-}
2600 {-# INLINABLE fanInt #-}
2581 fanInt e = R.EventSelectorInt $ SpiderEvent . selectInt (fanInt (unSpiderEvent e))
2601 fanInt e = R.EventSelectorInt $ SpiderEvent . selectInt (fanInt (unSpiderEvent e))