/// Actions /////////////////////////////////////////////////////////////////// effect Action "sequenceAction" "org.simantics.simulation.sequences.action.ActionContext" importJava "org.simantics.simulation.sequences.action.StopReason" where data StopReason STOPPED :: StopReason SIMULATION_DID_NOT_START :: StopReason DIVERGED :: StopReason INTERRUPTED :: StopReason importJava "org.simantics.simulation.sequences.action.ActionContext" where data ActionContext @JavaName stop stopActionContext :: ActionContext -> () """Gives the current simulation time.""" time :: Double @JavaName get getVar_ :: String -> Binding a -> a @JavaName set setVar_ :: String -> a -> Binding a -> () scheduleNow :: (() -> a) -> () scheduleNextStep :: (() -> a) -> () scheduleAt :: Double -> (() -> a) -> () scheduleWhenStopped :: (StopReason -> a) -> () @JavaName stop stop_ :: () """Returns the current value of a variable""" getVar :: Serializable a => String -> a getVar variableName = getVar_ variableName binding """Sets the value of a variable""" setVar :: Serializable a => String -> a -> () setVar variableName value = setVar_ variableName value binding /// Sequences ///////////////////////////////////////////////////////////////// """ `Sequence a` is a plan of some operations that may happen during the simulation and may take some (simulation) time. A sequence is initiated at a specific time and it may either finish at a specific time or operate forever. If it completes, it retuns a value of type `a`. """ data Sequence a = Sequence ( (a -> ()) -> () ) @private @inline execSequence (Sequence f) cont = f cont instance Functor Sequence where @inline fmap f seq = Sequence (\cont -> execSequence seq (cont . f)) instance Monad Sequence where @inline return v = Sequence (\cont -> cont v) @inline seq >>= f = Sequence (\cont -> execSequence seq (\result -> execSequence (f result) cont)) """ The sequence `execute action` is an instantious sequence that executes the operation `action` in the simulator. """ @inline execute :: ( a) -> Sequence a execute action = Sequence (\cont -> cont action) @inline executeWhenStopped :: (StopReason -> a) -> Sequence () executeWhenStopped handler = execute (scheduleWhenStopped handler) """ The sequence `fork seq` is an instantious sequence that creates a new sequence thread behaving like the sequence `seq`. """ fork :: Sequence a -> Sequence () fork seq = Sequence (\cont -> do { scheduleNow cont ; execSequence seq ignore }) """ The sequence `halt` ends the current sequence thread and the sequence . """ halt :: Sequence a halt = Sequence (\cont -> ()) """ The sequence `stop` stops all sequence threads, stopping the simulation completely. """ stop :: Sequence a stop = Sequence (\cont -> stop_) """ The sequence `waitStep` waits that the simulator takes one simulation step. It is a primitive mechanism that can be used to implement other events by inspecting the simulator state after each time step. """ waitStep :: Sequence () waitStep = Sequence (\cont -> scheduleNextStep cont) """The sequence `waitUntil time` waits until the simulation time is at least the given `time`.""" waitUntil :: Double -> Sequence () waitUntil t = Sequence (\cont -> scheduleAt t cont) """The sequence `wait duration` waits that `duration` seconds elapses from the current simulation time.""" wait :: Double -> Sequence () wait duration = Sequence (\cont -> scheduleAt (time+duration) cont) """The sequence `waitCondition condition` waits until the `condition` is satisfied.""" waitCondition :: ( Boolean) -> Sequence () waitCondition condition = Sequence (\cont -> let loop _ = if condition then cont () else scheduleNextStep loop in loop ())