Allow simulation stop handling in Simantics/Sequences
[simantics/platform.git] / bundles / org.simantics.simulation.sequences / scl / Simantics / Sequences.scl
1
2 /// Actions ///////////////////////////////////////////////////////////////////
3
4 effect Action 
5     "sequenceAction"
6     "org.simantics.simulation.sequences.action.ActionContext"
7
8 importJava "org.simantics.simulation.sequences.action.StopReason" where
9     data StopReason
10     STOPPED :: StopReason
11     SIMULATION_DID_NOT_START :: StopReason
12     DIVERGED :: StopReason
13     INTERRUPTED :: StopReason
14
15 importJava "org.simantics.simulation.sequences.action.ActionContext" where
16     data ActionContext
17     
18     @JavaName stop
19     stopActionContext :: ActionContext -> <Proc> ()
20
21     """Gives the current simulation time."""
22     time :: <Action> Double
23     @JavaName get
24     getVar_  :: String -> Binding a -> <Action> a
25     @JavaName set
26     setVar_  :: String -> a -> Binding a -> <Action> ()
27     
28     scheduleNow :: (() -> <Action,Proc> a) -> <Action> ()
29     scheduleNextStep :: (() -> <Action,Proc> a) -> <Action> ()
30     scheduleAt :: Double -> (() -> <Action,Proc> a) -> <Action> ()
31     scheduleWhenStopped :: (StopReason -> <Action,Proc> a) -> <Action> ()
32     @JavaName stop
33     stop_ :: <Action> ()
34
35 """Returns the current value of a variable"""
36 getVar :: Serializable a => String -> <Action> a
37 getVar variableName = getVar_ variableName binding
38
39 """Sets the value of a variable"""
40 setVar :: Serializable a => String -> a -> <Action> ()
41 setVar variableName value = setVar_ variableName value binding
42
43 /// Sequences /////////////////////////////////////////////////////////////////
44
45 """
46 `Sequence a` is a plan of some operations that may happen during the simulation and may take some
47 (simulation) time. A sequence is initiated at a specific time and it may either finish at a specific
48 time or operate forever. If it completes, it retuns a value of type `a`.
49 """
50 data Sequence a = Sequence ( (a -> <Action,Proc> ()) -> <Action,Proc> () )
51
52 @private
53 @inline
54 execSequence (Sequence f) cont = f cont
55
56 instance Functor Sequence where
57     @inline
58     fmap f seq = Sequence (\cont -> execSequence seq (cont . f))
59
60 instance Monad Sequence where
61     @inline
62     return v = Sequence (\cont -> cont v)
63     @inline
64     seq >>= f = Sequence (\cont -> execSequence seq (\result -> execSequence (f result) cont)) 
65
66 """
67 The sequence `execute action` is an instantious sequence that executes the operation `action` in the simulator.
68 """
69 @inline
70 execute :: (<Action,Proc> a) -> Sequence a
71 execute action = Sequence (\cont -> cont action)
72
73 @inline
74 executeWhenStopped :: (StopReason -> <Action,Proc> a) -> Sequence ()
75 executeWhenStopped handler = execute (scheduleWhenStopped handler)
76
77 """
78 The sequence `fork seq` is an instantious sequence that creates a new sequence thread behaving like the sequence `seq`.
79 """
80 fork :: Sequence a -> Sequence ()
81 fork seq = Sequence (\cont -> do { scheduleNow cont ; execSequence seq ignore })
82
83 """
84 The sequence `halt` ends the current sequence thread and the sequence .
85 """
86 halt :: Sequence a
87 halt = Sequence (\cont -> ())
88
89 """
90 The sequence `stop` stops all sequence threads, stopping the simulation completely.
91 """
92 stop :: Sequence a
93 stop = Sequence (\cont -> stop_)
94
95 """
96 The sequence `waitStep` waits that the simulator takes one simulation step.
97 It is a primitive mechanism that can be used to implement other events by
98 inspecting the simulator state after each time step.
99 """
100 waitStep :: Sequence ()
101 waitStep = Sequence (\cont -> scheduleNextStep cont)
102
103 """The sequence `waitUntil time` waits until the simulation time is at least the given `time`."""
104 waitUntil :: Double -> Sequence ()
105 waitUntil t = Sequence (\cont -> scheduleAt t cont)
106
107 """The sequence `wait duration` waits that `duration` seconds elapses from the current simulation time."""
108 wait :: Double -> Sequence ()
109 wait duration = Sequence (\cont -> scheduleAt (time+duration) cont)
110
111 """The sequence `waitCondition condition` waits until the `condition` is satisfied."""
112 waitCondition :: (<Action,Proc> Boolean) -> Sequence ()
113 waitCondition condition = Sequence (\cont ->
114     let loop _ = if condition
115                  then cont ()
116                  else scheduleNextStep loop 
117     in  loop ())
118