on develop help sign in
Moves PerformEvent to reflex.
commitdecca155481837fd4a01d2dbbe6ebf90505deee0 authorDave Laing <dave.laing.80@gmail.com> dateSun 14 Aug 2016, 14:32 (10 years ago) parentd004730
18 files changed+24−241
reflex-dom.cabal−2 src/Foreign/JavaScript/TH.hs+10−1 src/Reflex/Dom.hs−1 src/Reflex/Dom/Builder/Immediate.hs+1−1 src/Reflex/Dom/Builder/Static.hs+2−2 src/Reflex/Dom/Class.hs+1−1 src/Reflex/Dom/DynamicWriter.hs+1−1 src/Reflex/Dom/Internal.hs+1−1 src/Reflex/Dom/Old.hs+1−1 src/Reflex/Dom/PerformEvent/Base.hs−177 src/Reflex/Dom/PerformEvent/Class.hs−46 src/Reflex/Dom/PostBuild/Class.hs+1−1 src/Reflex/Dom/Time.hs+1−1 src/Reflex/Dom/WebSocket.hs+1−1 src/Reflex/Dom/Widget/Input.hs+1−1 src/Reflex/Dom/Widget/Lazy.hs+1−1 src/Reflex/Dom/Widget/Resize.hs+1−1 src/Reflex/Dom/Xhr.hs+1−1
reflex-dom.cabal−2
@@ -84,8 +84,6 @@ library
8484 Reflex.Dom.Internal
8585 Reflex.Dom.Internal.Foreign
8686 Reflex.Dom.Location
87− Reflex.Dom.PerformEvent.Base
88− Reflex.Dom.PerformEvent.Class
8987 Reflex.Dom.PostBuild.Class
9088 Reflex.Dom.Old
9189 Reflex.Dom.Time
src/Foreign/JavaScript/TH.hs+10−1
@@ -22,7 +22,8 @@ module Foreign.JavaScript.TH ( module Foreign.JavaScript.TH
2222
2323import Reflex.Class
2424import Reflex.Deletable.Class
25−import Reflex.Dom.PerformEvent.Class
25+import Reflex.PerformEvent.Base
26+import Reflex.PerformEvent.Class
2627import Reflex.Host.Class
2728
2829import Language.Haskell.TH
@@ -94,6 +95,10 @@ instance HasWebView m => HasWebView (Strict.StateT r m) where
9495 type WebViewPhantom (Strict.StateT r m) = WebViewPhantom m
9596 askWebView = lift askWebView
9697
98+instance (ReflexHost t, HasWebView (HostFrame t)) => HasWebView (PerformEventT t m) where
99+ type WebViewPhantom (PerformEventT t m) = WebViewPhantom (HostFrame t)
100+ askWebView = PerformEventT $ lift askWebView
101+
97102newtype WithWebView x m a = WithWebView { unWithWebView :: ReaderT (WebViewSingleton x) m a } deriving (Functor, Applicative, Monad, MonadIO, MonadFix, MonadTrans, MonadException, MonadAsyncException)
98103
99104instance MonadReflexCreateTrigger t m => MonadReflexCreateTrigger t (WithWebView x m) where
@@ -191,6 +196,10 @@ instance HasJS x m => HasJS x (ReaderT r m) where
191196 type JSM (ReaderT r m) = JSM m
192197 liftJS = lift . liftJS
193198
199+instance (HasJS x (HostFrame t), ReflexHost t) => HasJS x (PerformEventT t m) where
200+ type JSM (PerformEventT t m) = JSM (HostFrame t)
201+ liftJS = PerformEventT . lift . liftJS
202+
194203-- | A Monad that is capable of executing JavaScript
195204class Monad m => MonadJS x m | m -> x where
196205 runJS :: JSFFI -> [JSRef x] -> m (JSRef x)
src/Reflex/Dom.hs−1
@@ -9,7 +9,6 @@ import Reflex.Dom.DynamicWriter as X
99import Reflex.Dom.Internal as X
1010import Reflex.Dom.Location as X
1111import Reflex.Dom.Old as X
12−import Reflex.Dom.PerformEvent.Class as X
1312import Reflex.Dom.PostBuild.Class as X
1413import Reflex.Dom.Time as X
1514import Reflex.Dom.WebSocket as X
src/Reflex/Dom/Builder/Immediate.hs+1−1
@@ -19,7 +19,7 @@ module Reflex.Dom.Builder.Immediate where
1919import Foreign.JavaScript.TH
2020import Reflex
2121import Reflex.Dom.Builder.Class
22−import Reflex.Dom.PerformEvent.Class
22+import Reflex.PerformEvent.Class
2323import Reflex.Dom.PostBuild.Class
2424import Reflex.Host.Class
2525
src/Reflex/Dom/Builder/Static.hs+2−2
@@ -34,8 +34,8 @@ import Data.Text.Encoding
3434import GHC.Generics
3535import Reflex
3636import Reflex.Dom.Builder.Class
37−import Reflex.Dom.PerformEvent.Base
38−import Reflex.Dom.PerformEvent.Class
37+import Reflex.PerformEvent.Base
38+import Reflex.PerformEvent.Class
3939import Reflex.Dom.PostBuild.Class
4040import Reflex.Dom.Widget.Basic (applyMap)
4141import Reflex.Host.Class
src/Reflex/Dom/Class.hs+1−1
@@ -10,7 +10,7 @@ import Reflex.Class
1010import Web.KeyCode
1111
1212import Foreign.JavaScript.TH
13−import Reflex.Dom.PerformEvent.Class
13+import Reflex.PerformEvent.Class
1414import Reflex.Dom.PostBuild.Class
1515
1616import Prelude hiding (concat, mapM, mapM_, sequence)
src/Reflex/Dom/DynamicWriter.hs+1−1
@@ -29,7 +29,7 @@ import Data.Traversable
2929import Reflex
3030import Reflex.Dom.Builder.Class
3131import Reflex.Dom.Class
32−import Reflex.Dom.PerformEvent.Class
32+import Reflex.PerformEvent.Class
3333import Reflex.Dom.PostBuild.Class
3434import Reflex.Host.Class
3535
src/Reflex/Dom/Internal.hs+1−1
@@ -18,7 +18,7 @@ import Prelude hiding (concat, mapM, mapM_, sequence, sequence_)
1818import Reflex.Dom.Builder.Immediate
1919import Reflex.Dom.Class
2020import Reflex.Dom.Internal.Foreign
21−import Reflex.Dom.PerformEvent.Base
21+import Reflex.PerformEvent.Base
2222import Reflex.Dom.PostBuild.Class
2323import Reflex.Host.Class
2424import Reflex.Spider (Global, Spider, SpiderHost, runSpiderHost)
src/Reflex/Dom/Old.hs+1−1
@@ -67,7 +67,7 @@ import Reflex
6767import Reflex.Dom.Builder.Class
6868import Reflex.Dom.Builder.Immediate
6969import Reflex.Dom.Internal.Foreign
70−import Reflex.Dom.PerformEvent.Class
70+import Reflex.PerformEvent.Class
7171import Reflex.Dom.PostBuild.Class
7272import Reflex.Dom.Widget.Basic
7373import Reflex.Host.Class
src/Reflex/Dom/PerformEvent/Base.hsdeleted−177
@@ -1,177 +0,0 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE FlexibleInstances #-}
3−{-# LANGUAGE GeneralizedNewtypeDeriving #-}
4−{-# LANGUAGE MultiParamTypeClasses #-}
5−{-# LANGUAGE RankNTypes #-}
6−{-# LANGUAGE RecursiveDo #-}
7−{-# LANGUAGE ScopedTypeVariables #-}
8−{-# LANGUAGE StandaloneDeriving #-}
9−{-# LANGUAGE TypeFamilies #-}
10−{-# LANGUAGE TypeOperators #-}
11−{-# LANGUAGE UndecidableInstances #-}
12−module Reflex.Dom.PerformEvent.Base where
13−
14−import Foreign.JavaScript.TH
15−import Reflex
16−import Reflex.Deletable.Class
17−import Reflex.Dom.PerformEvent.Class
18−import Reflex.Host.Class
19−
20−import Control.Lens
21−import Control.Monad.Exception
22−import Control.Monad.Identity
23−import Control.Monad.Ref
24−import Control.Monad.State.Strict
25−import Data.Align
26−import Data.Dependent.Map (DMap)
27−import qualified Data.Dependent.Map as DMap
28−import Data.Dependent.Sum
29−import Data.Functor.Compose
30−import Data.Functor.Misc
31−import Data.Maybe
32−import Data.Semigroup
33−import Data.These
34−import Data.Word
35−
36−newtype EventTriggerRef t m a = EventTriggerRef { unEventTriggerRef :: Ref m (Maybe (EventTrigger t a)) }
37−
38−newtype FireCommand t m = FireCommand { runFireCommand :: forall a. [DSum (EventTrigger t) Identity] -> ReadPhase m a -> m [a] } --TODO: The handling of this ReadPhase seems wrong, or at least inelegant; how do we actually make the decision about what order frames run in?
39−
40−newtype PerformEventT t m a = PerformEventT { unPerformEventT :: StateT [Event t (These (PerformEventT t m [DSum (EventTriggerRef t m) Identity]) ())] (HostFrame t) a }
41−
42−deriving instance ReflexHost t => Functor (PerformEventT t m)
43−deriving instance ReflexHost t => Applicative (PerformEventT t m)
44−deriving instance ReflexHost t => Monad (PerformEventT t m)
45−deriving instance ReflexHost t => MonadFix (PerformEventT t m)
46−deriving instance (ReflexHost t, MonadIO (HostFrame t)) => MonadIO (PerformEventT t m)
47−deriving instance (ReflexHost t, MonadException (HostFrame t)) => MonadException (PerformEventT t m)
48−
49−instance (ReflexHost t, MonadAsyncException (HostFrame t)) => MonadAsyncException (PerformEventT t m) where
50− mask f = PerformEventT $ mask $ \unmask -> unPerformEventT $ f $ PerformEventT . unmask . unPerformEventT
51−
52−instance (ReflexHost t, HasWebView (HostFrame t)) => HasWebView (PerformEventT t m) where
53− type WebViewPhantom (PerformEventT t m) = WebViewPhantom (HostFrame t)
54− askWebView = PerformEventT $ lift askWebView
55−
56−instance (ReflexHost t, Ref m ~ Ref IO, MonadRef (HostFrame t), Ref (HostFrame t) ~ Ref IO) => PerformEvent t (PerformEventT t m) where
57− type Performable (PerformEventT t m) = PerformEventT t m
58− {-# INLINABLE performEvent_ #-}
59− performEvent_ = PerformEventT . modify . (:) . fmap (This . (>> return []))
60− {-# INLINABLE performEvent #-}
61− performEvent e = PerformEventT $ do
62− (eResult, reResultTrigger) <- newEventWithTriggerRef
63− modify $ (:) $ ffor e $ \o -> This $ do
64− result <- o
65− return [EventTriggerRef reResultTrigger :=> Identity result]
66− return eResult
67−
68−instance (ReflexHost t, Monad (HostFrame t), Ref (HostFrame t) ~ Ref IO, Ref m ~ Ref IO) => Deletable t (PerformEventT t m) where
69− {-# INLINABLE deletable #-}
70− deletable d a = PerformEventT $ do
71− (result, reverseEventsToPerform) <- lift $ runStateT (unPerformEventT a) []
72− let (numberedEvents, _) = numberWith (\n e -> Const2 n :=> e) (reverse reverseEventsToPerform) (1 :: Word64)
73− eventToPerform <- lift $ mergePerformEventsAndAdd (DMap.fromList numberedEvents) never
74− modify (align eventToPerform d :)
75− return result
76−
77−instance ReflexHost t => MonadReflexCreateTrigger t (PerformEventT t m) where
78− {-# INLINABLE newEventWithTrigger #-}
79− newEventWithTrigger = PerformEventT . lift . newEventWithTrigger
80− {-# INLINABLE newFanEventWithTrigger #-}
81− newFanEventWithTrigger f = PerformEventT $ lift $ newFanEventWithTrigger f
82−
83−{-# INLINABLE numberWith #-}
84−numberWith :: (Enum n, Traversable t) => (n -> a -> b) -> t a -> n -> (t b, n)
85−numberWith f t n0 = flip runState n0 $ forM t $ \x -> state $ \n -> (f n x, succ n)
86−
87−{-# INLINABLE mergePerformEventsAndAdd #-}
88−mergePerformEventsAndAdd :: forall t m. ReflexHost t
89− => DMap (Const2 Word64 (These (PerformEventT t m [DSum (EventTriggerRef t m) Identity]) ())) (Event t)
90− -> Event t (PatchDMap (DMap (Const2 Word64 (These (PerformEventT t m [DSum (EventTriggerRef t m) Identity]) ())) (Event t)))
91− -> HostFrame t (Event t (PerformEventT t m [DSum (EventTriggerRef t m) Identity]))
92−mergePerformEventsAndAdd initial eAddNew = do
93− rec events :: Incremental t PatchDMap (DMap (Const2 Word64 (These (PerformEventT t m [DSum (EventTriggerRef t m) Identity]) ())) (Event t))
94− <- holdIncremental initial $ eAddNew <> eDelete --TODO: Eliminate empty firings
95− let event = mergeWith DMap.union [mergeIncremental events, coincidence (fmap (\(PatchDMap m) -> merge $ DMap.mapMaybeWithKey (const getCompose) m) eAddNew)]
96− eventToPerform :: Event t (PerformEventT t m [DSum (EventTriggerRef t m) Identity])
97− eventToPerform = ffor event $
98− fmap concat .
99− sequence .
100− fmapMaybe (\(Const2 _ :=> Identity x) -> x ^? here) .
101− DMap.toList
102− eDelete :: Event t (PatchDMap (DMap (Const2 Word64 (These (PerformEventT t m [DSum (EventTriggerRef t m) Identity]) ())) (Event t)))
103− eDelete = fforMaybe event $
104− fmap (PatchDMap . DMap.fromList) .
105− (\l -> if null l then Nothing else Just l) .
106− fmapMaybe (\(Const2 k :=> Identity x) -> (Const2 k :=> Compose Nothing) <$ x ^? there) .
107− DMap.toList
108− return eventToPerform
109−
110−{-# INLINABLE runPerformEventT #-}
111−runPerformEventT :: forall t m a. (ReflexHost t, MonadRef (HostFrame t), Ref (HostFrame t) ~ Ref IO, Ref m ~ Ref IO) => PerformEventT t m a -> HostFrame t (a, Event t (HostFrame t [DSum (EventTriggerRef t m) Identity]))
112−runPerformEventT (PerformEventT a) = do
113− (result, reverseEventsToPerform) <- runStateT a []
114− (eAddNew, reAddNewTrigger) <- newEventWithTriggerRef
115− let (numberedEvents, nextNumber) = numberWith (\n e -> Const2 n :=> e) (reverse reverseEventsToPerform) (1 :: Word64)
116− nextNumberRef <- newRef nextNumber
117− let runResult :: PerformEventT t m [DSum (EventTriggerRef t m) Identity] -> HostFrame t [DSum (EventTriggerRef t m) Identity]
118− runResult (PerformEventT r) = do
119− (followups, reverseNewEventsToPerform) <- runStateT r []
120− oldN <- readRef nextNumberRef
121− let (numberedNewEvents, newN) = numberWith (\n e -> Const2 n :=> Compose (Just e)) (reverse reverseNewEventsToPerform) oldN
122− if newN == oldN then return followups else do
123− writeRef nextNumberRef newN
124− return $ (EventTriggerRef reAddNewTrigger :=> Identity (PatchDMap (DMap.fromList numberedNewEvents))) : followups
125− eventToPerform <- mergePerformEventsAndAdd (DMap.fromList numberedEvents) eAddNew
126− return (result, runResult <$> eventToPerform)
127−
128−{-# INLINABLE hostPerformEventT #-}
129−hostPerformEventT :: forall t m a. (Monad m, MonadSubscribeEvent t m, MonadReflexHost t m, MonadRef m, Ref m ~ Ref IO, MonadRef (HostFrame t), Ref (HostFrame t) ~ Ref IO) => PerformEventT t m a -> m (a, FireCommand t m)
130−hostPerformEventT a = do
131− (result, eventToPerform) <- runHostFrame $ runPerformEventT a
132− eventToPerformHandle <- subscribeEvent eventToPerform
133− return $ (,) result $ FireCommand $ \triggers (readPhase :: ReadPhase m a') -> do
134− let go :: [DSum (EventTrigger t) Identity] -> m [a']
135− go ts = do
136− (result', mToPerform) <- fireEventsAndRead ts $ do
137− mToPerform <- sequence =<< readEvent eventToPerformHandle
138− result' <- readPhase
139− return (result', mToPerform)
140− case mToPerform of
141− Nothing -> return [result']
142− Just toPerform -> do
143− followupEventTriggerRefs <- runHostFrame toPerform
144− followupEventTriggers <- forM followupEventTriggerRefs $ \(EventTriggerRef rt :=> x) -> do
145− mt <- readRef rt
146− return $ fmap (:=> x) mt
147− fmap (result':) $ go $ catMaybes followupEventTriggers
148− go triggers
149−
150−instance ReflexHost t => MonadSample t (PerformEventT t m) where
151− {-# INLINABLE sample #-}
152− sample = PerformEventT . lift . sample
153−
154−instance (ReflexHost t, MonadHold t m) => MonadHold t (PerformEventT t m) where
155− {-# INLINABLE hold #-}
156− hold v0 v' = PerformEventT $ lift $ hold v0 v'
157− {-# INLINABLE holdDyn #-}
158− holdDyn v0 v' = PerformEventT $ lift $ holdDyn v0 v'
159− {-# INLINABLE holdIncremental #-}
160− holdIncremental v0 v' = PerformEventT $ lift $ holdIncremental v0 v'
161−
162−instance (MonadRef (HostFrame t), ReflexHost t) => MonadRef (PerformEventT t m) where
163− type Ref (PerformEventT t m) = Ref (HostFrame t)
164− {-# INLINABLE newRef #-}
165− newRef = PerformEventT . lift . newRef
166− {-# INLINABLE readRef #-}
167− readRef = PerformEventT . lift . readRef
168− {-# INLINABLE writeRef #-}
169− writeRef r = PerformEventT . lift . writeRef r
170−
171−instance (MonadAtomicRef (HostFrame t), ReflexHost t) => MonadAtomicRef (PerformEventT t m) where
172− {-# INLINABLE atomicModifyRef #-}
173− atomicModifyRef r = PerformEventT . lift . atomicModifyRef r
174−
175−instance (HasJS x (HostFrame t), ReflexHost t) => HasJS x (PerformEventT t m) where
176− type JSM (PerformEventT t m) = JSM (HostFrame t)
177− liftJS = PerformEventT . lift . liftJS
src/Reflex/Dom/PerformEvent/Class.hsdeleted−46
@@ -1,46 +0,0 @@
1−{-# LANGUAGE FlexibleContexts #-}
2−{-# LANGUAGE FlexibleInstances #-}
3−{-# LANGUAGE FunctionalDependencies #-}
4−{-# LANGUAGE MultiParamTypeClasses #-}
5−{-# LANGUAGE RankNTypes #-}
6−{-# LANGUAGE ScopedTypeVariables #-}
7−{-# LANGUAGE TypeFamilies #-}
8−{-# LANGUAGE TypeOperators #-}
9−{-# LANGUAGE UndecidableInstances #-}
10−module Reflex.Dom.PerformEvent.Class where
11−
12−import Reflex
13−
14−import Control.Monad.Reader
15−
16−class (Reflex t, Monad (Performable m), Monad m) => PerformEvent t m | m -> t where
17− type Performable m :: * -> *
18− performEvent :: Event t (Performable m a) -> m (Event t a)
19− performEvent_ :: Event t (Performable m ()) -> m ()
20−
21−--TODO: Shouldn't have IO hard-coded
22−class Monad m => TriggerEvent t m | m -> t where
23− newTriggerEvent :: m (Event t a, a -> IO ())
24− newTriggerEventWithOnComplete :: m (Event t a, a -> IO () -> IO ()) --TODO: This and newTriggerEvent should be unified somehow
25− newEventWithLazyTriggerWithOnComplete :: ((a -> IO () -> IO ()) -> IO (IO ())) -> m (Event t a)
26−
27−{-# INLINABLE performEventAsync #-}
28−performEventAsync :: (TriggerEvent t m, PerformEvent t m) => Event t ((a -> IO ()) -> Performable m ()) -> m (Event t a)
29−performEventAsync e = do
30− (eOut, triggerEOut) <- newTriggerEvent
31− performEvent_ $ fmap ($ triggerEOut) e
32− return eOut
33−
34−instance PerformEvent t m => PerformEvent t (ReaderT r m) where
35− type Performable (ReaderT r m) = ReaderT r (Performable m)
36− performEvent_ e = do
37− r <- ask
38− lift $ performEvent_ $ flip runReaderT r <$> e
39− performEvent e = do
40− r <- ask
41− lift $ performEvent $ flip runReaderT r <$> e
42−
43−instance TriggerEvent t m => TriggerEvent t (ReaderT r m) where
44− newTriggerEvent = lift newTriggerEvent
45− newTriggerEventWithOnComplete = lift newTriggerEventWithOnComplete
46− newEventWithLazyTriggerWithOnComplete = lift . newEventWithLazyTriggerWithOnComplete
src/Reflex/Dom/PostBuild/Class.hs+1−1
@@ -18,7 +18,7 @@ import Control.Monad.Trans.Control
1818import Foreign.JavaScript.TH
1919import Reflex
2020import Reflex.Dom.Builder.Class
21−import Reflex.Dom.PerformEvent.Class
21+import Reflex.PerformEvent.Class
2222import Reflex.Host.Class
2323
2424class (Reflex t, Monad m) => PostBuild t m | m -> t where
src/Reflex/Dom/Time.hs+1−1
@@ -7,7 +7,7 @@
77module Reflex.Dom.Time where
88
99import Reflex
10−import Reflex.Dom.PerformEvent.Class
10+import Reflex.PerformEvent.Class
1111import Reflex.Dom.PostBuild.Class
1212
1313import Control.Concurrent
src/Reflex/Dom/WebSocket.hs+1−1
@@ -25,7 +25,7 @@ import Prelude hiding (all, concat, concatMap, div, mapM, mapM_, sequence, span)
2525
2626import Reflex
2727import Reflex.Dom.Class
28−import Reflex.Dom.PerformEvent.Class
28+import Reflex.PerformEvent.Class
2929import Reflex.Dom.PostBuild.Class
3030import Reflex.Dom.WebSocket.Foreign
3131
src/Reflex/Dom/Widget/Input.hs+1−1
@@ -43,7 +43,7 @@ import Reflex
4343import Reflex.Dom.Builder.Class
4444import Reflex.Dom.Builder.Immediate
4545import Reflex.Dom.Class
46−import Reflex.Dom.PerformEvent.Class
46+import Reflex.PerformEvent.Class
4747import Reflex.Dom.PostBuild.Class
4848import Reflex.Dom.Widget.Basic
4949import qualified Text.Read as T
src/Reflex/Dom/Widget/Lazy.hs+1−1
@@ -10,7 +10,7 @@ import Reflex
1010import Reflex.Dom.Builder.Class
1111import Reflex.Dom.Builder.Immediate
1212import Reflex.Dom.Class
13−import Reflex.Dom.PerformEvent.Class
13+import Reflex.PerformEvent.Class
1414import Reflex.Dom.PostBuild.Class
1515import Reflex.Dom.Widget.Basic
1616
src/Reflex/Dom/Widget/Resize.hs+1−1
@@ -9,7 +9,7 @@ import Reflex
99import Reflex.Dom.Builder.Class
1010import Reflex.Dom.Builder.Immediate
1111import Reflex.Dom.Class
12−import Reflex.Dom.PerformEvent.Class
12+import Reflex.PerformEvent.Class
1313import Reflex.Dom.PostBuild.Class
1414import Reflex.Dom.Widget.Basic
1515
src/Reflex/Dom/Xhr.hs+1−1
@@ -57,7 +57,7 @@ where
5757
5858import Reflex
5959import Reflex.Dom.Class
60−import Reflex.Dom.PerformEvent.Class
60+import Reflex.PerformEvent.Class
6161import Reflex.Dom.Xhr.Exception
6262import Reflex.Dom.Xhr.Foreign
6363import Reflex.Dom.Xhr.ResponseType