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.Event
import Simulation.Aivika.Trans.Signal
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 -> Event IO (SignalHistory IO a)
newSignalHistory =
newSignalHistoryStartingWith Nothing
newSignalHistoryStartingWith :: Maybe a -> Signal IO a -> Event IO (SignalHistory IO a)
newSignalHistoryStartingWith init signal =
Event $ \p ->
do ts <- liftIO UV.newVector
xs <- liftIO V.newVector
case init of
Nothing -> return ()
Just a ->
liftIO $
do UV.appendVector ts (pointTime p)
V.appendVector xs a
invokeEvent p $
handleSignal_ 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)
readSignalHistory history =
Event $ \p ->
liftIO $
do xs <- UV.freezeVector (signalHistoryTimes history)
ys <- V.freezeVector (signalHistoryValues history)
return (xs, ys)