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