SUMO - Simulation of Urban MObility
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.dlr.de/
12 // Copyright (C) 2001-2017 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>
42 #include "GUIApplicationWindow.h"
43 #include "GUIRunThread.h"
44 #include "GUIGlobals.h"
48 #include <utils/common/SysUtils.h>
53 
54 #ifndef NO_TRACI
56 #include <traci-server/lib/TraCI.h>
57 #endif
58 
59 
60 // ===========================================================================
61 // member method definitions
62 // ===========================================================================
66  : FXSingleEventThread(app, parent),
67  myNet(0), myHalting(true), myQuit(false), mySimulationInProgress(false), myOk(true), myHaveSignaledEnd(false),
68  mySimDelay(simDelay), myEventQue(eq), myEventThrow(ev) {
72 }
73 
74 
76  // the thread shall stop
77  myQuit = true;
78  deleteSim();
79  delete myErrorRetriever;
80  delete myMessageRetriever;
81  delete myWarningRetriever;
82  // wait for the thread
83  while (mySimulationInProgress || myNet != 0);
84 }
85 
86 
87 bool
89  assert(net != 0);
90  // assign new values
91  myOk = true;
92  myNet = net;
93  mySimStartTime = start;
94  mySimEndTime = end;
95  // register message callbacks
98  if (!OptionsCont::getOptions().getBool("no-warnings")) {
100  }
101  // preload the routes especially for TraCI
103  try {
104  net->setCurrentTimeStep(start);
105  net->loadRoutes();
106  } catch (ProcessError& e2) {
107  if (std::string(e2.what()) != std::string("Process Error") && std::string(e2.what()) != std::string("")) {
108  WRITE_ERROR(e2.what());
109  }
110  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
111  myHalting = true;
112  myOk = false;
113  mySimulationInProgress = false;
114 #ifndef _DEBUG
115  } catch (...) {
116  myHalting = true;
117  myOk = false;
118  mySimulationInProgress = false;
119 #endif
120  }
122  return myOk;
123 }
124 
125 
126 FXint
128  long beg = 0;
129  long end = -1;
130  // perform an endless loop
131  while (!myQuit) {
132  // if the simulation shall be perfomed, do it
133  if (!myHalting && myNet != 0 && myOk) {
134  if (getNet().logSimulationDuration()) {
136  if (end != -1) {
137  getNet().setIdleDuration((int)(beg - end));
138  }
139  }
140  // check whether we shall stop at this step
141  myBreakpointLock.lock();
142  const bool haltAfter = find(myBreakpoints.begin(), myBreakpoints.end(), myNet->getCurrentTimeStep()) != myBreakpoints.end();
143  myBreakpointLock.unlock();
144  // do the step
145  makeStep();
147  // stop if wished
148  if (haltAfter) {
149  stop();
150  }
151  // wait if wanted
152  long wait = (long) mySimDelay.getValue();
153  if (getNet().logSimulationDuration()) {
155  getNet().setSimDuration((int)(end - beg));
156  wait -= (end - beg);
157  }
158  if (wait > 0) {
159  sleep(wait);
160  }
161  } else {
162  // sleep if the simulation is not running
163  sleep(50);
164  }
165  }
166  // delete a maybe existing simulation at the end
167  deleteSim();
168  return 0;
169 }
170 
171 
172 void
174  GUIEvent* e = 0;
175  // simulation is being perfomed
176  mySimulationInProgress = true;
177  // execute a single step
178  try {
183 
184  // inform parent that a step has been performed
185  e = new GUIEvent_SimulationStep();
186  myEventQue.add(e);
188 
189  e = 0;
191 #ifndef NO_TRACI
192  if (state == MSNet::SIMSTATE_LOADING) {
194  TraCI::getLoadArgs().clear();
195  } else if (state != MSNet::SIMSTATE_RUNNING) {
197  state = MSNet::SIMSTATE_RUNNING;
198  }
199  }
200 #endif
201  switch (state) {
208  WRITE_MESSAGE("Simulation ended at time: " + time2string(myNet->getCurrentTimeStep()));
209  WRITE_MESSAGE("Reason: " + MSNet::getStateMessage(state));
211  myHaveSignaledEnd = true;
212  }
213  break;
214  default:
215  break;
216  }
217  if (e != 0) {
218  myEventQue.add(e);
220  myHalting = true;
221  }
222  // stop the execution when only a single step should have
223  // been performed
224  if (mySingle) {
225  myHalting = true;
226  }
227  // simulation step is over
228  mySimulationInProgress = false;
229  } catch (ProcessError& e2) {
230  if (std::string(e2.what()) != std::string("Process Error") && std::string(e2.what()) != std::string("")) {
231  WRITE_ERROR(e2.what());
232  }
233  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
235  mySimulationInProgress = false;
237  myEventQue.add(e);
239  myHalting = true;
240  myOk = false;
241 #ifndef _DEBUG
242  } catch (...) {
244  mySimulationInProgress = false;
246  myEventQue.add(e);
248  myHalting = true;
249  myOk = false;
250 #endif
251  }
252 }
253 
254 
255 void
257  mySingle = false;
258  myHalting = false;
259 }
260 
261 
262 void
264  mySingle = true;
265  myHalting = false;
266 }
267 
268 
269 void
271  // report the begin when wished
272  WRITE_MESSAGE("Simulation started with time: " + time2string(mySimStartTime));
273  myOk = true;
274 }
275 
276 
277 void
279  mySingle = false;
280  myHalting = true;
281 }
282 
283 
284 bool
286  return myNet != 0;
287 }
288 
289 
290 void
292  myHalting = true;
293  // remove message callbacks
297  //
299  if (myNet != 0) {
301  }
302  while (mySimulationInProgress);
303  delete myNet;
305  myNet = 0;
309 }
310 
311 
312 GUINet&
314  return *myNet;
315 }
316 
317 
318 void
320  myHalting = true;
321  myQuit = true;
322 }
323 
324 
325 void
326 GUIRunThread::retrieveMessage(const MsgHandler::MsgType type, const std::string& msg) {
327  GUIEvent* e = new GUIEvent_Message(type, msg);
328  myEventQue.add(e);
330 }
331 
332 
333 bool
335  return myNet != 0 && myHalting;
336 }
337 
338 
339 bool
341  return myNet != 0 && (!myHalting);
342 }
343 
344 
345 bool
347  return myNet != 0 && myHalting;
348 }
349 
350 
351 void
354  const bool wait = find(myApplicationSnapshots.begin(), myApplicationSnapshots.end(), snapShotTime) != myApplicationSnapshots.end();
355  //std::cout << SIMTIME << "waitForSnapshots " << toString(myApplicationSnapshots) << "\n";
357  if (wait && !myHalting) {
358  sleep(50);
359  waitForSnapshots(snapShotTime);
360  }
361 }
362 
363 /****************************************************************************/
364 
Event sent when the the simulation is over.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:67
The message is only something to show.
Definition: MsgHandler.h:62
static std::vector< std::string > & getLoadArgs()
Definition: TraCI.h:103
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:76
virtual bool simulationIsStepable() const
virtual FXint run()
starts the execution
virtual void deleteSim()
virtual bool init(GUINet *net, SUMOTime start, SUMOTime end)
initialises the thread with the new simulation
void waitForSnapshots(SUMOTime snapShotTime)
void add(T what)
Definition: MFXEventQue.h:59
std::set< SUMOTime > myApplicationSnapshots
List of snapshot times.
Definition: GUIRunThread.h:182
virtual bool simulationIsStartable() const
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:60
SUMOTime DELTA_T
Definition: SUMOTime.cpp:40
void setCurrentTimeStep(const SUMOTime step)
Sets the current simulation step (used by state loading)
Definition: MSNet.h:260
The final simulation step has been performed.
Definition: MSNet.h:100
void addRetriever(OutputDevice *retriever)
Adds a further retriever to the instance responsible for a certain msg type.
Definition: MsgHandler.cpp:157
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:252
void clear()
Clears this container.
SimulationState
Possible states of a simulation - running or stopped with different reasons.
Definition: MSNet.h:94
void setIdleDuration(int val)
Sets the duration of the last step&#39;s idle part.
Definition: GUINet.cpp:401
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition: OptionsIO.cpp:62
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:65
void retrieveMessage(const MsgHandler::MsgType type, const std::string &msg)
Retrieves messages from the loading module.
bool myHalting
information whether the simulation is halting (is not being executed)
Definition: GUIRunThread.h:144
bool myHaveSignaledEnd
whether the simulation already ended
Definition: GUIRunThread.h:161
The simulation does not contain further vehicles.
Definition: MSNet.h:102
An error occured during the simulation step.
Definition: MSNet.h:106
std::vector< SUMOTime > myBreakpoints
List of breakpoints.
Definition: GUIRunThread.h:176
static void cleanupOnEnd()
Removes pending handler.
Definition: MsgHandler.cpp:238
MFXMutex mySimulationLock
Definition: GUIRunThread.h:173
FXdouble getValue() const
Return current value.
static void sleep(long ms)
virtual ~GUIRunThread()
destructor
static void closeAll()
void closeSimulation(SUMOTime start)
Closes the simulation (all files, connections, etc.)
Definition: MSNet.cpp:372
SUMOTime mySimEndTime
Definition: GUIRunThread.h:141
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
The connection to a client was closed by the client.
Definition: MSNet.h:104
The simulation is running.
Definition: MSNet.h:98
void removeRetriever(OutputDevice *retriever)
Removes the retriever from the handler.
Definition: MsgHandler.cpp:171
bool mySimulationInProgress
Definition: GUIRunThread.h:153
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
Definition: MsgHandler.cpp:58
virtual bool simulationIsStopable() const
OutputDevice * myWarningRetriever
Definition: GUIRunThread.h:165
GUINet * myNet
the loaded simulation network
Definition: GUIRunThread.h:138
GUINet & getNet() const
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
void unlock()
release mutex lock
Definition: MFXMutex.cpp:94
OutputDevice * myMessageRetriever
Definition: GUIRunThread.h:165
The message is a warning.
Definition: MsgHandler.h:64
void setSimDuration(int val)
Sets the duration of the last step&#39;s simulation part.
Definition: GUINet.cpp:385
Encapsulates an object&#39;s method for using it as a message retriever.
The simulation is loading.
Definition: MSNet.h:96
OutputDevice * myErrorRetriever
The instances of message retriever encapsulations Needed to be deleted from the handler later on...
Definition: GUIRunThread.h:165
SimulationState simulationState(SUMOTime stopTime) const
Called after a simulation step, this method returns the current simulation state. ...
Definition: MSNet.cpp:560
void prepareDestruction()
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:89
MFXEventQue< GUIEvent * > & myEventQue
Definition: GUIRunThread.h:169
static TraCIServer * getInstance()
Definition: TraCIServer.h:86
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:85
The simulation had too many teleports.
Definition: MSNet.h:108
void lock()
lock mutex
Definition: MFXMutex.cpp:84
bool simulationAvailable() const
FXMutex myBreakpointLock
Lock for modifying the list of breakpoints.
Definition: GUIRunThread.h:179
static std::string getStateMessage(SimulationState state)
Returns the message to show if a certain state occurs.
Definition: MSNet.cpp:598
void simulationStep()
Performs a single simulation step (locking the simulation)
Definition: GUINet.cpp:226
long long int SUMOTime
Definition: TraCIDefs.h:52
virtual void begin()
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:46
void loadRoutes()
loads routes for the next few steps
Definition: MSNet.cpp:366
FXEX::FXThreadEvent & myEventThrow
Definition: GUIRunThread.h:171
SUMOTime mySimStartTime
the times the simulation starts and ends with
Definition: GUIRunThread.h:141
Spinner control.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
void guiSimulationStep()
Some further steps needed for gui processing.
Definition: GUINet.cpp:219
static bool wasClosed()
check whether close was requested
FXRealSpinDial & mySimDelay
Definition: GUIRunThread.h:167
The message is an error.
Definition: MsgHandler.h:66
FXMutex myApplicationSnapshotsLock
Lock for modifying the list of snapshot times.
Definition: GUIRunThread.h:185
GUIRunThread(FXApp *app, MFXInterThreadEventClient *mw, FXRealSpinDial &simDelay, MFXEventQue< GUIEvent * > &eq, FXEX::FXThreadEvent &ev)
constructor