@@ -41,6 +41,7 @@ import qualified Data.Dependent.Map as DMap
41import Data.Foldable hiding (concat, elem, sequence_)
41import Data.Foldable hiding (concat, elem, sequence_)
42import Data.Function
42import Data.Function
43import Data.Functor.Constant
43import Data.Functor.Constant
44+import Data.Functor.Misc
44import Data.Functor.Product
45import Data.Functor.Product
45import Data.GADT.Compare
46import Data.GADT.Compare
46import Data.IntMap.Strict (IntMap)
47import Data.IntMap.Strict (IntMap)
@@ -54,11 +55,11 @@ import Data.Some (Some)
54import qualified Data.Some as Some
55import qualified Data.Some as Some
55import Data.These
56import Data.These
56import Data.Traversable
57import Data.Traversable
57−import Data.Type.Coercion
58import Data.Word
58import Data.Word
59import GHC.Exts
59import GHC.Exts
60import GHC.IORef (IORef (..))
60import GHC.IORef (IORef (..))
61import GHC.Stack
61import GHC.Stack
62+import Reflex.FunctorMaybe
62import System.IO.Unsafe
63import System.IO.Unsafe
63import System.Mem.Weak
64import System.Mem.Weak
64import Unsafe.Coerce
65import Unsafe.Coerce
@@ -73,12 +74,13 @@ import Data.Tree (Forest, Tree (..), drawForest)
74import Data.WeakBag (WeakBag, WeakBagTicket)
75import Data.WeakBag (WeakBag, WeakBagTicket)
75import qualified Data.WeakBag as WeakBag
76import qualified Data.WeakBag as WeakBag
77+#ifndef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
78+import Data.Type.Coercion
79+import qualified Reflex.Class
76import qualified Reflex.Class as R
80import qualified Reflex.Class as R
77−#ifdef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
78−import Reflex.Class (SpiderTimeline, Global)
81+import qualified Reflex.Host.Class
80import Reflex.Patch
83import Reflex.Patch
81−import qualified Reflex.Host.Class as R
83-- Note: must come last to silence warnings due to AMP on GHC < 7.10
85-- Note: must come last to silence warnings due to AMP on GHC < 7.10
84import Prelude hiding (any, concat, mapM, mapM_, sequence)
86import Prelude hiding (any, concat, mapM, mapM_, sequence)
@@ -678,6 +680,8 @@ data Hold x p
681{-# NOINLINE globalSpiderTimelineEnv #-}
685{-# NOINLINE globalSpiderTimelineEnv #-}
682globalSpiderTimelineEnv :: SpiderTimelineEnv Global
686globalSpiderTimelineEnv :: SpiderTimelineEnv Global
683!globalSpiderTimelineEnv = unsafePerformIO unsafeNewSpiderTimelineEnv
687!globalSpiderTimelineEnv = unsafePerformIO unsafeNewSpiderTimelineEnv
@@ -1041,12 +1045,12 @@ newInvalidatorSwitch subd = return $! InvalidatorSwitch subd
1041newInvalidatorPull :: Pull x a -> IO (Invalidator x)
1045newInvalidatorPull :: Pull x a -> IO (Invalidator x)
1042newInvalidatorPull p = return $! InvalidatorPull p
1046newInvalidatorPull p = return $! InvalidatorPull p
1044−instance HasSpiderTimeline x => R.FunctorMaybe (Event x) where
1048+instance HasSpiderTimeline x => FunctorMaybe (Event x) where
1045 fmapMaybe f = push $ return . f
1049 fmapMaybe f = push $ return . f
1047instance HasSpiderTimeline x => Align (Event x) where
1051instance HasSpiderTimeline x => Align (Event x) where
1048 nil = eventNever
1052 nil = eventNever
1049− align ea eb = R.fmapMaybe R.dmapToThese $ merge $ dynamicConst $ DMap.fromList [R.LeftTag :=> ea, R.RightTag :=> eb]
1053+ align ea eb = fmapMaybe dmapToThese $ merge $ dynamicConst $ DMap.fromList [LeftTag :=> ea, RightTag :=> eb]
1051newtype Dyn x p = Dyn { unDyn :: IORef (Either (BehaviorM x (PatchTarget p), Event x p) (Hold x p)) }
1055newtype Dyn x p = Dyn { unDyn :: IORef (Either (BehaviorM x (PatchTarget p), Event x p) (Hold x p)) }
@@ -1073,15 +1077,6 @@ unsafeDyn :: BehaviorM x (PatchTarget p) -> Event x p -> Dyn x p
1073unsafeDyn readV0 v' = Dyn $ unsafeNewIORef x $ Left x
1077unsafeDyn readV0 v' = Dyn $ unsafeNewIORef x $ Left x
1074 where x = (readV0, v')
1078 where x = (readV0, v')
1076−newJoinDyn :: HasSpiderTimeline x => Dynamic x (Identity (Dynamic x (Identity a))) -> Dyn x (Identity a)
1078− let readV0 = readBehaviorTracked . dynamicCurrent =<< readBehaviorTracked (dynamicCurrent d)
1079− eOuter = push (fmap (Just . Identity) . readBehaviorUntracked . dynamicCurrent . runIdentity) $ dynamicUpdated d
1080− eInner = switch $ dynamicUpdated <$> dynamicCurrent d
1081− eBoth = coincidence $ dynamicUpdated . runIdentity <$> dynamicUpdated d
1082− v' = unSpiderEvent $ R.leftmost $ map SpiderEvent [eBoth, eOuter, eInner]
1083− in unsafeDyn readV0 v'
1085-- ResultM can read behaviors and events
1080-- ResultM can read behaviors and events
1086type ResultM = EventM
1081type ResultM = EventM
@@ -1855,14 +1850,12 @@ invalidate toReconnectRef wis = do
1855-- Reflex integration
1850-- Reflex integration
1856--------------------------------------------------------------------------------
1851--------------------------------------------------------------------------------
1858−-- | The default, global Spider environment
1859−type Spider = SpiderTimeline Global
1861#ifndef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
1853#ifndef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
1862-- When we're specializing, we include this from Reflex.Class instead, because
1854-- When we're specializing, we include this from Reflex.Class instead, because
1863-- it needs access to these types; when we're not, we want them here, so our
1855-- it needs access to these types; when we're not, we want them here, so our
1864-- instance isn't an orphan instance.
1856-- instance isn't an orphan instance.
1865#include "SpiderTimeline.include.hs"
1857#include "SpiderTimeline.include.hs"
1858+#include "SpiderTimelineHost.include.hs"
1868unsafeNewSpiderTimelineEnv :: forall x. IO (SpiderTimelineEnv x)
1861unsafeNewSpiderTimelineEnv :: forall x. IO (SpiderTimelineEnv x)
@@ -1892,34 +1885,7 @@ newtype SpiderPullM x a = SpiderPullM (BehaviorM x a) deriving (Functor, Applica
1893newtype SpiderPushM x a = SpiderPushM (ComputeM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
1886newtype SpiderPushM x a = SpiderPushM (ComputeM x a) deriving (Functor, Applicative, Monad, MonadIO, MonadFix)
1895−instance HasSpiderTimeline x => Functor (R.Dynamic (SpiderTimeline x)) where
1896− fmap f = SpiderDynamic . newMapDyn f . unSpiderDynamic
1898−instance HasSpiderTimeline x => Applicative (R.Dynamic (SpiderTimeline x)) where
1899− pure = SpiderDynamic . dynamicConst
1900− SpiderDynamic a <*> SpiderDynamic b = SpiderDynamic $ zipDynWith ($) a b
1904−instance HasSpiderTimeline x => Monad (R.Dynamic (SpiderTimeline x)) where
1905− {-# INLINE return #-}
1907− {-# INLINE (>>=) #-}
1908− x >>= f = SpiderDynamic $ dynamicDynIdentity $ newJoinDyn $ newMapDyn (unSpiderDynamic . f) $ unSpiderDynamic x
1909− {-# INLINE (>>) #-}
1911− {-# INLINE fail #-}
1912− fail _ = error "Dynamic does not support 'fail'"
1914−#ifdef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
1888+#ifndef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
1915−instance t ~ SpiderTimeline Global => R.Reflex t where
1916− newtype Behavior t a = SpiderBehavior { unSpiderBehavior :: Behavior Global a }
1917− newtype Event t a = SpiderEvent { unSpiderEvent :: Event Global a }
1918− newtype Dynamic t a = SpiderDynamic { unSpiderDynamic :: Dynamic Global (Identity a) } -- deriving (Functor, Applicative, Monad)
1919− newtype Incremental t p = SpiderIncremental { unSpiderIncremental :: Dynamic Global p }
1920− type PullM t = SpiderPullM Global
1921− type PushM t = SpiderPushM Global
1923instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
1889instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
1924 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
1890 {-# SPECIALIZE instance R.Reflex (SpiderTimeline Global) #-}
1925 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
1891 newtype Behavior (SpiderTimeline x) a = SpiderBehavior { unSpiderBehavior :: Behavior x a }
@@ -1928,7 +1894,6 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
1928 newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: Dynamic x p }
1894 newtype Incremental (SpiderTimeline x) p = SpiderIncremental { unSpiderIncremental :: Dynamic x p }
1929 type PullM (SpiderTimeline x) = SpiderPullM x
1895 type PullM (SpiderTimeline x) = SpiderPullM x
1930 type PushM (SpiderTimeline x) = SpiderPushM x
1896 type PushM (SpiderTimeline x) = SpiderPushM x
1932 {-# INLINABLE never #-}
1897 {-# INLINABLE never #-}
1933 never = SpiderEvent eventNever
1898 never = SpiderEvent eventNever
1934 {-# INLINABLE constant #-}
1899 {-# INLINABLE constant #-}
@@ -1966,63 +1931,7 @@ instance HasSpiderTimeline x => R.Reflex (SpiderTimeline x) where
1966 eventCoercion Coercion = Coercion
1931 eventCoercion Coercion = Coercion
1967 behaviorCoercion Coercion = Coercion
1932 behaviorCoercion Coercion = Coercion
1968 dynamicCoercion = unsafeCoerce --TODO: How can we avoid this unsafeCoerce? This is safe only because we know how Identity works as a Patch instance
1933 dynamicCoercion = unsafeCoerce --TODO: How can we avoid this unsafeCoerce? This is safe only because we know how Identity works as a Patch instance
1970−instance HasSpiderTimeline x => R.MonadSample (SpiderTimeline x) (EventM x) where
1971− {-# INLINABLE sample #-}
1972− sample (SpiderBehavior b) = readBehaviorUntracked b
1974−instance HasSpiderTimeline x => R.MonadHold (SpiderTimeline x) (EventM x) where
1975− {-# INLINABLE hold #-}
1976− hold = holdSpiderEventM
1977− {-# INLINABLE holdDyn #-}
1978− holdDyn = holdDynSpiderEventM
1979− {-# INLINABLE holdIncremental #-}
1980− holdIncremental = holdIncrementalSpiderEventM
1982−holdSpiderEventM :: HasSpiderTimeline x => a -> R.Event (SpiderTimeline x) a -> EventM x (R.Behavior (SpiderTimeline x) a)
1983−holdSpiderEventM v0 e = fmap (SpiderBehavior . behaviorHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
1985−holdDynSpiderEventM :: HasSpiderTimeline x => a -> R.Event (SpiderTimeline x) a -> EventM x (R.Dynamic (SpiderTimeline x) a)
1986−holdDynSpiderEventM v0 e = fmap (SpiderDynamic . dynamicHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
1988−holdIncrementalSpiderEventM :: (HasSpiderTimeline x, Patch p) => PatchTarget p -> R.Event (SpiderTimeline x) p -> EventM x (R.Incremental (SpiderTimeline x) p)
1989−holdIncrementalSpiderEventM v0 e = fmap (SpiderIncremental . dynamicHold) $ hold v0 $ unSpiderEvent e
1991−instance HasSpiderTimeline x => R.MonadHold (SpiderTimeline x) (SpiderHost x) where
1992− {-# INLINABLE hold #-}
1993− hold v0 e = R.runHostFrame $ R.hold v0 e
1994− {-# INLINABLE holdDyn #-}
1995− holdDyn v0 e = R.runHostFrame $ R.holdDyn v0 e
1996− {-# INLINABLE holdIncremental #-}
1997− holdIncremental v0 e = R.runHostFrame $ R.holdIncremental v0 e
1999−instance HasSpiderTimeline x => R.MonadSample (SpiderTimeline x) (SpiderHost x) where
2000− {-# INLINABLE sample #-}
2001− sample = runFrame . readBehaviorUntracked . unSpiderBehavior
2004−#ifdef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
2007− ) => R.MonadSample (SpiderTimeline x) (SpiderPullM x) where
2008− {-# INLINABLE sample #-}
2009− sample = coerce . readBehaviorTracked . unSpiderBehavior
2012−#ifdef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
2015− ) => R.MonadSample (SpiderTimeline x) (SpiderPushM x) where
2016− {-# INLINABLE sample #-}
2017− sample (SpiderBehavior b) = SpiderPushM $ readBehaviorUntracked b
2019−instance HasSpiderTimeline x => R.MonadHold (SpiderTimeline x) (SpiderPushM x) where
2020− {-# INLINABLE hold #-}
2021− hold v0 e = R.current <$> R.holdDyn v0 e
2022− {-# INLINABLE holdDyn #-}
2023− holdDyn v0 (SpiderEvent e) = SpiderPushM $ fmap (SpiderDynamic . dynamicHoldIdentity) $ hold v0 $ coerce e
2024− {-# INLINABLE holdIncremental #-}
2025− holdIncremental v0 (SpiderEvent e) = SpiderPushM $ SpiderIncremental . dynamicHold <$> hold v0 e
2027data RootTrigger x a = forall k. GCompare k => RootTrigger (WeakBag (Subscriber x a), IORef (DMap k Identity), k a)
1936data RootTrigger x a = forall k. GCompare k => RootTrigger (WeakBag (Subscriber x a), IORef (DMap k Identity), k a)
@@ -2031,35 +1940,6 @@ data SpiderEventHandle x a = SpiderEventHandle
2031 , spiderEventHandleValue :: IORef (Maybe a)
1940 , spiderEventHandleValue :: IORef (Maybe a)
2034−instance HasSpiderTimeline x => R.MonadSubscribeEvent (SpiderTimeline x) (SpiderHostFrame x) where
2035− {-# INLINABLE subscribeEvent #-}
2036− subscribeEvent e = SpiderHostFrame $ do
2037− --TODO: Unsubscribe eventually (manually and/or with weak ref)
2038− val <- liftIO $ newIORef Nothing
2039− subscription <- subscribe (unSpiderEvent e) $ Subscriber
2040− { subscriberPropagate = \a -> do
2041− liftIO $ writeIORef val $ Just a
2043− , subscriberInvalidateHeight = \_ -> return ()
2044− , subscriberRecalculateHeight = \_ -> return ()
2046− return $ SpiderEventHandle
2047− { spiderEventHandleSubscription = subscription
2048− , spiderEventHandleValue = val
2051−instance HasSpiderTimeline x => R.ReflexHost (SpiderTimeline x) where
2052− type EventTrigger (SpiderTimeline x) = RootTrigger x
2053− type EventHandle (SpiderTimeline x) = SpiderEventHandle x
2054− type HostFrame (SpiderTimeline x) = SpiderHostFrame x
2056−instance HasSpiderTimeline x => R.MonadReadEvent (SpiderTimeline x) (ReadPhase x) where
2057− {-# NOINLINE readEvent #-}
2058− readEvent h = ReadPhase $ fmap (fmap return) $ liftIO $ do
2059− result <- readIORef $ spiderEventHandleValue h
2063instance MonadRef (EventM x) where
1943instance MonadRef (EventM x) where
2064 type Ref (EventM x) = Ref IO
1944 type Ref (EventM x) = Ref IO
2065 {-# INLINABLE newRef #-}
1945 {-# INLINABLE newRef #-}
@@ -2108,17 +1988,6 @@ instance Monad (SpiderHostFrame x) where
2108 {-# INLINABLE fail #-}
1988 {-# INLINABLE fail #-}
2109 fail s = SpiderHostFrame $ fail s
1989 fail s = SpiderHostFrame $ fail s
2111−instance HasSpiderTimeline x => R.MonadSample (SpiderTimeline x) (SpiderHostFrame x) where
2112− sample = SpiderHostFrame . readBehaviorUntracked . unSpiderBehavior --TODO: This can cause problems with laziness, so we should get rid of it if we can
2114−instance HasSpiderTimeline x => R.MonadHold (SpiderTimeline x) (SpiderHostFrame x) where
2115− {-# INLINABLE hold #-}
2116− hold v0 e = SpiderHostFrame $ fmap (SpiderBehavior . behaviorHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
2117− {-# INLINABLE holdDyn #-}
2118− holdDyn v0 e = SpiderHostFrame $ fmap (SpiderDynamic . dynamicHoldIdentity) $ hold v0 $ coerce $ unSpiderEvent e
2119− {-# INLINABLE holdIncremental #-}
2120− holdIncremental v0 e = SpiderHostFrame $ fmap (SpiderIncremental . dynamicHold) $ hold v0 $ unSpiderEvent e
2122newEventWithTriggerIO :: (RootTrigger x a -> IO (IO ())) -> IO (Event x a)
1991newEventWithTriggerIO :: (RootTrigger x a -> IO (IO ())) -> IO (Event x a)
2123newEventWithTriggerIO f = do
1992newEventWithTriggerIO f = do
2124 es <- newFanEventWithTriggerIO $ \Refl -> f
1993 es <- newFanEventWithTriggerIO $ \Refl -> f
@@ -2135,49 +2004,8 @@ newFanEventWithTriggerIO f = do
2136 return $ EventSelector $ \k -> eventRoot k r
2005 return $ EventSelector $ \k -> eventRoot k r
2139−#ifdef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
2142− ) => R.MonadReflexCreateTrigger (SpiderTimeline x) (SpiderHost x) where
2143− newEventWithTrigger = SpiderHost . lift . fmap SpiderEvent . newEventWithTriggerIO
2144− newFanEventWithTrigger f = SpiderHost $ lift $ do
2145− es <- newFanEventWithTriggerIO f
2146− return $ R.EventSelector $ SpiderEvent . select es
2149−#ifdef SPECIALIZE_TO_SPIDERTIMELINE_GLOBAL
2152− ) => R.MonadReflexCreateTrigger (SpiderTimeline x) (SpiderHostFrame x) where
2153− newEventWithTrigger = SpiderHostFrame . EventM . liftIO . fmap SpiderEvent . newEventWithTriggerIO
2154− newFanEventWithTrigger f = SpiderHostFrame $ EventM $ liftIO $ do
2155− es <- newFanEventWithTriggerIO f
2156− return $ R.EventSelector $ SpiderEvent . select es
2158−instance HasSpiderTimeline x => R.MonadSubscribeEvent (SpiderTimeline x) (SpiderHost x) where
2159− {-# INLINABLE subscribeEvent #-}
2160− subscribeEvent = runFrame . runSpiderHostFrame . R.subscribeEvent
2162newtype ReadPhase x a = ReadPhase (ResultM x a) deriving (Functor, Applicative, Monad, MonadFix)
2007newtype ReadPhase x a = ReadPhase (ResultM x a) deriving (Functor, Applicative, Monad, MonadFix)
2164−instance HasSpiderTimeline x => R.MonadSample (SpiderTimeline x) (ReadPhase x) where
2165− {-# INLINABLE sample #-}
2166− sample = ReadPhase . R.sample
2168−instance HasSpiderTimeline x => R.MonadHold (SpiderTimeline x) (ReadPhase x) where
2169− {-# INLINABLE hold #-}
2170− hold v0 e = ReadPhase $ R.hold v0 e
2171− {-# INLINABLE holdDyn #-}
2172− holdDyn v0 e = ReadPhase $ R.holdDyn v0 e
2173− {-# INLINABLE holdIncremental #-}
2174− holdIncremental v0 e = ReadPhase $ R.holdIncremental v0 e
2176−instance HasSpiderTimeline x => R.MonadReflexHost (SpiderTimeline x) (SpiderHost x) where
2177− type ReadPhase (SpiderHost x) = ReadPhase x
2178− fireEventsAndRead es (ReadPhase a) = run es a
2179− runHostFrame = runFrame . runSpiderHostFrame
2181instance MonadRef (SpiderHost x) where
2009instance MonadRef (SpiderHost x) where
2182 type Ref (SpiderHost x) = Ref IO
2010 type Ref (SpiderHost x) = Ref IO
2183 newRef = SpiderHost . newRef
2011 newRef = SpiderHost . newRef
@@ -2199,10 +2027,3 @@ instance MonadAtomicRef (SpiderHostFrame x) where
2199instance PrimMonad (SpiderHostFrame x) where
2027instance PrimMonad (SpiderHostFrame x) where
2200 type PrimState (SpiderHostFrame x) = PrimState IO
2028 type PrimState (SpiderHostFrame x) = PrimState IO
2201 primitive = SpiderHostFrame . EventM . primitive
2029 primitive = SpiderHostFrame . EventM . primitive
2203−--------------------------------------------------------------------------------
2205−--------------------------------------------------------------------------------
2207−{-# DEPRECATED SpiderEnv "Use 'SpiderTimelineEnv' instead" #-}
2208−type SpiderEnv = SpiderTimeline