aivika 0.4.1 → 0.4.2
raw patch · 7 files changed
+62/−32 lines, 7 filesPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
API changes (from Hackage documentation)
+ Simulation.Aivika.Dynamics.Signal: emptySignal :: Signal a
- Simulation.Aivika.Dynamics.Signal: handleSignal :: Signal a -> (a -> Dynamics ()) -> Simulation (Simulation ())
+ Simulation.Aivika.Dynamics.Signal: handleSignal :: Signal a -> (a -> Dynamics ()) -> Dynamics (Dynamics ())
- Simulation.Aivika.Dynamics.Signal: handleSignal_ :: Signal a -> (a -> Dynamics ()) -> Simulation ()
+ Simulation.Aivika.Dynamics.Signal: handleSignal_ :: Signal a -> (a -> Dynamics ()) -> Dynamics ()
- Simulation.Aivika.Dynamics.Signal: newSignalHistory :: Signal a -> Simulation (SignalHistory a)
+ Simulation.Aivika.Dynamics.Signal: newSignalHistory :: Signal a -> Dynamics (SignalHistory a)
Files
- Simulation/Aivika/Dynamics/Agent.hs +4/−4
- Simulation/Aivika/Dynamics/Internal/Signal.hs +41/−11
- Simulation/Aivika/Dynamics/Ref.hs +3/−4
- Simulation/Aivika/Dynamics/Signal.hs +7/−6
- Simulation/Aivika/Dynamics/UVar.hs +3/−3
- Simulation/Aivika/Dynamics/Var.hs +3/−3
- aivika.cabal +1/−1
Simulation/Aivika/Dynamics/Agent.hs view
@@ -288,10 +288,10 @@ -- | Return a signal that notifies about every change of the state. agentStateChanged :: Agent -> Signal (Maybe AgentState)-agentStateChanged agent = merge2Signals m1 m2- where m1 = publishSignal (agentStateChangedSource agent)- m2 = publishSignal (agentStateUpdatedSource agent)- +agentStateChanged v = merge2Signals m1 m2 -- N.B. The order is important!+ where m1 = publishSignal (agentStateUpdatedSource v)+ m2 = publishSignal (agentStateChangedSource v)+ -- | Return a signal that notifies about every change of the state. agentStateChanged_ :: Agent -> Signal () agentStateChanged_ agent =
Simulation/Aivika/Dynamics/Internal/Signal.hs view
@@ -28,12 +28,14 @@ apSignal, filterSignal, filterSignalM,+ emptySignal, merge2Signals, merge3Signals, merge4Signals, merge5Signals) where import Data.IORef+import Data.Monoid import Control.Monad import Control.Monad.Trans@@ -54,7 +56,7 @@ -- | The signal that can have disposable handlers. data Signal a = Signal { handleSignal :: (a -> Dynamics ()) -> - Simulation (Simulation ()),+ Dynamics (Dynamics ()), -- ^ Subscribe the handler to the specified -- signal and return a nested computation -- that, being applied, unsubscribes the @@ -76,7 +78,7 @@ -- | Subscribe the handler to the specified signal. -- To subscribe the disposable handlers, use function 'handleSignal'.-handleSignal_ :: Signal a -> (a -> Dynamics ()) -> Simulation ()+handleSignal_ :: Signal a -> (a -> Dynamics ()) -> Dynamics () handleSignal_ signal h = do x <- handleSignal signal h return ()@@ -94,13 +96,16 @@ source = SignalSource { publishSignal = signal, triggerSignal = trigger } handle h =- Simulation $ \r ->- do x <- enqueueSignalHandler queue h- return $ liftIO $ dequeueSignalHandler queue x+ Dynamics $ \p ->+ do invokeDynamics p update+ x <- enqueueSignalHandler queue h+ return $ + Dynamics $ \p ->+ do invokeDynamics p update+ dequeueSignalHandler queue x trigger a = Dynamics $ \p ->- do let Dynamics m = update - m p+ do invokeDynamics p update let h = queueStart queue triggerSignalHandlers h a p return source@@ -118,7 +123,7 @@ source = SignalSource { publishSignal = signal, triggerSignal = trigger } handle h =- Simulation $ \r ->+ Dynamics $ \p -> do x <- enqueueSignalHandler queue h return $ liftIO $ dequeueSignalHandler queue x trigger a =@@ -192,6 +197,24 @@ writeIORef (handlerPrev y) prev writeIORef (handlerNext x) next +instance Functor Signal where+ fmap = mapSignal+ +instance Monoid (Signal a) where + + mempty = emptySignal+ + mappend = merge2Signals+ + mconcat [] = emptySignal+ mconcat [x1] = x1+ mconcat [x1, x2] = merge2Signals x1 x2+ mconcat [x1, x2, x3] = merge3Signals x1 x2 x3+ mconcat [x1, x2, x3, x4] = merge4Signals x1 x2 x3 x4+ mconcat [x1, x2, x3, x4, x5] = merge5Signals x1 x2 x3 x4 x5+ mconcat (x1 : x2 : x3 : x4 : x5 : xs) = + mconcat $ merge5Signals x1 x2 x3 x4 x5 : xs+ -- | Map the signal according the specified function. mapSignal :: (a -> b) -> Signal a -> Signal b mapSignal f m =@@ -200,9 +223,6 @@ updateSignal = updateSignal m } -instance Functor Signal where- fmap = mapSignal- -- | Filter only those signal values that satisfy to -- the specified predicate. filterSignal :: (a -> Bool) -> Signal a -> Signal a@@ -297,3 +317,13 @@ handleSignal m $ \a -> do { x <- f; h (x a) }, updateSignal = updateSignal m }++-- | An empty signal which is never triggered.+emptySignal :: Signal a+emptySignal =+ Signal { handleSignal = \h -> return $ return (),+ updateSignal = return () }+ +invokeDynamics :: Point -> Dynamics a -> IO a+{-# INLINE invokeDynamics #-}+invokeDynamics p (Dynamics m) = m p
Simulation/Aivika/Dynamics/Ref.hs view
@@ -75,10 +75,9 @@ -- | Return a signal that notifies about every change of the reference state. refChanged :: Ref a -> Signal a-refChanged r = merge2Signals m1 m2- where- m1 = publishSignal (refChangedSource r)- m2 = publishSignal (refUpdatedSource r)+refChanged v = merge2Signals m1 m2 -- N.B. The order is important!+ where m1 = publishSignal (refUpdatedSource v)+ m2 = publishSignal (refChangedSource v) -- | Return a signal that notifies about every change of the reference state. refChanged_ :: Ref a -> Signal ()
Simulation/Aivika/Dynamics/Signal.hs view
@@ -32,6 +32,7 @@ apSignal, filterSignal, filterSignalM,+ emptySignal, merge2Signals, merge3Signals, merge4Signals,@@ -60,7 +61,7 @@ -- | Create a new signal source when the state depends on the event queue. newSignalSource :: EventQueue -> Simulation (SignalSource a) newSignalSource queue = - newSignalSourceWithUpdate $ runQueue queue+ newSignalSourceWithUpdate $ runQueueSync queue -- | Await the signal. awaitSignal :: Signal a -> Process a@@ -69,7 +70,7 @@ Cont $ \c -> Dynamics $ \p -> do r <- newIORef Nothing- let Simulation m = + let Dynamics m = handleSignal signal $ \a -> Dynamics $ \p -> do x <- readIORef r@@ -77,11 +78,11 @@ Nothing -> error "The signal was lost: awaitSignal." Just x ->- do let Simulation m = x- m $ pointRun p+ do let Dynamics m = x+ m p let Dynamics m = resumeContByParams c a m p- h <- m $ pointRun p+ h <- m p writeIORef r $ Just h -- | Represents the history of the signal values.@@ -92,7 +93,7 @@ signalHistoryValues :: V.Vector a } -- | Create a history of the signal values.-newSignalHistory :: Signal a -> Simulation (SignalHistory a)+newSignalHistory :: Signal a -> Dynamics (SignalHistory a) newSignalHistory signal = do ts <- liftIO UV.newVector xs <- liftIO V.newVector
Simulation/Aivika/Dynamics/UVar.hs view
@@ -146,9 +146,9 @@ -- | Return a signal that notifies about every change of the variable state. uvarChanged :: UVar a -> Signal a-uvarChanged v = merge2Signals m1 m2- where m1 = publishSignal (uvarChangedSource v)- m2 = publishSignal (uvarUpdatedSource v)+uvarChanged v = merge2Signals m1 m2 -- N.B. The order is important!+ where m1 = publishSignal (uvarUpdatedSource v)+ m2 = publishSignal (uvarChangedSource v) -- | Return a signal that notifies about every change of the variable state. uvarChanged_ :: UVar a -> Signal ()
Simulation/Aivika/Dynamics/Var.hs view
@@ -145,9 +145,9 @@ -- | Return a signal that notifies about every change of the variable state. varChanged :: Var a -> Signal a-varChanged v = merge2Signals m1 m2- where m1 = publishSignal (varChangedSource v)- m2 = publishSignal (varUpdatedSource v)+varChanged v = merge2Signals m1 m2 -- N.B. The order is important!+ where m1 = publishSignal (varUpdatedSource v)+ m2 = publishSignal (varChangedSource v) -- | Return a signal that notifies about every change of the variable state. varChanged_ :: Var a -> Signal ()
aivika.cabal view
@@ -1,5 +1,5 @@ name: aivika-version: 0.4.1+version: 0.4.2 synopsis: A multi-paradigm simulation library description: Aivika is a small simulation library that covers many paradigms.