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 /****************************************************************************/
10 /// @file MsgHandler.cpp
11 /// @author Daniel Krajzewicz
12 /// @author Michael Behrisch
13 /// @date Tue, 17 Jun 2003
14 /// @version $Id$
15 ///
16 // Retrieves messages about the process and gives them further to output
17 /****************************************************************************/
18
19
20 // ===========================================================================
21 // included modules
22 // ===========================================================================
23 #include <config.h>
24
25 #include <string>
26 #include <cassert>
27 #include <vector>
28 #include <algorithm>
29 #include <iostream>
30 #ifdef HAVE_FOX
31 #include <fx.h>
32 #endif
33 #include <utils/options/OptionsCont.h>
34 #include <utils/iodevices/OutputDevice.h>
35 #include <utils/common/UtilExceptions.h>
36 #include "MsgHandler.h"
37
38
39 // ===========================================================================
40 // static member variables
41 // ===========================================================================
42
43 MsgHandler::Factory MsgHandler::myFactory = nullptr;
44 MsgHandler* MsgHandler::myDebugInstance = nullptr;
45 MsgHandler* MsgHandler::myGLDebugInstance = nullptr;
46 MsgHandler* MsgHandler::myErrorInstance = nullptr;
47 MsgHandler* MsgHandler::myWarningInstance = nullptr;
48 MsgHandler* MsgHandler::myMessageInstance = nullptr;
49 bool MsgHandler::myAmProcessingProcess = false;
50 bool MsgHandler::myWriteDebugMessages(false);
51 bool MsgHandler::myWriteDebugGLMessages(false);
52
53
54 // ===========================================================================
55 // method definitions
56 // ===========================================================================
57
58 MsgHandler*
getMessageInstance()59 MsgHandler::getMessageInstance() {
60 if (myMessageInstance == nullptr) {
61 if (myFactory == nullptr) {
62 myMessageInstance = new MsgHandler(MT_MESSAGE);
63 } else {
64 myMessageInstance = myFactory(MT_MESSAGE);
65 }
66 }
67 return myMessageInstance;
68 }
69
70
71 MsgHandler*
getWarningInstance()72 MsgHandler::getWarningInstance() {
73 if (myWarningInstance == nullptr) {
74 myWarningInstance = new MsgHandler(MT_WARNING);
75 }
76 return myWarningInstance;
77 }
78
79
80 MsgHandler*
getErrorInstance()81 MsgHandler::getErrorInstance() {
82 if (myErrorInstance == nullptr) {
83 myErrorInstance = new MsgHandler(MT_ERROR);
84 }
85 return myErrorInstance;
86 }
87
88
89 MsgHandler*
getDebugInstance()90 MsgHandler::getDebugInstance() {
91 if (myDebugInstance == nullptr) {
92 myDebugInstance = new MsgHandler(MT_DEBUG);
93 }
94 return myDebugInstance;
95 }
96
97
98 MsgHandler*
getGLDebugInstance()99 MsgHandler::getGLDebugInstance() {
100 if (myGLDebugInstance == nullptr) {
101 myGLDebugInstance = new MsgHandler(MT_GLDEBUG);
102 }
103 return myGLDebugInstance;
104 }
105
106
107 void
enableDebugMessages(bool enable)108 MsgHandler::enableDebugMessages(bool enable) {
109 myWriteDebugMessages = enable;
110 }
111
112 void
enableDebugGLMessages(bool enable)113 MsgHandler::enableDebugGLMessages(bool enable) {
114 myWriteDebugGLMessages = enable;
115 }
116
117 void
inform(std::string msg,bool addType)118 MsgHandler::inform(std::string msg, bool addType) {
119 // beautify progress output
120 if (myAmProcessingProcess) {
121 myAmProcessingProcess = false;
122 MsgHandler::getMessageInstance()->inform("");
123 }
124 msg = build(msg, addType);
125 // inform all receivers
126 for (auto i : myRetrievers) {
127 i->inform(msg);
128 }
129 // set the information that something occurred
130 myWasInformed = true;
131 }
132
133
134 void
beginProcessMsg(std::string msg,bool addType)135 MsgHandler::beginProcessMsg(std::string msg, bool addType) {
136 msg = build(msg, addType);
137 // inform all other receivers
138 for (auto i : myRetrievers) {
139 i->inform(msg, ' ');
140 myAmProcessingProcess = true;
141 }
142 // set the information that something occurred
143 myWasInformed = true;
144 }
145
146
147 void
endProcessMsg(std::string msg)148 MsgHandler::endProcessMsg(std::string msg) {
149 // inform all other receivers
150 for (auto i : myRetrievers) {
151 i->inform(msg);
152 }
153 // set the information that something occurred
154 myWasInformed = true;
155 myAmProcessingProcess = false;
156 }
157
158
159 void
clear()160 MsgHandler::clear() {
161 myWasInformed = false;
162 }
163
164
165 void
addRetriever(OutputDevice * retriever)166 MsgHandler::addRetriever(OutputDevice* retriever) {
167 if (!isRetriever(retriever)) {
168 myRetrievers.push_back(retriever);
169 }
170 }
171
172
173 void
removeRetriever(OutputDevice * retriever)174 MsgHandler::removeRetriever(OutputDevice* retriever) {
175 std::vector<OutputDevice*>::iterator i = find(myRetrievers.begin(), myRetrievers.end(), retriever);
176 if (i != myRetrievers.end()) {
177 myRetrievers.erase(i);
178 }
179 }
180
181
182 bool
isRetriever(OutputDevice * retriever) const183 MsgHandler::isRetriever(OutputDevice* retriever) const {
184 return std::find(myRetrievers.begin(), myRetrievers.end(), retriever) != myRetrievers.end();
185 }
186
187
188 void
removeRetrieverFromAllInstances(OutputDevice * out)189 MsgHandler::removeRetrieverFromAllInstances(OutputDevice* out) {
190 if (myDebugInstance != nullptr) {
191 myDebugInstance->removeRetriever(out);
192 }
193 if (myGLDebugInstance != nullptr) {
194 myGLDebugInstance->removeRetriever(out);
195 }
196 if (myErrorInstance != nullptr) {
197 myErrorInstance->removeRetriever(out);
198 }
199 if (myWarningInstance != nullptr) {
200 myWarningInstance->removeRetriever(out);
201 }
202 if (myMessageInstance != nullptr) {
203 myMessageInstance->removeRetriever(out);
204 }
205 }
206
207 void
initOutputOptions()208 MsgHandler::initOutputOptions() {
209 // initialize console properly
210 OutputDevice::getDevice("stdout");
211 OutputDevice::getDevice("stderr");
212 OptionsCont& oc = OptionsCont::getOptions();
213 if (oc.getBool("no-warnings")) {
214 getWarningInstance()->removeRetriever(&OutputDevice::getDevice("stderr"));
215 }
216 // build the logger if possible
217 if (oc.isSet("log", false)) {
218 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("log"));
219 getErrorInstance()->addRetriever(logFile);
220 if (!oc.getBool("no-warnings")) {
221 getWarningInstance()->addRetriever(logFile);
222 }
223 getMessageInstance()->addRetriever(logFile);
224 }
225 if (oc.isSet("message-log", false)) {
226 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("message-log"));
227 getMessageInstance()->addRetriever(logFile);
228 }
229 if (oc.isSet("error-log", false)) {
230 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("error-log"));
231 getErrorInstance()->addRetriever(logFile);
232 getWarningInstance()->addRetriever(logFile);
233 }
234 if (!oc.getBool("verbose")) {
235 getMessageInstance()->removeRetriever(&OutputDevice::getDevice("stdout"));
236 }
237 }
238
239
240 void
cleanupOnEnd()241 MsgHandler::cleanupOnEnd() {
242 delete myMessageInstance;
243 myMessageInstance = nullptr;
244 delete myWarningInstance;
245 myWarningInstance = nullptr;
246 delete myErrorInstance;
247 myErrorInstance = nullptr;
248 delete myDebugInstance;
249 myDebugInstance = nullptr;
250 delete myGLDebugInstance;
251 myGLDebugInstance = nullptr;
252 }
253
254
MsgHandler(MsgType type)255 MsgHandler::MsgHandler(MsgType type) :
256 myType(type), myWasInformed(false) {
257 if (type == MT_MESSAGE) {
258 addRetriever(&OutputDevice::getDevice("stdout"));
259 } else {
260 addRetriever(&OutputDevice::getDevice("stderr"));
261 }
262 }
263
264
~MsgHandler()265 MsgHandler::~MsgHandler() {
266 }
267
268
269 bool
wasInformed() const270 MsgHandler::wasInformed() const {
271 return myWasInformed;
272 }
273
274
275 /****************************************************************************/
276