module Data.Async ( Event(..), event, Async(..), newAsync, readAsync, modifyAsync, -- * Reexports Group, NFData ) where import Control.DeepSeq (NFData, force) import Control.Monad (forM_) import Control.Concurrent import Data.Group (Group(..)) -- | Event on async value data Event a = Append a | Remove a | Clear | Modify (a -> a) | Action (a -> IO a) -- | Event to function event :: Group a => Event a -> a -> IO a event (Append v) x = return $ add x v event (Remove v) x = return $ sub x v event Clear _ = return zero event (Modify p) x = return $ p x event (Action p) x = p x data Async a = Async { asyncVar :: MVar a, asyncEvents :: Chan (Event a) } newAsync :: (NFData a, Group a) => IO (Async a) newAsync = do var <- newMVar zero events <- newChan _ <- forkIO $ do evs <- getChanContents events forM_ evs $ \e -> modifyMVar_ var $ \val -> do x' <- event e val force x' `seq` return x' return $ Async var events readAsync :: Async a -> IO a readAsync = readMVar . asyncVar modifyAsync :: Async a -> Event a -> IO () modifyAsync avar = writeChan (asyncEvents avar)