module Sound.OSC.Transport.Monad where
import Control.Monad (liftM)
import Control.Monad.Trans.Reader
import Control.Monad.IO.Class as M
import Data.List
import Data.Maybe
import Sound.OSC.Datum
import qualified Sound.OSC.Transport.FD as T
import Sound.OSC.Packet
import Sound.OSC.Packet.Class
import Sound.OSC.Wait
class Monad m => SendOSC m where
sendOSC :: OSC o => o -> m ()
class Monad m => RecvOSC m where
recvPacket :: m Packet
class (SendOSC m,RecvOSC m) => DuplexOSC m where
class (DuplexOSC m,MonadIO m) => Transport m where
instance (T.Transport t,MonadIO io) => SendOSC (ReaderT t io) where
sendOSC o = ReaderT (M.liftIO . flip T.sendOSC o)
instance (T.Transport t,MonadIO io) => RecvOSC (ReaderT t io) where
recvPacket = ReaderT (M.liftIO . T.recvPacket)
instance (T.Transport t,MonadIO io) => DuplexOSC (ReaderT t io) where
instance (T.Transport t,MonadIO io) => Transport (ReaderT t io) where
type Connection t a = ReaderT t IO a
withTransport :: T.Transport t => IO t -> Connection t a -> IO a
withTransport u = T.withTransport u . runReaderT
sendMessage :: SendOSC m => Message -> m ()
sendMessage = sendOSC
sendBundle :: SendOSC m => Bundle -> m ()
sendBundle = sendOSC
recvOSC :: (RecvOSC m,OSC o) => m (Maybe o)
recvOSC = liftM fromPacket recvPacket
recvBundle :: (RecvOSC m) => m Bundle
recvBundle = liftM packet_to_bundle recvPacket
recvMessage :: (RecvOSC m) => m (Maybe Message)
recvMessage = liftM packet_to_message recvPacket
recvMessage_err :: RecvOSC m => m Message
recvMessage_err = fmap (fromMaybe (error "recvMessage")) recvMessage
recvMessages :: (RecvOSC m) => m [Message]
recvMessages = liftM packetMessages recvPacket
waitUntil :: (RecvOSC m) => (Packet -> Bool) -> m Packet
waitUntil f = untilPredicate f recvPacket
waitFor :: (RecvOSC m) => (Packet -> Maybe a) -> m a
waitFor f = untilMaybe f recvPacket
waitImmediate :: RecvOSC m => m Packet
waitImmediate = waitUntil packet_is_immediate
waitMessage :: RecvOSC m => m Message
waitMessage = waitFor packet_to_message
waitAddress :: RecvOSC m => Address_Pattern -> m Packet
waitAddress s =
let f o = if packet_has_address s o then Just o else Nothing
in waitFor f
waitReply :: RecvOSC m => Address_Pattern -> m Message
waitReply s =
let f = fromMaybe (error "waitReply: message not located?") .
find (message_has_address s) .
packetMessages
in liftM f (waitAddress s)
waitDatum :: RecvOSC m => Address_Pattern -> m [Datum]
waitDatum = liftM messageDatum . waitReply