From 4cf576af326b878fe7dc6d01b6b56696f2133cde Mon Sep 17 00:00:00 2001 From: Jens Nolte <git@queezle.net> Date: Sun, 8 Nov 2020 01:37:38 +0100 Subject: [PATCH] Implement some MVar-like helpers for ObservableVar --- src/lib/Qd/Observable.hs | 16 ++++++++++++++-- src/lib/Qd/Observable/ObservableHashMap.hs | 6 ++++++ 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/src/lib/Qd/Observable.hs b/src/lib/Qd/Observable.hs index eb216fc..2fc1a01 100644 --- a/src/lib/Qd/Observable.hs +++ b/src/lib/Qd/Observable.hs @@ -15,7 +15,9 @@ module Qd.Observable ( MessageReason(..), ObservableVar, newObservableVar, + withObservableVar, modifyObservableVar, + modifyObservableVar_, joinObservable, joinObservableMaybe, joinObservableMaybe', @@ -145,13 +147,23 @@ newObservableVar initialValue = do ObservableVar <$> newMVar (initialValue, HM.empty) -modifyObservableVar :: ObservableVar v -> (v -> v) -> IO () +modifyObservableVar :: ObservableVar v -> (v -> IO (v, a)) -> IO a modifyObservableVar (ObservableVar mvar) f = + modifyMVar mvar $ \(oldState, subscribers) -> do + (newState, result) <- f oldState + mapM_ (\callback -> callback (Update, newState)) subscribers + return ((newState, subscribers), result) + +modifyObservableVar_ :: ObservableVar v -> (v -> IO v) -> IO () +modifyObservableVar_ (ObservableVar mvar) f = modifyMVar_ mvar $ \(oldState, subscribers) -> do - let newState = f oldState + newState <- f oldState mapM_ (\callback -> callback (Update, newState)) subscribers return (newState, subscribers) +withObservableVar :: ObservableVar a -> (a -> IO b) -> IO b +withObservableVar (ObservableVar mvar) f = withMVar mvar (f . fst) + newtype JoinedObservable o = JoinedObservable o instance forall o i v. (Gettable i o, Gettable v i) => Gettable v (JoinedObservable o) where diff --git a/src/lib/Qd/Observable/ObservableHashMap.hs b/src/lib/Qd/Observable/ObservableHashMap.hs index c484ab6..6d93416 100644 --- a/src/lib/Qd/Observable/ObservableHashMap.hs +++ b/src/lib/Qd/Observable/ObservableHashMap.hs @@ -6,6 +6,7 @@ module Qd.Observable.ObservableHashMap ( observeKey, insert, delete, + lookup, lookupDelete, ) where @@ -153,6 +154,11 @@ delete key = modifyKeyHandleNotifying_ fn key let delta = if isJust oldValue then Just (Delete key) else Nothing return (keyHandle{value=Nothing}, delta) +lookup :: forall k v. (Eq k, Hashable k) => k -> ObservableHashMap k v -> IO (Maybe v) +lookup key (ObservableHashMap mvar) = do + Handle{keyHandles} <- readMVar mvar + return $ join $ value <$> HM.lookup key keyHandles + lookupDelete :: forall k v. (Eq k, Hashable k) => k -> ObservableHashMap k v -> IO (Maybe v) lookupDelete key = modifyKeyHandleNotifying fn key where -- GitLab