1 {-# LANGUAGE FlexibleContexts, MultiParamTypeClasses, TupleSections #-}
3 module RMCA.EventProvider ( EventProvider
5 , newEmptyEventProvider
9 , newEventProviderQueue
10 , newEmptyEventProviderQueue
15 import Control.Concurrent.MVar
17 import Data.ReactiveValue
18 import FRP.Yampa hiding (maybeToEvent)
21 newtype EventProvider a = EventProvider (MVar (Event a, [IO ()]))
23 newEventProvider :: Maybe a -> IO (EventProvider a)
24 newEventProvider = fmap EventProvider . newMVar . (,[]) . maybeToEvent
26 newEmptyEventProvider :: IO (EventProvider a)
27 newEmptyEventProvider = newEventProvider Nothing
29 -- Stop event production without triggering the callbacks.
30 stopProviding :: EventProvider a -> IO ()
31 stopProviding (EventProvider mvar) =
32 modifyMVar_ mvar (\(_,cbs) -> return (NoEvent,cbs))
34 getEPfromRV :: (ReactiveValueRead a b IO) => a -> IO (EventProvider b)
36 ep <- newEventProvider . Just =<< reactiveValueRead rv
40 instance ReactiveValueRead (EventProvider a) (Event a) IO where
41 reactiveValueRead (EventProvider mvar) =
42 modifyMVar mvar $ \(mval,cbs) -> return ((NoEvent,cbs), mval)
43 reactiveValueOnCanRead (EventProvider mvar) io =
44 modifyMVar_ mvar $ \(mval,cbs) -> return (mval, cbs ++ [io])
46 instance ReactiveValueWrite (EventProvider a) (Event a) IO where
47 reactiveValueWrite (EventProvider mvar) val = do
48 modifyMVar_ mvar (\(_,cbs) -> return (val,cbs))
49 readMVar mvar >>= sequence_ . snd
51 instance ReactiveValueReadWrite (EventProvider a) (Event a) IO where
53 newtype EventProviderQueue a = EventProviderQueue (MVar ([a], [IO ()]))
55 newEventProviderQueue :: [a] -> IO (EventProviderQueue a)
56 newEventProviderQueue = fmap EventProviderQueue . newMVar . (,[])
58 newEmptyEventProviderQueue :: IO (EventProviderQueue a)
59 newEmptyEventProviderQueue = newEventProviderQueue []
61 emptyProviderQueue :: EventProviderQueue a -> IO ()
62 emptyProviderQueue (EventProviderQueue mvar) =
63 modifyMVar_ mvar (\(_,cbs) -> return ([],cbs))
65 getEPQfromRV :: (ReactiveValueRead a b IO) => a -> IO (EventProviderQueue b)
67 ep <- newEventProviderQueue . (:[]) =<< reactiveValueRead rv
71 instance ReactiveValueRead (EventProviderQueue a) (Event a) IO where
72 reactiveValueRead (EventProviderQueue mvar) =
73 modifyMVar mvar popEventMVar
74 where popEventMVar ([],cbs) = return (([],cbs), NoEvent)
75 popEventMVar (el,cbs) = return ((init el,cbs), Event $ last el)
76 reactiveValueOnCanRead (EventProviderQueue mvar) io =
77 modifyMVar_ mvar $ \(mval,cbs) -> return (mval, cbs ++ [io])
79 instance ReactiveValueWrite (EventProviderQueue a) (Event a) IO where
80 reactiveValueWrite (EventProviderQueue mvar) val = do
82 modifyMVar_ mvar $ \(mval,cbs) -> return (fromEvent val:mval,cbs)
83 readMVar mvar >>= sequence_ . snd