I had defined another instance of Transport, namely writing to a file. It is no longer much important since you can generate a message stream and output it either via OpenSoundControl or write it to a bytestring. Nevertheless the File transport allows to write to a file whereever code is written for immediate communication with the SuperCollider server. It just replies to every 'recv' with a "/done" message. If we need more specific answers, we could collect the incoming messages in an IORef and ship according answers in the same order. It is however unfortunate that everything runs in IO monad since instead of writing to disk it would be better to write to bytestring and stay away from IO.
We could also emit an error if an asynchronous message without 'Bundle' shall be written to disk. Even better would be to encourage time stamps for asynchronous messages and enforce waiting for synchronous messages by type system. I'm still thinking about how this could be done.
module Sound.OpenSoundControl.Transport.File (File, open) where import Sound.OpenSoundControl.Transport (Transport(..)) import Sound.OpenSoundControl.Byte (encode_u32) import Sound.OpenSoundControl.OSC (encodeOSC, OSC(Message)) import Control.Monad (liftM) import qualified Data.ByteString.Lazy as B import System.IO (Handle, openBinaryFile, hClose, IOMode(WriteMode)) -- | The File transport handle data type. data File = File Handle deriving (Eq, Show) instance Transport File where send (File fd) msg = let b = encodeOSC msg n = fromIntegral (B.length b) -- B.reverse - What byte order is generally needed? -- B.hPut fd (B.append (B.reverse (encode_u32 n)) b) in B.hPut fd (B.append (encode_u32 n) b) recv _ = return (Message "/done" []) close (File fd) = hClose fd -- | Open a command file open :: FilePath -> IO File open fileName = liftM File $ openBinaryFile fileName WriteMode
_______________________________________________ haskell-art mailing list haskell-art@lists.lurk.org http://lists.lurk.org/mailman/listinfo/haskell-art