Eclipse SUMO - Simulation of Urban MObility
GNERunNetgenerate.cpp
Go to the documentation of this file.
1 /****************************************************************************/
2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3 // Copyright (C) 2001-2024 German Aerospace Center (DLR) and others.
4 // This program and the accompanying materials are made available under the
5 // terms of the Eclipse Public License 2.0 which is available at
6 // https://www.eclipse.org/legal/epl-2.0/
7 // This Source Code may also be made available under the following Secondary
8 // Licenses when the conditions for such availability set forth in the Eclipse
9 // Public License 2.0 are satisfied: GNU General Public License, version 2
10 // or later which is available at
11 // https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12 // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13 /****************************************************************************/
18 // Thread for run netgenerate tool
19 /****************************************************************************/
20 
25 
26 #include "GNERunNetgenerate.h"
27 
28 // ============================================-===============================
29 // member method definitions
30 // ===========================================================================
31 
33  MFXSingleEventThread(runDialog->getGNEApp()->getApp(), runDialog->getGNEApp()),
34  myEventQueue(eq),
35  myEventThrow(ev) {
36 }
37 
38 
40 
41 
42 void
43 GNERunNetgenerate::run(const OptionsCont* netgenerateOptions) {
44  // set command
45 
46 #ifdef WIN32
47  std::string exePath = "netgenerate.exe";
48 #else
49  std::string exePath = "netgenerate";
50 #endif
51  const char* sumoHomeEnv = getenv("SUMO_HOME");
52  std::string sumoHome = "";
53  if (sumoHomeEnv != nullptr && sumoHomeEnv != std::string("")) {
54  sumoHome = std::string(sumoHomeEnv);
55  // harmonise slash
56  if (sumoHome.back() == '\\') {
57  sumoHome = sumoHome.substr(0, sumoHome.size() - 1);
58  }
59  // prevent double quotes
60  if (sumoHome.front() == '"') {
61  sumoHome.erase(sumoHome.begin());
62  }
63  if (sumoHome.size() > 0 && sumoHome.back() == '"') {
64  sumoHome.pop_back();
65  }
66  sumoHome += "/bin/";
67  }
68  // quote to handle spaces. note that this differs from GNEPythonTool because the python interpreter is a bit smarter
69  // when handling quoted parts within a path
70  myNetgenerateCommand = "\"" + sumoHome + exePath + "\"";
71 
72  // iterate over all topics
73  for (const auto& topic : netgenerateOptions->getSubTopics()) {
74  // ignore configuration
75  if (topic != "Configuration") {
76  const std::vector<std::string> entries = netgenerateOptions->getSubTopicsEntries(topic);
77  for (const auto& entry : entries) {
78  if (!netgenerateOptions->isDefault(entry)) {
79  myNetgenerateCommand += " --" + entry + " " + netgenerateOptions->getValueString(entry);
80  }
81  }
82  }
83  }
84  // reset flags
85  myRunning = false;
86  myErrorOccurred = false;
87  start();
88 }
89 
90 
91 void
93  if (myRunning) {
94  // cancel thread
95  cancel();
96  // reset flags
97  myRunning = false;
98  myErrorOccurred = false;
99  // show info
100  myEventQueue.push_back(new GUIEvent_Message(GUIEventType::ERROR_OCCURRED, std::string(TL("cancelled by user\n"))));
102  }
103 }
104 
105 
106 bool
108  return myRunning;
109 }
110 
111 
112 bool
114  return myErrorOccurred;
115 }
116 
117 
118 FXint
120  // declare buffer
121  char buffer[128];
122  for (int i = 0; i < 128; i++) {
123  buffer[i] = '\0';
124  }
125  // open process showing std::err in console
126 #ifdef WIN32
127  myPipe = _popen(StringUtils::transcodeToLocal(myNetgenerateCommand + " 2>&1").c_str(), "r");
128 #else
129  myPipe = popen((myNetgenerateCommand + " 2>&1").c_str(), "r");
130 #endif
131  if (!myPipe) {
132  // set error ocurred flag
133  myErrorOccurred = true;
137  return 1;
138  } else {
139  // set running flag
140  myRunning = true;
141  // Show command
143  // start process
144  myEventQueue.push_back(new GUIEvent_Message(GUIEventType::MESSAGE_OCCURRED, std::string(TL("starting process...\n"))));
146  try {
147  // add buffer
148  while (fgets(buffer, sizeof buffer, myPipe) != NULL) {
151  }
152  } catch (...) {
153  // close process
154 #ifdef WIN32
155  _pclose(myPipe);
156 #else
157  pclose(myPipe);
158 #endif
159  // set flags
160  myRunning = false;
161  myErrorOccurred = true;
162  myEventQueue.push_back(new GUIEvent_Message(GUIEventType::ERROR_OCCURRED, std::string(TL("error processing command\n"))));
164  return 1;
165  }
166  }
167  // close process
168 #ifdef WIN32
169  _pclose(myPipe);
170 #else
171  pclose(myPipe);
172 #endif
173  myPipe = nullptr;
174  // set running flag
175  myRunning = false;
176  // end process
177  myEventQueue.push_back(new GUIEvent_Message(GUIEventType::MESSAGE_OCCURRED, std::string(TL("process finished\n"))));
180  return 1;
181 }
182 
183 /****************************************************************************/
@ MESSAGE_OCCURRED
send when a message occured
@ ERROR_OCCURRED
send when a error occured
@ OUTPUT_OCCURRED
send when a tool produces output
@ TOOL_ENDED
send when a tool finishes
#define TL(string)
Definition: MsgHandler.h:315
Abstract dialog for tools.
FXEX::MFXThreadEvent & myEventThrow
event throw
bool myErrorOccurred
flag for check if during execution an error was Occurred
FILE * myPipe
pipe file
bool errorOccurred() const
check if during execution an error was Occurred
void abort()
abort netgenerate running
bool myRunning
flag for check if netgenerate is running
~GNERunNetgenerate()
destructor
FXint run()
starts the thread. The thread ends after the netgenerate is finished
MFXSynchQue< GUIEvent * > & myEventQueue
event Queue
GNERunNetgenerate(GNERunNetgenerateDialog *runDialog, MFXSynchQue< GUIEvent * > &eq, FXEX::MFXThreadEvent &ev)
Constructor.
bool isRunning() const
check if netgenerate is running
std::string myNetgenerateCommand
netgenerate command
void push_back(T what)
Definition: MFXSynchQue.h:113
A storage for options typed value containers)
Definition: OptionsCont.h:89
const std::vector< std::string > & getSubTopics() const
return the list of subtopics
bool isDefault(const std::string &name) const
Returns the information whether the named option has still the default value.
std::string getValueString(const std::string &name) const
Returns the string-value of the named option (all options)
std::vector< std::string > getSubTopicsEntries(const std::string &subtopic) const
return the list of entries for the given subtopic
static std::string transcodeToLocal(const std::string &utf8String)
convert a string from UTF-8 to the local codepage