[reconnectable connections Evan Martin **20060217031803] { hunk ./MPD.hs 7 - setVolume, getVolume + setVolume, getVolume, + + ReconnectableConnection, rcConnect, rcDo hunk ./MPD.hs 17 +-- for ReconnectableConnection +import Data.IORef + hunk ./MPD.hs 56 + +type ReconnectableConnection = (IORef Handle, (String, Int)) +rcConnect :: (String, Int) -> IO ReconnectableConnection +rcConnect addr = do + conn <- connect addr + connref <- newIORef conn + return (connref, addr) + +rcDo :: ReconnectableConnection -> (Connection -> IO ()) -> IO () +rcDo (connref, addr) job = do + conn <- readIORef connref + job conn `catch` \e -> do + -- print $ ioeGetErrorString e + newconn <- MPD.connect addr + writeIORef connref newconn + job newconn hunk ./MPDMate.hs 13 -loop :: a -> (a -> IO a) -> IO a -loop state iter = loop' state where - loop' state = iter state >>= loop' - hunk ./MPDMate.hs 24 +mainLoop :: Handle -> IO () +mainLoop pm = do + conn <- MPD.rcConnect mpdAddress + sequence_ $ repeat $ do + event <- PowerMate.readEventWithSkip pm Nothing + case event of + Nothing -> return () + Just ev -> MPD.rcDo conn (\mpd -> processEvent mpd ev) + hunk ./MPDMate.hs 39 - mpd <- MPD.connect mpdAddress - hunk ./MPDMate.hs 40 - loop mpd $ \mpd -> do - event <- PowerMate.readEventWithSkip handle_pm Nothing - (do maybe (return ()) (processEvent mpd) event - return mpd) - `catch` \e -> do - print $ ioeGetErrorString e - MPD.connect mpdAddress - return () + mainLoop handle_pm }