-- | -- Module : Xine.Internal.Stream -- Copyright : (c) Joachim Fasting 2010 -- License : LGPL (see COPYING) -- -- Maintainer : Joachim Fasting <joachim.fasting@gmail.com> -- Stability : unstable -- Portability : not portable -- -- Code for supporting multiple Xine input streams. module Xine.Internal.Stream ( -- * The stream container type StreamId, Streams, empty, streams, -- * Stream container operators insert, delete, lookup ) where import Xine.Foreign (Stream) import Prelude hiding (lookup) import qualified Data.Map as M -- | Identifies an open stream. type StreamId = Int -- | A container for streams. -- -- This is a 'Map StreamId Stream' that stores the last id. Each new id is -- the succ of the last id, making them unique within the map, even when items -- are deleted. The uniqueness property allows us to juggle stream identifiers -- around without having to keep track of deletes (i.e., we don't have to carry -- the actual mapping around with us). data Streams = Streams { mapping :: !(M.Map StreamId Stream) , lastKey :: !StreamId } -- | An empty container. empty :: Streams empty = Streams M.empty 0 -- | Add a stream, returning a new container along with the id of the -- recently added stream. insert :: Stream -> Streams -> (Streams, StreamId) insert x s = let nextId = succ (lastKey s) s' = s { mapping = M.insert nextId x (mapping s) , lastKey = nextId } in (s', nextId) -- | Remove the identified stream. delete :: StreamId -> Streams -> Streams delete sid s = s { mapping = M.delete sid (mapping s) } -- | Stream lookup. lookup :: StreamId -> Streams -> Maybe Stream lookup sid s = M.lookup sid (mapping s) -- | Return a list of streams in the container. streams :: Streams -> [Stream] streams = M.elems . mapping