SUMO - Simulation of Urban MObility
MsgHandler.cpp
Go to the documentation of this file.
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 // static member variables
00050 // ===========================================================================
00051 MsgHandler* MsgHandler::myErrorInstance = 0;
00052 MsgHandler* MsgHandler::myWarningInstance = 0;
00053 MsgHandler* MsgHandler::myMessageInstance = 0;
00054 bool MsgHandler::myAmProcessingProcess = false;
00055 AbstractMutex* MsgHandler::myLock = 0;
00056 
00057 
00058 // ===========================================================================
00059 // method definitions
00060 // ===========================================================================
00061 MsgHandler*
00062 MsgHandler::getMessageInstance() {
00063     if (myMessageInstance == 0) {
00064         myMessageInstance = new MsgHandler(MT_MESSAGE);
00065     }
00066     return myMessageInstance;
00067 }
00068 
00069 
00070 MsgHandler*
00071 MsgHandler::getWarningInstance() {
00072     if (myWarningInstance == 0) {
00073         myWarningInstance = new MsgHandler(MT_WARNING);
00074     }
00075     return myWarningInstance;
00076 }
00077 
00078 
00079 MsgHandler*
00080 MsgHandler::getErrorInstance() {
00081     if (myErrorInstance == 0) {
00082         myErrorInstance = new MsgHandler(MT_ERROR);
00083     }
00084     return myErrorInstance;
00085 }
00086 
00087 
00088 void
00089 MsgHandler::inform(std::string msg, bool addType) {
00090     if (myLock != 0) {
00091         myLock->lock();
00092     }
00093     // beautify progress output
00094     if (myAmProcessingProcess) {
00095         myAmProcessingProcess = false;
00096         MsgHandler::getMessageInstance()->inform("");
00097     }
00098     msg = build(msg, addType);
00099     // inform all receivers
00100     for (RetrieverVector::iterator i = myRetrievers.begin(); i != myRetrievers.end(); i++) {
00101         (*i)->inform(msg);
00102     }
00103     // set the information that something occured
00104     myWasInformed = true;
00105     if (myLock != 0) {
00106         myLock->unlock();
00107     }
00108 }
00109 
00110 
00111 void
00112 MsgHandler::beginProcessMsg(std::string msg, bool addType) {
00113     if (myLock != 0) {
00114         myLock->lock();
00115     }
00116     msg = build(msg, addType);
00117     // inform all other receivers
00118     for (RetrieverVector::iterator i = myRetrievers.begin(); i != myRetrievers.end(); i++) {
00119         (*i)->inform(msg, ' ');
00120         myAmProcessingProcess = true;
00121     }
00122     // set the information that something occured
00123     myWasInformed = true;
00124     if (myLock != 0) {
00125         myLock->unlock();
00126     }
00127 }
00128 
00129 
00130 void
00131 MsgHandler::endProcessMsg(std::string msg) {
00132     if (myLock != 0) {
00133         myLock->lock();
00134     }
00135     // inform all other receivers
00136     for (RetrieverVector::iterator i = myRetrievers.begin(); i != myRetrievers.end(); i++) {
00137         (*i)->inform(msg);
00138     }
00139     // set the information that something occured
00140     myWasInformed = true;
00141     myAmProcessingProcess = false;
00142     if (myLock != 0) {
00143         myLock->unlock();
00144     }
00145 }
00146 
00147 
00148 void
00149 MsgHandler::clear() {
00150     if (myLock != 0) {
00151         myLock->lock();
00152     }
00153     myWasInformed = false;
00154     if (myLock != 0) {
00155         myLock->unlock();
00156     }
00157 }
00158 
00159 
00160 void
00161 MsgHandler::addRetriever(OutputDevice* retriever) {
00162     if (myLock != 0) {
00163         myLock->lock();
00164     }
00165     RetrieverVector::iterator i =
00166         find(myRetrievers.begin(), myRetrievers.end(), retriever);
00167     if (i == myRetrievers.end()) {
00168         myRetrievers.push_back(retriever);
00169     }
00170     if (myLock != 0) {
00171         myLock->unlock();
00172     }
00173 }
00174 
00175 
00176 void
00177 MsgHandler::removeRetriever(OutputDevice* retriever) {
00178     if (myLock != 0) {
00179         myLock->lock();
00180     }
00181     RetrieverVector::iterator i =
00182         find(myRetrievers.begin(), myRetrievers.end(), retriever);
00183     if (i != myRetrievers.end()) {
00184         myRetrievers.erase(i);
00185     }
00186     if (myLock != 0) {
00187         myLock->unlock();
00188     }
00189 }
00190 
00191 
00192 void
00193 MsgHandler::initOutputOptions() {
00194     // initialize console properly
00195     OutputDevice::getDevice("stdout");
00196     OutputDevice::getDevice("stderr");
00197     OptionsCont& oc = OptionsCont::getOptions();
00198     if (!oc.getBool("verbose")) {
00199         getMessageInstance()->removeRetriever(&OutputDevice::getDevice("stdout"));
00200     }
00201     if (oc.getBool("no-warnings")) {
00202         getWarningInstance()->removeRetriever(&OutputDevice::getDevice("stderr"));
00203     }
00204     // build the logger if possible
00205     if (oc.isSet("log", false)) {
00206         try {
00207             OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("log"));
00208             getErrorInstance()->addRetriever(logFile);
00209             if (!oc.getBool("no-warnings")) {
00210                 getWarningInstance()->addRetriever(logFile);
00211             }
00212             getMessageInstance()->addRetriever(logFile);
00213         } catch (IOError&) {
00214             throw ProcessError("Could not build logging file '" + oc.getString("log") + "'");
00215         }
00216     }
00217     if (oc.isSet("message-log", false)) {
00218         try {
00219             OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("message-log"));
00220             getMessageInstance()->addRetriever(logFile);
00221         } catch (IOError&) {
00222             throw ProcessError("Could not build logging file '" + oc.getString("message-log") + "'");
00223         }
00224     }
00225     if (oc.isSet("error-log", false)) {
00226         try {
00227             OutputDevice* logFile = &OutputDevice::getDevice(oc.getString("error-log"));
00228             getErrorInstance()->addRetriever(logFile);
00229             getWarningInstance()->addRetriever(logFile);
00230         } catch (IOError&) {
00231             throw ProcessError("Could not build logging file '" + oc.getString("error-log") + "'");
00232         }
00233     }
00234 }
00235 
00236 
00237 void
00238 MsgHandler::cleanupOnEnd() {
00239     if (myLock != 0) {
00240         myLock->lock();
00241     }
00242     delete myMessageInstance;
00243     myMessageInstance = 0;
00244     delete myWarningInstance;
00245     myWarningInstance = 0;
00246     delete myErrorInstance;
00247     myErrorInstance = 0;
00248     if (myLock != 0) {
00249         myLock->unlock();
00250     }
00251 }
00252 
00253 
00254 MsgHandler::MsgHandler(MsgType type)
00255     : myType(type), myWasInformed(false) {
00256     if (type == MT_MESSAGE) {
00257         addRetriever(&OutputDevice::getDevice("stdout"));
00258     } else {
00259         addRetriever(&OutputDevice::getDevice("stderr"));
00260     }
00261 }
00262 
00263 
00264 MsgHandler::~MsgHandler() {
00265 }
00266 
00267 
00268 bool
00269 MsgHandler::wasInformed() const {
00270     return myWasInformed;
00271 }
00272 
00273 
00274 void
00275 MsgHandler::assignLock(AbstractMutex* lock) {
00276     assert(myLock == 0);
00277     myLock = lock ;
00278 }
00279 
00280 
00281 
00282 /****************************************************************************/
00283 
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Friends Defines