\begin{code}
module Delayed where
import IOExts
\end{code}


Support for delayed side-effects

The semantics of switcher/stepper/untilB says that the behavior changes
immediately after the occurrence time. In order to implement this semantics 
robustly, we don't update the behavior right away. Instead we add the update 
IO action to a collection of "pending actions". For each "primitive event" 
occurrence, we execute and clear the pending actions. For this to work, 
we must guarantee one important property. All of the delayed actions in the 
collection must be independent. We therefore need not assume any special 
ordering. The only time that we add delayed actions is to update a behavior
variable, and to set a cache to non-constant. Neither of these actions 
involve sampling another behavior, or event and they are therefore safely 
independent.

\begin{code}
delayInit :: IO DelayedActions 
delayInit = newIORef []

type DelayedActions = IORef [IO ()]

addDelayedAction :: IO () -> IO ()
addDelayedAction act = do
 xs <- readIORef delaysVar
 writeIORef delaysVar $! act:xs

-- Declare the new delayedAction time.  Clear out any old actions.
-- Delayed actions are executed in FIFO order
runDelayedActions :: IO ()
runDelayedActions = do
    readIORef  delaysVar >>= sequence_  . reverse -- execute them
    writeIORef delaysVar []

delaysVar :: DelayedActions
delaysVar = unsafePerformIO $ delayInit

{-# NOINLINE delaysVar #-}
\end{code}
