X-Git-Url: https://gerrit.simantics.org/r/gitweb?p=simantics%2Fplatform.git;a=blobdiff_plain;f=bundles%2Forg.simantics.simulation.sequences%2Fscl%2FSimantics%2FSequences.scl;fp=bundles%2Forg.simantics.simulation.sequences%2Fscl%2FSimantics%2FSequences.scl;h=3960b960819244560b7b0d55d14adf11c8348009;hp=0000000000000000000000000000000000000000;hb=969bd23cab98a79ca9101af33334000879fb60c5;hpb=866dba5cd5a3929bbeae85991796acb212338a08 diff --git a/bundles/org.simantics.simulation.sequences/scl/Simantics/Sequences.scl b/bundles/org.simantics.simulation.sequences/scl/Simantics/Sequences.scl new file mode 100644 index 000000000..3960b9608 --- /dev/null +++ b/bundles/org.simantics.simulation.sequences/scl/Simantics/Sequences.scl @@ -0,0 +1,106 @@ + +/// Actions /////////////////////////////////////////////////////////////////// + +effect Action + "sequenceAction" + "org.simantics.simulation.sequences.action.ActionContext" + +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) -> () + @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) + +""" +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 ()) +