module Simulation.Aivika.IO.Signal
(
SignalHistory,
signalHistorySignal,
newSignalHistory,
newSignalHistoryStartingWith,
readSignalHistory) where
import Data.Monoid
import Data.List
import Data.Array
import Data.Array.MArray.Safe
import Control.Monad
import Control.Monad.Trans
import Simulation.Aivika.Trans.DES
import Simulation.Aivika.Trans.Internal.Specs
import Simulation.Aivika.Trans.Internal.Dynamics
import Simulation.Aivika.Trans.Internal.Event
import Simulation.Aivika.Trans.Composite
import Simulation.Aivika.Trans.Signal hiding (SignalHistory,
signalHistorySignal,
newSignalHistory,
newSignalHistoryStartingWith,
readSignalHistory)
import Simulation.Aivika.IO.DES
import qualified Simulation.Aivika.Vector as V
import qualified Simulation.Aivika.Vector.Unboxed as UV
data SignalHistory m a =
SignalHistory { signalHistorySignal :: Signal m a,
signalHistoryTimes :: UV.Vector Double,
signalHistoryValues :: V.Vector a }
newSignalHistory :: Signal IO a -> Composite IO (SignalHistory IO a)
{-# INLINABLE newSignalHistory #-}
newSignalHistory =
newSignalHistoryStartingWith Nothing
newSignalHistoryStartingWith :: Maybe a -> Signal IO a -> Composite IO (SignalHistory IO a)
{-# INLINABLE newSignalHistoryStartingWith #-}
newSignalHistoryStartingWith init signal =
do ts <- liftIO UV.newVector
xs <- liftIO V.newVector
case init of
Nothing -> return ()
Just a ->
do t <- liftDynamics time
liftIO $
do UV.appendVector ts t
V.appendVector xs a
handleSignalComposite signal $ \a ->
Event $ \p ->
liftIO $
do UV.appendVector ts (pointTime p)
V.appendVector xs a
return SignalHistory { signalHistorySignal = signal,
signalHistoryTimes = ts,
signalHistoryValues = xs }
readSignalHistory :: SignalHistory IO a -> Event IO (Array Int Double, Array Int a)
{-# INLINABLE readSignalHistory #-}
readSignalHistory history =
Event $ \p ->
liftIO $
do xs <- UV.freezeVector (signalHistoryTimes history)
ys <- V.freezeVector (signalHistoryValues history)
return (xs, ys)