11module Wire.Event where
22
33import Prelude
4- import Control.Alt (class Alt )
5- import Control.Alternative (class Alternative , class Plus )
4+ import Control.Alt (class Alt , alt )
5+ import Control.Alternative (class Alternative , class Plus , empty )
66import Control.Apply (lift2 )
7+ import Control.Monad.Rec.Class (Step (..), tailRecM )
78import Data.Array as Array
8- import Data.Either (either , hush )
9+ import Data.Either (Either (..), either , hush )
910import Data.Filterable (class Compactable , class Filterable , filterMap , partitionMap )
10- import Data.Foldable (class Foldable , sequence_ , traverse_ )
11+ import Data.Foldable (class Foldable , for_ , sequence_ , traverse_ )
1112import Data.Maybe (Maybe (..), fromJust , isJust )
1213import Effect (Effect )
14+ import Effect.Aff (Milliseconds (..))
15+ import Effect.Aff as Aff
16+ import Effect.Class (liftEffect )
1317import Effect.Ref as Ref
1418import Partial.Unsafe (unsafePartial )
1519import Unsafe.Reference (unsafeRefEq )
20+ import Wire.Event.Queue as Queue
1621
1722newtype Event a
18- = Event (Subscribe a )
23+ = Event (Subscriber a -> Effect Canceller )
1924
20- type Subscribe a
21- = ( a -> Effect Unit ) -> Effect Canceler
25+ type Subscriber a
26+ = a -> Effect Unit
2227
23- type Canceler
28+ type Canceller
2429 = Effect Unit
2530
26- create :: forall a . Effect { event :: Event a , push :: a -> Effect Unit }
31+ create :: forall a . Effect { event :: Event a , push :: a -> Effect Unit , cancel :: Effect Unit }
2732create = do
2833 subscribers <- Ref .new []
34+ queue <- Queue .create \a -> Ref .read subscribers >>= traverse_ \k -> k a
2935 let
3036 event =
3137 Event \emit -> do
@@ -36,14 +42,12 @@ create = do
3642 pure do
3743 Ref .write true unsubscribing
3844 Ref .modify_ (Array .deleteBy unsafeRefEq subscriber) subscribers
45+ pure { event, push: (queue.push <<< pure), cancel: queue.kill }
3946
40- push a = Ref .read subscribers >>= traverse_ \emit -> emit a
41- pure { event, push }
42-
43- makeEvent :: forall a . Subscribe a -> Event a
47+ makeEvent :: forall a . (Subscriber a -> Effect Canceller ) -> Event a
4448makeEvent = Event
4549
46- subscribe :: forall a . Event a -> Subscribe a
50+ subscribe :: forall a . Event a -> Subscriber a -> Effect Canceller
4751subscribe (Event event) = event
4852
4953filter :: forall a . (a -> Boolean ) -> Event a -> Event a
@@ -62,16 +66,16 @@ share source = do
6266 shared <- create
6367 let
6468 incrementCount = do
65- count <- Ref .modify (_ + 1 ) subscriberCount
69+ count <- liftEffect do Ref .modify (_ + 1 ) subscriberCount
6670 when (count == 1 ) do
67- cancel <- subscribe source shared.push
68- Ref .write (Just cancel) cancelSource
71+ cancel <- subscribe source do liftEffect <<< shared.push
72+ liftEffect do Ref .write (Just cancel) cancelSource
6973
7074 decrementCount = do
71- count <- Ref .modify (_ - 1 ) subscriberCount
75+ count <- liftEffect do Ref .modify (_ - 1 ) subscriberCount
7276 when (count == 0 ) do
73- Ref .read cancelSource >>= sequence_
74- Ref .write Nothing cancelSource
77+ liftEffect ( Ref .read cancelSource) >>= sequence_
78+ liftEffect do Ref .write Nothing cancelSource
7579
7680 event =
7781 Event \emit -> do
@@ -90,34 +94,72 @@ distinct (Event event) =
9094 Ref .write (pure a) latest
9195 emit a
9296
93- bufferUntil :: forall a b . Event b -> Event a -> Event (Array a )
94- bufferUntil (Event flush) (Event event) =
95- Event \emit -> do
96- buffer <- Ref .new []
97- cancelEvent <- event \a -> Ref .modify_ (flip Array .snoc a) buffer
98- cancelFlush <- flush \_ -> Ref .modify' { state: [] , value: _ } buffer >>= emit
99- pure do cancelEvent *> cancelFlush
97+ bufferUntil :: forall b a . Event b -> Event a -> Event (Array a )
98+ bufferUntil flush source =
99+ alt (Nothing <$ flush) (Just <$> source)
100+ # fold
101+ ( \{ buffer } -> case _ of
102+ Nothing -> { buffer: [] , output: Just buffer }
103+ Just a -> { buffer: Array .snoc buffer a, output: Nothing }
104+ )
105+ { buffer: [] , output: Nothing }
106+ # filterMap _.output
100107
101108fromFoldable :: forall a f . Foldable f => f a -> Event a
102- fromFoldable xs = Event \emit -> traverse_ emit xs *> mempty
109+ fromFoldable xs =
110+ Event \emit -> do
111+ fiber <-
112+ Aff .launchAff do
113+ for_ xs \x -> do
114+ liftEffect do emit x
115+ Aff .delay (Milliseconds 0.0 )
116+ pure do
117+ Aff .launchAff_ do Aff .killFiber (Aff .error " cancelled" ) fiber
118+
119+ range :: Int -> Int -> Event Int
120+ range start end =
121+ Event \emit -> do
122+ let
123+ go pos
124+ | pos /= end = do
125+ liftEffect do emit pos
126+ Aff .delay (Milliseconds 0.0 )
127+ pure (Loop (pos + step))
128+
129+ go _ = do
130+ liftEffect do emit end
131+ pure (Done unit)
132+ fiber <- Aff .launchAff do tailRecM go start
133+ pure do
134+ Aff .launchAff_ do Aff .killFiber (Aff .error " cancelled" ) fiber
135+ where
136+ step = if start < end then 1 else -1
137+
138+ times :: Int -> Event Int
139+ times n
140+ | n > 0 = range 1 n
141+
142+ times _ = empty
103143
104144instance functorEvent :: Functor Event where
105- map f (Event event) = Event \emit -> event \a -> emit (f a)
145+ map f (Event event) =
146+ Event \emit -> do
147+ queue <- Queue .create (emit <<< f)
148+ cancel <- event (queue.push <<< pure)
149+ pure do
150+ cancel
151+ queue.kill
106152
107153instance applyEvent :: Apply Event where
108- apply (Event eventF) (Event eventA) =
109- Event \emitB -> do
110- latestF <- Ref .new Nothing
111- latestA <- Ref .new Nothing
112- cancelF <-
113- eventF \f -> do
114- Ref .write (Just f) latestF
115- Ref .read latestA >>= traverse_ \a -> emitB (f a)
116- cancelA <-
117- eventA \a -> do
118- Ref .write (Just a) latestA
119- Ref .read latestF >>= traverse_ \f -> emitB (f a)
120- pure do cancelF *> cancelA
154+ apply eventF eventA =
155+ alt (Left <$> eventF) (Right <$> eventA)
156+ # fold
157+ ( \{ left, right } -> case _ of
158+ Left l -> { left: Just l, right }
159+ Right r -> { left, right: Just r }
160+ )
161+ { left: Nothing , right: Nothing }
162+ # filterMap (\{ left, right } -> apply left right)
121163
122164instance applicativeEvent :: Applicative Event where
123165 pure a = Event \emit -> emit a *> mempty
@@ -127,10 +169,11 @@ instance bindEvent :: Bind Event where
127169 Event \emit -> do
128170 cancelInner <- Ref .new Nothing
129171 cancelOuter <-
130- outer \a -> do
131- Ref .read cancelInner >>= sequence_
132- cancel <- subscribe (f a) emit
133- Ref .write (Just cancel) cancelInner
172+ outer \a ->
173+ liftEffect do
174+ Ref .read cancelInner >>= sequence_
175+ cancel <- subscribe (f a) emit
176+ Ref .write (Just cancel) cancelInner
134177 pure do
135178 Ref .read cancelInner >>= sequence_
136179 cancelOuter
0 commit comments