rhine-1.3: src/FRP/Rhine/ResamplingBuffer/ClSF.hs
{- |
Collect and process all incoming values statefully and with time stamps.
-}
module FRP.Rhine.ResamplingBuffer.ClSF where
-- transformers
import Control.Monad.Trans.Reader (ReaderT, runReaderT)
-- automaton
import Data.Automaton
import Data.Stream
import Data.Stream.Optimized (toStreamT)
import Data.Stream.Result (mapResultState)
-- rhine
import FRP.Rhine.ClSF.Core
import FRP.Rhine.ResamplingBuffer
{- | Given a clocked signal function that accepts
a varying number of timestamped inputs (a list),
a `ResamplingBuffer` can be formed
that collects all this input and steps the signal function
whenever output is requested.
-}
clsfBuffer ::
(Monad m) =>
-- | The clocked signal function that consumes
-- and a list of timestamped inputs,
-- and outputs a single value.
-- The list will contain the /newest/ element in the head.
ClSF m cl2 [(TimeInfo cl1, a)] b ->
ResamplingBuffer m cl1 cl2 a b
clsfBuffer = clsfBuffer' . toStreamT . getAutomaton
where
clsfBuffer' ::
(Monad m) =>
StreamT (ReaderT [(TimeInfo cl1, a)] (ReaderT (TimeInfo cl2) m)) b ->
ResamplingBuffer m cl1 cl2 a b
clsfBuffer' StreamT {state, step} =
ResamplingBuffer
{ buffer = (state, [])
, put = \ti1 a (s, as) -> return (s, (ti1, a) : as)
, get = \ti2 (s, as) -> mapResultState (,[]) <$> runReaderT (runReaderT (step s) as) ti2
}