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