@@ -0,0 +1,70 @@
1+module Reflex.Base where
3+import Control.Concurrent
5+import Control.Monad.IO.Class
6+import Control.Monad.Ref
7+import Data.Dependent.Sum
9+import Data.Functor.Identity
11+import Data.Traversable
13+import Reflex.Host.Class
14+import Reflex.PerformEvent.Base
15+import Reflex.PostBuild.Class
16+import Reflex.Spider.Internal
17+import Reflex.TriggerEvent.Base
19+type ReflexBase x = PostBuildT (SpiderTimeline x) (TriggerEventT (SpiderTimeline x) (PerformEventT (SpiderTimeline x) (SpiderHost x)))
21+-- | Runs a program in a given timeline. Returns the result of the
22+-- program, a firing command for firing events in the program, and the
23+-- thread id for the event firing thread.
24+runReflexBaseForTimeline'
25+ :: HasSpiderTimeline x
27+ -> SpiderTimelineEnv x
28+ -> IO (a, FireCommand (SpiderTimeline x) (SpiderHost x), ThreadId)
29+runReflexBaseForTimeline' basic t = do
31+ (result, FireCommand fire) <-
32+ flip runSpiderHostForTimeline t $ do
33+ (postBuild, postBuildTriggerRef) <- newEventWithTriggerRef
34+ -- Run the various layers of event logic that exist over 'SpiderHost'
35+ results@(_, FireCommand fire) <-
37+ (runTriggerEventT (runPostBuildT basic postBuild) events)
38+ -- Read the trigger's ref, traverse into its 'Maybe', and fire the event
39+ readRef postBuildTriggerRef >>=
41+ (\postBuildTrigger ->
42+ fire [postBuildTrigger :=> Identity ()] $ return ())
44+ -- Start a thread that fires events forever
46+ forkIO . forever $ do
47+ triggers <- readChan events
48+ void . flip runSpiderHostForTimeline t $ do
50+ liftIO . for triggers $ \(EventTriggerRef tref :=> TriggerInvocation a _) ->
51+ fmap (\trigger -> trigger :=> Identity a) <$> readRef tref
52+ void . fire (catMaybes triggersToFire) $ return ()
53+ liftIO . for_ triggers $ \(_ :=> TriggerInvocation _ cb) -> cb
55+ return (result, FireCommand fire, eventThreadId)
57+-- | Like 'runReflexBasic'', but discards the less relevant outputs.
58+runReflexBaseForTimeline
59+ :: HasSpiderTimeline x
60+ => ReflexBase x a -> SpiderTimelineEnv x -> IO a
61+runReflexBaseForTimeline basic =
62+ fmap (\(a, _, _) -> a) . runReflexBaseForTimeline' basic
65+ :: ReflexBase Global a
66+ -> IO (a, FireCommand (SpiderTimeline Global) (SpiderHost Global), ThreadId)
67+runReflexBase' basic = runReflexBaseForTimeline' basic globalSpiderTimelineEnv
69+runReflexBase :: ReflexBase Global a -> IO a
70+runReflexBase basic = runReflexBaseForTimeline basic globalSpiderTimelineEnv