0 | module FS.Concurrent.Signal
2 | import public Data.Linear.Sink
3 | import Data.Linear.Deferred
4 | import Data.Linear.Ref1
5 | import Data.Linear.Traverse1
6 | import Data.List.Quantifiers.Extra
22 | listeners : List (Once World (a,Nat))
25 | putImpl : a -> ST a -> (ST a, IO1 ())
26 | putImpl v (SS _ lst []) = (SS v (S lst) [], (() # ))
27 | putImpl v (SS _ lst ls) =
29 | in (SS v n [], traverse1_ (\o => putOnce1 o (v,n)) ls)
32 | updImpl : (a -> (a,b)) -> ST a -> (ST a, IO1 b)
33 | updImpl f (SS cur lst ls) =
37 | , \t => let _ # t := traverse1_ (\o => putOnce1 o (v,n)) ls t in r # t
41 | nextImpl : Nat -> Once World (a,Nat) -> ST a -> (ST a, Async e es (a,Nat))
42 | nextImpl last once st@(SS v lst ls) =
44 | False => (st, pure (v,lst))
45 | True => (SS v lst (once :: ls), awaitOnce once)
48 | record SignalRef a where
51 | ref : Ref World (ST a)
55 | signal : Lift1 World f => a -> f (SignalRef a)
56 | signal v = SR <$> newref (SS v 1 [])
60 | get : Lift1 World f => SignalRef a -> f a
61 | get (SR ref) = value <$> readref ref
65 | put1 : SignalRef a -> (v : a) -> IO1 ()
67 | let act # t := casupdate1 ref (putImpl v) t
72 | put : Lift1 World f => SignalRef a -> (v : a) -> f ()
73 | put r = lift1 . put1 r
78 | update1 : SignalRef a -> (g : a -> (a,b)) -> IO1 b
79 | update1 (SR ref) g t =
80 | let act # t := casupdate1 ref (updImpl g) t
85 | update : Lift1 World f => SignalRef a -> (g : a -> (a,b)) -> f b
86 | update r = lift1 . update1 r
90 | modify1 : SignalRef a -> (g : a -> a) -> IO1 ()
91 | modify1 s g = update1 s (\v => (g v, ()))
95 | modify : Lift1 World f => SignalRef a -> (g : a -> a) -> f ()
96 | modify r = lift1 . modify1 r
100 | updateAndGet1 : SignalRef a -> (g : a -> a) -> IO1 a
101 | updateAndGet1 s g = update1 s (\v => let w := g v in (w,w))
105 | updateAndGet : Lift1 World f => SignalRef a -> (g : a -> a) -> f a
106 | updateAndGet r = lift1 . updateAndGet1 r
115 | next : SignalRef a -> Nat -> Async e es (a,Nat)
116 | next (SR ref) n = do
117 | def <- onceOf (a,Nat)
118 | act <- update ref (nextImpl n def)
122 | signalSink : SignalRef t -> Sink t
123 | signalSink r = S (put1 r)
126 | interface Reference (0 t : Type -> Type) where
127 | current1 : t a -> IO1 a
130 | current : LIO f => Reference t => t a -> f a
131 | current = lift1 . current1
134 | Reference IORef where
138 | Reference SignalRef where
139 | current1 = ioToF1 . get
145 | continuous : LIO (f es) => Reference t => t a -> Stream f es a
146 | continuous = repeat . eval . current
149 | interface Discrete (0 t : Type -> Type) where
160 | discrete : t a -> Stream (Async e) es a
163 | Discrete SignalRef where
164 | discrete s = unfoldEval 0 (map (uncurry More) . next s)
167 | Discrete (Once World) where
168 | discrete = eval . awaitOnce
171 | Discrete (Deferred World) where
172 | discrete = eval . await
178 | justs : Discrete t => t (Maybe a) -> Stream (Async e) es a
179 | justs s = discrete s |> catMaybes
184 | until : Discrete f => f a -> (a -> Bool) -> Async e [] ()
185 | until ref pred = assert_total $
discrete ref |> any pred |> drain |> mpull
189 | onChange : Eq b => Discrete f => f a -> (a -> b) -> Stream (Async e) es b
190 | onChange s f = discrete s |> mapOutput f |> distinct
196 | parameters {0 f : List Type -> Type -> Type}
199 | {auto lio : LIO (f es)}
200 | (sig : SignalRef p)
204 | modSig : (o -> p -> p) -> Pull f o es r -> Pull f o es r
205 | modSig f = observe (modify sig . f)
209 | setSig : Pull f p es r -> Pull f p es r
210 | setSig = observe (put sig)
215 | observeSig : (o -> p -> f es ()) -> Pull f o es r -> Pull f o es r
216 | observeSig f = observe $
\vo => get sig >>= f vo
220 | foreachSig : (o -> p -> f es ()) -> Pull f o es r -> Pull f q es r
221 | foreachSig f = foreach $
\vo => get sig >>= f vo
228 | interface Mutable (0 t : Type -> Type) where
229 | mutate : {0 a : Type} -> LIO f => t a -> (a -> a) -> f ()
232 | Mutable IORef where mutate = mod
235 | Mutable SignalRef where mutate = modify
237 | parameters {0 f : List Type -> Type -> Type}
239 | {0 t : Type -> Type}
240 | {auto lio : LIO (f es)}
241 | {auto mut : Mutable t}
244 | modAt : t a -> (o -> a -> a) -> Pull f o es r -> Pull f p es r
245 | modAt ref fun = foreach (mutate ref . fun)
248 | writeTo : t a -> Pull f a es r -> Pull f p es r
249 | writeTo ref = modAt ref const
252 | teeMod : t a -> (o -> a -> a) -> Pull f o es r -> Pull f o es r
253 | teeMod ref fun = observe (mutate ref . fun)
256 | teeTo : t a -> Pull f a es r -> Pull f a es r
257 | teeTo ref = teeMod ref const
263 | record EvST a where
265 | listeners : List (Once World a)
268 | evputImpl : a -> EvST a -> (EvST a, IO1 ())
269 | evputImpl v (EvSS ls) = (EvSS [], traverse1_ (\o => putOnce1 o v) ls)
272 | record Event e es a where
274 | events : Stream (Async e) es a
275 | {auto snk : Sink a}
277 | nextEv : IORef (EvST a) -> Async e es a
280 | act <- mod ref (\(EvSS ls) => EvSS $
def :: ls)
286 | event : (0 a : Type) -> Async e es (Event e fs a)
287 | event a = Prelude.do
288 | r <- newref (EvSS {a} [])
290 | (repeat $
eval (nextEv r))
291 | @{S $
\v,t => let f # t := casupdate1 r (evputImpl v) t in f t}
295 | eventFrom : (ini : a) -> Async e es (Event e fs a)
296 | eventFrom i = {events $= \es => cons i es} <$> event a