Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/gamestates3/src/libraries/util/OutputHandler.h @ 10240

Last change on this file since 10240 was 6105, checked in by rgrieder, 15 years ago

Merged console branch back to trunk.

  • Property svn:eol-style set to native
File size: 12.8 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@brief
32    Declaration of classes related to output (logging).
33*/
34
35#ifndef _OutputHandler_H__
36#define _OutputHandler_H__
37
38#include "UtilPrereqs.h"
39
40#include <list>
41#include <ostream>
42#include <string>
43#include <vector>
44#include <utility>
45
46namespace orxonox
47{
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    */
89    class _UtilExport OutputHandler
90    {
91        public:
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
106            static inline const std::string& log(const std::string& text)
107                { OutputHandler::getOutStream(0).output(text) << std::endl; return text; }
108
109            //! Writes an error message to the output
110            static inline const std::string& error(const std::string& text)
111                { OutputHandler::getOutStream(1).output(text) << std::endl; return text; }
112
113            //! Writes a warning message to the output
114            static inline const std::string& warning(const std::string& text)
115                { OutputHandler::getOutStream(2).output(text) << std::endl; return text; }
116
117            //! Writes an informational message to the output
118            static inline const std::string& info(const std::string& text)
119                { OutputHandler::getOutStream(3).output(text) << std::endl; return text; }
120
121            //! Writes a debug message to the output
122            static inline const std::string& debug(const std::string& text)
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
138            inline OutputHandler& setOutputLevel(int level)
139                { this->outputLevel_ = level; return *this; }
140
141            //! Returns the level of the incoming output
142            inline int getOutputLevel() const
143                { return this->outputLevel_; }
144
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            */
160            template <class T>
161            OutputHandler& output(const T& output);
162
163            //! Overloaded << operator, redirects the output to the listeners
164            inline OutputHandler& operator<<(unsigned char val)      { return this->output(val); }
165            //! Overloaded << operator, redirects the output to the listeners
166            inline OutputHandler& operator<<(short val)              { return this->output(val); }
167            //! Overloaded << operator, redirects the output to the listeners
168            inline OutputHandler& operator<<(unsigned short val)     { return this->output(val); }
169            //! Overloaded << operator, redirects the output to the listeners
170            inline OutputHandler& operator<<(int val)                { return this->output(val); }
171            //! Overloaded << operator, redirects the output to the listeners
172            inline OutputHandler& operator<<(unsigned int val)       { return this->output(val); }
173            //! Overloaded << operator, redirects the output to the listeners
174            inline OutputHandler& operator<<(long val)               { return this->output(val); }
175            //! Overloaded << operator, redirects the output to the listeners
176            inline OutputHandler& operator<<(unsigned long val)      { return this->output(val); }
177            //! Overloaded << operator, redirects the output to the listeners
178            inline OutputHandler& operator<<(long long val)          { return this->output(val); }
179            //! Overloaded << operator, redirects the output to the listeners
180            inline OutputHandler& operator<<(unsigned long long val) { return this->output(val); }
181            //! Overloaded << operator, redirects the output to the listeners
182            inline OutputHandler& operator<<(float val)              { return this->output(val); }
183            //! Overloaded << operator, redirects the output to the listeners
184            inline OutputHandler& operator<<(double val)             { return this->output(val); }
185            //! Overloaded << operator, redirects the output to the listeners
186            inline OutputHandler& operator<<(long double val)        { return this->output(val); }
187            //! Overloaded << operator, redirects the output to the listeners
188            inline OutputHandler& operator<<(const void* val)        { return this->output(val); }
189            //! Overloaded << operator, redirects the output to the listeners
190            inline OutputHandler& operator<<(bool val)               { return this->output(val); }
191
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;
211
212        private:
213            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
223    };
224
225    /**
226    @brief
227        Interface for listening to output.
228    @remarks
229        Remember to register the listener (not done automatically!)
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
264    template<class T>
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)
268        {
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            }
276        }
277
278        return *this;
279    }
280}
281
282#endif /* _OutputHandler_H__ */
Note: See TracBrowser for help on using the repository browser.