1 package org.opentrafficsim.simulationengine;
2
3 import javax.naming.NamingException;
4
5 import nl.tudelft.simulation.dsol.SimRuntimeException;
6 import nl.tudelft.simulation.dsol.experiment.ReplicationMode;
7 import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEvent;
8 import nl.tudelft.simulation.dsol.formalisms.eventscheduling.SimEventInterface;
9 import nl.tudelft.simulation.dsol.simulators.SimulatorInterface;
10
11 import org.opentrafficsim.core.dsol.OTSDEVSRealTimeClock;
12 import org.opentrafficsim.core.dsol.OTSModelInterface;
13 import org.opentrafficsim.core.dsol.OTSReplication;
14 import org.opentrafficsim.core.dsol.OTSSimTimeDouble;
15
16
17
18
19
20
21
22
23
24
25
26 public class SimpleAnimator extends OTSDEVSRealTimeClock implements SimpleSimulatorInterface
27 {
28
29 private static final long serialVersionUID = 20150511L;
30
31
32 private int lastReplication = 0;
33
34
35
36
37
38
39
40
41
42
43
44 public SimpleAnimator(final Time.Abs startTime, final Time.Rel warmupPeriod, final Time.Rel runLength,
45 final OTSModelInterface model) throws SimRuntimeException, NamingException
46 {
47 setPauseOnError(true);
48 initialize(new OTSReplication("rep" + ++this.lastReplication, new OTSSimTimeDouble(startTime), warmupPeriod,
49 runLength, model), ReplicationMode.TERMINATING);
50 }
51
52
53
54
55 public final SimEvent<OTSSimTimeDouble> scheduleEvent(final Time.Abs executionTime, final short priority,
56 final Object source, final Object target, final String method, final Object[] args) throws SimRuntimeException
57 {
58 SimEvent<OTSSimTimeDouble> result =
59 new SimEvent<OTSSimTimeDouble>(new OTSSimTimeDouble(new Time.Abs(executionTime.getSI(), SECOND)), priority,
60 source, target, method, args);
61 scheduleEvent(result);
62 return result;
63 }
64
65
66 @Override
67 @SuppressWarnings("checkstyle:designforextension")
68 public void run()
69 {
70 setAnimationDelay(20);
71 AnimationThread animationThread = new AnimationThread(this);
72 animationThread.start();
73
74 long clockTime0 = System.currentTimeMillis();
75 OTSSimTimeDouble simTime0 = this.simulatorTime;
76 double factor = getSpeedFactor();
77 double msec1 = relativeMillis(1.0).doubleValue();
78 Time.Rel r1 = this.relativeMillis(factor);
79
80 while (this.isRunning() && !this.eventList.isEmpty()
81 && this.simulatorTime.le(this.replication.getTreatment().getEndTime()))
82 {
83
84 if (factor != getSpeedFactor())
85 {
86 clockTime0 = System.currentTimeMillis();
87 simTime0 = this.simulatorTime;
88 factor = getSpeedFactor();
89 r1 = this.relativeMillis(factor);
90 }
91
92
93 SimEventInterface<OTSSimTimeDouble> event = this.eventList.first();
94 double simTimeDiffMillis = (event.getAbsoluteExecutionTime().minus(simTime0)).doubleValue() / (msec1 * factor);
95
96
97
98
99
100
101 if (simTimeDiffMillis < (System.currentTimeMillis() - clockTime0))
102 {
103
104 if (!isCatchup())
105 {
106
107 clockTime0 = System.currentTimeMillis();
108 simTime0 = this.simulatorTime;
109 }
110 else
111 {
112
113 this.fireTimedEvent(BACKLOG_EVENT, this.simulatorTime, null);
114 }
115 }
116 else
117 {
118 while (simTimeDiffMillis > System.currentTimeMillis() - clockTime0)
119 {
120 try
121 {
122 Thread.sleep(1);
123
124
125
126 if (factor != getSpeedFactor())
127 {
128 simTimeDiffMillis = 0.0;
129 }
130
131 }
132 catch (InterruptedException ie)
133 {
134
135 ie = null;
136 }
137
138
139
140 if (this.simulatorTime.plus(r1).lt(event.getAbsoluteExecutionTime()))
141 {
142 this.simulatorTime.add(r1);
143 }
144 }
145 }
146
147 synchronized (super.semaphore)
148 {
149 this.simulatorTime = event.getAbsoluteExecutionTime();
150 this.fireTimedEvent(SimulatorInterface.TIME_CHANGED_EVENT, this.simulatorTime, this.simulatorTime);
151
152
153 while (this.isRunning() && !this.eventList.isEmpty()
154 && event.getAbsoluteExecutionTime().eq(this.simulatorTime))
155 {
156 event = this.eventList.removeFirst();
157 try
158 {
159 event.execute();
160 }
161 catch (Exception exception)
162 {
163 exception.printStackTrace();
164 System.err.println(event.toString());
165 if (this.isPauseOnError())
166 {
167 this.stop();
168 }
169 }
170 if (!this.eventList.isEmpty())
171 {
172
173 event = this.eventList.first();
174 }
175 }
176 }
177 }
178 this.fireTimedEvent(SimulatorInterface.TIME_CHANGED_EVENT, this.simulatorTime, this.simulatorTime);
179 updateAnimation();
180 animationThread.stopAnimation();
181 }
182
183
184 @SuppressWarnings("checkstyle:designforextension")
185 public void runOld()
186 {
187 AnimationThread animationThread = new AnimationThread(this);
188 animationThread.start();
189
190 long clockTime0 = System.currentTimeMillis();
191 OTSSimTimeDouble simTime0 = this.simulatorTime;
192 double factor = getSpeedFactor();
193 double msec1 = relativeMillis(1.0).doubleValue();
194 Time.Rel r10 = this.relativeMillis(10.0 * factor);
195
196 while (this.isRunning() && !this.eventList.isEmpty()
197 && this.simulatorTime.le(this.replication.getTreatment().getEndTime()))
198 {
199
200 if (factor != getSpeedFactor())
201 {
202 clockTime0 = System.currentTimeMillis();
203 simTime0 = this.simulatorTime;
204 factor = getSpeedFactor();
205 r10 = this.relativeMillis(10.0 * factor);
206 }
207
208
209 SimEventInterface<OTSSimTimeDouble> event = this.eventList.first();
210 double simTimeDiffMillis = (event.getAbsoluteExecutionTime().minus(simTime0)).doubleValue() / (msec1 * factor);
211
212
213
214
215
216
217 if (simTimeDiffMillis < (System.currentTimeMillis() - clockTime0))
218 {
219
220 if (!isCatchup())
221 {
222
223 clockTime0 = System.currentTimeMillis();
224 simTime0 = this.simulatorTime;
225 }
226 else
227 {
228
229 this.fireTimedEvent(BACKLOG_EVENT, this.simulatorTime, null);
230 }
231 }
232 else
233 {
234 while (simTimeDiffMillis > System.currentTimeMillis() - clockTime0)
235 {
236 try
237 {
238 Thread.sleep(10);
239
240
241
242 if (factor != getSpeedFactor())
243 {
244 simTimeDiffMillis = 0.0;
245 }
246
247 }
248 catch (InterruptedException ie)
249 {
250
251 ie = null;
252 }
253
254
255
256 if (this.simulatorTime.plus(r10).lt(event.getAbsoluteExecutionTime()))
257 {
258 this.simulatorTime.add(r10);
259 this.fireTimedEvent(SimulatorInterface.TIME_CHANGED_EVENT, this.simulatorTime, this.simulatorTime);
260 updateAnimation();
261 }
262 }
263 }
264
265 synchronized (super.semaphore)
266 {
267 this.simulatorTime = event.getAbsoluteExecutionTime();
268 this.fireTimedEvent(SimulatorInterface.TIME_CHANGED_EVENT, this.simulatorTime, this.simulatorTime);
269
270
271 while (this.isRunning() && !this.eventList.isEmpty()
272 && event.getAbsoluteExecutionTime().eq(this.simulatorTime))
273 {
274 event = this.eventList.removeFirst();
275 try
276 {
277 event.execute();
278 }
279 catch (Exception exception)
280 {
281 exception.printStackTrace();
282 System.err.println(event.toString());
283 if (this.isPauseOnError())
284 {
285 this.stop();
286 }
287 }
288 if (!this.eventList.isEmpty())
289 {
290
291 event = this.eventList.first();
292 }
293 }
294 }
295 }
296 this.fireTimedEvent(SimulatorInterface.TIME_CHANGED_EVENT, this.simulatorTime, this.simulatorTime);
297 updateAnimation();
298 animationThread.stopAnimation();
299 }
300 }