Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/console/src/libraries/util/OutputHandler.h @ 6006

Last change on this file since 6006 was 6004, checked in by rgrieder, 16 years ago

De-singletonised Shell so that both consoles have their own Shell instance. However they share the history.
Also modified IOConsole to hopefully work with status lines.

  • Property svn:eol-style set to native
File size: 12.5 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:
[5994]25 *      Reto Grieder
[1505]26 *
27 */
28
29/**
[5994]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
[5994]40#include <list>
41#include <ostream>
[1505]42#include <string>
[5994]43#include <vector>
44#include <utility>
[1505]45
46namespace orxonox
47{
[5994]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    */
[5991]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
[5994]74    // Forward declarations for classes in the source file
75    class LogFileWriter;
76    class MemoryLogWriter;
77
78    /**
79    @brief
80        The OutputHandler acts like std::cout, but output isn't only shown in the console.
81
82        You can register your own listener for output by inheriting from OutputListner.
83        And if you need the output previously processed, iterate over it with
84        OutputHandler::getOutputVector[Begin/End].
85        The way to output text is to first set the desired output level with
86        OutputHandler::getOutStream(level) and then use the "<<" operator like with std::cout.
87    */
[1586]88    class _UtilExport OutputHandler
[1505]89    {
90        public:
[5994]91            //! Returns a reference to the only existing instance of the OutputHandler class.
92            static OutputHandler& getInstance();
[1505]93
[5994]94            //! Sets the output level and returns a stream to be used with "<<"
[5991]95            static inline OutputHandler& getOutStream(int level)
[5994]96                { return OutputHandler::getInstance().setOutputLevel(level); }
[1505]97
[5994]98            typedef std::vector<std::pair<int, std::string> >::const_iterator OutputVectorIterator;
99            //! Returns an iterator to the beginning of the all-output vector
100            OutputVectorIterator getOutputVectorBegin() const;
101            //! Returns an iterator to the end of the all-output vector
102            OutputVectorIterator getOutputVectorEnd() const;
103
104            //! Writes to all output devices
[3196]105            static inline const std::string& log(const std::string& text)
[5994]106                { OutputHandler::getOutStream(0).output(text) << std::endl; return text; }
[1505]107
[5994]108            //! Writes an error message to the output
[3196]109            static inline const std::string& error(const std::string& text)
[5994]110                { OutputHandler::getOutStream(1).output(text) << std::endl; return text; }
[1505]111
[5994]112            //! Writes a warning message to the output
[3196]113            static inline const std::string& warning(const std::string& text)
[5994]114                { OutputHandler::getOutStream(2).output(text) << std::endl; return text; }
[1505]115
[5994]116            //! Writes an informational message to the output
[3196]117            static inline const std::string& info(const std::string& text)
[5994]118                { OutputHandler::getOutStream(3).output(text) << std::endl; return text; }
[1505]119
[5994]120            //! Writes a debug message to the output
[3196]121            static inline const std::string& debug(const std::string& text)
[5994]122                { OutputHandler::getOutStream(4).output(text) << std::endl; return text; }
[1505]123
[5994]124            //! Registers an object that receives output via a provided std::ostream
125            void registerOutputListener(OutputListener* listener);
126            //! Unregisters an object that receives output via a provided std::ostream
127            void unregisterOutputListener(OutputListener* listener);
[1505]128
[5994]129            //! Set the log path once the program has been properly initialised
130            void setLogPath(const std::string& path);
[1586]131
[5994]132            //! Sets the level of the incoming output and returns the OutputHandler
[1505]133            inline OutputHandler& setOutputLevel(int level)
134                { this->outputLevel_ = level; return *this; }
135
[5994]136            //! Returns the level of the incoming output
[1505]137            inline int getOutputLevel() const
138                { return this->outputLevel_; }
139
[5994]140            //! Returns the maximum debug level over all registered listeners (devices)
141            static int getSoftDebugLevel() { return softDebugLevel_s; }
142            //! Returns the soft debug level for a device by its name   @return The level or -1 if the listener was not found
143            int  getSoftDebugLevel(const std::string& name) const;
[6004]144            //! Sets the soft debug level for a listener by its name   @remarks Only works for registered listeners!
[5994]145            void setSoftDebugLevel(const std::string& name, int level);
[1505]146
[5994]147            /**
148            @brief
149                General template that copes with all output.
150                Required because operator << might be ambiguous.
151                @a output will be streamed into every listener with an appropriate debug level
152            @return
153                Returns a reference to the OutputHandler so you can use it again directly
154            */
[1505]155            template <class T>
156            OutputHandler& output(const T& output);
157
[5994]158            //! Overloaded << operator, redirects the output to the listeners
[1725]159            inline OutputHandler& operator<<(unsigned char val)      { return this->output(val); }
[5994]160            //! Overloaded << operator, redirects the output to the listeners
[1725]161            inline OutputHandler& operator<<(short val)              { return this->output(val); }
[5994]162            //! Overloaded << operator, redirects the output to the listeners
[1725]163            inline OutputHandler& operator<<(unsigned short val)     { return this->output(val); }
[5994]164            //! Overloaded << operator, redirects the output to the listeners
[1725]165            inline OutputHandler& operator<<(int val)                { return this->output(val); }
[5994]166            //! Overloaded << operator, redirects the output to the listeners
[1725]167            inline OutputHandler& operator<<(unsigned int val)       { return this->output(val); }
[5994]168            //! Overloaded << operator, redirects the output to the listeners
[1725]169            inline OutputHandler& operator<<(long val)               { return this->output(val); }
[5994]170            //! Overloaded << operator, redirects the output to the listeners
[1725]171            inline OutputHandler& operator<<(unsigned long val)      { return this->output(val); }
[5994]172            //! Overloaded << operator, redirects the output to the listeners
[1725]173            inline OutputHandler& operator<<(long long val)          { return this->output(val); }
[5994]174            //! Overloaded << operator, redirects the output to the listeners
[1725]175            inline OutputHandler& operator<<(unsigned long long val) { return this->output(val); }
[5994]176            //! Overloaded << operator, redirects the output to the listeners
[1725]177            inline OutputHandler& operator<<(float val)              { return this->output(val); }
[5994]178            //! Overloaded << operator, redirects the output to the listeners
[1725]179            inline OutputHandler& operator<<(double val)             { return this->output(val); }
[5994]180            //! Overloaded << operator, redirects the output to the listeners
[1725]181            inline OutputHandler& operator<<(long double val)        { return this->output(val); }
[5994]182            //! Overloaded << operator, redirects the output to the listeners
[1725]183            inline OutputHandler& operator<<(const void* val)        { return this->output(val); }
[5994]184            //! Overloaded << operator, redirects the output to the listeners
[1725]185            inline OutputHandler& operator<<(bool val)               { return this->output(val); }
[1505]186
[5994]187            //! Overloaded << operator, redirects the output to the listeners
188            inline OutputHandler& operator<<(std::streambuf* sb)     { return this->output(sb); }
[1505]189
[5994]190            //! Overloaded << operator, redirect the output of classes with self defined 'operator <<' to the listeners
191            template <class T>
192            inline OutputHandler& operator<<(const T& val)           { return this->output(val); }
[1505]193
[5994]194            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
195            inline OutputHandler& operator<<(std::ostream&  (*manip)(std::ostream&))  { return this->output(manip); }
196            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
197            inline OutputHandler& operator<<(std::ios&      (*manip)(std::ios&))      { return this->output(manip); }
198            //! Overloaded << operator for std manipulators like std::endl, redirects the output to the listeners
199            inline OutputHandler& operator<<(std::ios_base& (*manip)(std::ios_base&)) { return this->output(manip); }
[5991]200
[5994]201            //! Dummy operator required by Debug.h for the ternary operator
202            inline operator int() const { return 0; }
203
204            //! Name of the OutputListener that writes to the log file
205            static const std::string logFileOutputListenerName_s;
206
[1505]207        private:
[5994]208            OutputHandler();
209            ~OutputHandler();
210            OutputHandler(const OutputHandler& rhs); //! Unused and undefined
[1586]211
[5994]212            std::list<OutputListener*> listeners_; //!< Array with all registered output listeners
213            int outputLevel_;                      //!< The level of the incoming output
214            LogFileWriter* logFile_;               //!< Listener that writes to the log file
215            MemoryLogWriter* output_;              //!< Listener that Stores ALL output below the current soft debug level
216            static int softDebugLevel_s;           //!< Maximum of all soft debug levels. @note This is only static for faster access
[1505]217    };
218
219    /**
[5994]220    @brief
221        Interface for listening to output.
222    @remarks
223        Remember to register the listener (not done automatically!)
[1505]224    */
[5994]225    class OutputListener
[1505]226    {
[5994]227        friend class OutputHandler;
[1505]228
[5994]229    public:
230        OutputListener(const std::string& name)
231            : outputStream_(NULL)
232            , name_(name)
[6004]233            , softDebugLevel_(OutputLevel::Info)
[5994]234        {}
235        virtual ~OutputListener() {}
[1505]236
[5994]237        //! Gets called whenever output is put into the stream
[6004]238        virtual void outputChanged(int level) {}
[5994]239        //! Returns the name of this output listener
240        const std::string& getOutputListenerName() const { return this->name_; }
[6004]241        //! Returns the soft debug level of the listener
242        int getSoftDebugLevel() const { return this->softDebugLevel_; }
243        //! Sets the soft debug level of the listener
244        void setSoftDebugLevel(int level)
245        {
246            this->softDebugLevel_ = level;
247            OutputHandler::getInstance().setSoftDebugLevel(this->name_, level);
248        }
[1505]249
[5994]250    protected:
251        std::ostream*     outputStream_;   //!< Pointer to the associated output stream, can be NULL
252
253    private:
254        const std::string name_;           //!< Name of the listener, constant and unique!
255        int               softDebugLevel_; //!< Current soft debug level that defines what kind of output is written to the stream
256    };
[5996]257
258    template<class T>
259    inline OutputHandler& OutputHandler::output(const T& output)
260    {
261        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
262        {
263            if (this->outputLevel_ <= (*it)->softDebugLevel_ && (*it)->outputStream_ != NULL)
264            {
265                std::ostream& stream = *((*it)->outputStream_);
266                stream << output;
267                stream.flush();
[6004]268                (*it)->outputChanged(this->outputLevel_);
[5996]269            }
270        }
271
272        return *this;
273    }
[1505]274}
275
276#endif /* _OutputHandler_H__ */
Note: See TracBrowser for help on using the repository browser.