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