1-- | This module defines 'PostBuildT', the standard implementation of
4{-# LANGUAGE DataKinds #-}
5{-# LANGUAGE FlexibleInstances #-}
6{-# LANGUAGE GeneralizedNewtypeDeriving #-}
7{-# LANGUAGE MultiParamTypeClasses #-}
8{-# LANGUAGE RankNTypes #-}
9{-# LANGUAGE RecursiveDo #-}
10{-# LANGUAGE ScopedTypeVariables #-}
11{-# LANGUAGE TypeFamilies #-}
12{-# LANGUAGE TypeOperators #-}
13{-# LANGUAGE UndecidableInstances #-}
14#ifdef USE_REFLEX_OPTIMIZER
15{-# OPTIONS_GHC -fplugin=Reflex.Optimizer #-}
17module Reflex.PostBuild.Base
21 , mapIntMapWithAdjustImpl
22 , mapDMapWithAdjustImpl
26import Reflex.Host.Class
27import Reflex.PerformEvent.Class
28import Reflex.PostBuild.Class
29import Reflex.TriggerEvent.Class
31import Control.Monad.Exception
32import Control.Monad.Identity
33import Control.Monad.Primitive
34import Control.Monad.Reader
35import Control.Monad.Ref
36import qualified Control.Monad.Trans.Control as TransControl
37import Data.Dependent.Map (DMap)
38import qualified Data.Dependent.Map as DMap
39import Data.Functor.Compose
40import Data.IntMap.Strict (IntMap)
41import qualified Data.IntMap.Strict as IntMap
43-- | Provides a basic implementation of 'PostBuild'.
44newtype PostBuildT t m a = PostBuildT { unPostBuildT :: ReaderT (Event t ()) m a } deriving (Functor, Applicative, Monad, MonadFix, MonadIO, MonadTrans, MonadException, MonadAsyncException)
46-- | Run a 'PostBuildT' action. An 'Event' should be provided that fires
47-- immediately after the action is finished running; no other 'Event's should
49{-# INLINABLE runPostBuildT #-}
50runPostBuildT :: PostBuildT t m a -> Event t () -> m a
51runPostBuildT (PostBuildT a) = runReaderT a
53instance PrimMonad m => PrimMonad (PostBuildT x m) where
54 type PrimState (PostBuildT x m) = PrimState m
55 primitive = lift . primitive
57instance (Reflex t, Monad m) => PostBuild t (PostBuildT t m) where
58 {-# INLINABLE getPostBuild #-}
59 getPostBuild = PostBuildT ask
61instance MonadSample t m => MonadSample t (PostBuildT t m) where
62 {-# INLINABLE sample #-}
63 sample = lift . sample
65instance MonadHold t m => MonadHold t (PostBuildT t m) where
66 {-# INLINABLE hold #-}
67 hold v0 = lift . hold v0
68 {-# INLINABLE holdDyn #-}
69 holdDyn v0 = lift . holdDyn v0
70 {-# INLINABLE holdIncremental #-}
71 holdIncremental v0 = lift . holdIncremental v0
72 {-# INLINABLE buildDynamic #-}
73 buildDynamic a0 = lift . buildDynamic a0
74 {-# INLINABLE headE #-}
77instance PerformEvent t m => PerformEvent t (PostBuildT t m) where
78 type Performable (PostBuildT t m) = Performable m
79 {-# INLINABLE performEvent_ #-}
80 performEvent_ = lift . performEvent_
81 {-# INLINABLE performEvent #-}
82 performEvent = lift . performEvent
84instance (ReflexHost t, MonadReflexCreateTrigger t m) => MonadReflexCreateTrigger t (PostBuildT t m) where
85 {-# INLINABLE newEventWithTrigger #-}
86 newEventWithTrigger = PostBuildT . lift . newEventWithTrigger
87 {-# INLINABLE newFanEventWithTrigger #-}
88 newFanEventWithTrigger f = PostBuildT $ lift $ newFanEventWithTrigger f
90instance TriggerEvent t m => TriggerEvent t (PostBuildT t m) where
91 {-# INLINABLE newTriggerEvent #-}
92 newTriggerEvent = lift newTriggerEvent
93 {-# INLINABLE newTriggerEventWithOnComplete #-}
94 newTriggerEventWithOnComplete = lift newTriggerEventWithOnComplete
95 newEventWithLazyTriggerWithOnComplete = lift . newEventWithLazyTriggerWithOnComplete
97instance MonadRef m => MonadRef (PostBuildT t m) where
98 type Ref (PostBuildT t m) = Ref m
99 {-# INLINABLE newRef #-}
100 newRef = lift . newRef
101 {-# INLINABLE readRef #-}
102 readRef = lift . readRef
103 {-# INLINABLE writeRef #-}
104 writeRef r = lift . writeRef r
106instance MonadAtomicRef m => MonadAtomicRef (PostBuildT t m) where
107 {-# INLINABLE atomicModifyRef #-}
108 atomicModifyRef r = lift . atomicModifyRef r
110instance (Reflex t, MonadHold t m, MonadFix m, MonadAdjust t m, PerformEvent t m) => MonadAdjust t (PostBuildT t m) where
111 runWithReplace a0 a' = do
112 postBuild <- getPostBuild
114 rec result@(_, result') <- runWithReplace (runPostBuildT a0 postBuild) $ fmap (\v -> runPostBuildT v =<< headE voidResult') a'
115 let voidResult' = fmapCheap (\_ -> ()) result'
117 {-# INLINABLE traverseIntMapWithKeyWithAdjust #-}
118 traverseIntMapWithKeyWithAdjust = mapIntMapWithAdjustImpl traverseIntMapWithKeyWithAdjust
119 {-# INLINABLE traverseDMapWithKeyWithAdjust #-}
120 traverseDMapWithKeyWithAdjust = mapDMapWithAdjustImpl traverseDMapWithKeyWithAdjust mapPatchDMap
121 traverseDMapWithKeyWithAdjustWithMove = mapDMapWithAdjustImpl traverseDMapWithKeyWithAdjustWithMove mapPatchDMapWithMove
123{-# INLINABLE mapIntMapWithAdjustImpl #-}
124mapIntMapWithAdjustImpl :: forall t m v v' p. (Reflex t, MonadFix m, MonadHold t m, Functor p)
125 => ( (IntMap.Key -> (Event t (), v) -> m v')
126 -> IntMap (Event t (), v)
127 -> Event t (p (Event t (), v))
128 -> m (IntMap v', Event t (p v'))
130 -> (IntMap.Key -> v -> PostBuildT t m v')
133 -> PostBuildT t m (IntMap v', Event t (p v'))
134mapIntMapWithAdjustImpl base f dm0 dm' = do
135 postBuild <- getPostBuild
136 let loweredDm0 = fmap ((,) postBuild) dm0
137 f' :: IntMap.Key -> (Event t (), v) -> m v'
139 runPostBuildT (f k v) e
141 rec (result0, result') <- base f' loweredDm0 loweredDm'
142 cohortDone <- numberOccurrencesFrom_ 1 result'
143 numberedDm' <- numberOccurrencesFrom 1 dm'
144 let postBuild' = fanInt $ fmapCheap (\n -> IntMap.singleton n ()) cohortDone
145 loweredDm' = flip pushAlways numberedDm' $ \(n, p) -> do
146 return $ fmap ((,) (selectInt postBuild' n)) p
147 return (result0, result')
149{-# INLINABLE mapDMapWithAdjustImpl #-}
150mapDMapWithAdjustImpl :: forall t m k v v' p. (Reflex t, MonadFix m, MonadHold t m)
151 => ( (forall a. k a -> Compose ((,) (Bool, Event t ())) v a -> m (v' a))
152 -> DMap k (Compose ((,) (Bool, Event t ())) v)
153 -> Event t (p k (Compose ((,) (Bool, Event t ())) v))
154 -> m (DMap k v', Event t (p k v'))
156 -> ((forall a. v a -> Compose ((,) (Bool, Event t ())) v a) -> p k v -> p k (Compose ((,) (Bool, Event t ())) v))
157 -> (forall a. k a -> v a -> PostBuildT t m (v' a))
160 -> PostBuildT t m (DMap k v', Event t (p k v'))
161mapDMapWithAdjustImpl base mapPatch f dm0 dm' = do
162 postBuild <- getPostBuild
163 let loweredDm0 = DMap.map (Compose . (,) (False, postBuild)) dm0
164 f' :: forall a. k a -> Compose ((,) (Bool, Event t ())) v a -> m (v' a)
165 f' k (Compose ((shouldHeadE, e), v)) = do
166 eOnce <- if shouldHeadE
167 then headE e --TODO: Avoid doing this headE so many times; once per loweredDm' firing ought to be OK, but it's not totally trivial to do because result' might be firing at the same time, and we don't want *that* to be the postBuild occurrence
169 runPostBuildT (f k v) eOnce
171 rec (result0, result') <- base f' loweredDm0 loweredDm'
172 let voidResult' = fmapCheap (\_ -> ()) result'
173 let loweredDm' = ffor dm' $ mapPatch (Compose . (,) (True, voidResult'))
174 return (result0, result')
176--------------------------------------------------------------------------------
177-- Deprecated functionality
178--------------------------------------------------------------------------------
181instance TransControl.MonadTransControl (PostBuildT t) where
182 type StT (PostBuildT t) a = TransControl.StT (ReaderT (Event t ())) a
183 {-# INLINABLE liftWith #-}
184 liftWith = TransControl.defaultLiftWith PostBuildT unPostBuildT
185 {-# INLINABLE restoreT #-}
186 restoreT = TransControl.defaultRestoreT PostBuildT
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list