{-# LANGUAGE RecordWildCards #-}

{- |
Different implementations of FIFO buffers.
-}
module FRP.Rhine.ResamplingBuffer.FIFO where

-- base
import Prelude hiding (length, take)

-- containers
import Data.Sequence

-- rhine
import FRP.Rhine.ResamplingBuffer
import FRP.Rhine.ResamplingBuffer.Timeless

-- * FIFO (first-in-first-out) buffers

{- | An unbounded FIFO buffer.
   If the buffer is empty, it will return 'Nothing'.
-}
fifoUnbounded :: Monad m => ResamplingBuffer m cl1 cl2 a (Maybe a)
fifoUnbounded :: forall (m :: Type -> Type) cl1 cl2 a.
Monad m =>
ResamplingBuffer m cl1 cl2 a (Maybe a)
fifoUnbounded = forall (m :: Type -> Type) s a b cl1 cl2.
Monad m =>
AsyncMealy m s a b -> s -> ResamplingBuffer m cl1 cl2 a b
timelessResamplingBuffer AsyncMealy {forall {m :: Type -> Type} {a}.
Monad m =>
Seq a -> m (Maybe a, Seq a)
forall {m :: Type -> Type} {a}. Monad m => Seq a -> a -> m (Seq a)
amGet :: Seq a -> m (Maybe a, Seq a)
amPut :: Seq a -> a -> m (Seq a)
amGet :: forall {m :: Type -> Type} {a}.
Monad m =>
Seq a -> m (Maybe a, Seq a)
amPut :: forall {m :: Type -> Type} {a}. Monad m => Seq a -> a -> m (Seq a)
..} forall a. Seq a
empty
  where
    amPut :: Seq a -> a -> m (Seq a)
amPut Seq a
as a
a = forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ a
a forall a. a -> Seq a -> Seq a
<| Seq a
as
    amGet :: Seq a -> m (Maybe a, Seq a)
amGet Seq a
as = case forall a. Seq a -> ViewR a
viewr Seq a
as of
      ViewR a
EmptyR -> forall (m :: Type -> Type) a. Monad m => a -> m a
return (forall a. Maybe a
Nothing, forall a. Seq a
empty)
      Seq a
as' :> a
a -> forall (m :: Type -> Type) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just a
a, Seq a
as')

{- |  A bounded FIFO buffer that forgets the oldest values when the size is above a given threshold.
    If the buffer is empty, it will return 'Nothing'.
-}
fifoBounded :: Monad m => Int -> ResamplingBuffer m cl1 cl2 a (Maybe a)
fifoBounded :: forall (m :: Type -> Type) cl1 cl2 a.
Monad m =>
Int -> ResamplingBuffer m cl1 cl2 a (Maybe a)
fifoBounded Int
threshold = forall (m :: Type -> Type) s a b cl1 cl2.
Monad m =>
AsyncMealy m s a b -> s -> ResamplingBuffer m cl1 cl2 a b
timelessResamplingBuffer AsyncMealy {Seq a -> a -> m (Seq a)
forall {m :: Type -> Type} {a}.
Monad m =>
Seq a -> m (Maybe a, Seq a)
amGet :: forall {m :: Type -> Type} {a}.
Monad m =>
Seq a -> m (Maybe a, Seq a)
amPut :: Seq a -> a -> m (Seq a)
amGet :: Seq a -> m (Maybe a, Seq a)
amPut :: Seq a -> a -> m (Seq a)
..} forall a. Seq a
empty
  where
    amPut :: Seq a -> a -> m (Seq a)
amPut Seq a
as a
a = forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ forall a. Int -> Seq a -> Seq a
take Int
threshold forall a b. (a -> b) -> a -> b
$ a
a forall a. a -> Seq a -> Seq a
<| Seq a
as
    amGet :: Seq a -> m (Maybe a, Seq a)
amGet Seq a
as = case forall a. Seq a -> ViewR a
viewr Seq a
as of
      ViewR a
EmptyR -> forall (m :: Type -> Type) a. Monad m => a -> m a
return (forall a. Maybe a
Nothing, forall a. Seq a
empty)
      Seq a
as' :> a
a -> forall (m :: Type -> Type) a. Monad m => a -> m a
return (forall a. a -> Maybe a
Just a
a, Seq a
as')

-- | An unbounded FIFO buffer that also returns its current size.
fifoWatch :: Monad m => ResamplingBuffer m cl1 cl2 a (Maybe a, Int)
fifoWatch :: forall (m :: Type -> Type) cl1 cl2 a.
Monad m =>
ResamplingBuffer m cl1 cl2 a (Maybe a, Int)
fifoWatch = forall (m :: Type -> Type) s a b cl1 cl2.
Monad m =>
AsyncMealy m s a b -> s -> ResamplingBuffer m cl1 cl2 a b
timelessResamplingBuffer AsyncMealy {forall {m :: Type -> Type} {a}.
Monad m =>
Seq a -> m ((Maybe a, Int), Seq a)
forall {m :: Type -> Type} {a}. Monad m => Seq a -> a -> m (Seq a)
amGet :: forall {m :: Type -> Type} {a}.
Monad m =>
Seq a -> m ((Maybe a, Int), Seq a)
amPut :: forall {m :: Type -> Type} {a}. Monad m => Seq a -> a -> m (Seq a)
amGet :: Seq a -> m ((Maybe a, Int), Seq a)
amPut :: Seq a -> a -> m (Seq a)
..} forall a. Seq a
empty
  where
    amPut :: Seq a -> a -> m (Seq a)
amPut Seq a
as a
a = forall (m :: Type -> Type) a. Monad m => a -> m a
return forall a b. (a -> b) -> a -> b
$ a
a forall a. a -> Seq a -> Seq a
<| Seq a
as
    amGet :: Seq a -> m ((Maybe a, Int), Seq a)
amGet Seq a
as = case forall a. Seq a -> ViewR a
viewr Seq a
as of
      ViewR a
EmptyR -> forall (m :: Type -> Type) a. Monad m => a -> m a
return ((forall a. Maybe a
Nothing, Int
0), forall a. Seq a
empty)
      Seq a
as' :> a
a -> forall (m :: Type -> Type) a. Monad m => a -> m a
return ((forall a. a -> Maybe a
Just a
a, forall a. Seq a -> Int
length Seq a
as'), Seq a
as')