Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 6987 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
RevLine 
[1505]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:
[6105]25 *      Reto Grieder
[1505]26 *
27 */
28
29/**
[6105]30@file
31@brief
32    Declaration of classes related to output (logging).
[1505]33*/
34
35#ifndef _OutputHandler_H__
36#define _OutputHandler_H__
37
[1586]38#include "UtilPrereqs.h"
[1505]39
[6105]40#include <list>
41#include <ostream>
[1505]42#include <string>
[6105]43#include <vector>
44#include <utility>
[1505]45
46namespace orxonox
47{
[6105]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    */
[1586]89    class _UtilExport OutputHandler
[1505]90    {
91        public:
[6105]92            //! Returns a reference to the only existing instance of the OutputHandler class.
93            static OutputHandler& getInstance();
[1505]94
[6105]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); }
[1505]98
[6105]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
[3196]106            static inline const std::string& log(const std::string& text)
[6105]107                { OutputHandler::getOutStream(0).output(text) << std::endl; return text; }
[1505]108
[6105]109            //! Writes an error message to the output
[3196]110            static inline const std::string& error(const std::string& text)
[6105]111                { OutputHandler::getOutStream(1).output(text) << std::endl; return text; }
[1505]112
[6105]113            //! Writes a warning message to the output
[3196]114            static inline const std::string& warning(const std::string& text)
[6105]115                { OutputHandler::getOutStream(2).output(text) << std::endl; return text; }
[1505]116
[6105]117            //! Writes an informational message to the output
[3196]118            static inline const std::string& info(const std::string& text)
[6105]119                { OutputHandler::getOutStream(3).output(text) << std::endl; return text; }
[1505]120
[6105]121            //! Writes a debug message to the output
[3196]122            static inline const std::string& debug(const std::string& text)
[6105]123                { OutputHandler::getOutStream(4).output(text) << std::endl; return text; }
[1505]124
[6105]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);
[1505]129
[6105]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();
[1586]136
[6105]137            //! Sets the level of the incoming output and returns the OutputHandler
[1505]138            inline OutputHandler& setOutputLevel(int level)
139                { this->outputLevel_ = level; return *this; }
140
[6105]141            //! Returns the level of the incoming output
[1505]142            inline int getOutputLevel() const
143                { return this->outputLevel_; }
144
[6105]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);
[1505]151
[6105]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            */
[1505]160            template <class T>
161            OutputHandler& output(const T& output);
162
[6105]163            //! Overloaded << operator, redirects the output to the listeners
[1725]164            inline OutputHandler& operator<<(unsigned char val)      { return this->output(val); }
[6105]165            //! Overloaded << operator, redirects the output to the listeners
[1725]166            inline OutputHandler& operator<<(short val)              { return this->output(val); }
[6105]167            //! Overloaded << operator, redirects the output to the listeners
[1725]168            inline OutputHandler& operator<<(unsigned short val)     { return this->output(val); }
[6105]169            //! Overloaded << operator, redirects the output to the listeners
[1725]170            inline OutputHandler& operator<<(int val)                { return this->output(val); }
[6105]171            //! Overloaded << operator, redirects the output to the listeners
[1725]172            inline OutputHandler& operator<<(unsigned int val)       { return this->output(val); }
[6105]173            //! Overloaded << operator, redirects the output to the listeners
[1725]174            inline OutputHandler& operator<<(long val)               { return this->output(val); }
[6105]175            //! Overloaded << operator, redirects the output to the listeners
[1725]176            inline OutputHandler& operator<<(unsigned long val)      { return this->output(val); }
[6105]177            //! Overloaded << operator, redirects the output to the listeners
[1725]178            inline OutputHandler& operator<<(long long val)          { return this->output(val); }
[6105]179            //! Overloaded << operator, redirects the output to the listeners
[1725]180            inline OutputHandler& operator<<(unsigned long long val) { return this->output(val); }
[6105]181            //! Overloaded << operator, redirects the output to the listeners
[1725]182            inline OutputHandler& operator<<(float val)              { return this->output(val); }
[6105]183            //! Overloaded << operator, redirects the output to the listeners
[1725]184            inline OutputHandler& operator<<(double val)             { return this->output(val); }
[6105]185            //! Overloaded << operator, redirects the output to the listeners
[1725]186            inline OutputHandler& operator<<(long double val)        { return this->output(val); }
[6105]187            //! Overloaded << operator, redirects the output to the listeners
[1725]188            inline OutputHandler& operator<<(const void* val)        { return this->output(val); }
[6105]189            //! Overloaded << operator, redirects the output to the listeners
[1725]190            inline OutputHandler& operator<<(bool val)               { return this->output(val); }
[1505]191
[6105]192            //! Overloaded << operator, redirects the output to the listeners
193            inline OutputHandler& operator<<(std::streambuf* sb)     { return this->output(sb); }
[1505]194
[6105]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); }
[1505]198
[6105]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
[1505]212        private:
[6105]213            OutputHandler();
214            ~OutputHandler();
215            OutputHandler(const OutputHandler& rhs); //! Unused and undefined
[1586]216
[6105]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
[1505]223    };
224
225    /**
[6105]226    @brief
227        Interface for listening to output.
228    @remarks
229        Remember to register the listener (not done automatically!)
[1505]230    */
[6105]231    class OutputListener
[1505]232    {
[6105]233        friend class OutputHandler;
[1505]234
[6105]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)
[1505]251        {
[6105]252            this->softDebugLevel_ = level;
253            OutputHandler::getInstance().setSoftDebugLevel(this->name_, level);
[1505]254        }
255
[6105]256    protected:
257        std::ostream*     outputStream_;   //!< Pointer to the associated output stream, can be NULL
[1505]258
[6105]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    };
[1505]263
264    template<class T>
[6105]265    inline OutputHandler& OutputHandler::output(const T& output)
[1505]266    {
[6105]267        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
[1505]268        {
[6105]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            }
[1505]276        }
277
[6105]278        return *this;
[1505]279    }
280}
281
282#endif /* _OutputHandler_H__ */
Note: See TracBrowser for help on using the repository browser.