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