module Simulation.Aivika.Experiment.ListSource
(ListSource,
providerToDoubleListSource,
providerToIntListSource,
ListData,
listSourceData,
listDataList,
ListRef,
newListRef,
addDataToListRef,
readListRef) where
import Data.IORef
import Control.Monad
import Simulation.Aivika.Dynamics
import Simulation.Aivika.Statistics
import Simulation.Aivika.Experiment
data ListSource a = SingleValueSource (Dynamics a)
| MultipleValueSource (Dynamics [a])
data ListData a = SingleValueData !a
| MultipleValueData [a]
providerToDoubleListSource :: SeriesProvider -> Maybe (ListSource Double)
providerToDoubleListSource provider =
case providerToDouble provider of
Just x -> Just $ SingleValueSource x
Nothing ->
case providerToDoubleList provider of
Just x -> Just $ MultipleValueSource x
Nothing -> Nothing
providerToIntListSource :: SeriesProvider -> Maybe (ListSource Int)
providerToIntListSource provider =
case providerToInt provider of
Just x -> Just $ SingleValueSource x
Nothing ->
case providerToIntList provider of
Just x -> Just $ MultipleValueSource x
Nothing -> Nothing
listSourceData :: ListSource a -> Dynamics (ListData a)
listSourceData (SingleValueSource x) = x >>= return . SingleValueData
listSourceData (MultipleValueSource xs) =
do ys <- xs
zs <- forM ys $ \y -> return $ y `seq` y
return $ MultipleValueData ys
listDataList :: ListData a -> [a]
listDataList (SingleValueData x) = [x]
listDataList (MultipleValueData xs) = xs
newtype ListRef a = ListRef { listRef :: IORef [ListData a] }
newListRef :: IO (ListRef a)
newListRef = fmap ListRef $ newIORef []
addDataToListRef :: ListRef a -> ListData a -> IO ()
addDataToListRef (ListRef r) a = modifyIORef r (a :)
readListRef :: ListRef a -> IO [a]
readListRef (ListRef r) =
do x <- readIORef r
return $ concat $ map listDataList x