Changeset 6105 for code/trunk/src/libraries/util
- Timestamp:
- Nov 20, 2009, 4:55:40 PM (15 years ago)
- Location:
- code/trunk
- Files:
-
- 2 deleted
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/console (added) merged: 5941,5945,5968-5975,5983,5985-5986,5991-5992,5994-5996,5998,6000,6004-6007,6010-6017,6034,6037,6041,6043-6044,6089,6103-6104
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/util/CMakeLists.txt
r5929 r6105 29 29 CRC32.cc 30 30 ExprParser.cc 31 OutputBuffer.cc32 31 OutputHandler.cc 33 32 SignalHandler.cc -
code/trunk/src/libraries/util/Debug.h
r5738 r6105 21 21 * 22 22 * Author: 23 * Benjamin Grauer 23 * Fabian 'x3n' Landau 24 * Reto Grieder 24 25 * Co-authors: 25 * Fabian 'x3n' Landau26 * ... 26 27 * 27 28 */ 28 29 29 30 /** 30 @file 31 @brief Handles different output-levels of errors, warnings, infos and debug information. 31 @file 32 @brief 33 Handles different output-levels of errors, warnings, infos and debug information. 32 34 33 35 The COUT(level) macro acts like std::cout, but the output is only performed if the given … … 35 37 36 38 There are two used values in this file: 37 - The hard debug level is used during compile time. It describes the highest allowed output level.39 - The hard debug level is used during compile time. It describes the highest allowed output level. 38 40 - The soft debug level is used during runtime and is the maximum of the three configurable 39 output-levels for console, log file and ingame shell.41 output-levels for console, log file and in game shell. 40 42 41 43 The separation between the three devices is done by the OutputHandler. … … 50 52 6: Crazy debug information 51 53 52 54 @example 53 55 COUT(0) << "Very important output" << std::endl; 54 56 COUT(1) << "Error: Something went wrong!" << std::endl; 55 57 COUT(2) << "Warning: There might be a problem." << std::endl; 56 COUT(3) << "Info: It's monday" << std::endl;58 COUT(3) << "Info: It's Monday" << std::endl; 57 59 COUT(4) << "Debug: x is 1.23456" << std::endl; 58 60 */ 59 61 60 #ifndef _ Debug_H__61 #define _ Debug_H__62 #ifndef _Util_Debug_H__ 63 #define _Util_Debug_H__ 62 64 63 65 #include "UtilPrereqs.h" 64 65 66 #include "OutputHandler.h" 66 67 67 68 namespace orxonox 68 69 { 69 /** 70 @brief Returns the soft debug level, stored in the only existing instance of the OutputHandler class, configured in the config-file. 71 @return The soft debug level 72 */ 73 inline int getSoftDebugLevel() 74 { 75 return OutputHandler::getSoftDebugLevel(); 76 } 70 // Just for convenience 71 using std::endl; 77 72 78 using std::endl; 73 //! Adjust to discard certain output with level > hardDebugLevel at compile time 74 const int hardDebugLevel = OutputLevel::Verbose; 79 75 } 80 76 81 // DEFINE ERROR MODES 82 #define ORX_NONE 0 83 #define ORX_ERROR 1 84 #define ORX_WARNING 2 85 #define ORX_INFO 3 86 #define ORX_DEBUG 4 87 #define ORX_VERBOSE 5 88 #define ORX_ULTRA 6 77 /** 78 @brief 79 Logs text output: use exactly like std::cout, but specify an output 80 level as argument. 81 @example 82 COUT(3) << "Some info" << std::endl; 83 @note 84 The ? : operator requires both possible results to have the type of 85 the first. This is achieved by the int conversion operator dummy 86 in the OutputHandler. 87 */ 88 #define COUT(level) \ 89 /*if*/ (level > orxonox::hardDebugLevel) ? \ 90 0 \ 91 /*else*/ : \ 92 /*if*/ (level > orxonox::OutputHandler::getSoftDebugLevel()) ? \ 93 0 \ 94 /*else*/ : \ 95 orxonox::OutputHandler::getOutStream(level) 89 96 90 //definitions 91 #define ORX_PRINT_DEBUG_OUTPUT 1 92 #define ORX_HARD_DEBUG_LEVEL ORX_VERBOSE 93 94 #define COUT_EXEC(x) orxonox::OutputHandler::getOutStream().setOutputLevel(x) 95 96 //////////////////////////////////////////////////////// 97 /// COUT: just prints output as is with std::cout /// 98 //////////////////////////////////////////////////////// 99 #define COUTORX_NONE COUT0 100 #define COUTORX_ERROR COUT1 101 #define COUTORX_WARNING COUT2 102 #define COUTORX_INFO COUT3 103 #define COUTORX_DEBUG COUT4 104 #define COUTORX_VERBOSE COUT5 105 #define COUTORX_ULTRA COUT6 106 107 #ifndef COUT 108 #if ORX_PRINT_DEBUG_OUTPUT 109 #define COUT(x) \ 110 COUT ## x 111 112 #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE 113 #define COUT0 \ 114 (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0) 115 #else 116 #define COUT0 \ 117 false ? COUT_EXEC(0) : COUT_EXEC(0) 118 #endif 119 120 #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR 121 #define COUT1 \ 122 (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1) 123 #else 124 #define COUT1 \ 125 false ? COUT_EXEC(1) : COUT_EXEC(1) 126 #endif 127 128 #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING 129 #define COUT2 \ 130 (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2) 131 #else 132 #define COUT2 \ 133 false ? COUT_EXEC(2) : COUT_EXEC(2) 134 #endif 135 136 #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO 137 #define COUT3 \ 138 (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3) 139 #else 140 #define COUT3 \ 141 false ? COUT_EXEC(3) : COUT_EXEC(3) 142 #endif 143 144 #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG 145 #define COUT4 \ 146 (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4) 147 #else 148 #define COUT4 \ 149 false ? COUT_EXEC(4) : COUT_EXEC(4) 150 #endif 151 152 #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE 153 #define COUT5 \ 154 (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5) 155 #else 156 #define COUT5 \ 157 false ? COUT_EXEC(5) : COUT_EXEC(5) 158 #endif 159 160 #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA 161 #define COUT6 \ 162 (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6) 163 #else 164 #define COUT6 \ 165 false ? COUT_EXEC(6) : COUT_EXEC(6) 166 #endif 167 168 #else /* if ORX_PRINT_DEBUG_OUTPUT */ 169 #define COUT(x) \ 170 false ? COUT_EXEC(6) : COUT_EXEC(6) 171 #endif /* if ORX_PRINT_DEBUG_OUTPUT */ 172 173 #endif /* ifndef COUT */ 174 175 176 ///////////////////////////////////////////////////////////////////// 177 /// CCOUT: Prints output with std::cout and adds the classname /// 178 ///////////////////////////////////////////////////////////////////// 179 #define CCOUTORX_NONE CCOUT0 180 #define CCOUTORX_ERROR CCOUT1 181 #define CCOUTORX_WARNING CCOUT2 182 #define CCOUTORX_INFO CCOUT3 183 #define CCOUTORX_DEBUG CCOUT4 184 #define CCOUTORX_VERBOSE CCOUT5 185 #define CCOUTORX_ULTRA CCOUT6 186 187 #define CCOUT_EXEC(x) \ 188 orxonox::OutputHandler::getOutStream().setOutputLevel(x) \ 189 << this->getIdentifier()->getName() << ": " 190 191 #ifndef CCOUT 192 #if ORX_PRINT_DEBUG_OUTPUT 193 #define CCOUT(x) \ 194 CCOUT ## x 195 196 #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE 197 #define CCOUT0 \ 198 (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0) 199 #else 200 #define CCOUT0 \ 201 false ? COUT_EXEC(0) : CCOUT_EXEC(0) 202 #endif 203 204 #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR 205 #define CCOUT1 \ 206 (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1) 207 #else 208 #define CCOUT1 \ 209 false ? COUT_EXEC(1) : CCOUT_EXEC(1) 210 #endif 211 212 #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING 213 #define CCOUT2 \ 214 (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2) 215 #else 216 #define CCOUT2 \ 217 false ? COUT_EXEC(2) : CCOUT_EXEC(2) 218 #endif 219 220 #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO 221 #define CCOUT3 \ 222 (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3) 223 #else 224 #define CCOUT3 \ 225 false ? COUT_EXEC(3) : CCOUT_EXEC(3) 226 #endif 227 228 #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG 229 #define CCOUT4 \ 230 (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4) 231 #else 232 #define CCOUT4 \ 233 false ? COUT_EXEC(4) : CCOUT_EXEC(4) 234 #endif 235 236 #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE 237 #define CCOUT5 \ 238 (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5) 239 #else 240 #define CCOUT5 \ 241 false ? COUT_EXEC(5) : CCOUT_EXEC(5) 242 #endif 243 244 #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA 245 #define CCOUT6 \ 246 (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6) 247 #else 248 #define CCOUT6 \ 249 false ? COUT_EXEC(6) : CCOUT_EXEC(6) 250 #endif 251 252 #else /* if ORX_PRINT_DEBUG_OUTPUT */ 253 #define CCOUT(x) \ 254 false ? CCOUT_EXEC(6) : CCOUT_EXEC(6) 255 #endif /* if ORX_PRINT_DEBUG_OUTPUT */ 256 257 #endif /* ifndef CCOUT */ 258 259 #endif /* _Debug_H__ */ 97 #endif /* _Util_Debug_H__ */ -
code/trunk/src/libraries/util/OrxAssert.h
r5738 r6105 44 44 #ifndef NDEBUG 45 45 #define OrxAssert(Assertion, ErrorMessage) \ 46 Assertion ? ((void)0) : (void)(orxonox::OutputHandler::getOutStream( ).setOutputLevel(1) << ErrorMessage << std::endl); \46 Assertion ? ((void)0) : (void)(orxonox::OutputHandler::getOutStream(1) << ErrorMessage << std::endl); \ 47 47 assert(Assertion) 48 48 #else -
code/trunk/src/libraries/util/OutputHandler.cc
r5738 r6105 23 23 * Fabian 'x3n' Landau 24 24 * Co-authors: 25 * ...25 * Reto Grieder 26 26 * 27 27 */ 28 28 29 29 /** 30 @file 31 @brief Implementation of the OutputHandler class. 30 @file 31 @brief 32 Definition of classes related to output (logging). 32 33 */ 33 34 34 35 #include "OutputHandler.h" 35 36 37 #include <algorithm> 36 38 #include <ctime> 37 39 #include <cstdlib> 40 #include <fstream> 41 #include <sstream> 42 43 #include "Debug.h" 38 44 39 45 namespace orxonox 40 46 { 47 //! How the log file shall be named on the filesystem 48 const std::string logFileBaseName_g = "orxonox.log"; 49 50 ///////////////////////// 51 ///// LogFileWriter ///// 52 ///////////////////////// 41 53 /** 42 @brief Constructor: Opens the logfile and writes the first line. 43 @param logfilename The name of the logfile 54 @brief 55 Writes the output to the log file. 56 @note 57 As long as the correct log path is not yet known (for pre main code), the 58 LogFileWriter will write to a temporary file in /temp (Unix) or %TEMP% (Windows). 59 As soon as you set the correct path setLogPath the content of the temporary file 60 is read and put into the new file as well. 44 61 */ 62 class LogFileWriter : public OutputListener 63 { 64 public: 65 /** 66 @brief 67 Gets temporary log path and starts the log file 68 @param outputHandler 69 This is only required to avoid another call to getInstance (this c'tor was 70 called from getInstance!) 71 */ 72 LogFileWriter() 73 : OutputListener(OutputHandler::logFileOutputListenerName_s) 74 { 75 // Get path for a temporary file 76 #ifdef ORXONOX_PLATFORM_WINDOWS 77 char* pTempDir = getenv("TEMP"); 78 this->logFilename_ = std::string(pTempDir) + "/" + logFileBaseName_g; 79 #else 80 this->logFilename_ = std::string("/tmp/") + logFileBaseName_g; 81 #endif 82 83 // Get current time 84 time_t rawtime; 85 struct tm* timeinfo; 86 time(&rawtime); 87 timeinfo = localtime(&rawtime); 88 89 this->logFile_.open(this->logFilename_.c_str(), std::fstream::out); 90 this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl; 91 this->logFile_.flush(); 92 93 this->outputStream_ = &this->logFile_; 94 } 95 96 //! Closes the log file 97 ~LogFileWriter() 98 { 99 this->logFile_ << "Closed log" << std::endl; 100 this->logFile_.close(); 101 } 102 103 //! Changes the log path 104 void setLogPath(const std::string& path) 105 { 106 this->logFile_.close(); 107 // Read old file into a buffer 108 std::ifstream old(this->logFilename_.c_str()); 109 this->logFilename_ = path + logFileBaseName_g; 110 // Open the new file and feed it the content of the old one 111 this->logFile_.open(this->logFilename_.c_str(), std::fstream::out); 112 this->logFile_ << old.rdbuf(); 113 this->logFile_.flush(); 114 old.close(); 115 } 116 117 private: 118 std::ofstream logFile_; //! File handle for the log file 119 std::string logFilename_; //! Filename of the log file 120 }; 121 122 123 ///////////////////////// 124 ///// ConsoleWriter ///// 125 ///////////////////////// 126 /** 127 @brief 128 Writes the output to std::cout. 129 @note 130 This listener will usually be disable once an actual shell with console is instantiated. 131 */ 132 class ConsoleWriter : public OutputListener 133 { 134 public: 135 //! Only assigns the output stream with std::cout 136 ConsoleWriter() 137 : OutputListener("consoleLog") 138 { 139 this->outputStream_ = &std::cout; 140 } 141 }; 142 143 144 /////////////////////////// 145 ///// MemoryLogWriter ///// 146 /////////////////////////// 147 /** 148 @brief 149 OutputListener that writes all the output piece by piece to an array 150 associated with the corresponding output level. 151 @note 152 Only output below or equal to the current soft debug level is written 153 to minimise huge arrays for the normal run. 154 */ 155 class MemoryLogWriter : public OutputListener 156 { 157 public: 158 friend class OutputHandler; 159 160 /** 161 @brief 162 Sets the right soft debug level and registers itself 163 @param outputHandler 164 This is only required to avoid another call to getInstance (this c'tor was 165 called from getInstance!) 166 */ 167 MemoryLogWriter() 168 : OutputListener("memoryLog") 169 { 170 this->outputStream_ = &this->buffer_; 171 } 172 173 //! Pushed the just written output to the internal array 174 void outputChanged(int level) 175 { 176 // Read ostringstream and store it 177 this->output_.push_back(std::make_pair(level, this->buffer_.str())); 178 // Clear content and flags 179 this->buffer_.str(std::string()); 180 this->buffer_.clear(); 181 } 182 183 private: 184 std::ostringstream buffer_; //! Stream object used to process the output 185 std::vector<std::pair<int, std::string> > output_; //! Vector containing ALL output 186 }; 187 188 189 ///////////////////////// 190 ///// OutputHandler ///// 191 ///////////////////////// 192 const std::string OutputHandler::logFileOutputListenerName_s = "logFile"; 193 int OutputHandler::softDebugLevel_s = hardDebugLevel; 194 195 //! Creates the LogFileWriter and the MemoryLogWriter 45 196 OutputHandler::OutputHandler() 46 { 47 #ifdef ORXONOX_PLATFORM_WINDOWS 48 char* pTempDir = getenv("TEMP"); 49 this->logfilename_ = std::string(pTempDir) + "/orxonox.log"; 197 : outputLevel_(OutputLevel::Verbose) 198 { 199 #ifdef ORXONOX_RELEASE 200 const OutputLevel::Value defaultLevelConsole = OutputLevel::Error; 201 const OutputLevel::Value defaultLevelLogFile = OutputLevel::Info; 50 202 #else 51 this->logfilename_ = "/tmp/orxonox.log"; 203 const OutputLevel::Value defaultLevelConsole = OutputLevel::Info; 204 const OutputLevel::Value defaultLevelLogFile = OutputLevel::Debug; 52 205 #endif 53 #ifdef NDEBUG 54 this->softDebugLevel_[LD_All] = this->softDebugLevel_[LD_Logfile] = 2; 55 this->softDebugLevel_[LD_Console] = this->softDebugLevel_[LD_Shell] = 1; 56 #else 57 this->softDebugLevel_[LD_All] = this->softDebugLevel_[LD_Logfile] = 3; 58 this->softDebugLevel_[LD_Console] = this->softDebugLevel_[LD_Shell] = 2; 59 #endif 60 61 this->outputBuffer_ = &this->fallbackBuffer_; 62 this->logfile_.open(this->logfilename_.c_str(), std::fstream::out); 63 64 time_t rawtime; 65 struct tm* timeinfo; 66 time(&rawtime); 67 timeinfo = localtime(&rawtime); 68 69 this->logfile_ << "Started log on " << asctime(timeinfo) << std::endl; 70 this->logfile_.flush(); 71 } 72 73 /** 74 @brief Destructor: Writes the last line to the logfile and closes it. 75 */ 206 207 this->logFile_ = new LogFileWriter(); 208 // Use default level until we get the configValue from the Core 209 this->logFile_->softDebugLevel_ = defaultLevelLogFile; 210 this->registerOutputListener(this->logFile_); 211 212 this->consoleWriter_ = new ConsoleWriter(); 213 this->consoleWriter_->softDebugLevel_ = defaultLevelConsole; 214 this->registerOutputListener(this->consoleWriter_); 215 216 this->output_ = new MemoryLogWriter(); 217 // We capture as much input as the listener with the highest level 218 this->output_->softDebugLevel_ = getSoftDebugLevel(); 219 this->registerOutputListener(this->output_); 220 } 221 222 //! Destroys the LogFileWriter and the MemoryLogWriter 76 223 OutputHandler::~OutputHandler() 77 224 { 78 this->logfile_ << "Closed log" << std::endl; 79 this->logfile_.close(); 80 } 81 82 /** 83 @brief Returns a reference to the only existing instance of the OutputHandler class. 84 @return The instance 85 */ 86 OutputHandler& OutputHandler::getOutStream() 225 delete this->logFile_; 226 delete this->output_; 227 } 228 229 OutputHandler& OutputHandler::getInstance() 87 230 { 88 231 static OutputHandler orxout; … … 90 233 } 91 234 92 /** 93 @brief Sets the soft debug level for a given output device. 94 @param device The output device 95 @param level The debug level 96 */ 97 void OutputHandler::setSoftDebugLevel(OutputHandler::OutputDevice device, int level) 98 { 99 OutputHandler::getOutStream().softDebugLevel_[static_cast<unsigned int>(device)] = level; 100 } 101 102 /** 103 @brief Returns the soft debug level for a given output device. 104 @param device The output device 105 @return The debug level 106 */ 107 int OutputHandler::getSoftDebugLevel(OutputHandler::OutputDevice device) 108 { 109 return OutputHandler::getOutStream().softDebugLevel_[static_cast<unsigned int>(device)]; 110 } 111 112 /** 113 @brief Sets the OutputBuffer, representing the third output stream. 114 @param buffer The OutputBuffer 115 */ 116 void OutputHandler::setOutputBuffer(OutputBuffer* buffer) 117 { 118 if (buffer == NULL) 119 this->outputBuffer_ = &this->fallbackBuffer_; 120 else 121 { 122 buffer->getStream() >> this->outputBuffer_->getStream().rdbuf(); 123 this->outputBuffer_ = buffer; 124 } 125 } 126 127 /** 128 @brief Sets the path where to create orxonox.log 129 @param Path string with trailing slash 130 */ 235 void OutputHandler::registerOutputListener(OutputListener* listener) 236 { 237 for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 238 { 239 if ((*it)->name_ == listener->name_) 240 { 241 COUT(2) << "OutputHandler, Warning: Trying to register two listeners with the same name!" << std::endl; 242 return; 243 } 244 } 245 this->listeners_.push_back(listener); 246 // Update global soft debug level 247 this->setSoftDebugLevel(listener->getOutputListenerName(), listener->getSoftDebugLevel()); 248 } 249 250 void OutputHandler::unregisterOutputListener(OutputListener* listener) 251 { 252 this->listeners_.remove(listener); 253 } 254 131 255 void OutputHandler::setLogPath(const std::string& path) 132 256 { 133 OutputHandler::getOutStream().logfile_.close(); 134 // store old content 135 std::ifstream old; 136 old.open(OutputHandler::getOutStream().logfilename_.c_str()); 137 OutputHandler::getOutStream().logfilename_ = path + "orxonox.log"; 138 OutputHandler::getOutStream().logfile_.open(OutputHandler::getOutStream().logfilename_.c_str(), std::fstream::out); 139 OutputHandler::getOutStream().logfile_ << old.rdbuf(); 140 old.close(); 141 OutputHandler::getOutStream().logfile_.flush(); 142 } 143 144 /** 145 @brief Overloaded << operator, redirects the output to the console and the logfile. 146 @param sb The streambuffer that should be shown in the console 147 @return A reference to the OutputHandler itself 148 */ 149 OutputHandler& OutputHandler::operator<<(std::streambuf* sb) 150 { 151 if (getSoftDebugLevel(OutputHandler::LD_Console) >= this->outputLevel_) 152 std::cout << sb; 153 154 if (getSoftDebugLevel(OutputHandler::LD_Logfile) >= this->outputLevel_) 155 { 156 this->logfile_ << sb; 157 this->logfile_.flush(); 158 } 159 160 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_) 161 (*this->outputBuffer_) << sb; 162 163 return *this; 164 } 165 166 /** 167 @brief Overloaded << operator, redirects the output to the console, the logfile and the ingame shell. 168 @param manipulator A function, manipulating the outstream. 169 @return A reference to the OutputHandler itself 170 */ 171 OutputHandler& OutputHandler::operator<<(std::ostream& (*manipulator)(std::ostream&)) 172 { 173 if (getSoftDebugLevel(OutputHandler::LD_Console) >= this->outputLevel_) 174 manipulator(std::cout); 175 176 if (getSoftDebugLevel(OutputHandler::LD_Logfile) >= this->outputLevel_) 177 { 178 manipulator(this->logfile_); 179 this->logfile_.flush(); 180 } 181 182 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_) 183 (*this->outputBuffer_) << manipulator; 184 185 return *this; 186 } 187 188 /** 189 @brief Overloaded << operator, redirects the output to the console, the logfile and the ingame shell. 190 @param manipulator A function, manipulating the outstream. 191 @return A reference to the OutputHandler itself 192 */ 193 OutputHandler& OutputHandler::operator<<(std::ios& (*manipulator)(std::ios&)) 194 { 195 if (getSoftDebugLevel(OutputHandler::LD_Console) >= this->outputLevel_) 196 manipulator(std::cout); 197 198 if (getSoftDebugLevel(OutputHandler::LD_Logfile) >= this->outputLevel_) 199 { 200 manipulator(this->logfile_); 201 this->logfile_.flush(); 202 } 203 204 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_) 205 (*this->outputBuffer_) << manipulator; 206 207 return *this; 208 } 209 210 /** 211 @brief Overloaded << operator, redirects the output to the console, the logfile and the ingame shell. 212 @param manipulator A function, manipulating the outstream. 213 @return A reference to the OutputHandler itself 214 */ 215 OutputHandler& OutputHandler::operator<<(std::ios_base& (*manipulator)(std::ios_base&)) 216 { 217 if (getSoftDebugLevel(OutputHandler::LD_Console) >= this->outputLevel_) 218 manipulator(std::cout); 219 220 if (getSoftDebugLevel(OutputHandler::LD_Logfile) >= this->outputLevel_) 221 { 222 manipulator(this->logfile_); 223 this->logfile_.flush(); 224 } 225 226 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_) 227 (*this->outputBuffer_) << manipulator; 228 229 return *this; 257 this->logFile_->setLogPath(path); 258 } 259 260 void OutputHandler::disableCout() 261 { 262 this->unregisterOutputListener(this->consoleWriter_); 263 } 264 265 void OutputHandler::enableCout() 266 { 267 this->registerOutputListener(this->consoleWriter_); 268 } 269 270 OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorBegin() const 271 { 272 return this->output_->output_.begin(); 273 } 274 275 OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorEnd() const 276 { 277 return this->output_->output_.end(); 278 } 279 280 int OutputHandler::getSoftDebugLevel(const std::string& name) const 281 { 282 for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 283 { 284 if ((*it)->name_ == name) 285 return (*it)->softDebugLevel_; 286 } 287 return -1; 288 } 289 290 void OutputHandler::setSoftDebugLevel(const std::string& name, int level) 291 { 292 int globalSoftDebugLevel = -1; 293 for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 294 { 295 if ((*it)->name_ == name) 296 (*it)->softDebugLevel_ = level; 297 if ((*it)->softDebugLevel_ > globalSoftDebugLevel) 298 globalSoftDebugLevel = (*it)->softDebugLevel_; 299 } 300 // Update global soft debug level 301 OutputHandler::softDebugLevel_s = globalSoftDebugLevel; 230 302 } 231 303 } -
code/trunk/src/libraries/util/OutputHandler.h
r5738 r6105 23 23 * Fabian 'x3n' Landau 24 24 * Co-authors: 25 * ...25 * Reto Grieder 26 26 * 27 27 */ 28 28 29 29 /** 30 @file 31 @brief Definition of the OutputHandler class. 32 33 The OutputHandler acts like std::cout, but output isn't only shown in the console, 34 but also written to the logfile and the ingame shell. 30 @file 31 @brief 32 Declaration of classes related to output (logging). 35 33 */ 36 34 … … 40 38 #include "UtilPrereqs.h" 41 39 42 #include < iostream>43 #include < fstream>40 #include <list> 41 #include <ostream> 44 42 #include <string> 45 46 #include "OutputBuffer.h"43 #include <vector> 44 #include <utility> 47 45 48 46 namespace orxonox 49 47 { 50 //! The OutputHandler acts like std::cout, but redirects output to the console, the logfile and the ingame shell. 48 /** 49 @brief 50 Denotes different levels of text output (log output) 51 52 0, None : Very important output 53 1, Error : Errors 54 2, Warning: Warnings 55 3, Info : Information 56 4, Debug : Debug information 57 5, Verbose: More debug information 58 6, Ultra : Crazy debug information 59 */ 60 namespace OutputLevel 61 { 62 enum Value 63 { 64 None = 0, 65 Error = 1, 66 Warning = 2, 67 Info = 3, 68 Debug = 4, 69 Verbose = 5, 70 Ultra = 6, 71 }; 72 } 73 74 // Forward declarations for classes in the source file 75 class LogFileWriter; 76 class ConsoleWriter; 77 class MemoryLogWriter; 78 79 /** 80 @brief 81 The OutputHandler acts like std::cout, but output isn't only shown in the console. 82 83 You can register your own listener for output by inheriting from OutputListner. 84 And if you need the output previously processed, iterate over it with 85 OutputHandler::getOutputVector[Begin/End]. 86 The way to output text is to first set the desired output level with 87 OutputHandler::getOutStream(level) and then use the "<<" operator like with std::cout. 88 */ 51 89 class _UtilExport OutputHandler 52 90 { 53 91 public: 54 enum OutputDevice 55 { 56 LD_All = 0, 57 LD_Console = 1, 58 LD_Logfile = 2, 59 LD_Shell = 3 60 }; 61 62 static OutputHandler& getOutStream(); 63 64 /** @brief Puts some text on the outstream. @param text The text */ 92 //! Returns a reference to the only existing instance of the OutputHandler class. 93 static OutputHandler& getInstance(); 94 95 //! Sets the output level and returns a stream to be used with "<<" 96 static inline OutputHandler& getOutStream(int level) 97 { return OutputHandler::getInstance().setOutputLevel(level); } 98 99 typedef std::vector<std::pair<int, std::string> >::const_iterator OutputVectorIterator; 100 //! Returns an iterator to the beginning of the all-output vector 101 OutputVectorIterator getOutputVectorBegin() const; 102 //! Returns an iterator to the end of the all-output vector 103 OutputVectorIterator getOutputVectorEnd() const; 104 105 //! Writes to all output devices 65 106 static inline const std::string& log(const std::string& text) 66 { OutputHandler::getOutStream( ).setOutputLevel(0); OutputHandler::getOutStream().output(text + "\n"); return text; }67 68 / ** @brief Puts an error on the outstream. @param text The text */107 { OutputHandler::getOutStream(0).output(text) << std::endl; return text; } 108 109 //! Writes an error message to the output 69 110 static inline const std::string& error(const std::string& text) 70 { OutputHandler::getOutStream( ).setOutputLevel(1); OutputHandler::getOutStream().output(text + "\n"); return text; }71 72 / ** @brief Puts a warning on the outstream. @param text The text */111 { OutputHandler::getOutStream(1).output(text) << std::endl; return text; } 112 113 //! Writes a warning message to the output 73 114 static inline const std::string& warning(const std::string& text) 74 { OutputHandler::getOutStream( ).setOutputLevel(2); OutputHandler::getOutStream().output(text + "\n"); return text; }75 76 / ** @brief Puts an info on the outstream. @param text The text */115 { OutputHandler::getOutStream(2).output(text) << std::endl; return text; } 116 117 //! Writes an informational message to the output 77 118 static inline const std::string& info(const std::string& text) 78 { OutputHandler::getOutStream( ).setOutputLevel(3); OutputHandler::getOutStream().output(text + "\n"); return text; }79 80 / ** @brief Puts some debug output on the outstream. @param text The text */119 { OutputHandler::getOutStream(3).output(text) << std::endl; return text; } 120 121 //! Writes a debug message to the output 81 122 static inline const std::string& debug(const std::string& text) 82 { OutputHandler::getOutStream().setOutputLevel(4); OutputHandler::getOutStream().output(text + "\n"); return text; } 83 84 /** @brief Returns a reference to the logfile. @return The logfile */ 85 inline std::ofstream& getLogfile() 86 { return this->logfile_; } 87 88 /** @brief Returns a pointer to the OutputBuffer. @return The OutputBuffer */ 89 inline OutputBuffer* getOutputBuffer() 90 { return this->outputBuffer_; } 91 92 /** @brief Sets the level of the incoming output. @param level The level of the incoming output @return The OutputHandler itself */ 123 { OutputHandler::getOutStream(4).output(text) << std::endl; return text; } 124 125 //! Registers an object that receives output via a provided std::ostream 126 void registerOutputListener(OutputListener* listener); 127 //! Unregisters an object that receives output via a provided std::ostream 128 void unregisterOutputListener(OutputListener* listener); 129 130 //! Set the log path once the program has been properly initialised 131 void setLogPath(const std::string& path); 132 //! Disables the std::cout stream for output 133 void disableCout(); 134 //! Enables the std::cout stream for output (startup behaviour) 135 void enableCout(); 136 137 //! Sets the level of the incoming output and returns the OutputHandler 93 138 inline OutputHandler& setOutputLevel(int level) 94 139 { this->outputLevel_ = level; return *this; } 95 140 96 / ** @brief Returns the level of the incoming output. @return The level */141 //! Returns the level of the incoming output 97 142 inline int getOutputLevel() const 98 143 { return this->outputLevel_; } 99 144 100 static void setSoftDebugLevel(OutputHandler::OutputDevice device, int level); 101 static int getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All); 102 103 static void setLogPath(const std::string& path); 104 105 void setOutputBuffer(OutputBuffer* buffer); 106 145 //! Returns the maximum debug level over all registered listeners (devices) 146 static int getSoftDebugLevel() { return softDebugLevel_s; } 147 //! Returns the soft debug level for a device by its name @return The level or -1 if the listener was not found 148 int getSoftDebugLevel(const std::string& name) const; 149 //! Sets the soft debug level for a listener by its name @remarks Only works for registered listeners! 150 void setSoftDebugLevel(const std::string& name, int level); 151 152 /** 153 @brief 154 General template that copes with all output. 155 Required because operator << might be ambiguous. 156 @a output will be streamed into every listener with an appropriate debug level 157 @return 158 Returns a reference to the OutputHandler so you can use it again directly 159 */ 107 160 template <class T> 108 161 OutputHandler& output(const T& output); 109 162 110 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */163 //! Overloaded << operator, redirects the output to the listeners 111 164 inline OutputHandler& operator<<(unsigned char val) { return this->output(val); } 112 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */165 //! Overloaded << operator, redirects the output to the listeners 113 166 inline OutputHandler& operator<<(short val) { return this->output(val); } 114 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */167 //! Overloaded << operator, redirects the output to the listeners 115 168 inline OutputHandler& operator<<(unsigned short val) { return this->output(val); } 116 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */169 //! Overloaded << operator, redirects the output to the listeners 117 170 inline OutputHandler& operator<<(int val) { return this->output(val); } 118 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */171 //! Overloaded << operator, redirects the output to the listeners 119 172 inline OutputHandler& operator<<(unsigned int val) { return this->output(val); } 120 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */173 //! Overloaded << operator, redirects the output to the listeners 121 174 inline OutputHandler& operator<<(long val) { return this->output(val); } 122 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */175 //! Overloaded << operator, redirects the output to the listeners 123 176 inline OutputHandler& operator<<(unsigned long val) { return this->output(val); } 124 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */177 //! Overloaded << operator, redirects the output to the listeners 125 178 inline OutputHandler& operator<<(long long val) { return this->output(val); } 126 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */179 //! Overloaded << operator, redirects the output to the listeners 127 180 inline OutputHandler& operator<<(unsigned long long val) { return this->output(val); } 128 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */181 //! Overloaded << operator, redirects the output to the listeners 129 182 inline OutputHandler& operator<<(float val) { return this->output(val); } 130 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */183 //! Overloaded << operator, redirects the output to the listeners 131 184 inline OutputHandler& operator<<(double val) { return this->output(val); } 132 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */185 //! Overloaded << operator, redirects the output to the listeners 133 186 inline OutputHandler& operator<<(long double val) { return this->output(val); } 134 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */187 //! Overloaded << operator, redirects the output to the listeners 135 188 inline OutputHandler& operator<<(const void* val) { return this->output(val); } 136 / ** @brief Overloaded << operator, redirects the output to the console and the logfile. @param val The value that should be shown in the console @return A reference to the OutputHandler itself */189 //! Overloaded << operator, redirects the output to the listeners 137 190 inline OutputHandler& operator<<(bool val) { return this->output(val); } 138 191 139 OutputHandler& operator<<(std::streambuf* sb); 140 141 OutputHandler& operator<<(std::ostream& (*manipulator)(std::ostream&)); 142 OutputHandler& operator<<(std::ios& (*manipulator)(std::ios&)); 143 OutputHandler& operator<<(std::ios_base& (*manipulator)(std::ios_base&)); 192 //! Overloaded << operator, redirects the output to the listeners 193 inline OutputHandler& operator<<(std::streambuf* sb) { return this->output(sb); } 194 195 //! Overloaded << operator, redirect the output of classes with self defined 'operator <<' to the listeners 196 template <class T> 197 inline OutputHandler& operator<<(const T& val) { return this->output(val); } 198 199 //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners 200 inline OutputHandler& operator<<(std::ostream& (*manip)(std::ostream&)) { return this->output(manip); } 201 //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners 202 inline OutputHandler& operator<<(std::ios& (*manip)(std::ios&)) { return this->output(manip); } 203 //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners 204 inline OutputHandler& operator<<(std::ios_base& (*manip)(std::ios_base&)) { return this->output(manip); } 205 206 //! Dummy operator required by Debug.h for the ternary operator 207 inline operator int() const { return 0; } 208 209 //! Name of the OutputListener that writes to the log file 210 static const std::string logFileOutputListenerName_s; 144 211 145 212 private: 146 explicitOutputHandler();147 OutputHandler(const OutputHandler& oh);148 virtual ~OutputHandler();149 150 std:: ofstream logfile_; //!< The logfile where the output is logged151 std::string logfilename_; //!< The name of the logfile152 OutputBuffer fallbackBuffer_; //!< The OutputBuffer that gets used if there is no other OutputBuffer153 OutputBuffer* outputBuffer_; //!< The OutputBuffer to put output in (usually used by the Shell)154 int outputLevel_; //!< The level of the incoming output155 int softDebugLevel_[4]; //!< The soft debug level for each OutputDevice - the configurable maximal output level213 OutputHandler(); 214 ~OutputHandler(); 215 OutputHandler(const OutputHandler& rhs); //! Unused and undefined 216 217 std::list<OutputListener*> listeners_; //!< Array with all registered output listeners 218 int outputLevel_; //!< The level of the incoming output 219 LogFileWriter* logFile_; //!< Listener that writes to the log file 220 ConsoleWriter* consoleWriter_; //!< Listener for std::cout (just program beginning) 221 MemoryLogWriter* output_; //!< Listener that Stores ALL output below the current soft debug level 222 static int softDebugLevel_s; //!< Maximum of all soft debug levels. @note This is only static for faster access 156 223 }; 157 224 158 225 /** 159 @brief Redirects the output to the console and the logfile. 160 @param output The value that should be shown in the console 161 @return A reference to the OutputHandler itself 226 @brief 227 Interface for listening to output. 228 @remarks 229 Remember to register the listener (not done automatically!) 162 230 */ 231 class OutputListener 232 { 233 friend class OutputHandler; 234 235 public: 236 OutputListener(const std::string& name) 237 : outputStream_(NULL) 238 , name_(name) 239 , softDebugLevel_(OutputLevel::Info) 240 {} 241 virtual ~OutputListener() {} 242 243 //! Gets called whenever output is put into the stream 244 virtual void outputChanged(int level) {} 245 //! Returns the name of this output listener 246 const std::string& getOutputListenerName() const { return this->name_; } 247 //! Returns the soft debug level of the listener 248 int getSoftDebugLevel() const { return this->softDebugLevel_; } 249 //! Sets the soft debug level of the listener 250 void setSoftDebugLevel(int level) 251 { 252 this->softDebugLevel_ = level; 253 OutputHandler::getInstance().setSoftDebugLevel(this->name_, level); 254 } 255 256 protected: 257 std::ostream* outputStream_; //!< Pointer to the associated output stream, can be NULL 258 259 private: 260 const std::string name_; //!< Name of the listener, constant and unique! 261 int softDebugLevel_; //!< Current soft debug level that defines what kind of output is written to the stream 262 }; 263 163 264 template<class T> 164 OutputHandler& OutputHandler::output(const T& output) 165 { 166 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Console) >= this->outputLevel_) 167 std::cout << output; 168 169 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Logfile) >= this->outputLevel_) 265 inline OutputHandler& OutputHandler::output(const T& output) 266 { 267 for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 170 268 { 171 this->logfile_ << output; 172 this->logfile_.flush(); 269 if (this->outputLevel_ <= (*it)->softDebugLevel_ && (*it)->outputStream_ != NULL) 270 { 271 std::ostream& stream = *((*it)->outputStream_); 272 stream << output; 273 stream.flush(); 274 (*it)->outputChanged(this->outputLevel_); 275 } 173 276 } 174 175 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)176 (*this->outputBuffer_) << output;177 277 178 278 return *this; 179 279 } 180 181 /**182 @brief Overloading of the non-member << operator to redirect the output of classes with self defined '<< to std::ostream' operators to the console and the logfile.183 @param out The OutputHandler itself184 @param output The class that should be shown in the console185 @return The OutputHandler itself186 */187 template<class T>188 OutputHandler& operator<<(OutputHandler& out, const T& output)189 {190 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Console) >= out.getOutputLevel())191 std::cout << output;192 193 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Logfile) >= out.getOutputLevel())194 {195 out.getLogfile() << output;196 out.getLogfile().flush();197 }198 199 if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= out.getOutputLevel())200 (*out.getOutputBuffer()) << output;201 202 return out;203 }204 280 } 205 281 -
code/trunk/src/libraries/util/UtilPrereqs.h
r5929 r6105 87 87 class IntVector3; 88 88 class MultiType; 89 class OutputBuffer;90 class OutputBufferListener;91 89 class OutputHandler; 90 class OutputListener; 92 91 template <ScopeID::Value> 93 92 class Scope;
Note: See TracChangeset
for help on using the changeset viewer.