module Xine.Internal.Handle (
HandleState(..), XineHandle_(..), XineHandle(..), isClosed,
modifyXineHandle, withXineHandle, withStream
) where
import Xine.Foreign
import Xine.Internal.Stream (Streams, StreamId)
import qualified Xine.Internal.Stream as S
import Control.Concurrent.MVar
import Control.Monad (when)
data HandleState = Closed | Open deriving Eq
data XineHandle_ = XineHandle_
{ hEngine :: !Engine
, hAudioPort :: !AudioPort
, hVideoPort :: !VideoPort
, hStreams :: !Streams
, hCurrent :: !(Maybe StreamId)
, hState :: !HandleState
}
newtype XineHandle = XineHandle (MVar XineHandle_)
isClosed :: XineHandle -> IO Bool
isClosed (XineHandle hv) = withMVar hv $ \h -> return (hState h == Closed)
modifyXineHandle :: XineHandle -> (XineHandle_ -> IO XineHandle_) -> IO ()
modifyXineHandle h@(XineHandle hv) f = do
closed <- isClosed h
when closed (fail "XineHandle is closed")
modifyMVar_ hv f
withXineHandle :: XineHandle -> (XineHandle_ -> IO a) -> IO a
withXineHandle h@(XineHandle hv) f = do
closed <- isClosed h
when closed (fail "XineHandle is closed")
withMVar hv f
withStream :: XineHandle -> StreamId -> (Stream -> IO a) -> IO a
withStream h sid f = withXineHandle h $ \hv ->
case S.lookup sid (hStreams hv) of
Just s -> f s
Nothing -> fail $ "No such stream: " ++ show sid