1 /****************************************************************************/ 2 // Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.org/sumo 3 // Copyright (C) 2003-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.h 11 /// @author Daniel Krajzewicz 12 /// @author Michael Behrisch 13 /// @author Jakob Erdmann 14 /// @date Tue, 17 Jun 2003 15 /// @version $Id$ 16 /// 17 // Retrieves messages about the process and gives them further to output 18 /****************************************************************************/ 19 #ifndef MsgHandler_h 20 #define MsgHandler_h 21 22 23 // =========================================================================== 24 // included modules 25 // =========================================================================== 26 27 #include <string> 28 #include <vector> 29 #include <iostream> 30 31 32 // =========================================================================== 33 // class declarations 34 // =========================================================================== 35 class OutputDevice; 36 37 38 // =========================================================================== 39 // class definitions 40 // =========================================================================== 41 /** 42 * MsgHandler 43 */ 44 class MsgHandler { 45 public: 46 /** 47 * @enum MsgType 48 * An enumeration to differ between different types of messages 49 * (errors, warning and information) 50 */ 51 enum MsgType { 52 /// The message is only something to show 53 MT_MESSAGE, 54 /// The message is a warning 55 MT_WARNING, 56 /// The message is an error 57 MT_ERROR, 58 /// The message is an debug 59 MT_DEBUG, 60 /// The message is an debug 61 MT_GLDEBUG 62 }; 63 64 private: 65 typedef MsgHandler* (*Factory)(MsgType); 66 67 public: 68 /// @brief Sets the factory function to use for new MsgHandlers setFactory(Factory func)69 static void setFactory(Factory func) { 70 myFactory = func; 71 } 72 73 /// @brief Returns the instance to add normal messages to 74 static MsgHandler* getMessageInstance(); 75 76 /// @brief Returns the instance to add warnings to 77 static MsgHandler* getWarningInstance(); 78 79 /// @brief Returns the instance to add errors to 80 static MsgHandler* getErrorInstance(); 81 82 /// @brief Returns the instance to add debug to 83 static MsgHandler* getDebugInstance(); 84 85 /// @brief Returns the instance to add GLdebug to 86 static MsgHandler* getGLDebugInstance(); 87 88 /// @brief enable/disable debug messages 89 static void enableDebugMessages(bool enable); 90 91 /// @brief enable/disable gl-debug messages 92 static void enableDebugGLMessages(bool enable); 93 94 /// @brief check whether to enable/disable debug messages writeDebugMessages()95 static inline bool writeDebugMessages() { 96 return myWriteDebugMessages; 97 } 98 99 /// @brief check whether to enable/disable gl-debug messages writeDebugGLMessages()100 static inline bool writeDebugGLMessages() { 101 return myWriteDebugGLMessages; 102 } 103 104 /// @brief ensure that that given output device is no longer used as retriever by any instance 105 static void removeRetrieverFromAllInstances(OutputDevice* out); 106 107 ///@brief init output options 108 static void initOutputOptions(); 109 110 /// @brief Removes pending handler 111 static void cleanupOnEnd(); 112 113 /// @brief adds a new error to the list 114 virtual void inform(std::string msg, bool addType = true); 115 116 /** @brief Begins a process information 117 * 118 * When a longer action is started, this method should be used to inform the user about it. 119 * There will be no newline printed, but the message handler will be informed that 120 * a process message has been begun. If an error occurs, a newline will be printed. 121 * After the action has been performed, use endProcessMsg to inform the user about it. 122 */ 123 virtual void beginProcessMsg(std::string msg, bool addType = true); 124 125 /// @brief Ends a process information 126 virtual void endProcessMsg(std::string msg); 127 128 /// @brief Clears information whether an error occurred previously 129 virtual void clear(); 130 131 /// @brief Adds a further retriever to the instance responsible for a certain msg type 132 virtual void addRetriever(OutputDevice* retriever); 133 134 /// @brief Removes the retriever from the handler 135 virtual void removeRetriever(OutputDevice* retriever); 136 137 /// @brief Returns whether the given output device retrieves messages from the handler 138 bool isRetriever(OutputDevice* retriever) const; 139 140 /// @brief Returns the information whether any messages were added 141 bool wasInformed() const; 142 143 /** @brief Generic output operator 144 * @return The MsgHandler for further processing 145 */ 146 template <class T> 147 MsgHandler& operator<<(const T& t) { 148 // inform all other receivers 149 for (auto i : myRetrievers) { 150 (*i) << t; 151 } 152 return *this; 153 } 154 155 protected: 156 /// @brief Builds the string which includes the mml-message type build(const std::string & msg,bool addType)157 inline std::string build(const std::string& msg, bool addType) { 158 if (addType) { 159 switch (myType) { 160 case MT_MESSAGE: 161 break; 162 case MT_WARNING: 163 return "Warning: " + msg; 164 break; 165 case MT_ERROR: 166 return "Error: " + msg; 167 break; 168 case MT_DEBUG: 169 return "Debug: " + msg; 170 break; 171 case MT_GLDEBUG: 172 return "GLDebug: " + msg; 173 break; 174 default: 175 break; 176 } 177 } 178 return msg; 179 } 180 181 182 /// @brief standard constructor 183 MsgHandler(MsgType type); 184 185 /// @brief destructor 186 virtual ~MsgHandler(); 187 188 private: 189 /// @brief The function to call for new MsgHandlers, nullptr means use default constructor 190 static Factory myFactory; 191 192 /// @brief The instance to handle debug 193 static MsgHandler* myDebugInstance; 194 195 /// @brief The instance to handle glDebug 196 static MsgHandler* myGLDebugInstance; 197 198 /// @brief The instance to handle errors 199 static MsgHandler* myErrorInstance; 200 201 /// @brief The instance to handle warnings 202 static MsgHandler* myWarningInstance; 203 204 /// @brief The instance to handle normal messages 205 static MsgHandler* myMessageInstance; 206 207 /// @brief Information whether a process information is printed to cout 208 static bool myAmProcessingProcess; 209 210 private: 211 /// @brief The type of the instance 212 MsgType myType; 213 214 /// @brief information wehther an error occurred at all 215 bool myWasInformed; 216 217 /// @brief The list of retrievers that shall be informed about new messages or errors 218 std::vector<OutputDevice*> myRetrievers; 219 220 private: 221 /// @brief invalid copy constructor 222 MsgHandler(const MsgHandler& s) = delete; 223 224 /// @brief invalid assignment operator 225 MsgHandler& operator=(const MsgHandler& s) = delete; 226 227 /** @brief Flag to enable or disable debug GL Functions 228 * 229 * This value is used to show more internal information throught warning messages about certain operations 230 */ 231 static bool myWriteDebugMessages; 232 static bool myWriteDebugGLMessages; 233 }; 234 235 236 // =========================================================================== 237 // global definitions 238 // =========================================================================== 239 #define WRITE_WARNING(msg) MsgHandler::getWarningInstance()->inform(msg); 240 #define WRITE_MESSAGE(msg) MsgHandler::getMessageInstance()->inform(msg); 241 #define PROGRESS_BEGIN_MESSAGE(msg) MsgHandler::getMessageInstance()->beginProcessMsg((msg) + std::string("...")); 242 #define PROGRESS_DONE_MESSAGE() MsgHandler::getMessageInstance()->endProcessMsg("done."); 243 #define PROGRESS_TIME_MESSAGE(before) MsgHandler::getMessageInstance()->endProcessMsg("done (" + toString(SysUtils::getCurrentMillis() - before) + "ms)."); 244 #define PROGRESS_FAILED_MESSAGE() MsgHandler::getMessageInstance()->endProcessMsg("failed."); 245 #define WRITE_ERROR(msg) MsgHandler::getErrorInstance()->inform(msg); 246 #define WRITE_DEBUG(msg) if(MsgHandler::writeDebugMessages()){MsgHandler::getDebugInstance()->inform(msg);}; 247 #define WRITE_GLDEBUG(msg) if(MsgHandler::writeDebugGLMessages()){MsgHandler::getGLDebugInstance()->inform(msg);}; 248 249 #endif 250 251 /****************************************************************************/ 252