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