Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/util/OutputHandler.h @ 8270

Last change on this file since 8270 was 7401, checked in by landauf, 14 years ago

merged doc branch back to trunk

  • Property svn:eol-style set to native
File size: 13.1 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      Reto Grieder
26 *
27 */
28
29/**
30@file
31@ingroup Util Output
32@brief
33    Declaration of classes related to output (logging), most notably OutputHandler and OutputListener.
34*/
35
36#ifndef _OutputHandler_H__
37#define _OutputHandler_H__
38
39#include "UtilPrereqs.h"
40
41#include <list>
42#include <ostream>
43#include <string>
44#include <vector>
45#include <utility>
46
47namespace orxonox
48{
49    /**
50    @brief
51        Denotes different levels of text output (log output)
52
53         - 0, None   : Very important output
54         - 1, Error  : Errors
55         - 2, Warning: Warnings
56         - 3, Info   : Information
57         - 4, Debug  : Debug information
58         - 5, Verbose: More debug information
59         - 6, Ultra  : Crazy debug information
60    */
61    namespace OutputLevel
62    {
63        enum Value
64        {
65            None    = 0,
66            Error   = 1,
67            Warning = 2,
68            Info    = 3,
69            Debug   = 4,
70            Verbose = 5,
71            Ultra   = 6,
72        };
73    }
74
75    // Forward declarations for classes in the source file
76    class LogFileWriter;
77    class ConsoleWriter;
78    class MemoryLogWriter;
79
80    /**
81    @brief
82        The OutputHandler acts like @c std::cout, but output isn't only shown in the console.
83
84        Output passed to the OutputHandler is distributed to all registered listeners,
85        for example the console, the logfile, or the ingame shell.
86
87        You can register your own listener for output by inheriting from OutputListener.
88        And if you need the output previously processed, iterate over it with
89        OutputHandler::getOutputVectorBegin and OutputHandler::getOutputVectorEnd.
90
91        The way to output text is to first set the desired output level with
92        @ref getOutStream "OutputHandler::getOutStream(level)" and then use
93        the "<<" operator like with @c std::cout. Alternatively you can use the COUT() macro.
94    */
95    class _UtilExport OutputHandler
96    {
97        public:
98            //! Returns a reference to the only existing instance of the OutputHandler class.
99            static OutputHandler& getInstance();
100
101            //! Sets the output level and returns a stream to be used with "<<"
102            static inline OutputHandler& getOutStream(int level)
103                { return OutputHandler::getInstance().setOutputLevel(level); }
104
105            typedef std::vector<std::pair<int, std::string> >::const_iterator OutputVectorIterator;
106            //! Returns an iterator to the beginning of the all-output vector
107            OutputVectorIterator getOutputVectorBegin() const;
108            //! Returns an iterator to the end of the all-output vector
109            OutputVectorIterator getOutputVectorEnd() const;
110
111            //! Writes to all output devices
112            static inline void log(const std::string& text)
113                { OutputHandler::getOutStream(0).output(text) << std::endl; }
114
115            //! Writes an error message to the output
116            static inline void error(const std::string& text)
117                { OutputHandler::getOutStream(1).output(text) << std::endl; }
118
119            //! Writes a warning message to the output
120            static inline void warning(const std::string& text)
121                { OutputHandler::getOutStream(2).output(text) << std::endl; }
122
123            //! Writes an informational message to the output
124            static inline void info(const std::string& text)
125                { OutputHandler::getOutStream(3).output(text) << std::endl; }
126
127            //! Writes a debug message to the output
128            static inline void debug(const std::string& text)
129                { OutputHandler::getOutStream(4).output(text) << std::endl; }
130
131            //! Registers an object that receives output via a provided std::ostream
132            void registerOutputListener(OutputListener* listener);
133            //! Unregisters an object that receives output via a provided std::ostream
134            void unregisterOutputListener(OutputListener* listener);
135
136            //! Set the log path once the program has been properly initialised
137            void setLogPath(const std::string& path);
138            //! Disables the std::cout stream for output
139            void disableCout();
140            //! Enables the std::cout stream for output (startup behaviour)
141            void enableCout();
142
143            //! Sets the level of the incoming output and returns the OutputHandler
144            inline OutputHandler& setOutputLevel(int level)
145                { this->outputLevel_ = level; return *this; }
146
147            //! Returns the level of the incoming output
148            inline int getOutputLevel() const
149                { return this->outputLevel_; }
150
151            //! Returns the maximum debug level over all registered listeners (devices)
152            static int getSoftDebugLevel() { return softDebugLevel_s; }
153            //! Returns the soft debug level for a device by its name   @return The level or -1 if the listener was not found
154            int  getSoftDebugLevel(const std::string& name) const;
155            //! Sets the soft debug level for a listener by its name   @remarks Only works for registered listeners!
156            void setSoftDebugLevel(const std::string& name, int level);
157
158            /**
159            @brief
160                General template that copes with all output.
161                Required because operator << might be ambiguous.
162                @a output will be streamed into every listener with an appropriate debug level
163            @return
164                Returns a reference to the OutputHandler so you can use it again directly
165            */
166            template <class T>
167            OutputHandler& output(const T& output);
168
169            //! Overloaded << operator, redirects the output to the listeners
170            inline OutputHandler& operator<<(unsigned char val)      { return this->output(val); }
171            //! Overloaded << operator, redirects the output to the listeners
172            inline OutputHandler& operator<<(short val)              { return this->output(val); }
173            //! Overloaded << operator, redirects the output to the listeners
174            inline OutputHandler& operator<<(unsigned short val)     { return this->output(val); }
175            //! Overloaded << operator, redirects the output to the listeners
176            inline OutputHandler& operator<<(int val)                { return this->output(val); }
177            //! Overloaded << operator, redirects the output to the listeners
178            inline OutputHandler& operator<<(unsigned int val)       { return this->output(val); }
179            //! Overloaded << operator, redirects the output to the listeners
180            inline OutputHandler& operator<<(long val)               { return this->output(val); }
181            //! Overloaded << operator, redirects the output to the listeners
182            inline OutputHandler& operator<<(unsigned long val)      { return this->output(val); }
183            //! Overloaded << operator, redirects the output to the listeners
184            inline OutputHandler& operator<<(long long val)          { return this->output(val); }
185            //! Overloaded << operator, redirects the output to the listeners
186            inline OutputHandler& operator<<(unsigned long long val) { return this->output(val); }
187            //! Overloaded << operator, redirects the output to the listeners
188            inline OutputHandler& operator<<(float val)              { return this->output(val); }
189            //! Overloaded << operator, redirects the output to the listeners
190            inline OutputHandler& operator<<(double val)             { return this->output(val); }
191            //! Overloaded << operator, redirects the output to the listeners
192            inline OutputHandler& operator<<(long double val)        { return this->output(val); }
193            //! Overloaded << operator, redirects the output to the listeners
194            inline OutputHandler& operator<<(const void* val)        { return this->output(val); }
195            //! Overloaded << operator, redirects the output to the listeners
196            inline OutputHandler& operator<<(bool val)               { return this->output(val); }
197
198            //! Overloaded << operator, redirects the output to the listeners
199            inline OutputHandler& operator<<(std::streambuf* sb)     { return this->output(sb); }
200
201            //! Overloaded << operator, redirect the output of classes with self defined 'operator <<' to the listeners
202            template <class T>
203            inline OutputHandler& operator<<(const T& val)           { return this->output(val); }
204
205            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
206            inline OutputHandler& operator<<(std::ostream&  (*manip)(std::ostream&))  { return this->output(manip); }
207            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
208            inline OutputHandler& operator<<(std::ios&      (*manip)(std::ios&))      { return this->output(manip); }
209            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
210            inline OutputHandler& operator<<(std::ios_base& (*manip)(std::ios_base&)) { return this->output(manip); }
211
212            //! Dummy operator required by Debug.h for the ternary operator
213            inline operator int() const { return 0; }
214
215            //! Name of the OutputListener that writes to the log file
216            static const std::string logFileOutputListenerName_s;
217
218        private:
219            OutputHandler();
220            ~OutputHandler();
221            OutputHandler(const OutputHandler& rhs);      //!< Copy-constructor: Unused and undefined
222
223            std::list<OutputListener*> listeners_;        //!< Array with all registered output listeners
224            int                        outputLevel_;      //!< The level of the incoming output
225            LogFileWriter*             logFile_;          //!< Listener that writes to the log file
226            ConsoleWriter*             consoleWriter_;    //!< Listener for std::cout (just program beginning)
227            MemoryLogWriter*           output_;           //!< Listener that Stores ALL output below the current soft debug level
228            static int                 softDebugLevel_s;  //!< Maximum of all soft debug levels. @note This is only static for faster access
229    };
230
231    /**
232    @brief
233        Interface for listening to output.
234    @remarks
235        Remember to register the listener (not done automatically!)
236    */
237    class OutputListener
238    {
239        friend class OutputHandler;
240
241    public:
242        OutputListener(const std::string& name)
243            : outputStream_(NULL)
244            , name_(name)
245            , softDebugLevel_(OutputLevel::Info)
246        {}
247        virtual ~OutputListener() {}
248
249        //! Gets called whenever output is put into the stream
250        virtual void outputChanged(int level) {}
251        //! Returns the name of this output listener
252        const std::string& getOutputListenerName() const { return this->name_; }
253        //! Returns the soft debug level of the listener
254        int getSoftDebugLevel() const { return this->softDebugLevel_; }
255        //! Sets the soft debug level of the listener
256        void setSoftDebugLevel(int level)
257        {
258            this->softDebugLevel_ = level;
259            OutputHandler::getInstance().setSoftDebugLevel(this->name_, level);
260        }
261
262    protected:
263        std::ostream*     outputStream_;   //!< Pointer to the associated output stream, can be NULL
264
265    private:
266        const std::string name_;           //!< Name of the listener, constant and unique!
267        int               softDebugLevel_; //!< Current soft debug level that defines what kind of output is written to the stream
268    };
269
270    template<class T>
271    inline OutputHandler& OutputHandler::output(const T& output)
272    {
273        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
274        {
275            if (this->outputLevel_ <= (*it)->softDebugLevel_ && (*it)->outputStream_ != NULL)
276            {
277                std::ostream& stream = *((*it)->outputStream_);
278                stream << output;
279                stream.flush();
280                (*it)->outputChanged(this->outputLevel_);
281            }
282        }
283
284        return *this;
285    }
286}
287
288#endif /* _OutputHandler_H__ */
Note: See TracBrowser for help on using the repository browser.