hosc-0.6: Sound/OpenSoundControl/Transport.hs
-- | An abstract transport layer with implementations for UDP and TCP
-- transport.
module Sound.OpenSoundControl.Transport ( Transport(..)
, withTransport
, waitFor, wait ) where
import Control.Exception
import Sound.OpenSoundControl.OSC
-- | Abstract over the underlying transport protocol.
class Transport t where
-- | Encode and send an OSC packet.
send :: t -> OSC -> IO ()
-- | Receive and decode an OSC packet.
recv :: t -> IO OSC
-- | Close an existing connection.
close :: t -> IO ()
-- Does the OSC message have the specified address.
has_address :: String -> OSC -> Bool
has_address x (Message y _) = x == y
has_address _ _ = False
-- Repeat action until function does not give Nothing when applied to result.
untilM :: Monad m => (a -> Maybe b) -> m a -> m b
untilM f act = recurse
where g p = let q = f p in case q of { Nothing -> recurse
; Just r -> return r }
recurse = act >>= g
-- | Wait for an OSC message where the supplied function does not give
-- Nothing, discarding intervening messages.
waitFor :: Transport t => t -> (OSC -> Maybe a) -> IO a
waitFor t f = untilM f (recv t)
-- | A 'waitFor' for variant matching on address string of messages.
wait :: Transport t => t -> String -> IO OSC
wait t s = waitFor t (\o -> if has_address s o then Just o else Nothing)
-- | Bracket OSC communication.
withTransport :: Transport t => IO t -> (t -> IO a) -> IO a
withTransport u = bracket u close