1 /* 2 ----------------------------------------------------------------------------- 3 This source file is part of OGRE 4 (Object-oriented Graphics Rendering Engine) 5 For the latest info, see http://www.ogre3d.org/ 6 7 Copyright (c) 2000-2014 Torus Knot Software Ltd 8 9 Permission is hereby granted, free of charge, to any person obtaining a copy 10 of this software and associated documentation files (the "Software"), to deal 11 in the Software without restriction, including without limitation the rights 12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 copies of the Software, and to permit persons to whom the Software is 14 furnished to do so, subject to the following conditions: 15 16 The above copyright notice and this permission notice shall be included in 17 all copies or substantial portions of the Software. 18 19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 THE SOFTWARE. 26 ----------------------------------------------------------------------------- 27 */ 28 29 #ifndef __Log_H__ 30 #define __Log_H__ 31 32 #include "OgrePrerequisites.h" 33 #include "OgreCommon.h" 34 #include "Threading/OgreThreadHeaders.h" 35 #include "OgreHeaderPrefix.h" 36 37 namespace Ogre { 38 39 /** \addtogroup Core 40 * @{ 41 */ 42 /** \addtogroup General 43 * @{ 44 */ 45 // LogMessageLevel + LoggingLevel > OGRE_LOG_THRESHOLD = message logged 46 #define OGRE_LOG_THRESHOLD 4 47 48 /** The level of detail to which the log will go into. 49 */ 50 enum LoggingLevel 51 { 52 LL_LOW = 1, 53 LL_NORMAL = 2, 54 LL_BOREME = 3 55 }; 56 57 /** The importance of a logged message. 58 */ 59 enum LogMessageLevel 60 { 61 LML_TRIVIAL = 1, 62 LML_NORMAL = 2, 63 LML_WARNING = 3, 64 LML_CRITICAL = 4 65 }; 66 67 /** @remarks Pure Abstract class, derive this class and register to the Log to listen to log messages */ 68 class LogListener 69 { 70 public: ~LogListener()71 virtual ~LogListener() {} 72 73 /** 74 @remarks 75 This is called whenever the log receives a message and is about to write it out 76 @param message 77 The message to be logged 78 @param lml 79 The message level the log is using 80 @param maskDebug 81 If we are printing to the console or not 82 @param logName 83 The name of this log (so you can have several listeners for different logs, and identify them) 84 @param skipThisMessage 85 If set to true by the messageLogged() implementation message will not be logged 86 */ 87 virtual void messageLogged( const String& message, LogMessageLevel lml, bool maskDebug, const String &logName, bool& skipThisMessage ) = 0; 88 }; 89 90 91 /** 92 @remarks 93 Log class for writing debug/log data to files. 94 @note 95 <br>Should not be used directly, but trough the LogManager class. 96 */ 97 class _OgreExport Log : public LogAlloc 98 { 99 protected: 100 std::ofstream mLog; 101 LoggingLevel mLogLevel; 102 bool mDebugOut; 103 bool mSuppressFile; 104 bool mTimeStamp; 105 String mLogName; 106 bool mTermHasColours; 107 108 typedef std::vector<LogListener*> mtLogListener; 109 mtLogListener mListeners; 110 public: 111 112 class Stream; 113 114 OGRE_AUTO_MUTEX; // public to allow external locking 115 /** 116 @remarks 117 Usual constructor - called by LogManager. 118 */ 119 Log( const String& name, bool debugOutput = true, bool suppressFileOutput = false); 120 121 /** 122 @remarks 123 Default destructor. 124 */ 125 ~Log(); 126 127 /// Return the name of the log getName()128 const String& getName() const { return mLogName; } 129 /// Get whether debug output is enabled for this log isDebugOutputEnabled()130 bool isDebugOutputEnabled() const { return mDebugOut; } 131 /// Get whether file output is suppressed for this log isFileOutputSuppressed()132 bool isFileOutputSuppressed() const { return mSuppressFile; } 133 /// Get whether time stamps are printed for this log isTimeStampEnabled()134 bool isTimeStampEnabled() const { return mTimeStamp; } 135 136 /** Log a message to the debugger and to log file (the default is 137 "<code>OGRE.log</code>"), 138 */ 139 void logMessage( const String& message, LogMessageLevel lml = LML_NORMAL, bool maskDebug = false ); 140 141 /** Get a stream object targeting this log. */ 142 Stream stream(LogMessageLevel lml = LML_NORMAL, bool maskDebug = false); 143 144 /** 145 @remarks 146 Enable or disable outputting log messages to the debugger. 147 */ 148 void setDebugOutputEnabled(bool debugOutput); 149 /** 150 @remarks 151 Sets the level of the log detail. 152 */ 153 void setLogDetail(LoggingLevel ll); 154 /** 155 @remarks 156 Enable or disable time stamps. 157 */ 158 void setTimeStampEnabled(bool timeStamp); 159 /** Gets the level of the log detail. 160 */ getLogDetail()161 LoggingLevel getLogDetail() const { return mLogLevel; } 162 /** 163 @remarks 164 Register a listener to this log 165 @param listener 166 A valid listener derived class 167 */ 168 void addListener(LogListener* listener); 169 170 /** 171 @remarks 172 Unregister a listener from this log 173 @param listener 174 A valid listener derived class 175 */ 176 void removeListener(LogListener* listener); 177 178 /** Stream object which targets a log. 179 @remarks 180 A stream logger object makes it simpler to send various things to 181 a log. You can just use the operator<< implementation to stream 182 anything to the log, which is cached until a Stream::Flush is 183 encountered, or the stream itself is destroyed, at which point the 184 cached contents are sent to the underlying log. You can use Log::stream() 185 directly without assigning it to a local variable and as soon as the 186 streaming is finished, the object will be destroyed and the message 187 logged. 188 @par 189 You can stream control operations to this object too, such as 190 std::setw() and std::setfill() to control formatting. 191 @note 192 Each Stream object is not thread safe, so do not pass it between 193 threads. Multiple threads can hold their own Stream instances pointing 194 at the same Log though and that is threadsafe. 195 */ 196 class _OgrePrivate Stream 197 { 198 protected: 199 Log* mTarget; 200 LogMessageLevel mLevel; 201 bool mMaskDebug; 202 typedef StringStream BaseStream; 203 BaseStream mCache; 204 205 public: 206 207 /// Simple type to indicate a flush of the stream to the log 208 struct Flush {}; 209 Stream(Log * target,LogMessageLevel lml,bool maskDebug)210 Stream(Log* target, LogMessageLevel lml, bool maskDebug) 211 :mTarget(target), mLevel(lml), mMaskDebug(maskDebug) 212 { 213 214 } 215 // copy constructor Stream(const Stream & rhs)216 Stream(const Stream& rhs) 217 : mTarget(rhs.mTarget), mLevel(rhs.mLevel), mMaskDebug(rhs.mMaskDebug) 218 { 219 // explicit copy of stream required, gcc doesn't like implicit 220 mCache.str(rhs.mCache.str()); 221 } ~Stream()222 ~Stream() 223 { 224 // flush on destroy 225 if (mCache.tellp() > 0) 226 { 227 mTarget->logMessage(mCache.str(), mLevel, mMaskDebug); 228 } 229 } 230 231 template <typename T> 232 Stream& operator<< (const T& v) 233 { 234 mCache << v; 235 return *this; 236 } 237 238 Stream& operator<< (const Flush& v) 239 { 240 (void)v; 241 mTarget->logMessage(mCache.str(), mLevel, mMaskDebug); 242 mCache.str(BLANKSTRING); 243 return *this; 244 } 245 246 247 }; 248 249 }; 250 /** @} */ 251 /** @} */ 252 } 253 254 #include "OgreHeaderSuffix.h" 255 256 #endif 257