SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
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-2016 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"
47 #include <utils/common/SysUtils.h>
52 
53 #ifndef NO_TRACI
55 #endif
56 
57 #ifdef CHECK_MEMORY_LEAKS
58 #include <foreign/nvwa/debug_new.h>
59 #endif // CHECK_MEMORY_LEAKS
60 
61 
62 // ===========================================================================
63 // member method definitions
64 // ===========================================================================
68  : FXSingleEventThread(app, parent),
69  myNet(0), myHalting(true), myQuit(false), mySimulationInProgress(false), myOk(true),
70  mySimDelay(simDelay), myEventQue(eq), myEventThrow(ev) {
74 }
75 
76 
78  // the thread shall stop
79  myQuit = true;
80  deleteSim();
81  delete myErrorRetriever;
82  delete myMessageRetriever;
83  delete myWarningRetriever;
84  // wait for the thread
85  while (mySimulationInProgress || myNet != 0);
86 }
87 
88 
89 bool
91  assert(net != 0);
92  // assign new values
93  myOk = true;
94  myNet = net;
95  mySimStartTime = start;
96  mySimEndTime = end;
97  // register message callbacks
100  if (!OptionsCont::getOptions().getBool("no-warnings")) {
102  }
103  // preload the routes especially for TraCI
105  try {
106  net->setCurrentTimeStep(start);
107  net->loadRoutes();
108  } catch (ProcessError& e2) {
109  if (std::string(e2.what()) != std::string("Process Error") && std::string(e2.what()) != std::string("")) {
110  WRITE_ERROR(e2.what());
111  }
112  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
113  myHalting = true;
114  myOk = false;
115  mySimulationInProgress = false;
116 #ifndef _DEBUG
117  } catch (...) {
118  myHalting = true;
119  myOk = false;
120  mySimulationInProgress = false;
121 #endif
122  }
124  return myOk;
125 }
126 
127 
128 FXint
130  long beg = 0;
131  long end = -1;
132  // perform an endless loop
133  while (!myQuit) {
134  // if the simulation shall be perfomed, do it
135  if (!myHalting && myNet != 0 && myOk) {
136  if (getNet().logSimulationDuration()) {
138  if (end != -1) {
139  getNet().setIdleDuration((int)(beg - end));
140  }
141  }
142  // check whether we shall stop at this step
143  myBreakpointLock.lock();
144  const bool haltAfter = find(myBreakpoints.begin(), myBreakpoints.end(), myNet->getCurrentTimeStep()) != myBreakpoints.end();
145  myBreakpointLock.unlock();
146  // do the step
147  makeStep();
148  // stop if wished
149  if (haltAfter) {
150  stop();
151  }
152  // wait if wanted
153  long wait = (long) mySimDelay.getValue();
154  if (getNet().logSimulationDuration()) {
156  getNet().setSimDuration((int)(end - beg));
157  wait -= (end - beg);
158  }
159  if (wait > 0) {
160  sleep(wait);
161  }
162  } else {
163  // sleep if the simulation is not running
164  sleep(50);
165  }
166  }
167  // delete a maybe existing simulation at the end
168  deleteSim();
169  return 0;
170 }
171 
172 
173 void
175  GUIEvent* e = 0;
176  // simulation is being perfomed
177  mySimulationInProgress = true;
178  // execute a single step
179  try {
184 
185  // inform parent that a step has been performed
186  e = new GUIEvent_SimulationStep();
187  myEventQue.add(e);
189 
190  e = 0;
192 #ifndef NO_TRACI
193  if (state != MSNet::SIMSTATE_RUNNING) {
194  if (OptionsCont::getOptions().getInt("remote-port") != 0 && !TraCIServer::wasClosed()) {
195  state = MSNet::SIMSTATE_RUNNING;
196  }
197  }
198 #endif
199  switch (state) {
204  WRITE_MESSAGE("Simulation ended at time: " + time2string(myNet->getCurrentTimeStep()));
205  WRITE_MESSAGE("Reason: " + MSNet::getStateMessage(state));
207  break;
208  default:
209  break;
210  }
211  if (e != 0) {
212  myEventQue.add(e);
214  myHalting = true;
215  }
216  // stop the execution when only a single step should have
217  // been performed
218  if (mySingle) {
219  myHalting = true;
220  }
221  // simulation step is over
222  mySimulationInProgress = false;
223  } catch (ProcessError& e2) {
224  if (std::string(e2.what()) != std::string("Process Error") && std::string(e2.what()) != std::string("")) {
225  WRITE_ERROR(e2.what());
226  }
227  MsgHandler::getErrorInstance()->inform("Quitting (on error).", false);
229  mySimulationInProgress = false;
231  myEventQue.add(e);
233  myHalting = true;
234  myOk = false;
235 #ifndef _DEBUG
236  } catch (...) {
238  mySimulationInProgress = false;
240  myEventQue.add(e);
242  myHalting = true;
243  myOk = false;
244 #endif
245  }
246 }
247 
248 
249 void
251  mySingle = false;
252  myHalting = false;
253 }
254 
255 
256 void
258  mySingle = true;
259  myHalting = false;
260 }
261 
262 
263 void
265  // report the begin when wished
266  WRITE_MESSAGE("Simulation started with time: " + time2string(mySimStartTime));
267  myOk = true;
268 }
269 
270 
271 void
273  mySingle = false;
274  myHalting = true;
275 }
276 
277 
278 bool
280  return myNet != 0;
281 }
282 
283 
284 void
286  myHalting = true;
287  // remove message callbacks
291  //
293  if (myNet != 0) {
295  }
296  while (mySimulationInProgress);
297  delete myNet;
299  myNet = 0;
303 }
304 
305 
306 GUINet&
308  return *myNet;
309 }
310 
311 
312 void
314  myHalting = true;
315  myQuit = true;
316 }
317 
318 
319 void
320 GUIRunThread::retrieveMessage(const MsgHandler::MsgType type, const std::string& msg) {
321  GUIEvent* e = new GUIEvent_Message(type, msg);
322  myEventQue.add(e);
324 }
325 
326 
327 bool
329  return myNet != 0 && myHalting;
330 }
331 
332 
333 bool
335  return myNet != 0 && (!myHalting);
336 }
337 
338 
339 bool
341  return myNet != 0 && myHalting;
342 }
343 
344 
345 
346 /****************************************************************************/
347 
Event sent when the the simulation is over.
static MsgHandler * getWarningInstance()
Returns the instance to add warnings to.
Definition: MsgHandler.cpp:71
The message is only something to show.
Definition: MsgHandler.h:62
static MsgHandler * getErrorInstance()
Returns the instance to add errors to.
Definition: MsgHandler.cpp:80
long long int SUMOTime
Definition: SUMOTime.h:43
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
The simulation contains too many vehicles (.
Definition: MSNet.h:110
void add(T what)
Definition: MFXEventQue.h:59
virtual bool simulationIsStartable() const
std::string time2string(SUMOTime t)
Definition: SUMOTime.cpp:59
SUMOTime DELTA_T
Definition: SUMOTime.cpp:39
void setCurrentTimeStep(const SUMOTime step)
Sets the current simulation step (used by state loading)
Definition: MSNet.h:262
The final simulation step has been performed.
Definition: MSNet.h:102
void addRetriever(OutputDevice *retriever)
Adds a further retriever to the instance responsible for a certain msg type.
Definition: MsgHandler.cpp:161
SUMOTime getCurrentTimeStep() const
Returns the current simulation step.
Definition: MSNet.h:254
void clear()
Clears this container.
SimulationState
Possible states of a simulation - running or stopped with different reasons.
Definition: MSNet.h:98
void setIdleDuration(int val)
Sets the duration of the last step's idle part.
Definition: GUINet.cpp:398
static OptionsCont & getOptions()
Retrieves the options.
Definition: OptionsCont.cpp:69
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:134
The simulation does not contain further vehicles.
Definition: MSNet.h:104
An error occured during the simulation step.
Definition: MSNet.h:108
std::vector< SUMOTime > myBreakpoints
List of breakpoints.
Definition: GUIRunThread.h:163
static void cleanupOnEnd()
Removes pending handler.
Definition: MsgHandler.cpp:242
MFXMutex mySimulationLock
Definition: GUIRunThread.h:160
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:357
SUMOTime mySimEndTime
Definition: GUIRunThread.h:131
static GUIGlObjectStorage gIDStorage
A single static instance of this class.
The connection to a client was closed by the client.
Definition: MSNet.h:106
The simulation is running.
Definition: MSNet.h:100
void removeRetriever(OutputDevice *retriever)
Removes the retriever from the handler.
Definition: MsgHandler.cpp:175
bool mySimulationInProgress
Definition: GUIRunThread.h:143
static MsgHandler * getMessageInstance()
Returns the instance to add normal messages to.
Definition: MsgHandler.cpp:62
virtual bool simulationIsStopable() const
OutputDevice * myWarningRetriever
Definition: GUIRunThread.h:152
GUINet * myNet
the loaded simulation network
Definition: GUIRunThread.h:128
GUINet & getNet() const
#define WRITE_ERROR(msg)
Definition: MsgHandler.h:206
void unlock()
release mutex lock
Definition: MFXMutex.cpp:96
OutputDevice * myMessageRetriever
Definition: GUIRunThread.h:152
The message is a warning.
Definition: MsgHandler.h:64
void setSimDuration(int val)
Sets the duration of the last step's simulation part.
Definition: GUINet.cpp:382
Encapsulates an object's method for using it as a message retriever.
OutputDevice * myErrorRetriever
The instances of message retriever encapsulations Needed to be deleted from the handler later on...
Definition: GUIRunThread.h:152
SimulationState simulationState(SUMOTime stopTime) const
Called after a simulation step, this method returns the current simulation state. ...
Definition: MSNet.cpp:522
void prepareDestruction()
A MSNet extended by some values for usage within the gui.
Definition: GUINet.h:89
MFXEventQue< GUIEvent * > & myEventQue
Definition: GUIRunThread.h:156
void inform(std::string msg, bool addType=true)
adds a new error to the list
Definition: MsgHandler.cpp:89
void lock()
lock mutex
Definition: MFXMutex.cpp:86
bool simulationAvailable() const
FXMutex myBreakpointLock
Lock for modifying the list of breakpoints.
Definition: GUIRunThread.h:166
static std::string getStateMessage(SimulationState state)
Returns the message to show if a certain state occurs.
Definition: MSNet.cpp:554
void simulationStep()
Performs a single simulation step (locking the simulation)
Definition: GUINet.cpp:230
virtual void begin()
static long getCurrentMillis()
Returns the current time in milliseconds.
Definition: SysUtils.cpp:50
void loadRoutes()
loads routes for the next few steps
Definition: MSNet.cpp:351
FXEX::FXThreadEvent & myEventThrow
Definition: GUIRunThread.h:158
SUMOTime mySimStartTime
the times the simulation starts and ends with
Definition: GUIRunThread.h:131
Spinner control.
#define WRITE_MESSAGE(msg)
Definition: MsgHandler.h:201
void guiSimulationStep()
Some further steps needed for gui processing.
Definition: GUINet.cpp:223
static bool wasClosed()
check whether close was requested
FXRealSpinDial & mySimDelay
Definition: GUIRunThread.h:154
The message is an error.
Definition: MsgHandler.h:66
GUIRunThread(FXApp *app, MFXInterThreadEventClient *mw, FXRealSpinDial &simDelay, MFXEventQue< GUIEvent * > &eq, FXEX::FXThreadEvent &ev)
constructor