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