@@ -20,16 +20,7 @@
20{-# LANGUAGE UndecidableInstances #-}
20{-# LANGUAGE UndecidableInstances #-}
21-- | This module is the implementation of the 'Spider' 'Reflex' engine. It uses
21-- | This module is the implementation of the 'Spider' 'Reflex' engine. It uses
22-- a graph traversal algorithm to propagate 'Event's and 'Behavior's.
22-- a graph traversal algorithm to propagate 'Event's and 'Behavior's.
23−module Reflex.Spider.Internal
23+module Reflex.Spider.Internal where
34import Control.Applicative
25import Control.Applicative
35import Control.Concurrent
26import Control.Concurrent
@@ -691,7 +682,7 @@ data Hold x p a
693data EventEnv x
684data EventEnv x
694− = EventEnv { eventEnvSpiderEnv :: !(SpiderEnv x)
685+ = EventEnv { eventEnvSpiderTimeline :: !(SpiderTimeline x)
695 , eventEnvAssignments :: !(IORef [SomeAssignment x]) -- Needed for Subscribe
686 , eventEnvAssignments :: !(IORef [SomeAssignment x]) -- Needed for Subscribe
696 , eventEnvHoldInits :: !(IORef [SomeHoldInit x]) -- Needed for Subscribe
687 , eventEnvHoldInits :: !(IORef [SomeHoldInit x]) -- Needed for Subscribe
697 , eventEnvMergeUpdates :: !(IORef [SomeMergeUpdate x])
688 , eventEnvMergeUpdates :: !(IORef [SomeMergeUpdate x])
@@ -750,17 +741,17 @@ instance HasCurrentHeight x (EventM x) where
750 delayedRef <- asks eventEnvDelayedMerges
741 delayedRef <- asks eventEnvDelayedMerges
751 liftIO $ modifyIORef' delayedRef $ IntMap.insertWith (++) (unHeight height) [DelayedMerge subscribed]
742 liftIO $ modifyIORef' delayedRef $ IntMap.insertWith (++) (unHeight height) [DelayedMerge subscribed]
753−class HasSpiderEnv x m | m -> x where
744+class HasSpiderTimeline x m | m -> x where
754− -- | Retrieve the current SpiderEnv
745+ -- | Retrieve the current SpiderTimeline
755− askSpiderEnv :: m (SpiderEnv x)
746+ askSpiderTimeline :: m (SpiderTimeline x)
757−instance HasSpiderEnv x (EventM x) where
748+instance HasSpiderTimeline x (EventM x) where
758− {-# INLINE askSpiderEnv #-}
749+ {-# INLINE askSpiderTimeline #-}
759− askSpiderEnv = EventM $ asks eventEnvSpiderEnv
750+ askSpiderTimeline = EventM $ asks eventEnvSpiderTimeline
761−instance HasSpiderEnv x (SpiderHost x) where
752+instance HasSpiderTimeline x (SpiderHost x) where
762− {-# INLINE askSpiderEnv #-}
753+ {-# INLINE askSpiderTimeline #-}
763− askSpiderEnv = SpiderHost ask
754+ askSpiderTimeline = SpiderHost ask
765putCurrentHeight :: Height -> EventM x ()
756putCurrentHeight :: Height -> EventM x ()
766putCurrentHeight h = EventM $ do
757putCurrentHeight h = EventM $ do
@@ -811,7 +802,7 @@ hold v0 e = do
813{-# INLINE getHoldEventSubscription #-}
804{-# INLINE getHoldEventSubscription #-}
814−getHoldEventSubscription :: forall m p a 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, HasSpiderEnv x m, m ~ EventM x) => Hold x p a -> m (EventSubscription x (p a))
805+getHoldEventSubscription :: forall m p a 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, m ~ EventM x) => Hold x p a -> m (EventSubscription x (p a))
815getHoldEventSubscription h = do
806getHoldEventSubscription h = do
816 ep <- liftIO $ readIORef $ holdParent h
807 ep <- liftIO $ readIORef $ holdParent h
817 case ep of
808 case ep of
@@ -1182,8 +1173,8 @@ coincidence a = eventCoincidence $ Coincidence
1182run :: [DSum (RootTrigger x) Identity] -> ResultM x b -> SpiderHost x b
1173run :: [DSum (RootTrigger x) Identity] -> ResultM x b -> SpiderHost x b
1183run roots after = do
1174run roots after = do
1184 tracePropagate $ "Running an event frame with " <> show (length roots) <> " events"
1175 tracePropagate $ "Running an event frame with " <> show (length roots) <> " events"
1185− spiderEnv <- SpiderHost ask
1176+ spiderTimeline <- SpiderHost ask
1186− result <- SpiderHost $ lift $ withMVar (_spiderEnv_lock spiderEnv) $ \_ -> flip runReaderT spiderEnv $ unSpiderHost $ runFrame $ do
1177+ result <- SpiderHost $ lift $ withMVar (_spiderTimeline_lock spiderTimeline) $ \_ -> flip runReaderT spiderTimeline $ unSpiderHost $ runFrame $ do
1187 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
1178 rootsToPropagate <- forM roots $ \r@(RootTrigger (_, occRef, k) :=> a) -> do
1188 occBefore <- liftIO $ do
1179 occBefore <- liftIO $ do
1189 occBefore <- readIORef occRef
1180 occBefore <- readIORef occRef
@@ -1249,17 +1240,17 @@ type WeakList a = [Weak a]
1249#ifdef DEBUG
1240#ifdef DEBUG
1250withIncreasedDepth :: CanTrace x m => m a -> m a
1241withIncreasedDepth :: CanTrace x m => m a -> m a
1251withIncreasedDepth a = do
1242withIncreasedDepth a = do
1252− spiderEnv <- askSpiderEnv
1243+ spiderTimeline <- askSpiderTimeline
1253− liftIO $ modifyIORef' (_spiderEnv_depth spiderEnv) succ
1244+ liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) succ
1254 result <- a
1245 result <- a
1255− liftIO $ modifyIORef' (_spiderEnv_depth spiderEnv) pred
1246+ liftIO $ modifyIORef' (_spiderTimeline_depth spiderTimeline) pred
1256 return result
1247 return result
1258withIncreasedDepth :: m a -> m a
1249withIncreasedDepth :: m a -> m a
1259withIncreasedDepth = id
1250withIncreasedDepth = id
1262−type CanTrace x m = (HasSpiderEnv x m, MonadIO m)
1253+type CanTrace x m = (HasSpiderTimeline x m, MonadIO m)
1264{-# INLINE tracePropagate #-}
1255{-# INLINE tracePropagate #-}
1265tracePropagate :: (CanTrace x m) => String -> m ()
1256tracePropagate :: (CanTrace x m) => String -> m ()
@@ -1278,8 +1269,8 @@ traceMWhen :: (CanTrace x m) => Bool -> m String -> m ()
1278traceMWhen b getMessage = when b $ do
1269traceMWhen b getMessage = when b $ do
1279 message <- getMessage
1270 message <- getMessage
1280#ifdef DEBUG
1271#ifdef DEBUG
1281− spiderEnv <- askSpiderEnv
1272+ spiderTimeline <- askSpiderTimeline
1282− d <- liftIO $ readIORef $ _spiderEnv_depth spiderEnv
1273+ d <- liftIO $ readIORef $ _spiderTimeline_depth spiderTimeline
1284 let d = 0
1275 let d = 0
@@ -1360,7 +1351,7 @@ zeroRef :: IORef Height
1360zeroRef = unsafePerformIO $ newIORef zeroHeight
1351zeroRef = unsafePerformIO $ newIORef zeroHeight
1362type CanSubscribe x m =
1353type CanSubscribe x m =
1363− ( HasSpiderEnv x m
1354+ ( HasSpiderTimeline x m
1364 , HasCurrentHeight x m
1355 , HasCurrentHeight x m
1365 , Defer (SomeHoldInit x) m, Defer (SomeMergeInit x) m -- The things we need to lazily initialize state
1356 , Defer (SomeHoldInit x) m, Defer (SomeMergeInit x) m -- The things we need to lazily initialize state
1366 , Defer SomeClear m -- Wiping out event firings
1357 , Defer SomeClear m -- Wiping out event firings
@@ -1530,7 +1521,7 @@ subscribeMergeSubscribed :: MergeSubscribed x k -> Subscriber x (DMap k Identity
1530subscribeMergeSubscribed subscribed sub = WeakBag.insert sub (mergeSubscribedSubscribers subscribed) (mergeSubscribedWeakSelf subscribed) cleanupMergeSubscribed
1521subscribeMergeSubscribed subscribed sub = WeakBag.insert sub (mergeSubscribedSubscribers subscribed) (mergeSubscribedWeakSelf subscribed) cleanupMergeSubscribed
1532{-# SPECIALIZE getFanSubscribed :: GCompare k => k a -> Fan x k -> Subscriber x a -> EventM x (WeakBagTicket (Subscriber x a), FanSubscribed x k, Maybe a) #-}
1523{-# SPECIALIZE getFanSubscribed :: GCompare k => k a -> Fan x k -> Subscriber x a -> EventM x (WeakBagTicket (Subscriber x a), FanSubscribed x k, Maybe a) #-}
1533−getFanSubscribed :: (Defer (SomeAssignment x) m, Defer (SomeHoldInit x) m, Defer (SomeMergeInit x) m, Defer SomeClear m, HasCurrentHeight x m, Defer (SomeResetCoincidence x) m, HasSpiderEnv x m, m ~ EventM x, GCompare k) => k a -> Fan x k -> Subscriber x a -> m (WeakBagTicket (Subscriber x a), FanSubscribed x k, Maybe a)
1524+getFanSubscribed :: (Defer (SomeAssignment x) m, Defer (SomeHoldInit x) m, Defer (SomeMergeInit x) m, Defer SomeClear m, HasCurrentHeight x m, Defer (SomeResetCoincidence x) m, HasSpiderTimeline x m, m ~ EventM x, GCompare k) => k a -> Fan x k -> Subscriber x a -> m (WeakBagTicket (Subscriber x a), FanSubscribed x k, Maybe a)
1534getFanSubscribed k f sub = do
1525getFanSubscribed k f sub = do
1535 mSubscribed <- liftIO $ readIORef $ fanSubscribed f
1526 mSubscribed <- liftIO $ readIORef $ fanSubscribed f
1536 case mSubscribed of
1527 case mSubscribed of
@@ -1589,7 +1580,7 @@ subscribeFanSubscribed k subscribed sub = do
1589 Just (FanSubscribedChildren list _ weakSelf) -> {-# SCC "hitSubscribeFanSubscribed" #-} WeakBag.insert sub list weakSelf cleanupFanSubscribed
1580 Just (FanSubscribedChildren list _ weakSelf) -> {-# SCC "hitSubscribeFanSubscribed" #-} WeakBag.insert sub list weakSelf cleanupFanSubscribed
1591{-# SPECIALIZE getSwitchSubscribed :: Switch x a -> Subscriber x a -> EventM x (WeakBagTicket (Subscriber x a), SwitchSubscribed x a, Maybe a) #-}
1582{-# SPECIALIZE getSwitchSubscribed :: Switch x a -> Subscriber x a -> EventM x (WeakBagTicket (Subscriber x a), SwitchSubscribed x a, Maybe a) #-}
1592−getSwitchSubscribed :: (Defer (SomeHoldInit x) m, Defer (SomeAssignment x) m, Defer (SomeMergeInit x) m, Defer SomeClear m, Defer (SomeResetCoincidence x) m, HasCurrentHeight x m, HasSpiderEnv x m, m ~ EventM x) => Switch x a -> Subscriber x a -> m (WeakBagTicket (Subscriber x a), SwitchSubscribed x a, Maybe a)
1583+getSwitchSubscribed :: (Defer (SomeHoldInit x) m, Defer (SomeAssignment x) m, Defer (SomeMergeInit x) m, Defer SomeClear m, Defer (SomeResetCoincidence x) m, HasCurrentHeight x m, HasSpiderTimeline x m, m ~ EventM x) => Switch x a -> Subscriber x a -> m (WeakBagTicket (Subscriber x a), SwitchSubscribed x a, Maybe a)
1593getSwitchSubscribed s sub = do
1584getSwitchSubscribed s sub = do
1594 mSubscribed <- liftIO $ readIORef $ switchSubscribed s
1585 mSubscribed <- liftIO $ readIORef $ switchSubscribed s
1595 case mSubscribed of
1586 case mSubscribed of
@@ -1645,7 +1636,7 @@ subscribeSwitchSubscribed :: SwitchSubscribed x a -> Subscriber x a -> IO (WeakB
1645subscribeSwitchSubscribed subscribed sub = WeakBag.insert sub (switchSubscribedSubscribers subscribed) (switchSubscribedWeakSelf subscribed) cleanupSwitchSubscribed
1636subscribeSwitchSubscribed subscribed sub = WeakBag.insert sub (switchSubscribedSubscribers subscribed) (switchSubscribedWeakSelf subscribed) cleanupSwitchSubscribed
1647{-# SPECIALIZE getCoincidenceSubscribed :: Coincidence x a -> Subscriber x a -> EventM x (WeakBagTicket (Subscriber x a), CoincidenceSubscribed x a, Maybe a) #-}
1638{-# SPECIALIZE getCoincidenceSubscribed :: Coincidence x a -> Subscriber x a -> EventM x (WeakBagTicket (Subscriber x a), CoincidenceSubscribed x a, Maybe a) #-}
1648−getCoincidenceSubscribed :: forall x a m. (Defer (SomeAssignment x) m, Defer (SomeHoldInit x) m, Defer (SomeMergeInit x) m, Defer SomeClear m, HasCurrentHeight x m, Defer (SomeResetCoincidence x) m, HasSpiderEnv x m, m ~ EventM x) => Coincidence x a -> Subscriber x a -> m (WeakBagTicket (Subscriber x a), CoincidenceSubscribed x a, Maybe a)
1639+getCoincidenceSubscribed :: forall x a m. (Defer (SomeAssignment x) m, Defer (SomeHoldInit x) m, Defer (SomeMergeInit x) m, Defer SomeClear m, HasCurrentHeight x m, Defer (SomeResetCoincidence x) m, HasSpiderTimeline x m, m ~ EventM x) => Coincidence x a -> Subscriber x a -> m (WeakBagTicket (Subscriber x a), CoincidenceSubscribed x a, Maybe a)
1649getCoincidenceSubscribed c sub = do
1640getCoincidenceSubscribed c sub = do
1650 mSubscribed <- liftIO $ readIORef $ coincidenceSubscribed c
1641 mSubscribed <- liftIO $ readIORef $ coincidenceSubscribed c
1651 case mSubscribed of
1642 case mSubscribed of
@@ -1738,9 +1729,9 @@ initMerge (SomeMergeInit subscribed changed) = do
1739-- | Run an event action outside of a frame
1730-- | Run an event action outside of a frame
1740runFrame :: forall x a. EventM x a -> SpiderHost x a --TODO: This function also needs to hold the mutex
1731runFrame :: forall x a. EventM x a -> SpiderHost x a --TODO: This function also needs to hold the mutex
1741−runFrame a = SpiderHost $ ask >>= \spiderEnv -> lift $ do
1732+runFrame a = SpiderHost $ ask >>= \spiderTimeline -> lift $ do
1742 -- Clear out pending unsubscriptions; these will need to happen eventually anyway, and might cause us a lot of extra work during the frame, so get rid of them now
1733 -- Clear out pending unsubscriptions; these will need to happen eventually anyway, and might cause us a lot of extra work during the frame, so get rid of them now
1743− pendingCleanups <- atomicModifyIORef (_spiderEnv_cleanups spiderEnv) $ \x -> ([], x)
1734+ pendingCleanups <- atomicModifyIORef (_spiderTimeline_cleanups spiderTimeline) $ \x -> ([], x)
1744 {-# SCC "cleanups" #-} sequence_ pendingCleanups
1735 {-# SCC "cleanups" #-} sequence_ pendingCleanups
1745 toAssignRef <- newIORef [] -- This should only actually get used when events are firing
1736 toAssignRef <- newIORef [] -- This should only actually get used when events are firing
1746 holdInitRef <- newIORef []
1737 holdInitRef <- newIORef []
@@ -1751,7 +1742,7 @@ runFrame a = SpiderHost $ ask >>= \spiderEnv -> lift $ do
1751 toClearRootRef <- newIORef []
1742 toClearRootRef <- newIORef []
1752 coincidenceInfosRef <- newIORef []
1743 coincidenceInfosRef <- newIORef []
1753 delayedRef <- liftIO $ newIORef IntMap.empty
1744 delayedRef <- liftIO $ newIORef IntMap.empty
1754− let env = EventEnv spiderEnv toAssignRef holdInitRef mergeUpdateRef mergeInitRef toClearRef toClearRootRef heightRef coincidenceInfosRef delayedRef
1745+ let env = EventEnv spiderTimeline toAssignRef holdInitRef mergeUpdateRef mergeInitRef toClearRef toClearRootRef heightRef coincidenceInfosRef delayedRef
1755 let go = do
1746 let go = do
1756 result <- a
1747 result <- a
1757 runHoldInits holdInitRef mergeInitRef -- This must happen before doing the assignments, in case subscribing a Hold causes existing Holds to be read by the newly-propagated events
1748 runHoldInits holdInitRef mergeInitRef -- This must happen before doing the assignments, in case subscribing a Hold causes existing Holds to be read by the newly-propagated events
@@ -1808,7 +1799,7 @@ runFrame a = SpiderHost $ ask >>= \spiderEnv -> lift $ do
1808 runEventM (runHoldInits holdInitRef mergeInitRef) env --TODO: Is this actually OK? It seems like it should be, since we know that no events are firing at this point, but it still seems inelegant
1799 runEventM (runHoldInits holdInitRef mergeInitRef) env --TODO: Is this actually OK? It seems like it should be, since we know that no events are firing at this point, but it still seems inelegant
1809 --TODO: Make sure we touch the pieces of the SwitchSubscribed at the appropriate times
1800 --TODO: Make sure we touch the pieces of the SwitchSubscribed at the appropriate times
1810 sub <- newSubscriberSwitch subscribed
1801 sub <- newSubscriberSwitch subscribed
1811− subscription <- runReaderT (unSpiderHost (runFrame ({-# SCC "subscribeSwitch" #-} subscribe e sub))) spiderEnv --TODO: Assert that the event isn't firing --TODO: This should not loop because none of the events should be firing, but still, it is inefficient
1802+ subscription <- runReaderT (unSpiderHost (runFrame ({-# SCC "subscribeSwitch" #-} subscribe e sub))) spiderTimeline --TODO: Assert that the event isn't firing --TODO: This should not loop because none of the events should be firing, but still, it is inefficient
1813 stackTrace <- liftIO $ fmap renderStack $ ccsToStrings =<< (getCCSOf $! switchSubscribedParent subscribed)
1804 stackTrace <- liftIO $ fmap renderStack $ ccsToStrings =<< (getCCSOf $! switchSubscribedParent subscribed)
1814 liftIO $ putStrLn $ (++stackTrace) $ "subd' subscribed to " ++ case e of
1805 liftIO $ putStrLn $ (++stackTrace) $ "subd' subscribed to " ++ case e of
@@ -1963,64 +1954,68 @@ invalidate toReconnectRef wis = do
1963--------------------------------------------------------------------------------
1954--------------------------------------------------------------------------------
1965-- | The default, global Spider environment
1956-- | The default, global Spider environment
1966−type Spider = SpiderEnv Global
1957+type Spider = SpiderTimeline Global
1968-- | Designates the default, global Spider timeline
1959-- | Designates the default, global Spider timeline
1969data Global
1960data Global
1971−{-# NOINLINE globalSpiderEnv #-}
1962+{-# NOINLINE globalSpiderTimeline #-}
1972−globalSpiderEnv :: SpiderEnv Global
1963+globalSpiderTimeline :: SpiderTimeline Global
1973−globalSpiderEnv = unsafePerformIO unsafeNewSpiderEnv
1964+globalSpiderTimeline = unsafePerformIO unsafeNewSpiderTimeline
1975-- | Stores all global data relevant to a particular Spider timeline; only one
1966-- | Stores all global data relevant to a particular Spider timeline; only one
1976-- value should exist for each type @x@
1967-- value should exist for each type @x@
1977−data SpiderEnv x = SpiderEnv
1968+data SpiderTimeline x = SpiderTimeline
1978− { _spiderEnv_toUnsubscribe :: !(IORef [SomeEventSubscription x])
1969+ { _spiderTimeline_toUnsubscribe :: !(IORef [SomeEventSubscription x])
1979− , _spiderEnv_lock :: !(MVar ())
1970+ , _spiderTimeline_lock :: !(MVar ())
1980− , _spiderEnv_cleanups :: !(IORef [IO ()])
1971+ , _spiderTimeline_cleanups :: !(IORef [IO ()])
1981#ifdef DEBUG
1972#ifdef DEBUG
1982− , _spiderEnv_depth :: !(IORef Int)
1973+ , _spiderTimeline_depth :: !(IORef Int)
1985−type role SpiderEnv nominal
1976+type role SpiderTimeline nominal
1987−instance GEq SpiderEnv where
1978+instance GEq SpiderTimeline where
1988− a `geq` b = if _spiderEnv_lock a == _spiderEnv_lock b
1979+ a `geq` b = if _spiderTimeline_lock a == _spiderTimeline_lock b
1989− then Just $ unsafeCoerce Refl -- This unsafeCoerce is safe because the same SpiderEnv can't have two different 'x' arguments
1980+ then Just $ unsafeCoerce Refl -- This unsafeCoerce is safe because the same SpiderTimeline can't have two different 'x' arguments
1990 else Nothing
1981 else Nothing
1992−unsafeNewSpiderEnv :: forall x. IO (SpiderEnv x)
1983+unsafeNewSpiderTimeline :: forall x. IO (SpiderTimeline x)
1993−unsafeNewSpiderEnv = do
1984+unsafeNewSpiderTimeline = do
1994 toUnsubscribe <- newIORef []
1985 toUnsubscribe <- newIORef []
1995 lock <- newMVar ()
1986 lock <- newMVar ()
1996 cleanups <- newIORef []
1987 cleanups <- newIORef []
1997#ifdef DEBUG
1988#ifdef DEBUG
1998 depthRef <- newIORef 0
1989 depthRef <- newIORef 0
2000− return $ SpiderEnv
1991+ return $ SpiderTimeline
2001− { _spiderEnv_toUnsubscribe = toUnsubscribe
1992+ { _spiderTimeline_toUnsubscribe = toUnsubscribe
2002− , _spiderEnv_lock = lock
1993+ , _spiderTimeline_lock = lock
2003− , _spiderEnv_cleanups = cleanups
1994+ , _spiderTimeline_cleanups = cleanups
2004#ifdef DEBUG
1995#ifdef DEBUG
2005− , _spiderEnv_depth = depthRef
1996+ , _spiderTimeline_depth = depthRef
2009−-- | Create a new SpiderEnv
2000+-- | Create a new SpiderTimeline
2010−newSpiderEnv :: IO (Some SpiderEnv)
2001+newSpiderTimeline :: IO (Some SpiderTimeline)
2011−newSpiderEnv = Some.This <$> unsafeNewSpiderEnv
2002+newSpiderTimeline = withSpiderTimeline (pure . Some.This)
2004+-- | Pass a new timeline to the given function.
2005+withSpiderTimeline :: (forall x. SpiderTimeline x -> IO r) -> IO r
2006+withSpiderTimeline k = unsafeNewSpiderTimeline >>= k
2013newtype SpiderPullM x a = SpiderPullM (BehaviorM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
2008newtype SpiderPullM x a = SpiderPullM (BehaviorM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
2015newtype SpiderPushM x a = SpiderPushM (ComputeM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
2010newtype SpiderPushM x a = SpiderPushM (ComputeM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
2017−instance R.Reflex (SpiderEnv x) where
2012+instance R.Reflex (SpiderTimeline x) where
2018− newtype Behavior (SpiderEnv x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
2013+ newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
2019− newtype Event (SpiderEnv x) a = SpiderEvent { unSpiderEvent :: Event x a }
2014+ newtype Event (SpiderTimeline x) a = SpiderEvent { unSpiderEvent :: Event x a }
2020− newtype Dynamic (SpiderEnv x) a = SpiderDynamic { unSpiderDynamic :: Dynamic x Identity a } deriving (Functor, Applicative, Monad)
2015+ newtype Dynamic (SpiderTimeline x) a = SpiderDynamic { unSpiderDynamic :: Dynamic x Identity a } deriving (Functor, Applicative, Monad)
2021− newtype Incremental (SpiderEnv x) p a = SpiderIncremental { unSpiderIncremental :: Dynamic x p a }
2016+ newtype Incremental (SpiderTimeline x) p a = SpiderIncremental { unSpiderIncremental :: Dynamic x p a }
2022− type PullM (SpiderEnv x) = SpiderPullM x
2017+ type PullM (SpiderTimeline x) = SpiderPullM x
2023− type PushM (SpiderEnv x) = SpiderPushM x
2018+ type PushM (SpiderTimeline x) = SpiderPushM x
2024 {-# INLINABLE never #-}
2019 {-# INLINABLE never #-}
2025 never = SpiderEvent eventNever
2020 never = SpiderEvent eventNever
2026 {-# INLINABLE constant #-}
2021 {-# INLINABLE constant #-}
@@ -2030,13 +2025,13 @@ instance R.Reflex (SpiderEnv x) where
2030 {-# INLINABLE pull #-}
2025 {-# INLINABLE pull #-}
2031 pull = SpiderBehavior . pull . coerce
2026 pull = SpiderBehavior . pull . coerce
2032 {-# INLINABLE merge #-}
2027 {-# INLINABLE merge #-}
2033− merge = SpiderEvent . merge . dynamicConst . (coerce :: DMap k (R.Event (SpiderEnv x)) -> DMap k (Event x))
2028+ merge = SpiderEvent . merge . dynamicConst . (coerce :: DMap k (R.Event (SpiderTimeline x)) -> DMap k (Event x))
2034 {-# INLINABLE fan #-}
2029 {-# INLINABLE fan #-}
2035 fan e = R.EventSelector $ SpiderEvent . select (fan (unSpiderEvent e))
2030 fan e = R.EventSelector $ SpiderEvent . select (fan (unSpiderEvent e))
2036 {-# INLINABLE switch #-}
2031 {-# INLINABLE switch #-}
2037− switch = SpiderEvent . switch . (coerce :: Behavior x (R.Event (SpiderEnv x) a) -> Behavior x (Event x a)) . unSpiderBehavior
2032+ switch = SpiderEvent . switch . (coerce :: Behavior x (R.Event (SpiderTimeline x) a) -> Behavior x (Event x a)) . unSpiderBehavior
2038 {-# INLINABLE coincidence #-}
2033 {-# INLINABLE coincidence #-}
2039− coincidence = SpiderEvent . coincidence . (coerce :: Event x (R.Event (SpiderEnv x) a) -> Event x (Event x a)) . unSpiderEvent
2034+ coincidence = SpiderEvent . coincidence . (coerce :: Event x (R.Event (SpiderTimeline x) a) -> Event x (Event x a)) . unSpiderEvent
2040 {-# INLINABLE current #-}
2035 {-# INLINABLE current #-}
2041 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
2036 current = SpiderBehavior . dynamicCurrent . unSpiderDynamic
2042 {-# INLINABLE updated #-}
2037 {-# INLINABLE updated #-}
@@ -2046,7 +2041,7 @@ instance R.Reflex (SpiderEnv x) where
2046 {-# INLINABLE unsafeBuildIncremental #-}
2041 {-# INLINABLE unsafeBuildIncremental #-}
2047 unsafeBuildIncremental readV0 dv = SpiderIncremental $ dynamicDyn $ unsafeDyn (coerce readV0) $ unSpiderEvent dv
2042 unsafeBuildIncremental readV0 dv = SpiderIncremental $ dynamicDyn $ unsafeDyn (coerce readV0) $ unSpiderEvent dv
2048 {-# INLINABLE mergeIncremental #-}
2043 {-# INLINABLE mergeIncremental #-}
2049− mergeIncremental = SpiderEvent . merge . (unsafeCoerce :: Dynamic x R.PatchDMap (DMap k (R.Event (SpiderEnv x))) -> Dynamic x R.PatchDMap (DMap k (Event x))) . unSpiderIncremental
2044+ mergeIncremental = SpiderEvent . merge . (unsafeCoerce :: Dynamic x R.PatchDMap (DMap k (R.Event (SpiderTimeline x))) -> Dynamic x R.PatchDMap (DMap k (Event x))) . unSpiderIncremental
2050 {-# INLINABLE currentIncremental #-}
2045 {-# INLINABLE currentIncremental #-}
2051 currentIncremental = SpiderBehavior . dynamicCurrent . unSpiderIncremental
2046 currentIncremental = SpiderBehavior . dynamicCurrent . unSpiderIncremental
2052 {-# INLINABLE updatedIncremental #-}
2047 {-# INLINABLE updatedIncremental #-}
@@ -2056,11 +2051,11 @@ instance R.Reflex (SpiderEnv x) where
2056 c <- readBehaviorUntracked $ dynamicCurrent i
2051 c <- readBehaviorUntracked $ dynamicCurrent i
2057 return $ Identity <$> R.apply p c --TODO: Avoid the redundant 'apply'
2052 return $ Identity <$> R.apply p c --TODO: Avoid the redundant 'apply'
2059−instance R.MonadSample (SpiderEnv x) (EventM x) where
2054+instance R.MonadSample (SpiderTimeline x) (EventM x) where
2060 {-# INLINABLE sample #-}
2055 {-# INLINABLE sample #-}
2061 sample (SpiderBehavior b) = readBehaviorUntracked b
2056 sample (SpiderBehavior b) = readBehaviorUntracked b
2063−instance R.MonadHold (SpiderEnv x) (EventM x) where
2058+instance R.MonadHold (SpiderTimeline x) (EventM x) where
2064 {-# INLINABLE hold #-}
2059 {-# INLINABLE hold #-}
2065 hold = holdSpiderEventM
2060 hold = holdSpiderEventM
2066 {-# INLINABLE holdDyn #-}
2061 {-# INLINABLE holdDyn #-}
@@ -2068,16 +2063,16 @@ instance R.MonadHold (SpiderEnv x) (EventM x) where
2068 {-# INLINABLE holdIncremental #-}
2063 {-# INLINABLE holdIncremental #-}
2069 holdIncremental = holdIncrementalSpiderEventM
2064 holdIncremental = holdIncrementalSpiderEventM
2071−holdSpiderEventM :: a -> R.Event (SpiderEnv x) a -> EventM x (R.Behavior (SpiderEnv x) a)
2066+holdSpiderEventM :: a -> R.Event (SpiderTimeline x) a -> EventM x (R.Behavior (SpiderTimeline x) a)
2072holdSpiderEventM v0 e = fmap (SpiderBehavior . behaviorHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
2067holdSpiderEventM v0 e = fmap (SpiderBehavior . behaviorHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
2074−holdDynSpiderEventM :: a -> R.Event (SpiderEnv x) a -> EventM x (R.Dynamic (SpiderEnv x) a)
2069+holdDynSpiderEventM :: a -> R.Event (SpiderTimeline x) a -> EventM x (R.Dynamic (SpiderTimeline x) a)
2075holdDynSpiderEventM v0 e = fmap (SpiderDynamic . dynamicHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
2070holdDynSpiderEventM v0 e = fmap (SpiderDynamic . dynamicHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
2077−holdIncrementalSpiderEventM :: R.Patch p => a -> R.Event (SpiderEnv x) (p a) -> EventM x (R.Incremental (SpiderEnv x) p a)
2072+holdIncrementalSpiderEventM :: R.Patch p => a -> R.Event (SpiderTimeline x) (p a) -> EventM x (R.Incremental (SpiderTimeline x) p a)
2078holdIncrementalSpiderEventM v0 e = fmap (SpiderIncremental . dynamicHold) $ hold v0 $ unSpiderEvent e
2073holdIncrementalSpiderEventM v0 e = fmap (SpiderIncremental . dynamicHold) $ hold v0 $ unSpiderEvent e
2080−instance R.MonadHold (SpiderEnv x) (SpiderHost x) where
2075+instance R.MonadHold (SpiderTimeline x) (SpiderHost x) where
2081 {-# INLINABLE hold #-}
2076 {-# INLINABLE hold #-}
2082 hold v0 e = R.runHostFrame $ R.hold v0 e
2077 hold v0 e = R.runHostFrame $ R.hold v0 e
2083 {-# INLINABLE holdDyn #-}
2078 {-# INLINABLE holdDyn #-}
@@ -2085,19 +2080,19 @@ instance R.MonadHold (SpiderEnv x) (SpiderHost x) where
2085 {-# INLINABLE holdIncremental #-}
2080 {-# INLINABLE holdIncremental #-}
2086 holdIncremental v0 e = R.runHostFrame $ R.holdIncremental v0 e
2081 holdIncremental v0 e = R.runHostFrame $ R.holdIncremental v0 e
2088−instance R.MonadSample (SpiderEnv x) (SpiderHost x) where
2083+instance R.MonadSample (SpiderTimeline x) (SpiderHost x) where
2089 {-# INLINABLE sample #-}
2084 {-# INLINABLE sample #-}
2090 sample = runFrame . readBehaviorUntracked . unSpiderBehavior
2085 sample = runFrame . readBehaviorUntracked . unSpiderBehavior
2092−instance R.MonadSample (SpiderEnv x) (SpiderPullM x) where
2087+instance R.MonadSample (SpiderTimeline x) (SpiderPullM x) where
2093 {-# INLINABLE sample #-}
2088 {-# INLINABLE sample #-}
2094 sample = coerce . readBehaviorTracked . unSpiderBehavior
2089 sample = coerce . readBehaviorTracked . unSpiderBehavior
2096−instance R.MonadSample (SpiderEnv x) (SpiderPushM x) where
2091+instance R.MonadSample (SpiderTimeline x) (SpiderPushM x) where
2097 {-# INLINABLE sample #-}
2092 {-# INLINABLE sample #-}
2098 sample (SpiderBehavior b) = SpiderPushM $ readBehaviorUntracked b
2093 sample (SpiderBehavior b) = SpiderPushM $ readBehaviorUntracked b
2100−instance R.MonadHold (SpiderEnv x) (SpiderPushM x) where
2095+instance R.MonadHold (SpiderTimeline x) (SpiderPushM x) where
2101 {-# INLINABLE hold #-}
2096 {-# INLINABLE hold #-}
2102 hold v0 e = R.current <$> R.holdDyn v0 e
2097 hold v0 e = R.current <$> R.holdDyn v0 e
2103 {-# INLINABLE holdDyn #-}
2098 {-# INLINABLE holdDyn #-}
@@ -2112,7 +2107,7 @@ data SpiderEventHandle x a = SpiderEventHandle
2112 , spiderEventHandleValue :: IORef (Maybe a)
2107 , spiderEventHandleValue :: IORef (Maybe a)
2115−instance R.MonadSubscribeEvent (SpiderEnv x) (SpiderHostFrame x) where
2110+instance R.MonadSubscribeEvent (SpiderTimeline x) (SpiderHostFrame x) where
2116 {-# INLINABLE subscribeEvent #-}
2111 {-# INLINABLE subscribeEvent #-}
2117 subscribeEvent e = SpiderHostFrame $ do
2112 subscribeEvent e = SpiderHostFrame $ do
2118 --TODO: Unsubscribe eventually (manually and/or with weak ref)
2113 --TODO: Unsubscribe eventually (manually and/or with weak ref)
@@ -2129,12 +2124,12 @@ instance R.MonadSubscribeEvent (SpiderEnv x) (SpiderHostFrame x) where
2129 , spiderEventHandleValue = val
2124 , spiderEventHandleValue = val
2132−instance R.ReflexHost (SpiderEnv x) where
2127+instance R.ReflexHost (SpiderTimeline x) where
2133− type EventTrigger (SpiderEnv x) = RootTrigger x
2128+ type EventTrigger (SpiderTimeline x) = RootTrigger x
2134− type EventHandle (SpiderEnv x) = SpiderEventHandle x
2129+ type EventHandle (SpiderTimeline x) = SpiderEventHandle x
2135− type HostFrame (SpiderEnv x) = SpiderHostFrame x
2130+ type HostFrame (SpiderTimeline x) = SpiderHostFrame x
2137−instance R.MonadReadEvent (SpiderEnv x) (ReadPhase x) where
2132+instance R.MonadReadEvent (SpiderTimeline x) (ReadPhase x) where
2138 {-# NOINLINE readEvent #-}
2133 {-# NOINLINE readEvent #-}
2139 readEvent h = ReadPhase $ fmap (fmap return) $ liftIO $ do
2134 readEvent h = ReadPhase $ fmap (fmap return) $ liftIO $ do
2140 result <- readIORef $ spiderEventHandleValue h
2135 result <- readIORef $ spiderEventHandleValue h
@@ -2155,7 +2150,7 @@ instance MonadAtomicRef (EventM x) where
2155 atomicModifyRef r f = liftIO $ atomicModifyRef r f
2150 atomicModifyRef r f = liftIO $ atomicModifyRef r f
2157-- | The monad for actions that manipulate a Spider timeline identified by @x@
2152-- | The monad for actions that manipulate a Spider timeline identified by @x@
2158−newtype SpiderHost x a = SpiderHost { unSpiderHost :: ReaderT (SpiderEnv x) IO a } deriving (Functor, Applicative, MonadFix, MonadIO, MonadException, MonadAsyncException)
2153+newtype SpiderHost x a = SpiderHost { unSpiderHost :: ReaderT (SpiderTimeline x) IO a } deriving (Functor, Applicative, MonadFix, MonadIO, MonadException, MonadAsyncException)
2160instance Monad (SpiderHost x) where
2155instance Monad (SpiderHost x) where
2161 {-# INLINABLE (>>=) #-}
2156 {-# INLINABLE (>>=) #-}
@@ -2170,7 +2165,12 @@ instance Monad (SpiderHost x) where
2170-- | Run an action affecting the global Spider timeline; this will be guarded by
2165-- | Run an action affecting the global Spider timeline; this will be guarded by
2171-- a mutex for that timeline
2166-- a mutex for that timeline
2172runSpiderHost :: SpiderHost Global a -> IO a
2167runSpiderHost :: SpiderHost Global a -> IO a
2173−runSpiderHost (SpiderHost a) = runReaderT a globalSpiderEnv
2168+runSpiderHost (SpiderHost a) = runReaderT a globalSpiderTimeline
2170+-- | Run an action affecting a given Spider timeline; this will be guarded by a
2171+-- mutex for that timeline
2172+runSpiderHostForTimeline :: SpiderHost x a -> SpiderTimeline x -> IO a
2173+runSpiderHostForTimeline (SpiderHost a) = runReaderT a
2175newtype SpiderHostFrame x a = SpiderHostFrame { runSpiderHostFrame :: EventM x a } deriving (Functor, Applicative, MonadFix, MonadIO, MonadException, MonadAsyncException)
2175newtype SpiderHostFrame x a = SpiderHostFrame { runSpiderHostFrame :: EventM x a } deriving (Functor, Applicative, MonadFix, MonadIO, MonadException, MonadAsyncException)
@@ -2184,10 +2184,10 @@ instance Monad (SpiderHostFrame x) where
2184 {-# INLINABLE fail #-}
2184 {-# INLINABLE fail #-}
2185 fail s = SpiderHostFrame $ fail s
2185 fail s = SpiderHostFrame $ fail s
2187−instance R.MonadSample (SpiderEnv x) (SpiderHostFrame x) where
2187+instance R.MonadSample (SpiderTimeline x) (SpiderHostFrame x) where
2188 sample = SpiderHostFrame . readBehaviorUntracked . unSpiderBehavior --TODO: This can cause problems with laziness, so we should get rid of it if we can
2188 sample = SpiderHostFrame . readBehaviorUntracked . unSpiderBehavior --TODO: This can cause problems with laziness, so we should get rid of it if we can
2190−instance R.MonadHold (SpiderEnv x) (SpiderHostFrame x) where
2190+instance R.MonadHold (SpiderTimeline x) (SpiderHostFrame x) where
2191 {-# INLINABLE hold #-}
2191 {-# INLINABLE hold #-}
2192 hold v0 e = SpiderHostFrame $ fmap (SpiderBehavior . behaviorHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
2192 hold v0 e = SpiderHostFrame $ fmap (SpiderBehavior . behaviorHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
2193 {-# INLINABLE holdDyn #-}
2193 {-# INLINABLE holdDyn #-}
@@ -2211,29 +2211,29 @@ newFanEventWithTriggerIO f = do
2212 return $ EventSelector $ \k -> eventRoot k r
2212 return $ EventSelector $ \k -> eventRoot k r
2214−instance R.MonadReflexCreateTrigger (SpiderEnv x) (SpiderHost x) where
2214+instance R.MonadReflexCreateTrigger (SpiderTimeline x) (SpiderHost x) where
2215 newEventWithTrigger = SpiderHost . lift . fmap SpiderEvent . newEventWithTriggerIO
2215 newEventWithTrigger = SpiderHost . lift . fmap SpiderEvent . newEventWithTriggerIO
2216 newFanEventWithTrigger f = SpiderHost $ lift $ do
2216 newFanEventWithTrigger f = SpiderHost $ lift $ do
2217 es <- newFanEventWithTriggerIO f
2217 es <- newFanEventWithTriggerIO f
2218 return $ R.EventSelector $ SpiderEvent . select es
2218 return $ R.EventSelector $ SpiderEvent . select es
2220−instance R.MonadReflexCreateTrigger (SpiderEnv x) (SpiderHostFrame x) where
2220+instance R.MonadReflexCreateTrigger (SpiderTimeline x) (SpiderHostFrame x) where
2221 newEventWithTrigger = SpiderHostFrame . EventM . liftIO . fmap SpiderEvent . newEventWithTriggerIO
2221 newEventWithTrigger = SpiderHostFrame . EventM . liftIO . fmap SpiderEvent . newEventWithTriggerIO
2222 newFanEventWithTrigger f = SpiderHostFrame $ EventM $ liftIO $ do
2222 newFanEventWithTrigger f = SpiderHostFrame $ EventM $ liftIO $ do
2223 es <- newFanEventWithTriggerIO f
2223 es <- newFanEventWithTriggerIO f
2224 return $ R.EventSelector $ SpiderEvent . select es
2224 return $ R.EventSelector $ SpiderEvent . select es
2226−instance R.MonadSubscribeEvent (SpiderEnv x) (SpiderHost x) where
2226+instance R.MonadSubscribeEvent (SpiderTimeline x) (SpiderHost x) where
2227 {-# INLINABLE subscribeEvent #-}
2227 {-# INLINABLE subscribeEvent #-}
2228 subscribeEvent = runFrame . runSpiderHostFrame . R.subscribeEvent
2228 subscribeEvent = runFrame . runSpiderHostFrame . R.subscribeEvent
2230newtype ReadPhase x a = ReadPhase (ResultM x a) deriving (Functor, Applicative, Monad, MonadFix)
2230newtype ReadPhase x a = ReadPhase (ResultM x a) deriving (Functor, Applicative, Monad, MonadFix)
2232−instance R.MonadSample (SpiderEnv x) (ReadPhase x) where
2232+instance R.MonadSample (SpiderTimeline x) (ReadPhase x) where
2233 {-# INLINABLE sample #-}
2233 {-# INLINABLE sample #-}
2234 sample = ReadPhase . R.sample
2234 sample = ReadPhase . R.sample
2236−instance R.MonadHold (SpiderEnv x) (ReadPhase x) where
2236+instance R.MonadHold (SpiderTimeline x) (ReadPhase x) where
2237 {-# INLINABLE hold #-}
2237 {-# INLINABLE hold #-}
2238 hold v0 e = ReadPhase $ R.hold v0 e
2238 hold v0 e = ReadPhase $ R.hold v0 e
2239 {-# INLINABLE holdDyn #-}
2239 {-# INLINABLE holdDyn #-}
@@ -2241,7 +2241,7 @@ instance R.MonadHold (SpiderEnv x) (ReadPhase x) where
2241 {-# INLINABLE holdIncremental #-}
2241 {-# INLINABLE holdIncremental #-}
2242 holdIncremental v0 e = ReadPhase $ R.holdIncremental v0 e
2242 holdIncremental v0 e = ReadPhase $ R.holdIncremental v0 e
2244−instance R.MonadReflexHost (SpiderEnv x) (SpiderHost x) where
2244+instance R.MonadReflexHost (SpiderTimeline x) (SpiderHost x) where
2245 type ReadPhase (SpiderHost x) = ReadPhase x
2245 type ReadPhase (SpiderHost x) = ReadPhase x
2246 fireEventsAndRead es (ReadPhase a) = run es a
2246 fireEventsAndRead es (ReadPhase a) = run es a
2247 runHostFrame = runFrame . runSpiderHostFrame
2247 runHostFrame = runFrame . runSpiderHostFrame
@@ -2263,3 +2263,10 @@ instance MonadRef (SpiderHostFrame x) where
2264instance MonadAtomicRef (SpiderHostFrame x) where
2264instance MonadAtomicRef (SpiderHostFrame x) where
2265 atomicModifyRef r = SpiderHostFrame . atomicModifyRef r
2265 atomicModifyRef r = SpiderHostFrame . atomicModifyRef r
2267+--------------------------------------------------------------------------------
2269+--------------------------------------------------------------------------------
2271+{-# DEPRECATED SpiderEnv "Use 'SpiderTimeline' instead" #-}
2272+type SpiderEnv = SpiderTimeline