mediabus-0.2.0.0: src/Data/MediaBus/Sequence.hs
module Data.MediaBus.Sequence
( SeqNum(..)
, type SeqNum8
, type SeqNum16
, type SeqNum32
, type SeqNum64
, HasSeqNumT(..)
, HasSeqNum(..)
, fromSeqNum
, synchronizeToSeqNum
) where
import Test.QuickCheck ( Arbitrary(..) )
import Conduit
import Data.MediaBus.Monotone
import Data.MediaBus.Series
import Control.Lens
import Control.Monad.State.Strict
import Data.Default
import Text.Printf
import GHC.Generics ( Generic )
import Control.DeepSeq
import System.Random
import Data.Word
class SetSeqNum t (GetSeqNum t) ~ t =>
HasSeqNumT t where
type GetSeqNum t
type SetSeqNum t s
class HasSeqNumT t =>
HasSeqNum t where
seqNum :: Lens t (SetSeqNum t s) (GetSeqNum t) s
instance (HasSeqNumT a, HasSeqNumT b, GetSeqNum a ~ GetSeqNum b) =>
HasSeqNumT (Series a b) where
type GetSeqNum (Series a b) = GetSeqNum a
type SetSeqNum (Series a b) t = Series (SetSeqNum a t) (SetSeqNum b t)
instance (HasSeqNum a, HasSeqNum b, GetSeqNum a ~ GetSeqNum b) =>
HasSeqNum (Series a b) where
seqNum f (Start !a) = Start <$> seqNum f a
seqNum f (Next !b) = Next <$> seqNum f b
newtype SeqNum s = MkSeqNum { _fromSeqNum :: s }
deriving (Num, Eq, Bounded, Enum, LocalOrd, Arbitrary, Default, Generic, Random)
type SeqNum8 = SeqNum Word8
type SeqNum16 = SeqNum Word16
type SeqNum32 = SeqNum Word32
type SeqNum64 = SeqNum Word64
instance NFData s =>
NFData (SeqNum s)
makeLenses ''SeqNum
instance HasSeqNumT (SeqNum s) where
type GetSeqNum (SeqNum s) = s
type SetSeqNum (SeqNum s) s' = SeqNum s'
instance HasSeqNum (SeqNum s) where
seqNum = fromSeqNum
instance Show s =>
Show (SeqNum s) where
show (MkSeqNum s) = printf "SEQNUM: %10s" (show s)
instance (Eq a, LocalOrd a) =>
Ord (SeqNum a) where
compare !x !y
| x == y = EQ
| x `succeeds` y = GT
| otherwise = LT
deriving instance (Real a, Num a, Eq a, LocalOrd a) => Real
(SeqNum a)
deriving instance (Integral a, Enum a, Real a, Eq a, LocalOrd a) =>
Integral (SeqNum a)
synchronizeToSeqNum :: (HasSeqNum a, Monad m, Integral i)
=> i
-> Conduit a m (SetSeqNum a i)
synchronizeToSeqNum startSeq =
evalStateC startSeq (awaitForever yieldSeq)
where
yieldSeq !a = do
!nextSeq <- get
modify (+ 1)
yield (a & seqNum .~ nextSeq)