Eclipse SUMO - Simulation of Urban MObility
GUIRunThread.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo
3 // Copyright (C) 2001-2019 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials
5 // are made available under the terms of the Eclipse Public License v2.0
6 // which accompanies this distribution, and is available at
7 // http://www.eclipse.org/legal/epl-v20.html
8 // SPDX-License-Identifier: EPL-2.0
9 /****************************************************************************/
16 // The thread that runs the simulation
17 /****************************************************************************/
18 
19 
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24 
25 #include <cassert>
26 #include <string>
27 #include <iostream>
28 #include <algorithm>
29 
30 #include <guisim/GUINet.h>
34 #include "GUIApplicationWindow.h"
35 #include "GUIRunThread.h"
36 #include "GUIGlobals.h"
40 #include <utils/common/SysUtils.h>
46 #include <libsumo/Simulation.h>
47 
48 
49 // ===========================================================================
50 // member method definitions
51 // ===========================================================================
53  double& simDelay, FXSynchQue<GUIEvent*>& eq,
55  : FXSingleEventThread(app, parent),
56  myNet(nullptr), myHalting(true), myQuit(false), mySimulationInProgress(false), myOk(true), myHaveSignaledEnd(false),
57  mySimDelay(simDelay), myEventQue(eq), myEventThrow(ev) {
61 }
62 
63 
65  // the thread shall stop
66  myQuit = true;
67  deleteSim();
68  delete myErrorRetriever;
69  delete myMessageRetriever;
70  delete myWarningRetriever;
71  // wait for the thread
72  while (mySimulationInProgress || myNet != nullptr);
73 }
74 
75 
76 bool
78  assert(net != 0);
79  // assign new values
80  myOk = true;
81  myNet = net;
82  mySimStartTime = start;
83  mySimEndTime = end;
84  // register message callbacks
87  if (!OptionsCont::getOptions().getBool("no-warnings")) {
89  }
90  // preload the routes especially for TraCI
91  mySimulationLock.lock();
92  try {
93  net->setCurrentTimeStep(start);
94  net->loadRoutes();
95  } catch (ProcessError& e2) {
96  if (std::string(e2.what()) != std::string("Process Error") && std::string(e2.what()) != std::string("")) {
97  WRITE_ERROR(e2.what());
98  }
99  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
100  myHalting = true;
101  myOk = false;
102  mySimulationInProgress = false;
103 #ifndef _DEBUG
104  } catch (...) {
105  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
106  myHalting = true;
107  myOk = false;
108  mySimulationInProgress = false;
109 #endif
110  }
111  mySimulationLock.unlock();
112  return myOk;
113 }
114 
115 
116 FXint
118  long beg = 0;
119  long end = -1;
120  // perform an endless loop
121  while (!myQuit) {
122  // if the simulation shall be perfomed, do it
123  if (!myHalting && myNet != nullptr && myOk) {
125  if (end != -1) {
126  getNet().setIdleDuration((int)(beg - end));
127  }
128  // check whether we shall stop at this step
129  myBreakpointLock.lock();
130  const bool haltAfter = std::find(myBreakpoints.begin(), myBreakpoints.end(), myNet->getCurrentTimeStep()) != myBreakpoints.end();
131  myBreakpointLock.unlock();
132  // do the step
133  makeStep();
135  // stop if wished
136  if (haltAfter) {
137  stop();
138  }
139  // wait if wanted (delay is per simulated second)
140  long wait = (long)(mySimDelay * TS);
142  getNet().setSimDuration((int)(end - beg));
143  wait -= (end - beg);
144  if (wait > 0) {
145  sleep(wait);
146  }
147  } else {
148  // sleep if the simulation is not running
149  sleep(50);
150  }
151  }
152  // delete a maybe existing simulation at the end
153  deleteSim();
154  return 0;
155 }
156 
157 
158 void
160  GUIEvent* e = nullptr;
161  // simulation is being perfomed
162  mySimulationInProgress = true;
163  // execute a single step
164  try {
165  mySimulationLock.lock();
168  mySimulationLock.unlock();
169 
170  // inform parent that a step has been performed
171  e = new GUIEvent_SimulationStep();
174 
175  e = nullptr;
177  if (state == MSNet::SIMSTATE_LOADING) {
180  } else if (state != MSNet::SIMSTATE_RUNNING) {
181  if (TraCIServer::getInstance() != nullptr && !TraCIServer::wasClosed()) {
182  state = MSNet::SIMSTATE_RUNNING;
183  }
184  }
185  switch (state) {
192  WRITE_MESSAGE("Simulation ended at time: " + time2string(myNet->getCurrentTimeStep()));
193  WRITE_MESSAGE("Reason: " + MSNet::getStateMessage(state));
195  // ensure that files are closed (deleteSim is called a bit later by the gui thread)
196  // MSNet destructor may trigger MsgHandler (via routing device cleanup). Closing output devices here is not safe
197  // OutputDevice::closeAll();
198  myHaveSignaledEnd = true;
199  }
200  break;
201  default:
202  break;
203  }
204  if (e != nullptr) {
207  myHalting = true;
208  }
209  // stop the execution when only a single step should have
210  // been performed
211  if (mySingle) {
212  myHalting = true;
213  }
214  // simulation step is over
215  mySimulationInProgress = false;
216  } catch (ProcessError& e2) {
217  if (std::string(e2.what()) != std::string("Process Error") && std::string(e2.what()) != std::string("")) {
218  WRITE_ERROR(e2.what());
219  }
220  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
221  mySimulationLock.unlock();
222  mySimulationInProgress = false;
226  myHalting = true;
227  myOk = false;
228 #ifndef _DEBUG
229  } catch (...) {
230  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
231  mySimulationLock.unlock();
232  mySimulationInProgress = false;
236  myHalting = true;
237  myOk = false;
238 #endif
239  }
240 }
241 
242 
243 void
245  mySingle = false;
246  myHalting = false;
247 }
248 
249 
250 void
252  mySingle = true;
253  myHalting = false;
254 }
255 
256 
257 void
259  // report the begin when wished
260  WRITE_MESSAGE("Simulation started with time: " + time2string(mySimStartTime));
261  myOk = true;
262 }
263 
264 
265 void
267  mySingle = false;
268  myHalting = true;
269 }
270 
271 
272 bool
274  return myNet != nullptr;
275 }
276 
277 
278 void
280  myHalting = true;
281  // remove message callbacks
285  //
286  mySimulationLock.lock();
287  if (myNet != nullptr) {
289  }
290  while (mySimulationInProgress);
291  delete myNet;
293  myNet = nullptr;
295  mySimulationLock.unlock();
297 }
298 
299 
300 GUINet&
302  return *myNet;
303 }
304 
305 
306 void
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);
318 }
319 
320 
321 bool
323  return myNet != nullptr && myHalting;
324 }
325 
326 
327 bool
329  return myNet != nullptr && (!myHalting);
330 }
331 
332 
333 bool
335  return myNet != nullptr && myHalting;
336 }
337 
338 
339 void
342  if (mw != nullptr) {
343  for (GUIGlChildWindow* const window : mw->getViews()) {
344  window->getView()->waitForSnapshots(snapshotTime);
345  }
346  }
347 }
348 
349 
350 /****************************************************************************/
GUINet::setIdleDuration
void setIdleDuration(int val)
Sets the duration of the last step's idle part.
Definition: GUINet.cpp:404
MsgHandler::MsgType
MsgType
Definition: MsgHandler.h:45
MsgHandler::MT_ERROR
The message is an error.
Definition: MsgHandler.h:51
GUIRunThread::mySimStartTime
SUMOTime mySimStartTime
the times the simulation starts and ends with
Definition: GUIRunThread.h:126
GUIRunThread::simulationIsStopable
virtual bool simulationIsStopable() const
Definition: GUIRunThread.cpp:328
MFXInterThreadEventClient
Definition: MFXInterThreadEventClient.h:27
GUIRunThread::singleStep
void singleStep()
Definition: GUIRunThread.cpp:251
FXSingleEventThread::sleep
static void sleep(long ms)
Definition: FXSingleEventThread.cpp:140
GUIRunThread::myBreakpointLock
FXMutex myBreakpointLock
Lock for modifying the list of breakpoints.
Definition: GUIRunThread.h:164
OutputDevice::closeAll
static void closeAll(bool keepErrorRetrievers=false)
Definition: OutputDevice.cpp:126
DELTA_T
SUMOTime DELTA_T
Definition: SUMOTime.cpp:36
GUIRunThread::makeStep
void makeStep()
Definition: GUIRunThread.cpp:159
GUIRunThread::myHaveSignaledEnd
bool myHaveSignaledEnd
whether the simulation already ended
Definition: GUIRunThread.h:146
OptionsCont.h
MsgHandler::MT_MESSAGE
The message is only something to show.
Definition: MsgHandler.h:47
GUIRunThread::begin
virtual void begin()
Definition: GUIRunThread.cpp:258
MSNet::simulationState
SimulationState simulationState(SUMOTime stopTime) const
Called after a simulation step, this method returns the current simulation state.
Definition: MSNet.cpp:592
MsgHandler.h
MsgRetrievingFunction
Encapsulates an object's method for using it as a message retriever.
Definition: MsgRetrievingFunction.h:41
MsgHandler::MT_WARNING
The message is a warning.
Definition: MsgHandler.h:49
GUIRunThread::mySingle
bool mySingle
Definition: GUIRunThread.h:143
MsgHandler::inform
virtual void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:118
SUMOTime
long long int SUMOTime
Definition: SUMOTime.h:34
GUIRunThread::myOk
bool myOk
Definition: GUIRunThread.h:140
GUIRunThread::~GUIRunThread
virtual ~GUIRunThread()
destructor
Definition: GUIRunThread.cpp:64
GUIRunThread::retrieveMessage
void retrieveMessage(const MsgHandler::MsgType type, const std::string &msg)
Retrieves messages from the loading module.
Definition: GUIRunThread.cpp:314
OptionsCont::getOptions
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:57
GUIRunThread::myHalting
bool myHalting
information whether the simulation is halting (is not being executed)
Definition: GUIRunThread.h:129
GUIRunThread::mySimEndTime
SUMOTime mySimEndTime
Definition: GUIRunThread.h:126
GUIEvent_Message.h
GUIEvent_SimulationEnded.h
GUIRunThread::simulationIsStartable
virtual bool simulationIsStartable() const
Definition: GUIRunThread.cpp:322
GUIRunThread.h
GUINet.h
MSNet::setCurrentTimeStep
void setCurrentTimeStep(const SUMOTime step)
Sets the current simulation step (used by state loading)
Definition: MSNet.h:291
MsgHandler::cleanupOnEnd
static void cleanupOnEnd()
Removes pending handler.
Definition: MsgHandler.cpp:250
GUIEvent_SimulationStep.h
GUIEvent_SimulationEnded
Event sent when the the simulation is over.
Definition: GUIEvent_SimulationEnded.h:40
MSNet::closeSimulation
void closeSimulation(SUMOTime start)
Closes the simulation (all files, connections, etc.)
Definition: MSNet.cpp:445
SysUtils::getCurrentMillis
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:38
FXEX::FXThreadEvent::signal
void signal()
Definition: FXThreadEvent.cpp:99
GUIRunThread::mySimDelay
double & mySimDelay
Definition: GUIRunThread.h:152
MSNet::SIMSTATE_NO_FURTHER_VEHICLES
The simulation does not contain further vehicles.
Definition: MSNet.h:104
TraCIServer::getLoadArgs
std::vector< std::string > & getLoadArgs()
Definition: TraCIServer.h:248
MSNet::SimulationState
SimulationState
Possible states of a simulation - running or stopped with different reasons.
Definition: MSNet.h:96
GUIRunThread::simulationAvailable
bool simulationAvailable() const
Definition: GUIRunThread.cpp:273
Simulation.h
GUIRunThread::mySimulationInProgress
bool mySimulationInProgress
Definition: GUIRunThread.h:138
GUIMainWindow::getInstance
static GUIMainWindow * getInstance()
Definition: GUIMainWindow.cpp:182
MSNet::SIMSTATE_END_STEP_REACHED
The final simulation step has been performed.
Definition: MSNet.h:102
GUIRunThread::mySimulationLock
FXMutex mySimulationLock
Definition: GUIRunThread.h:158
GUIRunThread::getNet
GUINet & getNet() const
Definition: GUIRunThread.cpp:301
MsgHandler::getWarningInstance
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:68
TS
#define TS
Definition: SUMOTime.h:43
SysUtils.h
MSNet::getCurrentTimeStep
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:283
GUIRunThread::myWarningRetriever
OutputDevice * myWarningRetriever
Definition: GUIRunThread.h:150
GUIRunThread::myNet
GUINet * myNet
the loaded simulation network
Definition: GUIRunThread.h:123
GUIGlobals.h
MSNet::SIMSTATE_ERROR_IN_SIM
An error occurred during the simulation step.
Definition: MSNet.h:108
GUIRunThread::simulationIsStepable
virtual bool simulationIsStepable() const
Definition: GUIRunThread.cpp:334
OutputDevice.h
GUIRunThread::resume
void resume()
Definition: GUIRunThread.cpp:244
ProcessError
Definition: UtilExceptions.h:39
GUIApplicationWindow.h
GUIRunThread::myMessageRetriever
OutputDevice * myMessageRetriever
Definition: GUIRunThread.h:150
GUIRunThread::myQuit
bool myQuit
Definition: GUIRunThread.h:133
time2string
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:67
MSNet::SIMSTATE_LOADING
The simulation is loading.
Definition: MSNet.h:98
UtilExceptions.h
GUIRunThread::stop
void stop()
Definition: GUIRunThread.cpp:266
MSNet::loadRoutes
void loadRoutes()
loads routes for the next few steps
Definition: MSNet.cpp:381
GUIRunThread::myErrorRetriever
OutputDevice * myErrorRetriever
The instances of message retriever encapsulations Needed to be deleted from the handler later on.
Definition: GUIRunThread.h:150
GUIMainWindow::getViews
const std::vector< GUIGlChildWindow * > & getViews() const
Definition: GUIMainWindow.h:60
GUIRunThread::myBreakpoints
std::vector< SUMOTime > myBreakpoints
List of breakpoints.
Definition: GUIRunThread.h:161
GUIRunThread::waitForSnapshots
void waitForSnapshots(const SUMOTime snapshotTime)
Definition: GUIRunThread.cpp:340
MSNet::SIMSTATE_CONNECTION_CLOSED
The connection to a client was closed by the client.
Definition: MSNet.h:106
FXSynchQue< GUIEvent * >
GUIRunThread::myEventQue
FXSynchQue< GUIEvent * > & myEventQue
Definition: GUIRunThread.h:154
GUIMainWindow
Definition: GUIMainWindow.h:46
MSNet::SIMSTATE_RUNNING
The simulation is running.
Definition: MSNet.h:100
GUIEvent
Definition: GUIEvent.h:76
GUIRunThread::myEventThrow
FXEX::FXThreadEvent & myEventThrow
Definition: GUIRunThread.h:156
GUIGlObjectStorage::gIDStorage
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
Definition: GUIGlObjectStorage.h:140
MsgHandler::addRetriever
virtual void addRetriever(OutputDevice *retriever)
Adds a further retriever to the instance responsible for a certain msg type.
Definition: MsgHandler.cpp:174
GUIEvent_SimulationStep
Definition: GUIEvent_SimulationStep.h:36
OptionsIO::setArgs
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition: OptionsIO.cpp:54
TraCIServer.h
MsgRetrievingFunction.h
FXSynchQue::push_back
void push_back(T what)
Definition: FXSynchQue.h:115
config.h
TraCIServer::getInstance
static TraCIServer * getInstance()
Definition: TraCIServer.h:70
FXSingleEventThread
Definition: FXSingleEventThread.h:34
TraCIServer::wasClosed
static bool wasClosed()
check whether close was requested
Definition: TraCIServer.cpp:314
FXEX::FXThreadEvent
Definition: FXThreadEvent.h:105
GUIGlChildWindow
Definition: GUIGlChildWindow.h:40
MsgHandler::getErrorInstance
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:81
MSNet::getStateMessage
static std::string getStateMessage(SimulationState state)
Returns the message to show if a certain state occurs.
Definition: MSNet.cpp:628
GUINet
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:82
GUINet::simulationStep
void simulationStep()
Performs a single simulation step (locking the simulation)
Definition: GUINet.cpp:223
GUINet::setSimDuration
void setSimDuration(int val)
Sets the duration of the last step's simulation part.
Definition: GUINet.cpp:388
MSVehicleControl.h
MSNet::SIMSTATE_TOO_MANY_TELEPORTS
The simulation had too many teleports.
Definition: MSNet.h:112
GUIRunThread::run
virtual FXint run()
starts the execution
Definition: GUIRunThread.cpp:117
WRITE_ERROR
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:283
GUINet::guiSimulationStep
void guiSimulationStep()
Some further steps needed for gui processing.
Definition: GUINet.cpp:216
GUIEvent_Message
Definition: GUIEvent_Message.h:38
GUIRunThread::deleteSim
virtual void deleteSim()
Definition: GUIRunThread.cpp:279
WRITE_MESSAGE
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:277
GUIRunThread::init
virtual bool init(GUINet *net, SUMOTime start, SUMOTime end)
initialises the thread with the new simulation
Definition: GUIRunThread.cpp:77
OptionsIO.h
GUIRunThread::prepareDestruction
void prepareDestruction()
Definition: GUIRunThread.cpp:307
GUIGlObjectStorage::clear
void clear()
Clears this container.
Definition: GUIGlObjectStorage.cpp:111
GUIRunThread::GUIRunThread
GUIRunThread(FXApp *app, MFXInterThreadEventClient *mw, double &simDelay, FXSynchQue< GUIEvent * > &eq, FXEX::FXThreadEvent &ev)
constructor
Definition: GUIRunThread.cpp:52
MsgHandler::removeRetriever
virtual void removeRetriever(OutputDevice *retriever)
Removes the retriever from the handler.
Definition: MsgHandler.cpp:182
MsgHandler::getMessageInstance
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
Definition: MsgHandler.cpp:55