Newer
Older
module Qd.Observable.Delta where
import Qd.Observable
import Qd.Prelude
import Conduit
import qualified Data.HashMap.Strict as HM
import Data.Binary (Binary(..))
data Delta k v = Reset (HM.HashMap k v) | Add k v | Change k v | Remove k
deriving (Eq, Show, Generic)
instance (Binary k, Binary v) => Binary (Delta k v) where
get = undefined
put = undefined
class Observable (HM.HashMap k v) o => DeltaObservable k v o | o -> k, o -> v where
subscribeDelta :: o -> (Delta k v -> IO ()) -> IO SubscriptionHandle
subscribeDelta = undefined
subscribeDeltaC :: o -> ConduitT () (Delta k v) IO ()
subscribeDeltaC = undefined
{-# MINIMAL subscribeDelta | subscribeDeltaC #-}
observeHashMapDefaultImpl :: forall k v o. (Eq k, Hashable k) => DeltaObservable k v o => o -> (HM.HashMap k v -> IO ()) -> IO SubscriptionHandle
observeHashMapDefaultImpl o callback = do
hashMapRef <- newIORef HM.empty
subscribeDelta o (deltaCallback hashMapRef)
where
deltaCallback :: IORef (HM.HashMap k v) -> Delta k v -> IO ()
deltaCallback hashMapRef delta = callback =<< atomicModifyIORef' hashMapRef ((\x->(x,x)) . (applyDelta delta))
applyDelta :: Delta k v -> HM.HashMap k v -> HM.HashMap k v
applyDelta (Reset state) = const state
applyDelta (Add key value) = HM.insert key value
applyDelta (Change key value) = HM.insert key value
applyDelta (Remove key) = HM.delete key