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-2017 German Aerospace Center (DLR) and others.
4 /****************************************************************************/
5 //
6 // This program and the accompanying materials
7 // are made available under the terms of the Eclipse Public License v2.0
8 // which accompanies this distribution, and is available at
9 // http://www.eclipse.org/legal/epl-v20.html
10 //
11 /****************************************************************************/
19 // The thread that runs the simulation
20 /****************************************************************************/
21 
22 
23 // ===========================================================================
24 // included modules
25 // ===========================================================================
26 #ifdef _MSC_VER
27 #include <windows_config.h>
28 #else
29 #include <config.h>
30 #endif
31 
32 #include <cassert>
33 #include <string>
34 #include <iostream>
35 #include <algorithm>
36 
37 #include <guisim/GUINet.h>
41 #include "GUIApplicationWindow.h"
42 #include "GUIRunThread.h"
43 #include "GUIGlobals.h"
47 #include <utils/common/SysUtils.h>
52 
53 #ifndef NO_TRACI
55 #include <libsumo/Simulation.h>
56 #endif
57 
58 
59 // ===========================================================================
60 // member method definitions
61 // ===========================================================================
65  : FXSingleEventThread(app, parent),
66  myNet(0), myHalting(true), myQuit(false), mySimulationInProgress(false), myOk(true), myHaveSignaledEnd(false),
67  mySimDelay(simDelay), myEventQue(eq), myEventThrow(ev) {
71 }
72 
73 
75  // the thread shall stop
76  myQuit = true;
77  deleteSim();
78  delete myErrorRetriever;
79  delete myMessageRetriever;
80  delete myWarningRetriever;
81  // wait for the thread
82  while (mySimulationInProgress || myNet != 0);
83 }
84 
85 
86 bool
88  assert(net != 0);
89  // assign new values
90  myOk = true;
91  myNet = net;
92  mySimStartTime = start;
93  mySimEndTime = end;
94  // register message callbacks
97  if (!OptionsCont::getOptions().getBool("no-warnings")) {
99  }
100  // preload the routes especially for TraCI
102  try {
103  net->setCurrentTimeStep(start);
104  net->loadRoutes();
105  } catch (ProcessError& e2) {
106  if (std::string(e2.what()) != std::string("Process Error") && std::string(e2.what()) != std::string("")) {
107  WRITE_ERROR(e2.what());
108  }
109  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
110  myHalting = true;
111  myOk = false;
112  mySimulationInProgress = false;
113 #ifndef _DEBUG
114  } catch (...) {
115  myHalting = true;
116  myOk = false;
117  mySimulationInProgress = false;
118 #endif
119  }
121  return myOk;
122 }
123 
124 
125 FXint
127  long beg = 0;
128  long end = -1;
129  // perform an endless loop
130  while (!myQuit) {
131  // if the simulation shall be perfomed, do it
132  if (!myHalting && myNet != 0 && myOk) {
133  if (getNet().logSimulationDuration()) {
135  if (end != -1) {
136  getNet().setIdleDuration((int)(beg - end));
137  }
138  }
139  // check whether we shall stop at this step
140  myBreakpointLock.lock();
141  const bool haltAfter = find(myBreakpoints.begin(), myBreakpoints.end(), myNet->getCurrentTimeStep()) != myBreakpoints.end();
142  myBreakpointLock.unlock();
143  // do the step
144  makeStep();
146  // stop if wished
147  if (haltAfter) {
148  stop();
149  }
150  // wait if wanted
151  long wait = (long) mySimDelay.getValue();
152  if (getNet().logSimulationDuration()) {
154  getNet().setSimDuration((int)(end - beg));
155  wait -= (end - beg);
156  }
157  if (wait > 0) {
158  sleep(wait);
159  }
160  } else {
161  // sleep if the simulation is not running
162  sleep(50);
163  }
164  }
165  // delete a maybe existing simulation at the end
166  deleteSim();
167  return 0;
168 }
169 
170 
171 void
173  GUIEvent* e = 0;
174  // simulation is being perfomed
175  mySimulationInProgress = true;
176  // execute a single step
177  try {
182 
183  // inform parent that a step has been performed
184  e = new GUIEvent_SimulationStep();
185  myEventQue.add(e);
187 
188  e = 0;
190 #ifndef NO_TRACI
191  if (state == MSNet::SIMSTATE_LOADING) {
194  } else if (state != MSNet::SIMSTATE_RUNNING) {
196  state = MSNet::SIMSTATE_RUNNING;
197  }
198  }
199 #endif
200  switch (state) {
207  WRITE_MESSAGE("Simulation ended at time: " + time2string(myNet->getCurrentTimeStep()));
208  WRITE_MESSAGE("Reason: " + MSNet::getStateMessage(state));
210  myHaveSignaledEnd = true;
211  }
212  break;
213  default:
214  break;
215  }
216  if (e != 0) {
217  myEventQue.add(e);
219  myHalting = true;
220  }
221  // stop the execution when only a single step should have
222  // been performed
223  if (mySingle) {
224  myHalting = true;
225  }
226  // simulation step is over
227  mySimulationInProgress = false;
228  } catch (ProcessError& e2) {
229  if (std::string(e2.what()) != std::string("Process Error") && std::string(e2.what()) != std::string("")) {
230  WRITE_ERROR(e2.what());
231  }
232  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
234  mySimulationInProgress = false;
236  myEventQue.add(e);
238  myHalting = true;
239  myOk = false;
240 #ifndef _DEBUG
241  } catch (...) {
243  mySimulationInProgress = false;
245  myEventQue.add(e);
247  myHalting = true;
248  myOk = false;
249 #endif
250  }
251 }
252 
253 
254 void
256  mySingle = false;
257  myHalting = false;
258 }
259 
260 
261 void
263  mySingle = true;
264  myHalting = false;
265 }
266 
267 
268 void
270  // report the begin when wished
271  WRITE_MESSAGE("Simulation started with time: " + time2string(mySimStartTime));
272  myOk = true;
273 }
274 
275 
276 void
278  mySingle = false;
279  myHalting = true;
280 }
281 
282 
283 bool
285  return myNet != 0;
286 }
287 
288 
289 void
291  myHalting = true;
292  // remove message callbacks
296  //
298  if (myNet != 0) {
300  }
301  while (mySimulationInProgress);
302  delete myNet;
304  myNet = 0;
308 }
309 
310 
311 GUINet&
313  return *myNet;
314 }
315 
316 
317 void
319  myHalting = true;
320  myQuit = true;
321 }
322 
323 
324 void
325 GUIRunThread::retrieveMessage(const MsgHandler::MsgType type, const std::string& msg) {
326  GUIEvent* e = new GUIEvent_Message(type, msg);
327  myEventQue.add(e);
329 }
330 
331 
332 bool
334  return myNet != 0 && myHalting;
335 }
336 
337 
338 bool
340  return myNet != 0 && (!myHalting);
341 }
342 
343 
344 bool
346  return myNet != 0 && myHalting;
347 }
348 
349 
350 void
353  const bool wait = find(myApplicationSnapshots.begin(), myApplicationSnapshots.end(), snapShotTime) != myApplicationSnapshots.end();
354  //std::cout << SIMTIME << "waitForSnapshots " << toString(myApplicationSnapshots) << "\n";
356  if (wait && !myHalting) {
357  sleep(50);
358  waitForSnapshots(snapShotTime);
359  }
360 }
361 
362 /****************************************************************************/
363 
Event sent when the the simulation is over.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:66
The message is only something to show.
Definition: MsgHandler.h:61
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:75
GUIRunThread(FXApp *app, MFXInterThreadEventClient *mw, FXRealSpinDial &simDelay, MFXEventQue< GUIEvent *> &eq, FXEX::FXThreadEvent &ev)
constructor
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:58
std::set< SUMOTime > myApplicationSnapshots
List of snapshot times.
Definition: GUIRunThread.h:181
GUINet & getNet() const
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
virtual bool simulationIsStopable() const
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
void setCurrentTimeStep(const SUMOTime step)
Sets the current simulation step (used by state loading)
Definition: MSNet.h:261
The final simulation step has been performed.
Definition: MSNet.h:101
void addRetriever(OutputDevice *retriever)
Adds a further retriever to the instance responsible for a certain msg type.
Definition: MsgHandler.cpp:156
std::vector< std::string > & getLoadArgs()
Definition: TraCIServer.h:269
void clear()
Clears this container.
SimulationState
Possible states of a simulation - running or stopped with different reasons.
Definition: MSNet.h:95
virtual bool simulationIsStepable() const
void setIdleDuration(int val)
Sets the duration of the last step&#39;s idle part.
Definition: GUINet.cpp:398
static void setArgs(int argc, char **argv)
Stores the command line arguments for later parsing.
Definition: OptionsIO.cpp:61
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:64
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:143
bool myHaveSignaledEnd
whether the simulation already ended
Definition: GUIRunThread.h:160
The simulation does not contain further vehicles.
Definition: MSNet.h:103
An error occured during the simulation step.
Definition: MSNet.h:107
std::vector< SUMOTime > myBreakpoints
List of breakpoints.
Definition: GUIRunThread.h:175
static void cleanupOnEnd()
Removes pending handler.
Definition: MsgHandler.cpp:237
SimulationState simulationState(SUMOTime stopTime) const
Called after a simulation step, this method returns the current simulation state. ...
Definition: MSNet.cpp:560
MFXMutex mySimulationLock
Definition: GUIRunThread.h:172
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:140
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
virtual bool simulationIsStartable() const
The connection to a client was closed by the client.
Definition: MSNet.h:105
The simulation is running.
Definition: MSNet.h:99
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:253
bool simulationAvailable() const
void removeRetriever(OutputDevice *retriever)
Removes the retriever from the handler.
Definition: MsgHandler.cpp:170
bool mySimulationInProgress
Definition: GUIRunThread.h:152
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
Definition: MsgHandler.cpp:57
OutputDevice * myWarningRetriever
Definition: GUIRunThread.h:164
GUINet * myNet
the loaded simulation network
Definition: GUIRunThread.h:137
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:205
void unlock()
release mutex lock
Definition: MFXMutex.cpp:93
OutputDevice * myMessageRetriever
Definition: GUIRunThread.h:164
The message is a warning.
Definition: MsgHandler.h:63
void setSimDuration(int val)
Sets the duration of the last step&#39;s simulation part.
Definition: GUINet.cpp:382
Encapsulates an object&#39;s method for using it as a message retriever.
The simulation is loading.
Definition: MSNet.h:97
OutputDevice * myErrorRetriever
The instances of message retriever encapsulations Needed to be deleted from the handler later on...
Definition: GUIRunThread.h:164
void prepareDestruction()
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:88
MFXEventQue< GUIEvent * > & myEventQue
Definition: GUIRunThread.h:168
static TraCIServer * getInstance()
Definition: TraCIServer.h:81
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:84
The simulation had too many teleports.
Definition: MSNet.h:109
FXdouble getValue() const
Return current value.
void lock()
lock mutex
Definition: MFXMutex.cpp:83
FXMutex myBreakpointLock
Lock for modifying the list of breakpoints.
Definition: GUIRunThread.h:178
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:225
long long int SUMOTime
Definition: TraCIDefs.h:51
virtual void begin()
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:45
void loadRoutes()
loads routes for the next few steps
Definition: MSNet.cpp:366
FXEX::FXThreadEvent & myEventThrow
Definition: GUIRunThread.h:170
SUMOTime mySimStartTime
the times the simulation starts and ends with
Definition: GUIRunThread.h:140
Spinner control.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:200
void guiSimulationStep()
Some further steps needed for gui processing.
Definition: GUINet.cpp:218
static bool wasClosed()
check whether close was requested
FXRealSpinDial & mySimDelay
Definition: GUIRunThread.h:166
The message is an error.
Definition: MsgHandler.h:65
FXMutex myApplicationSnapshotsLock
Lock for modifying the list of snapshot times.
Definition: GUIRunThread.h:184