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-2013 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
// used namespaces
64
// ===========================================================================
65
using namespace
FXEX;
66
using namespace
std;
67
68
69
// ===========================================================================
70
// member method definitions
71
// ===========================================================================
72
GUIRunThread::GUIRunThread
(FXApp* app,
MFXInterThreadEventClient
* parent,
73
FXRealSpinDial
& simDelay,
MFXEventQue
& eq,
74
FXEX::FXThreadEvent
& ev)
75
:
FXSingleEventThread
(app, parent),
76
myNet(0), myHalting(true), myQuit(false), mySimulationInProgress(false), myOk(true),
77
mySimDelay(simDelay), myEventQue(eq), myEventThrow(ev) {
78
myErrorRetriever
=
new
MsgRetrievingFunction<GUIRunThread>
(
this
, &
GUIRunThread::retrieveMessage
,
MsgHandler::MT_ERROR
);
79
myMessageRetriever
=
new
MsgRetrievingFunction<GUIRunThread>
(
this
, &
GUIRunThread::retrieveMessage
,
MsgHandler::MT_MESSAGE
);
80
myWarningRetriever
=
new
MsgRetrievingFunction<GUIRunThread>
(
this
, &
GUIRunThread::retrieveMessage
,
MsgHandler::MT_WARNING
);
81
}
82
83
84
GUIRunThread::~GUIRunThread
() {
85
// the thread shall stop
86
myQuit
=
true
;
87
deleteSim
();
88
delete
myErrorRetriever
;
89
delete
myMessageRetriever
;
90
delete
myWarningRetriever
;
91
// wait for the thread
92
while
(
mySimulationInProgress
||
myNet
!= 0);
93
}
94
95
96
bool
97
GUIRunThread::init
(
GUINet
* net,
SUMOTime
start,
SUMOTime
end) {
98
assert(net != 0);
99
// assign new values
100
myNet
= net;
101
mySimStartTime
= start;
102
mySimEndTime
= end;
103
// register message callbacks
104
MsgHandler::getErrorInstance
()->
addRetriever
(
myErrorRetriever
);
105
MsgHandler::getMessageInstance
()->
addRetriever
(
myMessageRetriever
);
106
MsgHandler::getWarningInstance
()->
addRetriever
(
myWarningRetriever
);
107
// preload the routes especially for TraCI
108
mySimulationLock
.
lock
();
109
try
{
110
net->
loadRoutes
();
111
}
catch
(
ProcessError
& e2) {
112
if
(
string
(e2.what()) !=
string
(
"Process Error"
) && std::string(e2.what()) !=
string
(
""
)) {
113
WRITE_ERROR
(e2.what());
114
}
115
MsgHandler::getErrorInstance
()->
inform
(
"Quitting (on error)."
,
false
);
116
myHalting
=
true
;
117
myOk
=
false
;
118
mySimulationInProgress
=
false
;
119
#ifndef _DEBUG
120
}
catch
(...) {
121
myHalting
=
true
;
122
myOk
=
false
;
123
mySimulationInProgress
=
false
;
124
#endif
125
}
126
mySimulationLock
.
unlock
();
127
return
myOk
;
128
}
129
130
131
FXint
132
GUIRunThread::run
() {
133
long
beg = 0;
134
long
end = -1;
135
// perform an endless loop
136
while
(!
myQuit
) {
137
// if the simulation shall be perfomed, do it
138
if
(!
myHalting
&&
myNet
!= 0 &&
myOk
) {
139
if
(
getNet
().logSimulationDuration()) {
140
beg =
SysUtils::getCurrentMillis
();
141
if
(end != -1) {
142
getNet
().
setIdleDuration
((
int
)(beg - end));
143
}
144
}
145
// check whether we shall stop at this step
146
const
bool
haltAfter = find(
GUIGlobals::gBreakpoints
.
begin
(),
GUIGlobals::gBreakpoints
.end(),
myNet
->
getCurrentTimeStep
()) !=
GUIGlobals::gBreakpoints
.end();
147
// do the step
148
makeStep
();
149
// stop if wished
150
if
(haltAfter) {
151
stop
();
152
}
153
// wait if wanted
154
long
wait = (
long
)
mySimDelay
.
getValue
();
155
if
(
getNet
().logSimulationDuration()) {
156
end =
SysUtils::getCurrentMillis
();
157
getNet
().
setSimDuration
((
int
)(end - beg));
158
wait -= (end - beg);
159
}
160
if
(wait > 0) {
161
sleep
(wait);
162
}
163
}
else
{
164
// sleep if the simulation is not running
165
sleep
(500);
166
}
167
}
168
// delete a maybe existing simulation at the end
169
deleteSim
();
170
return
0;
171
}
172
173
174
void
175
GUIRunThread::makeStep
() {
176
GUIEvent
* e = 0;
177
// simulation is being perfomed
178
mySimulationInProgress
=
true
;
179
// execute a single step
180
try
{
181
mySimulationLock
.
lock
();
182
myNet
->
simulationStep
();
183
myNet
->
guiSimulationStep
();
184
mySimulationLock
.
unlock
();
185
186
// inform parent that a step has been performed
187
e =
new
GUIEvent_SimulationStep
();
188
myEventQue
.
add
(e);
189
myEventThrow
.
signal
();
190
191
e = 0;
192
MSNet::SimulationState
state =
myNet
->
simulationState
(
mySimEndTime
);
193
#ifndef NO_TRACI
194
if
(state !=
MSNet::SIMSTATE_RUNNING
) {
195
if
(
OptionsCont::getOptions
().getInt(
"remote-port"
) != 0 && !
traci::TraCIServer::wasClosed
()) {
196
state =
MSNet::SIMSTATE_RUNNING
;
197
}
198
}
199
#endif
200
switch
(state) {
201
case
MSNet::SIMSTATE_END_STEP_REACHED
:
202
case
MSNet::SIMSTATE_NO_FURTHER_VEHICLES
:
203
case
MSNet::SIMSTATE_CONNECTION_CLOSED
:
204
case
MSNet::SIMSTATE_TOO_MANY_VEHICLES
:
205
WRITE_MESSAGE
(
"Simulation ended at time: "
+
time2string
(
myNet
->
getCurrentTimeStep
()));
206
WRITE_MESSAGE
(
"Reason: "
+
MSNet::getStateMessage
(state));
207
e =
new
GUIEvent_SimulationEnded
(state,
myNet
->
getCurrentTimeStep
() -
DELTA_T
);
208
break
;
209
default
:
210
break
;
211
}
212
if
(e != 0) {
213
myEventQue
.
add
(e);
214
myEventThrow
.
signal
();
215
myHalting
=
true
;
216
}
217
// stop the execution when only a single step should have
218
// been performed
219
if
(
mySingle
) {
220
myHalting
=
true
;
221
}
222
// simulation step is over
223
mySimulationInProgress
=
false
;
224
}
catch
(
ProcessError
& e2) {
225
if
(
string
(e2.what()) !=
string
(
"Process Error"
) && std::string(e2.what()) !=
string
(
""
)) {
226
WRITE_ERROR
(e2.what());
227
}
228
MsgHandler::getErrorInstance
()->
inform
(
"Quitting (on error)."
,
false
);
229
mySimulationLock
.
unlock
();
230
mySimulationInProgress
=
false
;
231
e =
new
GUIEvent_SimulationEnded
(
MSNet::SIMSTATE_ERROR_IN_SIM
,
myNet
->
getCurrentTimeStep
());
232
myEventQue
.
add
(e);
233
myEventThrow
.
signal
();
234
myHalting
=
true
;
235
myOk
=
false
;
236
#ifndef _DEBUG
237
}
catch
(...) {
238
mySimulationLock
.
unlock
();
239
mySimulationInProgress
=
false
;
240
e =
new
GUIEvent_SimulationEnded
(
MSNet::SIMSTATE_ERROR_IN_SIM
,
myNet
->
getCurrentTimeStep
());
241
myEventQue
.
add
(e);
242
myEventThrow
.
signal
();
243
myHalting
=
true
;
244
myOk
=
false
;
245
#endif
246
}
247
}
248
249
250
void
251
GUIRunThread::resume
() {
252
mySingle
=
false
;
253
myHalting
=
false
;
254
}
255
256
257
void
258
GUIRunThread::singleStep
() {
259
mySingle
=
true
;
260
myHalting
=
false
;
261
}
262
263
264
void
265
GUIRunThread::begin
() {
266
// report the begin when wished
267
WRITE_MESSAGE
(
"Simulation started with time: "
+
time2string
(
mySimStartTime
));
268
myOk
=
true
;
269
}
270
271
272
void
273
GUIRunThread::stop
() {
274
mySingle
=
false
;
275
myHalting
=
true
;
276
}
277
278
279
bool
280
GUIRunThread::simulationAvailable
()
const
{
281
return
myNet
!= 0;
282
}
283
284
285
void
286
GUIRunThread::deleteSim
() {
287
myHalting
=
true
;
288
// remove message callbacks
289
MsgHandler::getErrorInstance
()->
removeRetriever
(
myErrorRetriever
);
290
MsgHandler::getWarningInstance
()->
removeRetriever
(
myWarningRetriever
);
291
MsgHandler::getMessageInstance
()->
removeRetriever
(
myMessageRetriever
);
292
//
293
mySimulationLock
.
lock
();
294
if
(
myNet
!= 0) {
295
myNet
->
closeSimulation
(
mySimStartTime
);
296
}
297
while
(
mySimulationInProgress
);
298
delete
myNet
;
299
GUIGlObjectStorage::gIDStorage
.
clear
();
300
myNet
= 0;
301
OutputDevice::closeAll
();
302
mySimulationLock
.
unlock
();
303
MsgHandler::cleanupOnEnd
();
304
}
305
306
307
GUINet
&
308
GUIRunThread::getNet
()
const
{
309
return
*
myNet
;
310
}
311
312
313
void
314
GUIRunThread::prepareDestruction
() {
315
myHalting
=
true
;
316
myQuit
=
true
;
317
}
318
319
320
void
321
GUIRunThread::retrieveMessage
(
const
MsgHandler::MsgType
type,
const
std::string& msg) {
322
GUIEvent
* e =
new
GUIEvent_Message
(type, msg);
323
myEventQue
.
add
(e);
324
myEventThrow
.
signal
();
325
}
326
327
328
bool
329
GUIRunThread::simulationIsStartable
()
const
{
330
return
myNet
!= 0 &&
myHalting
;
331
}
332
333
334
bool
335
GUIRunThread::simulationIsStopable
()
const
{
336
return
myNet
!= 0 && (!
myHalting
);
337
}
338
339
340
bool
341
GUIRunThread::simulationIsStepable
()
const
{
342
return
myNet
!= 0 &&
myHalting
;
343
}
344
345
346
347
/****************************************************************************/
348
build
buildd
sumo-0.18~dfsg
src
gui
GUIRunThread.cpp
Generated on Wed Oct 23 2013 01:15:08 for SUMO - Simulation of Urban MObility by
1.8.4