-- |-- Module : Simulation.Aivika.Ref-- Copyright : Copyright (c) 2009-2017, David Sorokin <david.sorokin@gmail.com>-- License : BSD3-- Maintainer : David Sorokin <david.sorokin@gmail.com>-- Stability : experimental-- Tested with: GHC 8.0.1---- This module defines an updatable reference that depends on the event queue.--moduleSimulation.Aivika.Ref(Ref,refChanged,refChanged_,newRef,readRef,writeRef,modifyRef)whereimportData.IORefimportControl.MonadimportControl.Monad.TransimportSimulation.Aivika.Internal.SimulationimportSimulation.Aivika.Internal.EventimportSimulation.Aivika.Signal-- | The 'Ref' type represents a mutable variable similar to the 'IORef' variable -- but only dependent on the event queue, which allows synchronizing the reference-- with the model explicitly through the 'Event' monad.dataRefa=Ref{refValue::IORefa,refChangedSource::SignalSourcea}-- | Create a new reference.newRef::a->Simulation(Refa)newRefa=dox<-liftIO$newIORefas<-newSignalSourcereturnRef{refValue=x,refChangedSource=s}-- | Read the value of a reference.readRef::Refa->EventareadRefr=Event$\p->readIORef(refValuer)-- | Write a new value into the reference.writeRef::Refa->a->Event()writeRefra=Event$\p->doa`seq`writeIORef(refValuer)ainvokeEventp$triggerSignal(refChangedSourcer)a-- | Mutate the contents of the reference.modifyRef::Refa->(a->a)->Event()modifyRefrf=Event$\p->doa<-readIORef(refValuer)letb=fab`seq`writeIORef(refValuer)binvokeEventp$triggerSignal(refChangedSourcer)b-- | Return a signal that notifies about every change of the reference state.refChanged::Refa->SignalarefChangedv=publishSignal(refChangedSourcev)-- | Return a signal that notifies about every change of the reference state.refChanged_::Refa->Signal()refChanged_r=mapSignal(const())$refChangedr