Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

Changed Output concept a little bit to allow for more general use.
Every output (log) target has to be implemented as OutputListener. There is already a LogFileWriter and a MemoryLogWriter (stores ALL the log in a vector and provides iterators).
The OutputListener has a unique and constant name, a stream pointer and a soft debug level (that can only be changed via OutputHandler::setSoftDebugLevel(name, level)).
This concept doesn't require the OutputBuffer anymore, so I deleted it.

The adjustments in the Shell are just preliminary for this commit.

  • Property svn:eol-style set to native
File size: 12.0 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 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    */
88    class _UtilExport OutputHandler
89    {
90        public:
91            //! Returns a reference to the only existing instance of the OutputHandler class.
92            static OutputHandler& getInstance();
93
94            //! Sets the output level and returns a stream to be used with "<<"
95            static inline OutputHandler& getOutStream(int level)
96                { return OutputHandler::getInstance().setOutputLevel(level); }
97
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
105            static inline const std::string& log(const std::string& text)
106                { OutputHandler::getOutStream(0).output(text) << std::endl; return text; }
107
108            //! Writes an error message to the output
109            static inline const std::string& error(const std::string& text)
110                { OutputHandler::getOutStream(1).output(text) << std::endl; return text; }
111
112            //! Writes a warning message to the output
113            static inline const std::string& warning(const std::string& text)
114                { OutputHandler::getOutStream(2).output(text) << std::endl; return text; }
115
116            //! Writes an informational message to the output
117            static inline const std::string& info(const std::string& text)
118                { OutputHandler::getOutStream(3).output(text) << std::endl; return text; }
119
120            //! Writes a debug message to the output
121            static inline const std::string& debug(const std::string& text)
122                { OutputHandler::getOutStream(4).output(text) << std::endl; return text; }
123
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);
128
129            //! Set the log path once the program has been properly initialised
130            void setLogPath(const std::string& path);
131
132            //! Sets the level of the incoming output and returns the OutputHandler
133            inline OutputHandler& setOutputLevel(int level)
134                { this->outputLevel_ = level; return *this; }
135
136            //! Returns the level of the incoming output
137            inline int getOutputLevel() const
138                { return this->outputLevel_; }
139
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;
144            //! Sets the soft debug level for a listener by its name
145            void setSoftDebugLevel(const std::string& name, int level);
146
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            */
155            template <class T>
156            OutputHandler& output(const T& output);
157
158            //! Overloaded << operator, redirects the output to the listeners
159            inline OutputHandler& operator<<(unsigned char val)      { return this->output(val); }
160            //! Overloaded << operator, redirects the output to the listeners
161            inline OutputHandler& operator<<(short val)              { return this->output(val); }
162            //! Overloaded << operator, redirects the output to the listeners
163            inline OutputHandler& operator<<(unsigned short val)     { return this->output(val); }
164            //! Overloaded << operator, redirects the output to the listeners
165            inline OutputHandler& operator<<(int val)                { return this->output(val); }
166            //! Overloaded << operator, redirects the output to the listeners
167            inline OutputHandler& operator<<(unsigned int val)       { return this->output(val); }
168            //! Overloaded << operator, redirects the output to the listeners
169            inline OutputHandler& operator<<(long val)               { return this->output(val); }
170            //! Overloaded << operator, redirects the output to the listeners
171            inline OutputHandler& operator<<(unsigned long val)      { return this->output(val); }
172            //! Overloaded << operator, redirects the output to the listeners
173            inline OutputHandler& operator<<(long long val)          { return this->output(val); }
174            //! Overloaded << operator, redirects the output to the listeners
175            inline OutputHandler& operator<<(unsigned long long val) { return this->output(val); }
176            //! Overloaded << operator, redirects the output to the listeners
177            inline OutputHandler& operator<<(float val)              { return this->output(val); }
178            //! Overloaded << operator, redirects the output to the listeners
179            inline OutputHandler& operator<<(double val)             { return this->output(val); }
180            //! Overloaded << operator, redirects the output to the listeners
181            inline OutputHandler& operator<<(long double val)        { return this->output(val); }
182            //! Overloaded << operator, redirects the output to the listeners
183            inline OutputHandler& operator<<(const void* val)        { return this->output(val); }
184            //! Overloaded << operator, redirects the output to the listeners
185            inline OutputHandler& operator<<(bool val)               { return this->output(val); }
186
187            //! Overloaded << operator, redirects the output to the listeners
188            inline OutputHandler& operator<<(std::streambuf* sb)     { return this->output(sb); }
189
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); }
193
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); }
200
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
207        private:
208            OutputHandler();
209            ~OutputHandler();
210            OutputHandler(const OutputHandler& rhs); //! Unused and undefined
211
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
217    };
218
219    template<class T>
220    inline OutputHandler& OutputHandler::output(const T& output)
221    {
222        for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
223        {
224            if (this->outputLevel_ <= (*it)->softDebugLevel_ && (*it)->outputStream_ != NULL)
225            {
226                std::ostream& stream = *((*it)->outputStream_);
227                stream << output;
228                stream.flush();
229                (*it)->outputChanged();
230            }
231        }
232
233        return *this;
234    }
235
236    /**
237    @brief
238        Interface for listening to output.
239    @remarks
240        Remember to register the listener (not done automatically!)
241    */
242    class OutputListener
243    {
244        friend class OutputHandler;
245
246    public:
247        OutputListener(const std::string& name)
248            : outputStream_(NULL)
249            , name_(name)
250        {}
251        virtual ~OutputListener() {}
252
253        //! Gets called whenever output is put into the stream
254        virtual void outputChanged() {}
255        //! Returns the name of this output listener
256        const std::string& getOutputListenerName() const { return this->name_; }
257
258    protected:
259        std::ostream*     outputStream_;   //!< Pointer to the associated output stream, can be NULL
260
261    private:
262        const std::string name_;           //!< Name of the listener, constant and unique!
263        int               softDebugLevel_; //!< Current soft debug level that defines what kind of output is written to the stream
264    };
265}
266
267#endif /* _OutputHandler_H__ */
Note: See TracBrowser for help on using the repository browser.