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