SUMO - Simulation of Urban MObility
Main Page
Related Pages
Modules
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
GUIRunThread.cpp
Go to the documentation of this file.
1
/****************************************************************************/
9
// The thread that runs the simulation
10
/****************************************************************************/
11
// SUMO, Simulation of Urban MObility; see http://sumo-sim.org/
12
// Copyright (C) 2001-2014 DLR (http://www.dlr.de/) and contributors
13
/****************************************************************************/
14
//
15
// This file is part of SUMO.
16
// SUMO is free software: you can redistribute it and/or modify
17
// it under the terms of the GNU General Public License as published by
18
// the Free Software Foundation, either version 3 of the License, or
19
// (at your option) any later version.
20
//
21
/****************************************************************************/
22
23
24
// ===========================================================================
25
// included modules
26
// ===========================================================================
27
#ifdef _MSC_VER
28
#include <
windows_config.h
>
29
#else
30
#include <
config.h
>
31
#endif
32
33
#include <cassert>
34
#include <string>
35
#include <iostream>
36
#include <algorithm>
37
38
#include <
guisim/GUINet.h
>
39
#include <
utils/gui/events/GUIEvent_Message.h
>
40
#include <
utils/gui/events/GUIEvent_SimulationStep.h
>
41
#include "
GUIEvent_SimulationEnded.h
"
42
#include "
GUIApplicationWindow.h
"
43
#include "
GUIRunThread.h
"
44
#include "
GUIGlobals.h
"
45
#include <
microsim/MSVehicleControl.h
>
46
#include <
utils/options/OptionsCont.h
>
47
#include <
utils/common/SysUtils.h
>
48
#include <
utils/common/MsgRetrievingFunction.h
>
49
#include <
utils/common/MsgHandler.h
>
50
#include <
utils/common/UtilExceptions.h
>
51
#include <
utils/iodevices/OutputDevice.h
>
52
53
#ifndef NO_TRACI
54
#include <
traci-server/TraCIServer.h
>
55
#endif
56
57
#ifdef CHECK_MEMORY_LEAKS
58
#include <
foreign/nvwa/debug_new.h
>
59
#endif // CHECK_MEMORY_LEAKS
60
61
62
// ===========================================================================
63
// member method definitions
64
// ===========================================================================
65
GUIRunThread::GUIRunThread
(FXApp* app,
MFXInterThreadEventClient
* parent,
66
FXRealSpinDial
& simDelay,
MFXEventQue
& eq,
67
FXEX::FXThreadEvent
& ev)
68
:
FXSingleEventThread
(app, parent),
69
myNet(0), myHalting(true), myQuit(false), mySimulationInProgress(false), myOk(true),
70
mySimDelay(simDelay), myEventQue(eq), myEventThrow(ev) {
71
myErrorRetriever
=
new
MsgRetrievingFunction<GUIRunThread>
(
this
, &
GUIRunThread::retrieveMessage
,
MsgHandler::MT_ERROR
);
72
myMessageRetriever
=
new
MsgRetrievingFunction<GUIRunThread>
(
this
, &
GUIRunThread::retrieveMessage
,
MsgHandler::MT_MESSAGE
);
73
myWarningRetriever
=
new
MsgRetrievingFunction<GUIRunThread>
(
this
, &
GUIRunThread::retrieveMessage
,
MsgHandler::MT_WARNING
);
74
}
75
76
77
GUIRunThread::~GUIRunThread
() {
78
// the thread shall stop
79
myQuit
=
true
;
80
deleteSim
();
81
delete
myErrorRetriever
;
82
delete
myMessageRetriever
;
83
delete
myWarningRetriever
;
84
// wait for the thread
85
while
(
mySimulationInProgress
||
myNet
!= 0);
86
}
87
88
89
bool
90
GUIRunThread::init
(
GUINet
* net,
SUMOTime
start,
SUMOTime
end) {
91
assert(net != 0);
92
// assign new values
93
myNet
= net;
94
mySimStartTime
= start;
95
mySimEndTime
= end;
96
// register message callbacks
97
MsgHandler::getErrorInstance
()->
addRetriever
(
myErrorRetriever
);
98
MsgHandler::getMessageInstance
()->
addRetriever
(
myMessageRetriever
);
99
if
(!
OptionsCont::getOptions
().getBool(
"no-warnings"
)) {
100
MsgHandler::getWarningInstance
()->
addRetriever
(
myWarningRetriever
);
101
}
102
// preload the routes especially for TraCI
103
mySimulationLock
.
lock
();
104
try
{
105
net->
setCurrentTimeStep
(start);
106
net->
loadRoutes
();
107
}
catch
(
ProcessError
& e2) {
108
if
(std::string(e2.what()) != std::string(
"Process Error"
) && std::string(e2.what()) != std::string(
""
)) {
109
WRITE_ERROR
(e2.what());
110
}
111
MsgHandler::getErrorInstance
()->
inform
(
"Quitting (on error)."
,
false
);
112
myHalting
=
true
;
113
myOk
=
false
;
114
mySimulationInProgress
=
false
;
115
#ifndef _DEBUG
116
}
catch
(...) {
117
myHalting
=
true
;
118
myOk
=
false
;
119
mySimulationInProgress
=
false
;
120
#endif
121
}
122
mySimulationLock
.
unlock
();
123
return
myOk
;
124
}
125
126
127
FXint
128
GUIRunThread::run
() {
129
long
beg = 0;
130
long
end = -1;
131
// perform an endless loop
132
while
(!
myQuit
) {
133
// if the simulation shall be perfomed, do it
134
if
(!
myHalting
&&
myNet
!= 0 &&
myOk
) {
135
if
(
getNet
().logSimulationDuration()) {
136
beg =
SysUtils::getCurrentMillis
();
137
if
(end != -1) {
138
getNet
().
setIdleDuration
((
int
)(beg - end));
139
}
140
}
141
// check whether we shall stop at this step
142
myBreakpointLock
.
lock
();
143
const
bool
haltAfter = find(
myBreakpoints
.begin(),
myBreakpoints
.end(),
myNet
->
getCurrentTimeStep
()) !=
myBreakpoints
.end();
144
myBreakpointLock
.
unlock
();
145
// do the step
146
makeStep
();
147
// stop if wished
148
if
(haltAfter) {
149
stop
();
150
}
151
// wait if wanted
152
long
wait = (
long
)
mySimDelay
.
getValue
();
153
if
(
getNet
().logSimulationDuration()) {
154
end =
SysUtils::getCurrentMillis
();
155
getNet
().
setSimDuration
((
int
)(end - beg));
156
wait -= (end - beg);
157
}
158
if
(wait > 0) {
159
sleep
(wait);
160
}
161
}
else
{
162
// sleep if the simulation is not running
163
sleep
(500);
164
}
165
}
166
// delete a maybe existing simulation at the end
167
deleteSim
();
168
return
0;
169
}
170
171
172
void
173
GUIRunThread::makeStep
() {
174
GUIEvent
* e = 0;
175
// simulation is being perfomed
176
mySimulationInProgress
=
true
;
177
// execute a single step
178
try
{
179
mySimulationLock
.
lock
();
180
myNet
->
simulationStep
();
181
myNet
->
guiSimulationStep
();
182
mySimulationLock
.
unlock
();
183
184
// inform parent that a step has been performed
185
e =
new
GUIEvent_SimulationStep
();
186
myEventQue
.
add
(e);
187
myEventThrow
.
signal
();
188
189
e = 0;
190
MSNet::SimulationState
state =
myNet
->
simulationState
(
mySimEndTime
);
191
#ifndef NO_TRACI
192
if
(state !=
MSNet::SIMSTATE_RUNNING
) {
193
if
(
OptionsCont::getOptions
().getInt(
"remote-port"
) != 0 && !
TraCIServer::wasClosed
()) {
194
state =
MSNet::SIMSTATE_RUNNING
;
195
}
196
}
197
#endif
198
switch
(state) {
199
case
MSNet::SIMSTATE_END_STEP_REACHED
:
200
case
MSNet::SIMSTATE_NO_FURTHER_VEHICLES
:
201
case
MSNet::SIMSTATE_CONNECTION_CLOSED
:
202
case
MSNet::SIMSTATE_TOO_MANY_VEHICLES
:
203
WRITE_MESSAGE
(
"Simulation ended at time: "
+
time2string
(
myNet
->
getCurrentTimeStep
()));
204
WRITE_MESSAGE
(
"Reason: "
+
MSNet::getStateMessage
(state));
205
e =
new
GUIEvent_SimulationEnded
(state,
myNet
->
getCurrentTimeStep
() -
DELTA_T
);
206
break
;
207
default
:
208
break
;
209
}
210
if
(e != 0) {
211
myEventQue
.
add
(e);
212
myEventThrow
.
signal
();
213
myHalting
=
true
;
214
}
215
// stop the execution when only a single step should have
216
// been performed
217
if
(
mySingle
) {
218
myHalting
=
true
;
219
}
220
// simulation step is over
221
mySimulationInProgress
=
false
;
222
}
catch
(
ProcessError
& e2) {
223
if
(std::string(e2.what()) != std::string(
"Process Error"
) && std::string(e2.what()) != std::string(
""
)) {
224
WRITE_ERROR
(e2.what());
225
}
226
MsgHandler::getErrorInstance
()->
inform
(
"Quitting (on error)."
,
false
);
227
mySimulationLock
.
unlock
();
228
mySimulationInProgress
=
false
;
229
e =
new
GUIEvent_SimulationEnded
(
MSNet::SIMSTATE_ERROR_IN_SIM
,
myNet
->
getCurrentTimeStep
());
230
myEventQue
.
add
(e);
231
myEventThrow
.
signal
();
232
myHalting
=
true
;
233
myOk
=
false
;
234
#ifndef _DEBUG
235
}
catch
(...) {
236
mySimulationLock
.
unlock
();
237
mySimulationInProgress
=
false
;
238
e =
new
GUIEvent_SimulationEnded
(
MSNet::SIMSTATE_ERROR_IN_SIM
,
myNet
->
getCurrentTimeStep
());
239
myEventQue
.
add
(e);
240
myEventThrow
.
signal
();
241
myHalting
=
true
;
242
myOk
=
false
;
243
#endif
244
}
245
}
246
247
248
void
249
GUIRunThread::resume
() {
250
mySingle
=
false
;
251
myHalting
=
false
;
252
}
253
254
255
void
256
GUIRunThread::singleStep
() {
257
mySingle
=
true
;
258
myHalting
=
false
;
259
}
260
261
262
void
263
GUIRunThread::begin
() {
264
// report the begin when wished
265
WRITE_MESSAGE
(
"Simulation started with time: "
+
time2string
(
mySimStartTime
));
266
myOk
=
true
;
267
}
268
269
270
void
271
GUIRunThread::stop
() {
272
mySingle
=
false
;
273
myHalting
=
true
;
274
}
275
276
277
bool
278
GUIRunThread::simulationAvailable
()
const
{
279
return
myNet
!= 0;
280
}
281
282
283
void
284
GUIRunThread::deleteSim
() {
285
myHalting
=
true
;
286
// remove message callbacks
287
MsgHandler::getErrorInstance
()->
removeRetriever
(
myErrorRetriever
);
288
MsgHandler::getWarningInstance
()->
removeRetriever
(
myWarningRetriever
);
289
MsgHandler::getMessageInstance
()->
removeRetriever
(
myMessageRetriever
);
290
//
291
mySimulationLock
.
lock
();
292
if
(
myNet
!= 0) {
293
myNet
->
closeSimulation
(
mySimStartTime
);
294
}
295
while
(
mySimulationInProgress
);
296
delete
myNet
;
297
GUIGlObjectStorage::gIDStorage
.
clear
();
298
myNet
= 0;
299
OutputDevice::closeAll
();
300
mySimulationLock
.
unlock
();
301
MsgHandler::cleanupOnEnd
();
302
}
303
304
305
GUINet
&
306
GUIRunThread::getNet
()
const
{
307
return
*
myNet
;
308
}
309
310
311
void
312
GUIRunThread::prepareDestruction
() {
313
myHalting
=
true
;
314
myQuit
=
true
;
315
}
316
317
318
void
319
GUIRunThread::retrieveMessage
(
const
MsgHandler::MsgType
type,
const
std::string& msg) {
320
GUIEvent
* e =
new
GUIEvent_Message
(type, msg);
321
myEventQue
.
add
(e);
322
myEventThrow
.
signal
();
323
}
324
325
326
bool
327
GUIRunThread::simulationIsStartable
()
const
{
328
return
myNet
!= 0 &&
myHalting
;
329
}
330
331
332
bool
333
GUIRunThread::simulationIsStopable
()
const
{
334
return
myNet
!= 0 && (!
myHalting
);
335
}
336
337
338
bool
339
GUIRunThread::simulationIsStepable
()
const
{
340
return
myNet
!= 0 &&
myHalting
;
341
}
342
343
344
345
/****************************************************************************/
346
tmp
buildd
sumo-0.21.0+dfsg
src
gui
GUIRunThread.cpp
Generated on Thu Nov 20 2014 19:49:54 for SUMO - Simulation of Urban MObility by
1.8.1.2