GUIRunThread.cpp
Go to the documentation of this file.00001
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifdef _MSC_VER
00025 #include <windows_config.h>
00026 #else
00027 #include <config.h>
00028 #endif
00029
00030 #include <cassert>
00031 #include <string>
00032 #include <iostream>
00033 #include <algorithm>
00034
00035 #include <utils/common/MsgRetrievingFunction.h>
00036 #include <utils/common/MsgHandler.h>
00037 #include <utils/common/UtilExceptions.h>
00038 #include <guisim/GUINet.h>
00039 #include <microsim/MSVehicleControl.h>
00040 #include <microsim/MSEmitControl.h>
00041 #include <utils/gui/events/GUIEvent_Message.h>
00042 #include <utils/gui/events/GUIEvent_SimulationStep.h>
00043 #include "GUIEvent_SimulationEnded.h"
00044 #include "GUIApplicationWindow.h"
00045 #include "GUIRunThread.h"
00046 #include "GUIGlobals.h"
00047 #include <utils/options/OptionsCont.h>
00048 #include <utils/gui/windows/GUIAppGlobals.h>
00049 #include <utils/common/SysUtils.h>
00050 #include <utils/iodevices/OutputDevice.h>
00051
00052 #ifndef NO_TRACI
00053 #include <traci-server/TraCIServer.h>
00054 #endif
00055
00056 #ifdef CHECK_MEMORY_LEAKS
00057 #include <foreign/nvwa/debug_new.h>
00058 #endif // CHECK_MEMORY_LEAKS
00059
00060
00061
00062
00063
00064 using namespace FXEX;
00065 using namespace std;
00066
00067
00068
00069
00070
00071 GUIRunThread::GUIRunThread(MFXInterThreadEventClient *parent,
00072 FXRealSpinDial &simDelay, MFXEventQue &eq,
00073 FXEX::FXThreadEvent &ev)
00074 : FXSingleEventThread(gFXApp, parent),
00075 myNet(0), myQuit(false), mySimulationInProgress(false), myOk(true),
00076 mySimDelay(simDelay), myEventQue(eq), myEventThrow(ev) {
00077 myErrorRetriever = new MsgRetrievingFunction<GUIRunThread>(this, &GUIRunThread::retrieveMessage, MsgHandler::MT_ERROR);
00078 myMessageRetriever = new MsgRetrievingFunction<GUIRunThread>(this, &GUIRunThread::retrieveMessage, MsgHandler::MT_MESSAGE);
00079 myWarningRetriever = new MsgRetrievingFunction<GUIRunThread>(this, &GUIRunThread::retrieveMessage, MsgHandler::MT_WARNING);
00080 }
00081
00082
00083 GUIRunThread::~GUIRunThread() {
00084
00085 myQuit = true;
00086 deleteSim();
00087 delete myErrorRetriever;
00088 delete myMessageRetriever;
00089 delete myWarningRetriever;
00090
00091 while (mySimulationInProgress||myNet!=0);
00092 }
00093
00094
00095 void
00096 GUIRunThread::init(GUINet *net, SUMOTime start, SUMOTime end) {
00097
00098 myNet = net;
00099 mySimStartTime = start;
00100 mySimEndTime = end;
00101
00102 MsgHandler::getErrorInstance()->addRetriever(myErrorRetriever);
00103 MsgHandler::getMessageInstance()->addRetriever(myMessageRetriever);
00104 MsgHandler::getWarningInstance()->addRetriever(myWarningRetriever);
00105 }
00106
00107
00108 FXint
00109 GUIRunThread::run() {
00110 long beg = 0;
00111 long end = 0;
00112 long end2 = -1;
00113
00114 while (!myQuit) {
00115
00116 if (!myHalting&&myNet!=0&&myOk) {
00117 if (getNet().logSimulationDuration()) {
00118 beg = SysUtils::getCurrentMillis();
00119 if (end2!=-1) {
00120 getNet().setIdleDuration((int)(beg-end2));
00121 }
00122 }
00123
00124 bool haltAfter =
00125 find(gBreakpoints.begin(), gBreakpoints.end(), myNet->getCurrentTimeStep())!=gBreakpoints.end();
00126
00127 makeStep();
00128
00129 if (haltAfter) {
00130 stop();
00131 }
00132
00133 SUMOReal val = (SUMOReal) mySimDelay.getValue();
00134 if (getNet().logSimulationDuration()) {
00135 end = SysUtils::getCurrentMillis();
00136 getNet().setSimDuration((int)(end-beg));
00137 end2 = SysUtils::getCurrentMillis();
00138 }
00139 if ((int) val!=0) {
00140 sleep((int) val);
00141 }
00142 } else {
00143
00144 sleep(500);
00145 }
00146 }
00147
00148 deleteSim();
00149 return 0;
00150 }
00151
00152
00153 void
00154 GUIRunThread::makeStep() throw() {
00155 GUIEvent *e = 0;
00156
00157 mySimulationInProgress = true;
00158
00159 try {
00160 mySimulationLock.lock();
00161 myNet->simulationStep();
00162 myNet->guiSimulationStep();
00163 mySimulationLock.unlock();
00164
00165
00166 e = new GUIEvent_SimulationStep();
00167 myEventQue.add(e);
00168 myEventThrow.signal();
00169
00170 e = 0;
00171 MSNet::SimulationState state = myNet->simulationState(mySimEndTime);
00172 #ifndef NO_TRACI
00173 if (state!=MSNet::SIMSTATE_RUNNING) {
00174 if (OptionsCont::getOptions().getInt("remote-port")!=0&&!traci::TraCIServer::wasClosed()) {
00175 state = MSNet::SIMSTATE_RUNNING;
00176 }
00177 }
00178 #endif
00179 switch (state) {
00180 case MSNet::SIMSTATE_END_STEP_REACHED:
00181 case MSNet::SIMSTATE_NO_FURTHER_VEHICLES:
00182 case MSNet::SIMSTATE_CONNECTION_CLOSED:
00183 case MSNet::SIMSTATE_TOO_MANY_VEHICLES:
00184 e = new GUIEvent_SimulationEnded(state, myNet->getCurrentTimeStep()-DELTA_T);
00185 break;
00186 default:
00187 break;
00188 }
00189 if (e!=0) {
00190 myEventQue.add(e);
00191 myEventThrow.signal();
00192 myHalting = true;
00193 }
00194
00195
00196 if (mySingle) {
00197 myHalting = true;
00198 }
00199
00200 mySimulationInProgress = false;
00201 } catch (ProcessError &e2) {
00202 if (string(e2.what())!=string("Process Error") && std::string(e2.what())!=string("")) {
00203 MsgHandler::getErrorInstance()->inform(e2.what());
00204 }
00205 MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
00206 mySimulationLock.unlock();
00207 mySimulationInProgress = false;
00208 e = new GUIEvent_SimulationEnded(MSNet::SIMSTATE_ERROR_IN_SIM, myNet->getCurrentTimeStep());
00209 myEventQue.add(e);
00210 myEventThrow.signal();
00211 myHalting = true;
00212 myOk = false;
00213 #ifndef _DEBUG
00214 } catch (...) {
00215 mySimulationLock.unlock();
00216 mySimulationInProgress = false;
00217 e = new GUIEvent_SimulationEnded(MSNet::SIMSTATE_ERROR_IN_SIM, myNet->getCurrentTimeStep());
00218 myEventQue.add(e);
00219 myEventThrow.signal();
00220 myHalting = true;
00221 myOk = false;
00222 #endif
00223 }
00224 }
00225
00226
00227 void
00228 GUIRunThread::resume() {
00229 mySingle = false;
00230 myHalting = false;
00231 }
00232
00233
00234 void
00235 GUIRunThread::singleStep() {
00236 mySingle = true;
00237 myHalting = false;
00238 }
00239
00240
00241 void
00242 GUIRunThread::begin() {
00243 myOk = true;
00244 }
00245
00246
00247 void
00248 GUIRunThread::stop() {
00249 mySingle = false;
00250 myHalting = true;
00251 }
00252
00253
00254 bool
00255 GUIRunThread::simulationAvailable() const {
00256 return myNet!=0;
00257 }
00258
00259
00260 void
00261 GUIRunThread::deleteSim() {
00262 myHalting = true;
00263
00264 MsgHandler::getErrorInstance()->removeRetriever(myErrorRetriever);
00265 MsgHandler::getWarningInstance()->removeRetriever(myWarningRetriever);
00266 MsgHandler::getMessageInstance()->removeRetriever(myMessageRetriever);
00267
00268 mySimulationLock.lock();
00269 if (myNet!=0) {
00270 myNet->closeSimulation(mySimStartTime);
00271 }
00272 while (mySimulationInProgress);
00273 delete myNet;
00274 myNet = 0;
00275 OutputDevice::closeAll();
00276 mySimulationLock.unlock();
00277 MsgHandler::cleanupOnEnd();
00278 }
00279
00280
00281 GUINet &
00282 GUIRunThread::getNet() const {
00283 return *myNet;
00284 }
00285
00286
00287 void
00288 GUIRunThread::prepareDestruction() {
00289 myHalting = true;
00290 myQuit = true;
00291 }
00292
00293
00294 void
00295 GUIRunThread::retrieveMessage(const MsgHandler::MsgType type, const std::string &msg) {
00296 GUIEvent *e = new GUIEvent_Message(type, msg);
00297 myEventQue.add(e);
00298 myEventThrow.signal();
00299 }
00300
00301
00302 bool
00303 GUIRunThread::simulationIsStartable() const {
00304 return myNet!=0&&myHalting;
00305 }
00306
00307
00308 bool
00309 GUIRunThread::simulationIsStopable() const {
00310 return myNet!=0&&(!myHalting);
00311 }
00312
00313
00314 bool
00315 GUIRunThread::simulationIsStepable() const {
00316 return myNet!=0&&myHalting;
00317 }
00318
00319
00320
00321
00322