@@ -18,6 +18,8 @@
18{-# LANGUAGE TypeOperators #-}
18{-# LANGUAGE TypeOperators #-}
19{-# LANGUAGE UndecidableInstances #-}
19{-# LANGUAGE UndecidableInstances #-}
20{-# LANGUAGE PolyKinds #-}
20{-# LANGUAGE PolyKinds #-}
21+{-# LANGUAGE DeriveFunctor #-}
22+{-# LANGUAGE StandaloneDeriving #-}
21{-# LANGUAGE InstanceSigs #-}
23{-# LANGUAGE InstanceSigs #-}
23#ifdef USE_REFLEX_OPTIMIZER
25#ifdef USE_REFLEX_OPTIMIZER
@@ -37,7 +39,10 @@ import Control.Monad hiding (forM, forM_, mapM, mapM_)
37import Control.Monad.Exception
39import Control.Monad.Exception
38import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
40import Control.Monad.Identity hiding (forM, forM_, mapM, mapM_)
39import Control.Monad.Primitive
41import Control.Monad.Primitive
40−import Control.Monad.Reader hiding (forM, forM_, mapM, mapM_)
42+--import Control.Monad.Reader hiding (forM, forM_, mapM, mapM_)
43+import Control.Monad.Reader.Class
44+import Control.Monad.IO.Class
45+import Control.Monad.ReaderIO
41import Control.Monad.Ref
46import Control.Monad.Ref
42import Data.Align
47import Data.Align
43import Data.Coerce
48import Data.Coerce
@@ -545,6 +550,11 @@ propagateFast a subscribers = withIncreasedDepth $ do
545toAny :: a -> Any
550toAny :: a -> Any
546toAny = unsafeCoerce
551toAny = unsafeCoerce
553+-- Why do we use Any here, instead of just giving eventSubscribedRetained an
554+-- existential type? Sadly, GHC does not currently know how to unbox types
555+-- with existentially quantified fields. So instead we just coerce values
556+-- to type Any on the way in. Since we never coerce them back, this is
548data EventSubscribed x = EventSubscribed
558data EventSubscribed x = EventSubscribed
549 { eventSubscribedHeightRef :: {-# UNPACK #-} !(IORef Height)
559 { eventSubscribedHeightRef :: {-# UNPACK #-} !(IORef Height)
550 , eventSubscribedRetained :: {-# NOUNPACK #-} !Any
560 , eventSubscribedRetained :: {-# NOUNPACK #-} !Any
@@ -668,7 +678,7 @@ behaviorPull !p = Behavior $ do
668 wi <- liftIO $ mkWeakPtrWithDebug i "InvalidatorPull"
678 wi <- liftIO $ mkWeakPtrWithDebug i "InvalidatorPull"
669 parentsRef <- liftIO $ newIORef []
679 parentsRef <- liftIO $ newIORef []
670 holdInits <- askBehaviorHoldInits
680 holdInits <- askBehaviorHoldInits
671− a <- liftIO $ runReaderT (unBehaviorM $ pullCompute p) (Just (wi, parentsRef), holdInits)
681+ a <- liftIO $ runReaderIO (unBehaviorM $ pullCompute p) (Just (wi, parentsRef), holdInits)
672 invsRef <- liftIO . newIORef . maybeToList =<< askInvalidator
682 invsRef <- liftIO . newIORef . maybeToList =<< askInvalidator
673 parents <- liftIO $ readIORef parentsRef
683 parents <- liftIO $ readIORef parentsRef
674 let subscribed = PullSubscribed
684 let subscribed = PullSubscribed
@@ -703,42 +713,46 @@ readBehaviorUntracked b = do
703-- Dynamic
713-- Dynamic
704--------------------------------------------------------------------------------
714--------------------------------------------------------------------------------
716+type DynamicS x p = Dynamic x (PatchTarget p) p
706−data Dynamic x p = Dynamic
718+data Dynamic x target p = Dynamic
707− { dynamicCurrent :: !(Behavior x (PatchTarget p))
719+ { 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`?
720 , dynamicUpdated :: Event x p -- This must be lazy; see the comment on holdEvent --TODO: Would this let us eliminate `Dyn`?
723+deriving instance (HasSpiderTimeline x) => Functor (Dynamic x target)
711−dynamicHold :: Hold x p -> Dynamic x p
728+dynamicHold :: Hold x p -> DynamicS x p
712dynamicHold !h = Dynamic
729dynamicHold !h = Dynamic
713 { dynamicCurrent = behaviorHold h
730 { dynamicCurrent = behaviorHold h
714 , dynamicUpdated = eventHold h
731 , dynamicUpdated = eventHold h
717−dynamicHoldIdentity :: Hold x (Identity a) -> Dynamic x (Identity a)
734+dynamicHoldIdentity :: Hold x (Identity a) -> DynamicS x (Identity a)
718dynamicHoldIdentity = dynamicHold
735dynamicHoldIdentity = dynamicHold
720−dynamicConst :: PatchTarget p -> Dynamic x p
737+dynamicConst :: PatchTarget p -> DynamicS x p
721dynamicConst !a = Dynamic
738dynamicConst !a = Dynamic
722 { dynamicCurrent = behaviorConst a
739 { dynamicCurrent = behaviorConst a
723 , dynamicUpdated = eventNever
740 , dynamicUpdated = eventNever
726−dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> Dynamic x p
743+dynamicDyn :: (HasSpiderTimeline x, Patch p) => Dyn x p -> DynamicS x p
727dynamicDyn !d = Dynamic
744dynamicDyn !d = Dynamic
728 { dynamicCurrent = behaviorDyn d
745 { dynamicCurrent = behaviorDyn d
729 , dynamicUpdated = eventDyn d
746 , dynamicUpdated = eventDyn d
732−dynamicDynIdentity :: HasSpiderTimeline x => Dyn x (Identity a) -> Dynamic x (Identity a)
749+dynamicDynIdentity :: HasSpiderTimeline x => Dyn x (Identity a) -> DynamicS x (Identity a)
733dynamicDynIdentity = dynamicDyn
750dynamicDynIdentity = dynamicDyn
735--------------------------------------------------------------------------------
752--------------------------------------------------------------------------------
736-- Combinators
753-- Combinators
737--------------------------------------------------------------------------------
754--------------------------------------------------------------------------------
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
756--type role Hold representational
743data Hold x p
757data Hold x p
744 = Hold { holdValue :: !(IORef (PatchTarget p))
758 = Hold { holdValue :: !(IORef (PatchTarget p))
@@ -759,20 +773,25 @@ globalSpiderTimelineEnv = unsafePerformIO unsafeNewSpiderTimelineEnv
760-- | Stores all global data relevant to a particular Spider timeline; only one
774-- | Stores all global data relevant to a particular Spider timeline; only one
761-- value should exist for each type @x@
775-- value should exist for each type @x@
776+newtype SpiderTimelineEnv x = STE {unSTE :: SpiderTimelineEnv' x}
777+-- We implement SpiderTimelineEnv with a newtype wrapper so
778+-- we can get the coercions we want safely.
779+type role SpiderTimelineEnv nominal
762−data SpiderTimelineEnv x = SpiderTimelineEnv
781+data SpiderTimelineEnv' x = SpiderTimelineEnv
763 { _spiderTimeline_lock :: {-# UNPACK #-} !(MVar ())
782 { _spiderTimeline_lock :: {-# UNPACK #-} !(MVar ())
764 , _spiderTimeline_eventEnv :: {-# UNPACK #-} !(EventEnv x)
783 , _spiderTimeline_eventEnv :: {-# UNPACK #-} !(EventEnv x)
765#ifdef DEBUG
784#ifdef DEBUG
766 , _spiderTimeline_depth :: {-# UNPACK #-} !(IORef Int)
785 , _spiderTimeline_depth :: {-# UNPACK #-} !(IORef Int)
769−type role SpiderTimelineEnv nominal
788+type role SpiderTimelineEnv' phantom
771instance Eq (SpiderTimelineEnv x) where
790instance Eq (SpiderTimelineEnv x) where
772 _ == _ = True -- Since only one exists of each type
791 _ == _ = True -- Since only one exists of each type
774instance GEq SpiderTimelineEnv where
793instance GEq SpiderTimelineEnv where
775− a `geq` b = if _spiderTimeline_lock a == _spiderTimeline_lock b
794+ 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
795 then Just $ unsafeCoerce Refl -- This unsafeCoerce is safe because the same SpiderTimelineEnv can't have two different 'x' arguments
777 else Nothing
796 else Nothing
@@ -795,7 +814,7 @@ runEventM :: EventM x a -> IO a
795runEventM = unEventM
814runEventM = unEventM
797asksEventEnv :: forall x a. HasSpiderTimeline x => (EventEnv x -> a) -> EventM x a
816asksEventEnv :: forall x a. HasSpiderTimeline x => (EventEnv x -> a) -> EventM x a
798−asksEventEnv f = return $ f $ _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
817+asksEventEnv f = return $ f $ _spiderTimeline_eventEnv (unSTE (spiderTimeline :: SpiderTimelineEnv x))
800class MonadIO m => Defer a m where
819class MonadIO m => Defer a m where
801 getDeferralQueue :: m (IORef [a])
820 getDeferralQueue :: m (IORef [a])
@@ -933,9 +952,9 @@ getHoldEventSubscription h = do
934type BehaviorEnv x = (Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]), IORef [SomeHoldInit x])
953type BehaviorEnv x = (Maybe (Weak (Invalidator x), IORef [SomeBehaviorSubscribed x]), IORef [SomeHoldInit x])
936−--type role BehaviorM representational
937-- BehaviorM can sample behaviors
955-- BehaviorM can sample behaviors
938−newtype BehaviorM x a = BehaviorM { unBehaviorM :: ReaderT (BehaviorEnv x) IO a } deriving (Functor, Applicative, MonadIO, MonadFix)
956+newtype BehaviorM x a = BehaviorM { unBehaviorM :: ReaderIO (BehaviorEnv x) a }
957+ deriving (Functor, Applicative, MonadIO, MonadFix, MonadReader (BehaviorEnv x))
940instance Monad (BehaviorM x) where
959instance Monad (BehaviorM x) where
941 {-# INLINE (>>=) #-}
960 {-# INLINE (>>=) #-}
@@ -1145,11 +1164,11 @@ data DynType x p = UnsafeDyn !(BehaviorM x (PatchTarget p), Event x p)
1146newtype Dyn (x :: Type) p = Dyn { unDyn :: IORef (DynType x p) }
1165newtype Dyn (x :: Type) p = Dyn { unDyn :: IORef (DynType x p) }
1148−newMapDyn :: HasSpiderTimeline x => (a -> b) -> Dynamic x (Identity a) -> Dynamic x (Identity b)
1167+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)
1168newMapDyn f d = dynamicDynIdentity $ unsafeBuildDynamic (fmap f $ readBehaviorTracked $ dynamicCurrent d) (Identity . f . runIdentity <$> dynamicUpdated d)
1151--TODO: Avoid the duplication between this and R.zipDynWith
1170--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)
1171+zipDynWith :: HasSpiderTimeline x => (a -> b -> c) -> DynamicS x (Identity a) -> DynamicS x (Identity b) -> DynamicS x (Identity c)
1153zipDynWith f da db =
1172zipDynWith f da db =
1154 let eab = align (dynamicUpdated da) (dynamicUpdated db)
1173 let eab = align (dynamicUpdated da) (dynamicUpdated db)
1155 ec = flip push eab $ \o -> do
1174 ec = flip push eab $ \o -> do
@@ -1225,7 +1244,7 @@ run :: forall x b. HasSpiderTimeline x => [DSum (RootTrigger x) Identity] -> Res
1225run roots after = do
1244run roots after = do
1226 tracePropagate (Proxy :: Proxy x) $ "Running an event frame with " <> show (length roots) <> " events"
1245 tracePropagate (Proxy :: Proxy x) $ "Running an event frame with " <> show (length roots) <> " events"
1227 let t = spiderTimeline :: SpiderTimelineEnv x
1246 let t = spiderTimeline :: SpiderTimelineEnv x
1228− result <- SpiderHost $ withMVar (_spiderTimeline_lock t) $ \_ -> unSpiderHost $ runFrame $ do
1247+ result <- SpiderHost $ withMVar (_spiderTimeline_lock (unSTE t)) $ \_ -> unSpiderHost $ runFrame $ do
1229 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
1248 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
1230 occBefore <- liftIO $ do
1249 occBefore <- liftIO $ do
1231 occBefore <- readIORef occRef
1250 occBefore <- readIORef occRef
@@ -1289,9 +1308,9 @@ type WeakList a = [Weak a]
1289withIncreasedDepth :: CanTrace x m => m a -> m a
1308withIncreasedDepth :: CanTrace x m => m a -> m a
1290withIncreasedDepth a = do
1309withIncreasedDepth a = do
1291 spiderTimeline <- askSpiderTimelineEnv
1310 spiderTimeline <- askSpiderTimelineEnv
1292− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) succ
1311+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) succ
1293 result <- a
1312 result <- a
1294− liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) pred
1313+ liftIO $ modifyIORef' (_spiderTimeline_depth (unSTE spiderTimeline)) pred
1295 return result
1314 return result
1297withIncreasedDepth :: m a -> m a
1316withIncreasedDepth :: m a -> m a
@@ -1318,7 +1337,7 @@ traceMWhen _ b getMessage = when b $ do
1318 message <- getMessage
1337 message <- getMessage
1319#ifdef DEBUG
1338#ifdef DEBUG
1320 spiderTimeline <- askSpiderTimelineEnv
1339 spiderTimeline <- askSpiderTimelineEnv
1321− d <- liftIO $ readIORef $ _spiderTimeline_depth spiderTimeline
1340+ d <- liftIO $ readIORef $ _spiderTimeline_depth $ unSTE spiderTimeline
1323 let d = 0
1342 let d = 0
@@ -1359,25 +1378,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
1378data 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
1380runBehaviorM :: 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)
1381+runBehaviorM a mwi holdInits = runReaderIO (unBehaviorM a) (mwi, holdInits)
1364askInvalidator :: BehaviorM x (Maybe (Weak (Invalidator x)))
1383askInvalidator :: BehaviorM x (Maybe (Weak (Invalidator x)))
1365askInvalidator = do
1384askInvalidator = do
1366− (!m, _) <- BehaviorM ask
1385+ (!m, _) <- ask
1367 case m of
1386 case m of
1368 Nothing -> return Nothing
1387 Nothing -> return Nothing
1369 Just (!wi, _) -> return $ Just wi
1388 Just (!wi, _) -> return $ Just wi
1371askParentsRef :: BehaviorM x (Maybe (IORef [SomeBehaviorSubscribed x]))
1390askParentsRef :: BehaviorM x (Maybe (IORef [SomeBehaviorSubscribed x]))
1372askParentsRef = do
1391askParentsRef = do
1373− (!m, _) <- BehaviorM ask
1392+ (!m, _) <- ask
1374 case m of
1393 case m of
1375 Nothing -> return Nothing
1394 Nothing -> return Nothing
1376 Just (_, !p) -> return $ Just p
1395 Just (_, !p) -> return $ Just p
1378askBehaviorHoldInits :: BehaviorM x (IORef [SomeHoldInit x])
1397askBehaviorHoldInits :: BehaviorM x (IORef [SomeHoldInit x])
1379askBehaviorHoldInits = do
1398askBehaviorHoldInits = do
1380− (_, !his) <- BehaviorM ask
1399+ (_, !his) <- ask
1381 return his
1400 return his
1383{-# INLINE getDynHold #-}
1402{-# INLINE getDynHold #-}
@@ -1701,20 +1720,20 @@ subscribeCoincidenceSubscribed subscribed sub = WeakBag.insert sub (coincidenceS
1701{-# INLINE mergeG #-}
1720{-# INLINE mergeG #-}
1702mergeG :: forall k q x v. (HasSpiderTimeline x, GCompare k)
1721mergeG :: forall k q x v. (HasSpiderTimeline x, GCompare k)
1703 => (forall a. q a -> Event x (v a))
1722 => (forall a. q a -> Event x (v a))
1704− -> Dynamic x (PatchDMap k q) -> Event x (DMap k v)
1723+ -> DynamicS x (PatchDMap k q) -> Event x (DMap k v)
1705mergeG nt d = cacheEvent (mergeCheap nt d)
1724mergeG nt d = cacheEvent (mergeCheap nt d)
1707{-# INLINE mergeWithMove #-}
1726{-# INLINE mergeWithMove #-}
1708mergeWithMove :: forall k v q x. (HasSpiderTimeline x, GCompare k)
1727mergeWithMove :: forall k v q x. (HasSpiderTimeline x, GCompare k)
1709 => (forall a. q a -> Event x (v a))
1728 => (forall a. q a -> Event x (v a))
1710− -> Dynamic x (PatchDMapWithMove k q) -> Event x (DMap k v)
1729+ -> DynamicS x (PatchDMapWithMove k q) -> Event x (DMap k v)
1711mergeWithMove nt d = cacheEvent (mergeCheapWithMove nt d)
1730mergeWithMove nt d = cacheEvent (mergeCheapWithMove nt d)
1713{-# INLINE [1] mergeCheap #-}
1732{-# INLINE [1] mergeCheap #-}
1714mergeCheap
1733mergeCheap
1715 :: forall k x q v. (HasSpiderTimeline x, GCompare k)
1734 :: forall k x q v. (HasSpiderTimeline x, GCompare k)
1716 => (forall a. q a -> Event x (v a))
1735 => (forall a. q a -> Event x (v a))
1717− -> Dynamic x (PatchDMap k q)
1736+ -> DynamicS x (PatchDMap k q)
1718 -> Event x (DMap k v)
1737 -> Event x (DMap k v)
1719mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
1738mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
@@ -1754,7 +1773,7 @@ mergeCheap nt = mergeGCheap' getInitialSubscribers updateMe destroy
1754{-# INLINE [1] mergeCheapWithMove #-}
1773{-# INLINE [1] mergeCheapWithMove #-}
1755mergeCheapWithMove :: forall k x v q. (HasSpiderTimeline x, GCompare k)
1774mergeCheapWithMove :: forall k x v q. (HasSpiderTimeline x, GCompare k)
1756 => (forall a. q a -> Event x (v a))
1775 => (forall a. q a -> Event x (v a))
1757− -> Dynamic x (PatchDMapWithMove k q)
1776+ -> DynamicS x (PatchDMapWithMove k q)
1758 -> Event x (DMap k v)
1777 -> Event x (DMap k v)
1759mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
1778mergeCheapWithMove nt = mergeGCheap' getInitialSubscribers updateMe destroy
@@ -1902,7 +1921,7 @@ updateMerge m updateFunc p = SomeMergeUpdate updateMe (invalidateMergeHeight m)
1903{-# INLINE mergeGCheap' #-}
1922{-# INLINE mergeGCheap' #-}
1904mergeGCheap' :: forall k v x p s q. (HasSpiderTimeline x, GCompare k, PatchTarget p ~ DMap k q)
1923mergeGCheap' :: 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)
1924+ => 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
1925mergeGCheap' getInitialSubscribers updateFunc destroy d = Event $ \sub -> do
1907 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1926 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1908 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
1927 accumRef <- liftIO $ newIORef $ error "merge: accumRef not yet initialized"
@@ -1951,11 +1970,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)
1973+mergeInt :: forall x a. (HasSpiderTimeline x) => DynamicS x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1955mergeInt = cacheEvent . mergeIntCheap
1974mergeInt = cacheEvent . mergeIntCheap
1957{-# INLINABLE mergeIntCheap #-}
1976{-# INLINABLE mergeIntCheap #-}
1958−mergeIntCheap :: forall x a. (HasSpiderTimeline x) => Dynamic x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1977+mergeIntCheap :: forall x a. (HasSpiderTimeline x) => DynamicS x (PatchIntMap (Event x a)) -> Event x (IntMap a)
1959mergeIntCheap d = Event $ \sub -> do
1978mergeIntCheap d = Event $ \sub -> do
1960 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1979 initialParents <- readBehaviorUntracked $ dynamicCurrent d
1961 accum <- liftIO $ FastMutableIntMap.newEmpty
1980 accum <- liftIO $ FastMutableIntMap.newEmpty
@@ -2115,7 +2134,7 @@ clearEventEnv (EventEnv toAssignRef holdInitRef dynInitRef mergeUpdateRef mergeI
2115-- | Run an event action outside of a frame
2134-- | 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
2135runFrame :: forall x a. HasSpiderTimeline x => EventM x a -> SpiderHost x a --TODO: This function also needs to hold the mutex
2117runFrame a = SpiderHost $ do
2136runFrame a = SpiderHost $ do
2118− let env = _spiderTimeline_eventEnv (spiderTimeline :: SpiderTimelineEnv x)
2137+ let env = _spiderTimeline_eventEnv $ unSTE (spiderTimeline :: SpiderTimelineEnv x)
2119 let go = do
2138 let go = do
2120 result <- a
2139 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
2140 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 +2345,7 @@ instance HasSpiderTimeline x => Monad (Reflex.Class.Dynamic (SpiderTimeline x))
2326 fail _ = error "Dynamic does not support 'fail'"
2345 fail _ = error "Dynamic does not support 'fail'"
2328{-# INLINABLE newJoinDyn #-}
2347{-# 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)
2348+newJoinDyn :: HasSpiderTimeline x => DynamicS x (Identity (DynamicS x (Identity a))) -> Reflex.Spider.Internal.Dyn x (Identity a)
2330newJoinDyn d =
2349newJoinDyn d =
2331 let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
2350 let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
2332 eOuter = Reflex.Spider.Internal.push (fmap (Just . Identity) . readBehaviorUntracked . dynamicCurrent . runIdentity) $ dynamicUpdated d
2351 eOuter = Reflex.Spider.Internal.push (fmap (Just . Identity) . readBehaviorUntracked . dynamicCurrent . runIdentity) $ dynamicUpdated d
@@ -2476,7 +2495,7 @@ unsafeNewSpiderTimelineEnv = do
2476#ifdef DEBUG
2495#ifdef DEBUG
2477 depthRef <- newIORef 0
2496 depthRef <- newIORef 0
2479− return $ SpiderTimelineEnv
2498+ return $ STE $ SpiderTimelineEnv
2480 { _spiderTimeline_lock = lock
2499 { _spiderTimeline_lock = lock
2481 , _spiderTimeline_eventEnv = env
2500 , _spiderTimeline_eventEnv = env
2482#ifdef DEBUG
2501#ifdef DEBUG
@@ -2492,13 +2511,13 @@ data LocalSpiderTimeline (x :: Type) s
2493instance Reifies s (SpiderTimelineEnv x) =>
2512instance Reifies s (SpiderTimelineEnv x) =>
2494 HasSpiderTimeline (LocalSpiderTimeline x s) where
2513 HasSpiderTimeline (LocalSpiderTimeline x s) where
2495− spiderTimeline = localSpiderTimeline (Proxy :: Proxy s) $ reflect (Proxy :: Proxy s)
2514+ spiderTimeline = localSpiderTimeline Proxy $ reflect (Proxy :: Proxy s)
2497localSpiderTimeline
2516localSpiderTimeline
2498− :: Proxy s
2517+ :: proxy s
2499 -> SpiderTimelineEnv x
2518 -> SpiderTimelineEnv x
2500 -> SpiderTimelineEnv (LocalSpiderTimeline x s)
2519 -> SpiderTimelineEnv (LocalSpiderTimeline x s)
2501−localSpiderTimeline _ = unsafeCoerce
2520+localSpiderTimeline _ = coerce
2503-- | Pass a new timeline to the given function.
2522-- | Pass a new timeline to the given function.
2504withSpiderTimeline :: (forall x. HasSpiderTimeline x => SpiderTimelineEnv x -> IO r) -> IO r
2523withSpiderTimeline :: (forall x. HasSpiderTimeline x => SpiderTimelineEnv x -> IO r) -> IO r
@@ -2516,8 +2535,8 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2516 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
2535 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
2517 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
2536 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
2518 newtype Event (SpiderTimeline x) a = SpiderEvent { unSpiderEvent :: Event x a }
2537 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)
2538+ 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 }
2539+ newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: DynamicS x p }
2521 type PullM (SpiderTimeline x) = SpiderPullM x
2540 type PullM (SpiderTimeline x) = SpiderPullM x
2522 type PushM (SpiderTimeline x) = SpiderPushM x
2541 type PushM (SpiderTimeline x) = SpiderPushM x
2523 {-# INLINABLE never #-}
2542 {-# INLINABLE never #-}
@@ -2546,7 +2565,7 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2546 {-# INLINABLE current #-}
2565 {-# INLINABLE current #-}
2547 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
2566 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
2548 {-# INLINABLE updated #-}
2567 {-# INLINABLE updated #-}
2549− updated = coerce $ SpiderEvent . dynamicUpdated . unSpiderDynamic
2568+ updated = SpiderEvent #. dynamicUpdated .# fmap coerce . unSpiderDynamic
2550 {-# INLINABLE unsafeBuildDynamic #-}
2569 {-# INLINABLE unsafeBuildDynamic #-}
2551 unsafeBuildDynamic readV0 v' = SpiderDynamic $ dynamicDynIdentity $ unsafeBuildDynamic (coerce readV0) $ coerce $ unSpiderEvent v'
2570 unsafeBuildDynamic readV0 v' = SpiderDynamic $ dynamicDynIdentity $ unsafeBuildDynamic (coerce readV0) $ coerce $ unSpiderEvent v'
2552 {-# INLINABLE unsafeBuildIncremental #-}
2571 {-# INLINABLE unsafeBuildIncremental #-}
@@ -2565,9 +2584,10 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
2565 return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
2584 return $ Identity <$> apply p c --TODO: Avoid the redundant 'apply'
2566 eventCoercion Coercion = Coercion
2585 eventCoercion Coercion = Coercion
2567 behaviorCoercion Coercion = Coercion
2586 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
2587+ dynamicCoercion Coercion = Coercion
2588+ incrementalCoercion Coercion Coercion = Coercion
2569 {-# INLINABLE mergeIntIncremental #-}
2589 {-# INLINABLE mergeIntIncremental #-}
2570− mergeIntIncremental = SpiderEvent . mergeInt . (unsafeCoerce :: Dynamic x (PatchIntMap (R.Event (SpiderTimeline x) a)) -> Dynamic x (PatchIntMap (Event x a))) . unSpiderIncremental
2590+ mergeIntIncremental = SpiderEvent . mergeInt . coerce
2571 {-# INLINABLE fanInt #-}
2591 {-# INLINABLE fanInt #-}
2572 fanInt e = R.EventSelectorInt $ SpiderEvent . selectInt (fanInt (unSpiderEvent e))
2592 fanInt e = R.EventSelectorInt $ SpiderEvent . selectInt (fanInt (unSpiderEvent e))