uni-util-2.2.0.0: Util/KeyedChanges.hs
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE MultiParamTypeClasses #-}
-- | This implements a SinkSource with keyed changes.
module Util.KeyedChanges(
KeyedChanges,
-- The idea is to keep track of changes to which a key is attached.
-- When a new sink is attached, only the most recent changes for each
-- key are returned.
-- Producer's interface
newKeyedChanges,
-- :: Ord key => IO (KeyedChanges key delta)
sendKeyedChanges,
-- :: Ord key => key -> delta -> KeyedChanges key delta -> IO ()
-- Used for sending changes which restore the situation to its default.
-- If there is no entry for the key, nothing is done. Otherwise the
-- given delta is sent, and the entry is deleted.
deleteKeyedChange,
-- :: Ord key => key -> delta -> KeyedChanges key delta -> IO ()
-- Consumer's interface
-- instance Ord key => HasSource (KeyedChanges key delta) [delta] delta
) where
import qualified Data.Map as Map
import Util.Sources
import Util.Broadcaster
newtype KeyedChanges key delta
= KeyedChanges (Broadcaster (Map.Map key delta) delta)
-- ------------------------------------------------------------------------
-- Producer's interface
-- ------------------------------------------------------------------------
newKeyedChanges :: Ord key => IO (KeyedChanges key delta)
newKeyedChanges =
do
broadcaster <- newBroadcaster Map.empty
return (KeyedChanges broadcaster)
sendKeyedChanges :: Ord key => key -> delta -> KeyedChanges key delta -> IO ()
sendKeyedChanges key delta (KeyedChanges broadcaster) =
applyUpdate broadcaster (\ map -> (Map.insert key delta map,[delta]))
deleteKeyedChange :: Ord key => key -> delta -> KeyedChanges key delta -> IO ()
deleteKeyedChange key delta (KeyedChanges broadcaster) =
applyUpdate broadcaster (\ map -> case Map.lookup key map of
Nothing -> (map,[])
Just _ -> (Map.delete key map,[delta])
)
-- ------------------------------------------------------------------------
-- Consumer's interface
-- ------------------------------------------------------------------------
instance Ord key => HasSource (KeyedChanges key delta) [delta] delta where
toSource (KeyedChanges broadcaster) = map1 Map.elems (toSource broadcaster)