|
SUMO - Simulation of Urban MObility
|
00001 /****************************************************************************/ 00008 // Retrieves messages about the process and gives them further to output 00009 /****************************************************************************/ 00010 // SUMO, Simulation of Urban MObility; see http://sumo.sourceforge.net/ 00011 // Copyright (C) 2001-2012 DLR (http://www.dlr.de/) and contributors 00012 /****************************************************************************/ 00013 // 00014 // This file is part of SUMO. 00015 // SUMO is free software: you can redistribute it and/or modify 00016 // it under the terms of the GNU General Public License as published by 00017 // the Free Software Foundation, either version 3 of the License, or 00018 // (at your option) any later version. 00019 // 00020 /****************************************************************************/ 00021 00022 00023 // =========================================================================== 00024 // included modules 00025 // =========================================================================== 00026 #ifdef _MSC_VER 00027 #include <windows_config.h> 00028 #else 00029 #include <config.h> 00030 #endif 00031 00032 #include <string> 00033 #include <cassert> 00034 #include <vector> 00035 #include <algorithm> 00036 #include <iostream> 00037 #include "MsgHandler.h" 00038 #include <utils/options/OptionsCont.h> 00039 #include <utils/iodevices/OutputDevice.h> 00040 #include <utils/common/UtilExceptions.h> 00041 #include "AbstractMutex.h" 00042 00043 #ifdef CHECK_MEMORY_LEAKS 00044 #include <foreign/nvwa/debug_new.h> 00045 #endif // CHECK_MEMORY_LEAKS 00046 00047 00048 // =========================================================================== 00049 // global variable definitions 00050 // =========================================================================== 00051 bool gSuppressWarnings = false; 00052 bool gSuppressMessages = false; 00053 00054 00055 // =========================================================================== 00056 // static member variables 00057 // =========================================================================== 00058 MsgHandler* MsgHandler::myErrorInstance = 0; 00059 MsgHandler* MsgHandler::myWarningInstance = 0; 00060 MsgHandler* MsgHandler::myMessageInstance = 0; 00061 bool MsgHandler::myAmProcessingProcess = false; 00062 AbstractMutex* MsgHandler::myLock = 0; 00063 00064 00065 // =========================================================================== 00066 // method definitions 00067 // =========================================================================== 00068 MsgHandler* 00069 MsgHandler::getMessageInstance() { 00070 if (myMessageInstance == 0) { 00071 myMessageInstance = new MsgHandler(MT_MESSAGE); 00072 } 00073 return myMessageInstance; 00074 } 00075 00076 00077 MsgHandler* 00078 MsgHandler::getWarningInstance() { 00079 if (myWarningInstance == 0) { 00080 myWarningInstance = new MsgHandler(MT_WARNING); 00081 } 00082 return myWarningInstance; 00083 } 00084 00085 00086 MsgHandler* 00087 MsgHandler::getErrorInstance() { 00088 if (myErrorInstance == 0) { 00089 myErrorInstance = new MsgHandler(MT_ERROR); 00090 } 00091 return myErrorInstance; 00092 } 00093 00094 00095 void 00096 MsgHandler::inform(std::string msg, bool addType) { 00097 if (myLock != 0) { 00098 myLock->lock(); 00099 } 00100 // beautify progress output 00101 if (myAmProcessingProcess && (myReport2COUT || myReport2CERR)) { 00102 std::cout << std::endl; 00103 } 00104 msg = build(msg, addType); 00105 // report to std::cout if wished 00106 if (myReport2COUT) { 00107 std::cout << msg << std::endl; 00108 } 00109 // report to std::cerr if wished 00110 if (myReport2CERR) { 00111 std::cerr << msg << std::endl; 00112 } 00113 // inform all other receivers 00114 for (RetrieverVector::iterator i = myRetrievers.begin(); i != myRetrievers.end(); i++) { 00115 (*i)->inform(msg); 00116 } 00117 // set the information that something occured 00118 myWasInformed = true; 00119 myAmProcessingProcess = false; 00120 if (myLock != 0) { 00121 myLock->unlock(); 00122 } 00123 } 00124 00125 00126 void 00127 MsgHandler::progressMsg(std::string msg, bool addType) { 00128 if (myLock != 0) { 00129 myLock->lock(); 00130 } 00131 // beautify progress output 00132 if (myAmProcessingProcess && (myReport2COUT || myReport2CERR)) { 00133 std::cout << std::endl; 00134 } 00135 msg = build(msg, addType); 00136 // report to std::cout if wished 00137 if (myReport2COUT) { 00138 std::cout << msg << '\r'; 00139 } 00140 // report to std::cerr if wished 00141 if (myReport2CERR) { 00142 std::cerr << msg << '\r'; 00143 } 00144 // inform all other receivers 00145 for (RetrieverVector::iterator i = myRetrievers.begin(); i != myRetrievers.end(); i++) { 00146 (*i)->inform(msg); 00147 } 00148 // set the information that something occured 00149 myWasInformed = true; 00150 myAmProcessingProcess = false; 00151 if (myLock != 0) { 00152 myLock->unlock(); 00153 } 00154 } 00155 00156 00157 void 00158 MsgHandler::beginProcessMsg(std::string msg, bool addType) { 00159 if (myLock != 0) { 00160 myLock->lock(); 00161 } 00162 msg = build(msg, addType); 00163 // report to std::cout if wished 00164 if (myReport2COUT) { 00165 std::cout << msg << ' '; 00166 std::cout.flush(); 00167 myAmProcessingProcess = true; 00168 } 00169 // report to std::cerr if wished 00170 if (myReport2CERR) { 00171 std::cerr << msg << ' '; 00172 std::cerr.flush(); 00173 myAmProcessingProcess = true; 00174 } 00175 // inform all other receivers 00176 for (RetrieverVector::iterator i = myRetrievers.begin(); i != myRetrievers.end(); i++) { 00177 (*i)->inform(msg + " "); 00178 myAmProcessingProcess = true; 00179 } 00180 // set the information that something occured 00181 myWasInformed = true; 00182 if (myLock != 0) { 00183 myLock->unlock(); 00184 } 00185 } 00186 00187 00188 void 00189 MsgHandler::endProcessMsg(std::string msg) { 00190 if (myLock != 0) { 00191 myLock->lock(); 00192 } 00193 // report to std::cout if wished 00194 if (myReport2COUT) { 00195 std::cout << msg << std::endl; 00196 } 00197 // report to std::cerr if wished 00198 if (myReport2CERR) { 00199 std::cerr << msg << std::endl; 00200 } 00201 // inform all other receivers 00202 for (RetrieverVector::iterator i = myRetrievers.begin(); i != myRetrievers.end(); i++) { 00203 (*i)->inform(msg); 00204 } 00205 // set the information that something occured 00206 myWasInformed = true; 00207 myAmProcessingProcess = false; 00208 if (myLock != 0) { 00209 myLock->unlock(); 00210 } 00211 } 00212 00213 00214 void 00215 MsgHandler::clear() { 00216 if (myLock != 0) { 00217 myLock->lock(); 00218 } 00219 myWasInformed = false; 00220 if (myLock != 0) { 00221 myLock->unlock(); 00222 } 00223 } 00224 00225 00226 void 00227 MsgHandler::addRetriever(OutputDevice* retriever) { 00228 if (myLock != 0) { 00229 myLock->lock(); 00230 } 00231 RetrieverVector::iterator i = 00232 find(myRetrievers.begin(), myRetrievers.end(), retriever); 00233 if (i == myRetrievers.end()) { 00234 myRetrievers.push_back(retriever); 00235 } 00236 // check whether the message shall be generated 00237 if (myType == MT_WARNING) { 00238 gSuppressWarnings = OptionsCont::getOptions().exists("no-warnings") 00239 ? OptionsCont::getOptions().getBool("no-warnings") 00240 : false; 00241 } else if (myType == MT_MESSAGE) { 00242 gSuppressMessages = false; 00243 } 00244 if (myLock != 0) { 00245 myLock->unlock(); 00246 } 00247 } 00248 00249 00250 void 00251 MsgHandler::removeRetriever(OutputDevice* retriever) { 00252 if (myLock != 0) { 00253 myLock->lock(); 00254 } 00255 RetrieverVector::iterator i = 00256 find(myRetrievers.begin(), myRetrievers.end(), retriever); 00257 if (i != myRetrievers.end()) { 00258 myRetrievers.erase(i); 00259 } 00260 // check whether the message shall be generated 00261 if (myType == MT_WARNING) { 00262 gSuppressWarnings = OptionsCont::getOptions().exists("no-warnings") 00263 ? OptionsCont::getOptions().getBool("no-warnings") 00264 : myRetrievers.size() == 0; 00265 } else if (myType == MT_MESSAGE) { 00266 gSuppressMessages = !(myRetrievers.size() == 0 || myReport2COUT); 00267 } 00268 if (myLock != 0) { 00269 myLock->unlock(); 00270 } 00271 } 00272 00273 00274 void 00275 MsgHandler::report2cout(bool value) { 00276 if (myLock != 0) { 00277 myLock->lock(); 00278 } 00279 myReport2COUT = value; 00280 if (myType == MT_WARNING) { 00281 gSuppressWarnings = OptionsCont::getOptions().exists("no-warnings") 00282 ? OptionsCont::getOptions().getBool("no-warnings") 00283 : !myReport2COUT; 00284 } else if (myType == MT_MESSAGE) { 00285 gSuppressMessages = myRetrievers.size() == 0 && !myReport2COUT; 00286 } 00287 std::cout.setf(std::ios::fixed, std::ios::floatfield); 00288 if (myLock != 0) { 00289 myLock->unlock(); 00290 } 00291 } 00292 00293 00294 void 00295 MsgHandler::report2cerr(bool value) { 00296 if (myLock != 0) { 00297 myLock->lock(); 00298 } 00299 myReport2CERR = value; 00300 if (myType == MT_WARNING) { 00301 gSuppressWarnings = OptionsCont::getOptions().exists("no-warnings") 00302 ? OptionsCont::getOptions().getBool("no-warnings") 00303 : !myReport2CERR; 00304 } else if (myType == MT_MESSAGE) { 00305 gSuppressMessages = myRetrievers.size() == 0 && !myReport2COUT; 00306 } 00307 std::cerr.setf(std::ios::fixed, std::ios::floatfield); 00308 if (myLock != 0) { 00309 myLock->unlock(); 00310 } 00311 } 00312 00313 00314 void 00315 MsgHandler::initOutputOptions(bool gui) { 00316 OptionsCont& oc = OptionsCont::getOptions(); 00317 getMessageInstance()->report2cout(!gui && oc.getBool("verbose")); 00318 getWarningInstance()->report2cerr(!gui && !oc.getBool("no-warnings")); 00319 // build the logger if possible 00320 if (oc.isSet("log")) { 00321 try { 00322 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("log")); 00323 getErrorInstance()->addRetriever(logFile); 00324 getWarningInstance()->addRetriever(logFile); 00325 getMessageInstance()->addRetriever(logFile); 00326 } catch (IOError&) { 00327 throw ProcessError("Could not build logging file '" + oc.getString("log") + "'"); 00328 } 00329 } 00330 if (oc.isSet("message-log")) { 00331 try { 00332 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("message-log")); 00333 getMessageInstance()->addRetriever(logFile); 00334 } catch (IOError&) { 00335 throw ProcessError("Could not build logging file '" + oc.getString("message-log") + "'"); 00336 } 00337 } 00338 if (oc.isSet("error-log")) { 00339 try { 00340 OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("error-log")); 00341 getErrorInstance()->addRetriever(logFile); 00342 getWarningInstance()->addRetriever(logFile); 00343 } catch (IOError&) { 00344 throw ProcessError("Could not build logging file '" + oc.getString("error-log") + "'"); 00345 } 00346 } 00347 } 00348 00349 00350 void 00351 MsgHandler::cleanupOnEnd() { 00352 if (myLock != 0) { 00353 myLock->lock(); 00354 } 00355 delete myMessageInstance; 00356 myMessageInstance = 0; 00357 delete myWarningInstance; 00358 myWarningInstance = 0; 00359 delete myErrorInstance; 00360 myErrorInstance = 0; 00361 if (myLock != 0) { 00362 myLock->unlock(); 00363 } 00364 } 00365 00366 00367 MsgHandler::MsgHandler(MsgType type) 00368 : myType(type), myWasInformed(false), myReport2COUT(type == MT_MESSAGE), 00369 myReport2CERR(type != MT_MESSAGE) {} 00370 00371 00372 MsgHandler::~MsgHandler() { 00373 } 00374 00375 00376 bool 00377 MsgHandler::wasInformed() const { 00378 return myWasInformed; 00379 } 00380 00381 00382 void 00383 MsgHandler::assignLock(AbstractMutex* lock) { 00384 assert(myLock == 0); 00385 myLock = lock ; 00386 } 00387 00388 00389 00390 /****************************************************************************/ 00391