haste-compiler-0.2.99: libraries/fursuit/src/FRP/Fursuit/Pipe.hs
{-# LANGUAGE BangPatterns, CPP #-}
-- | Pipes are the only way to cause a 'Signal' to fire from the outside.
module FRP.Fursuit.Pipe (Pipe, pipe, emptyPipe, write) where
import Data.IORef
import FRP.Fursuit.Signal
import qualified Data.IntMap as M
import FRP.Fursuit.Locking
-- | Create a pipe. Writing to a pipe is the only way to manually trigger a
-- signal.
emptyPipe :: IO (Pipe a, Signal a)
emptyPipe = do
ref <- newIORef Nothing
orig <- newIORef False
sinks <- newIORef M.empty
return (P ref sinks orig, Pipe ref sinks orig)
-- | Create a pipe with an initial value.
pipe :: a -> IO (Pipe a, Signal a)
pipe !initially = do
ps@(P ref _ _, _) <- emptyPipe
writeIORef ref (Just initially)
return ps
-- | Write a value into a pipe. This will cause the pipe's associated signal
-- to fire.
write :: Pipe a -> a -> IO ()
write (P value listeners origin) !x = withFursuitLock $ do
writeIORef origin True
writeIORef value (Just x)
readIORef listeners >>= M.foldl' (>>) (return ())
writeIORef origin False