Skip to content
Snippets Groups Projects
Commit e6369769 authored by Jens Nolte's avatar Jens Nolte
Browse files

Implement joinObservable

parent 32501a55
No related branches found
No related tags found
No related merge requests found
{-# LANGUAGE UndecidableInstances #-}
module Qd.Observable ( module Qd.Observable (
SomeObservable(..), SomeObservable(..),
Observable(..), Observable(..),
...@@ -11,6 +13,7 @@ module Qd.Observable ( ...@@ -11,6 +13,7 @@ module Qd.Observable (
mkBasicObservable, mkBasicObservable,
setBasicObservable, setBasicObservable,
updateBasicObservable, updateBasicObservable,
joinObservable,
) where ) where
import Control.Concurrent.MVar import Control.Concurrent.MVar
...@@ -95,3 +98,34 @@ updateBasicObservable (BasicObservable mvar) f = ...@@ -95,3 +98,34 @@ updateBasicObservable (BasicObservable mvar) f =
let newState = (\v -> f v) <$> oldState let newState = (\v -> f v) <$> oldState
mapM_ (\callback -> callback (Update, newState)) subscribers mapM_ (\callback -> callback (Update, newState)) subscribers
return (newState, subscribers) return (newState, subscribers)
newtype JoinedObservable o = JoinedObservable o
instance forall o i v. (Observable i o, Observable v i) => Observable v (JoinedObservable o) where
getValue :: JoinedObservable o -> IO (ObservableState v)
getValue (JoinedObservable outer) = do
state <- getValue outer
case state of
Just inner -> getValue inner
Nothing -> return Nothing
subscribe :: (JoinedObservable o) -> (ObservableMessage v -> IO ()) -> IO SubscriptionHandle
subscribe (JoinedObservable outer) handler = do
innerSubscriptionMVar <- newMVar dummySubscription
outerSubscription <- subscribe outer (outerHandler innerSubscriptionMVar)
return $ SubscriptionHandle{unsubscribe = unsubscribe' outerSubscription}
where
dummySubscription = SubscriptionHandle { unsubscribe = return () }
outerHandler innerSubscriptionMVar = outerHandler'
where
outerHandler' (_, Just inner) = do
unsubscribe =<< takeMVar innerSubscriptionMVar
innerSubscription <- subscribe inner handler
putMVar innerSubscriptionMVar innerSubscription
outerHandler' (reason, Nothing) = do
unsubscribe =<< takeMVar innerSubscriptionMVar
handler (reason, Nothing)
putMVar innerSubscriptionMVar dummySubscription
unsubscribe' outerSubscription = do
unsubscribe outerSubscription
joinObservable :: (Observable i o, Observable v i) => o -> SomeObservable v
joinObservable outer = SomeObservable $ JoinedObservable outer
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment