module Sound.OSC.Transport.Monad where
import Control.Monad.Trans.Reader
import Control.Monad.IO.Class as M
import Data.List
import Data.Maybe
import Sound.OpenSoundControl.Class
import qualified Sound.OSC.Transport.FD as T
import Sound.OpenSoundControl.Type
import Sound.OpenSoundControl.Wait
class (Functor m,Monad m,MonadIO m) => Transport m where
sendOSC :: OSC o => o -> m ()
recvPacket :: m Packet
instance (T.Transport t,Functor io,MonadIO io) => Transport (ReaderT t io) where
sendOSC o = ReaderT (M.liftIO . flip T.sendOSC o)
recvPacket = ReaderT (M.liftIO . T.recvPacket)
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 :: Transport m => Message -> m ()
sendMessage = sendOSC
sendBundle :: Transport m => Bundle -> m ()
sendBundle = sendOSC
recvOSC :: (Transport m,OSC o) => m (Maybe o)
recvOSC = fmap fromPacket recvPacket
recvBundle :: (Transport m) => m Bundle
recvBundle = fmap packet_to_bundle recvPacket
recvMessage :: (Transport m) => m (Maybe Message)
recvMessage = fmap packet_to_message recvPacket
recvMessages :: (Transport m) => m [Message]
recvMessages = fmap packetMessages recvPacket
waitUntil :: (Transport m) => (Packet -> Bool) -> m Packet
waitUntil f = untilPredicate f recvPacket
waitFor :: (Transport m) => (Packet -> Maybe a) -> m a
waitFor f = untilMaybe f recvPacket
waitImmediate :: Transport m => m Packet
waitImmediate = waitUntil packet_is_immediate
waitMessage :: Transport m => m Message
waitMessage = waitFor packet_to_message
waitAddress :: Transport 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 :: Transport m => Address_Pattern -> m Message
waitReply s =
let f = fromMaybe (error "waitReply: message not located?") .
find (message_has_address s) .
packetMessages
in fmap f (waitAddress s)
waitDatum :: Transport m => Address_Pattern -> m [Datum]
waitDatum = fmap messageDatum . waitReply