GUIRunThread.cpp

Go to the documentation of this file.
00001 /****************************************************************************/
00007 // The thread that runs the simulation
00008 /****************************************************************************/
00009 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/
00010 // Copyright 2001-2010 DLR (http://www.dlr.de/) and contributors
00011 /****************************************************************************/
00012 //
00013 //   This program is free software; you can redistribute it and/or modify
00014 //   it under the terms of the GNU General Public License as published by
00015 //   the Free Software Foundation; either version 2 of the License, or
00016 //   (at your option) any later version.
00017 //
00018 /****************************************************************************/
00019 
00020 
00021 // ===========================================================================
00022 // included modules
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 // used namespaces
00063 // ===========================================================================
00064 using namespace FXEX;
00065 using namespace std;
00066 
00067 
00068 // ===========================================================================
00069 // member method definitions
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     // the thread shall stop
00085     myQuit = true;
00086     deleteSim();
00087     delete myErrorRetriever;
00088     delete myMessageRetriever;
00089     delete myWarningRetriever;
00090     // wait for the thread
00091     while (mySimulationInProgress||myNet!=0);
00092 }
00093 
00094 
00095 void
00096 GUIRunThread::init(GUINet *net, SUMOTime start, SUMOTime end) {
00097     // assign new values
00098     myNet = net;
00099     mySimStartTime = start;
00100     mySimEndTime = end;
00101     // register message callbacks
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     // perform an endless loop
00114     while (!myQuit) {
00115         // if the simulation shall be perfomed, do it
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             // check whether we shall stop at this step
00124             bool haltAfter =
00125                 find(gBreakpoints.begin(), gBreakpoints.end(), myNet->getCurrentTimeStep())!=gBreakpoints.end();
00126             // do the step
00127             makeStep();
00128             // stop if wished
00129             if (haltAfter) {
00130                 stop();
00131             }
00132             // wait if wanted
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             // sleep if the siulation is not running
00144             sleep(500);
00145         }
00146     }
00147     // delete a maybe existing simulation at the end
00148     deleteSim();
00149     return 0;
00150 }
00151 
00152 
00153 void
00154 GUIRunThread::makeStep() throw() {
00155     GUIEvent *e = 0;
00156     // simulation is being perfomed
00157     mySimulationInProgress = true;
00158     // execute a single step
00159     try {
00160         mySimulationLock.lock();
00161         myNet->simulationStep();
00162         myNet->guiSimulationStep();
00163         mySimulationLock.unlock();
00164 
00165         // inform parent that a step has been performed
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         // stop the execution when only a single step should have
00195         //  been performed
00196         if (mySingle) {
00197             myHalting = true;
00198         }
00199         // simulation step is over
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     // remove message callbacks
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 

Generated on Wed May 5 00:06:30 2010 for Sumo - Simulation of Urban MObility by  doxygen 1.5.6