[Orxonox-commit 4177] r8848 - in code/branches/output/src/libraries/util: . output

landauf at orxonox.net landauf at orxonox.net
Sun Aug 21 16:04:54 CEST 2011


Author: landauf
Date: 2011-08-21 16:04:54 +0200 (Sun, 21 Aug 2011)
New Revision: 8848

Modified:
   code/branches/output/src/libraries/util/Output.h
   code/branches/output/src/libraries/util/output/ConsoleWriter.cc
   code/branches/output/src/libraries/util/output/ConsoleWriter.h
   code/branches/output/src/libraries/util/output/LogWriter.cc
   code/branches/output/src/libraries/util/output/LogWriter.h
   code/branches/output/src/libraries/util/output/MemoryWriter.cc
   code/branches/output/src/libraries/util/output/MemoryWriter.h
   code/branches/output/src/libraries/util/output/OutputDefinitions.h
   code/branches/output/src/libraries/util/output/OutputListener.cc
   code/branches/output/src/libraries/util/output/OutputListener.h
   code/branches/output/src/libraries/util/output/OutputManager.cc
   code/branches/output/src/libraries/util/output/OutputManager.h
   code/branches/output/src/libraries/util/output/OutputStream.cc
   code/branches/output/src/libraries/util/output/OutputStream.h
Log:
added documentation and some comments

Modified: code/branches/output/src/libraries/util/Output.h
===================================================================
--- code/branches/output/src/libraries/util/Output.h	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/Output.h	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,39 @@
  *
  */
 
+/**
+    @defgroup Output Output system
+    @ingroup Util
+*/
+
+/**
+    @file
+    @ingroup Output
+    @brief Defines the helper function orxout() and includes all necessary headers to use the output system.
+
+    The output system is used to write output to the console, the logfile, and
+    other instances of orxonox::OutputListener. Each line of output is assigned
+    a level and a context. The level defines the type and importance of a
+    message, e.g. if it's a fatal error or just some internal information.
+    The context defines to which part of the program the output belongs.
+    Levels and contexts are defined in OutputDefinitions.h
+
+    Each orxonox::OutputListener can define a mask of desired levels and
+    contexts, to receive only a part of the output. A derivative of
+    orxonox::BaseWriter is able to define these masks through config values
+    and to filter specific subcontexts.
+
+    @attention
+    A message sent to the output system MUST end with "endl" or the message
+    won't be flushed.
+
+    @code
+    orxout() << "Debug output" << endl;
+    orxout(user_info) << "Orxonox version 1.2.3" << endl;
+    orxout(internal_status, context::input) << "Loading joystick" << endl;
+    @endcode
+*/
+
 #ifndef _Output_H__
 #define _Output_H__
 
@@ -37,6 +70,13 @@
     // Just for convenience
     using std::endl;
 
+    /**
+        @brief This helper function returns a reference to a commonly used
+        instance of OutputStream.
+
+        It can be used like std::cout except that it is a function. You can
+        pass level and context of the following output as function arguments.
+    */
     inline OutputStream& orxout(OutputLevel level = level::debug_output, const OutputContextContainer& context = context::undefined())
     {
         static OutputStream stream;
@@ -44,6 +84,15 @@
         return stream;
     }
 
+    /**
+        @brief Shortcut for orxout() to allow passing contexts directly as
+        functions without using "()".
+
+        @code
+        orxout(user_info, context::example) << "Hello World" << endl; // calls this function
+        orxout(user_info, context::example()) << "Hello World" << endl; // calls the other orxout function
+        @endcode
+    */
     inline OutputStream& orxout(OutputLevel level, OutputContextFunction context)
     {
         return orxout(level, context());
@@ -52,6 +101,11 @@
     // COUT() is deprecated, please use orxout()
     inline __DEPRECATED__(OutputStream& COUT(int level));
 
+    /**
+        @brief Writes output to the orxonox console. This function is deprecated, please use orxout()
+        @note The output level argument is ignored since it's not supported anymore. See orxout() for the new output levels.
+        @deprecated This function is deprecated. Use orxout() instead.
+    */
     inline OutputStream& COUT(int)
     {
         return orxout();

Modified: code/branches/output/src/libraries/util/output/ConsoleWriter.cc
===================================================================
--- code/branches/output/src/libraries/util/output/ConsoleWriter.cc	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/ConsoleWriter.cc	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,11 @@
  *
  */
 
+/**
+    @file
+    @brief Implementation of the ConsoleWriter singleton.
+*/
+
 #include "ConsoleWriter.h"
 
 #include <iostream>
@@ -34,6 +39,14 @@
 
 namespace orxonox
 {
+    /**
+        @brief Constructor, initializes the output level.
+
+        In debug builds, it writes output up to level::internal_warning to the
+        console, in release builds only up to level::user_info.
+
+        After creation, the instance is enabled.
+    */
     ConsoleWriter::ConsoleWriter() : BaseWriter("Console")
     {
 #ifdef ORXONOX_RELEASE
@@ -44,21 +57,33 @@
         this->bEnabled_ = true;
     }
 
+    /**
+        @brief Destructor.
+    */
     ConsoleWriter::~ConsoleWriter()
     {
     }
 
+    /**
+        @brief Returns the only existing instance of this class.
+    */
     /*static*/ ConsoleWriter& ConsoleWriter::getInstance()
     {
         static ConsoleWriter instance;
         return instance;
     }
 
+    /**
+        @brief Inherited function from BaseWriter, writes output to the console using std::cout.
+    */
     void ConsoleWriter::printLine(const std::string& line, OutputLevel)
     {
         std::cout << line << std::endl;
     }
 
+    /**
+        @brief Enables the instance by registering itself as listener at OutputManager.
+    */
     void ConsoleWriter::enable()
     {
         if (!this->bEnabled_)
@@ -68,6 +93,9 @@
         }
     }
 
+    /**
+        @brief Disables the instance by unregistering itself from OutputManager.
+    */
     void ConsoleWriter::disable()
     {
         if (this->bEnabled_)

Modified: code/branches/output/src/libraries/util/output/ConsoleWriter.h
===================================================================
--- code/branches/output/src/libraries/util/output/ConsoleWriter.h	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/ConsoleWriter.h	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,12 @@
  *
  */
 
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the ConsoleWriter singleton which is used to write output to the console.
+*/
+
 #ifndef _ConsoleWriter_H__
 #define _ConsoleWriter_H__
 
@@ -34,6 +40,12 @@
 
 namespace orxonox
 {
+    /**
+        @brief ConsoleWriter inherits from BaseWriter and writes output to the console.
+
+        This class can be seen as an equivalent to std::cout within the output
+        system. It is implemented as a singleton for static acces.
+    */
     class _UtilExport ConsoleWriter : public BaseWriter
     {
         public:
@@ -50,7 +62,7 @@
             ConsoleWriter(const ConsoleWriter&);
             virtual ~ConsoleWriter();
 
-            bool bEnabled_;
+            bool bEnabled_; ///< If false, the instance will not write output to the console.
     };
 }
 

Modified: code/branches/output/src/libraries/util/output/LogWriter.cc
===================================================================
--- code/branches/output/src/libraries/util/output/LogWriter.cc	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/LogWriter.cc	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,11 @@
  *
  */
 
+/**
+    @file
+    @brief Implementation of the LogWriter singleton.
+*/
+
 #include "LogWriter.h"
 
 #include <ctime>
@@ -36,13 +41,21 @@
 
 namespace orxonox
 {
+    /**
+        @brief Constructor, initializes the desired output levels and the name and path of the log-file, and opens the log-file.
+
+        By default, LogWriter receives all output up to level::internal_info.
+        The log-file has a default name which usually doesn't change. The path
+        is initialized with a temporary directory, depending on the system,
+        and can be changed later.
+    */
     LogWriter::LogWriter() : BaseWriter("Log")
     {
         this->setLevelMax(level::internal_info);
 
         this->filename_ = "orxonox.log";
 
-        // Get path for a temporary file
+        // get the path for a temporary file, depending on the system
 #ifdef ORXONOX_PLATFORM_WINDOWS
         this->path_ = getenv("TEMP");
 #else
@@ -53,32 +66,48 @@
         this->openFile();
     }
 
+    /**
+        @brief Destructor, closes the log-file.
+    */
     LogWriter::~LogWriter()
     {
         this->closeFile();
     }
 
+    /**
+        @brief Returns the only existing instance of this class.
+    */
     /*static*/ LogWriter& LogWriter::getInstance()
     {
         static LogWriter instance;
         return instance;
     }
 
+    /**
+        @brief Opens the log-file in order to write output to it.
+    */
     void LogWriter::openFile()
     {
+        // get the full file-name
         std::string name = this->path_ + '/' + this->filename_;
 
+        // if we open the log file in the default directory, send a message to the user so that he can find the file in the case of a crash.
         if (this->bDefaultPath_)
             OutputManager::getInstance().pushMessage(level::user_info, context::undefined(), "Opening log file " + name);
 
+        // open the file
         this->file_.open(name.c_str(), std::fstream::out);
 
+        // check if it worked and print some output
         if (this->file_.is_open())
             this->printLine("Log file opened", level::none);
         else
             OutputManager::getInstance().pushMessage(level::user_warning, context::undefined(), "Failed to open log file. File logging disabled.");
     }
 
+    /**
+        @brief Closes the log-file.
+    */
     void LogWriter::closeFile()
     {
         if (this->file_.is_open())
@@ -88,30 +117,39 @@
         }
     }
 
+    /**
+        @brief Changes the path of the log-file. Re-writes the log-file by using MemoryWriter.
+    */
     void LogWriter::setLogPath(const std::string& path)
     {
+        // notify about the change of the log-file (because the old file will no longer be updated)
         OutputManager::getInstance().pushMessage(level::internal_info, context::undefined(), "Migrating log file from " + this->path_ + "\nto " + path);
 
+        // close the old file, update the path and open the new file
         this->closeFile();
         this->path_ = path;
         this->bDefaultPath_ = false;
         this->openFile();
 
+        // request old output from MemoryWriter
         MemoryWriter::getInstance().resendOutput(this);
     }
 
+    /**
+        @brief Inherited function from BaseWriter, writers output together with a timestamp to the log-file.
+    */
     void LogWriter::printLine(const std::string& line, OutputLevel)
     {
         if (!this->file_.is_open())
             return;
 
-        // Get current time
+        // get the current time
         time_t rawtime;
         struct tm* timeinfo;
         time(&rawtime);
         timeinfo = localtime(&rawtime);
 
-        // print timestamp and line to the log file
+        // print timestamp and output line to the log file
         this->file_ << (timeinfo->tm_hour < 10 ? "0" : "") << timeinfo->tm_hour << ':' <<
                        (timeinfo->tm_min  < 10 ? "0" : "") << timeinfo->tm_min  << ':' <<
                        (timeinfo->tm_sec  < 10 ? "0" : "") << timeinfo->tm_sec  << ' ' << line << std::endl;

Modified: code/branches/output/src/libraries/util/output/LogWriter.h
===================================================================
--- code/branches/output/src/libraries/util/output/LogWriter.h	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/LogWriter.h	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,12 @@
  *
  */
 
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the LogWriter singleton which writes output to a log-file.
+*/
+
 #ifndef _LogWriter_H__
 #define _LogWriter_H__
 
@@ -37,6 +43,16 @@
 
 namespace orxonox
 {
+    /**
+        @brief The LogWriter class inherits from BaseWriter and writes output to a log-file.
+
+        It is implemented as singleton because we (currently) use only one
+        log-file. The path of the file can be changed, in which case the file
+        is rewritten by using the output stored by MemoryWriter. This adds the
+        possibility to change the desired output levels before changing the
+        path in order to get the complete output with the new output levels
+        at the new path.
+    */
     class _UtilExport LogWriter : public BaseWriter
     {
         public:
@@ -55,11 +71,11 @@
             void openFile();
             void closeFile();
 
-            std::string filename_;
-            std::string path_;
-            bool bDefaultPath_;
+            std::string filename_;  ///< The name of the log-file (without directories)
+            std::string path_;      ///< The path of the log-file (without file-name)
+            bool bDefaultPath_;     ///< If true, the log-file resides at the default path (which is usually a temporary directory)
 
-            std::ofstream file_;
+            std::ofstream file_;    ///< The output file stream.
     };
 }
 

Modified: code/branches/output/src/libraries/util/output/MemoryWriter.cc
===================================================================
--- code/branches/output/src/libraries/util/output/MemoryWriter.cc	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/MemoryWriter.cc	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,32 +26,51 @@
  *
  */
 
+/**
+    @file
+    @brief Implementation of the MemoryWriter singleton.
+*/
+
 #include "MemoryWriter.h"
-
 #include "OutputManager.h"
 
 namespace orxonox
 {
+    /**
+        @brief Constructor, initializes the level mask with all levels activated.
+    */
     MemoryWriter::MemoryWriter()
     {
         this->setLevelMask(level::all);
     }
 
+    /**
+        @brief Destructor.
+    */
     MemoryWriter::~MemoryWriter()
     {
     }
 
+    /**
+        @brief Returns the only existing instance of this singleton class.
+    */
     /*static*/ MemoryWriter& MemoryWriter::getInstance()
     {
         static MemoryWriter instance;
         return instance;
     }
 
+    /**
+        @brief Implementation of the output() function inherited from OutputListener, stores the received output in memory.
+    */
     void MemoryWriter::output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
     {
         this->messages_.push_back(Message(level, context, lines));
     }
 
+    /**
+        @brief Iterates over all stored output messages and sends them to the OutputListener.
+    */
     void MemoryWriter::resendOutput(OutputListener* listener) const
     {
         for (size_t i = 0; i < this->messages_.size(); ++i)
@@ -61,6 +80,9 @@
         }
     }
 
+    /**
+        @brief Unregisters the instance from OutputManager, hence it will not receive any further output.
+    */
     void MemoryWriter::disable()
     {
         OutputManager::getInstance().unregisterListener(this);

Modified: code/branches/output/src/libraries/util/output/MemoryWriter.h
===================================================================
--- code/branches/output/src/libraries/util/output/MemoryWriter.h	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/MemoryWriter.h	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,12 @@
  *
  */
 
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the MemoryWriter singleton.
+*/
+
 #ifndef _MemoryWriter_H__
 #define _MemoryWriter_H__
 
@@ -34,16 +40,29 @@
 
 namespace orxonox
 {
+    /**
+        @brief MemoryWriter is a singleton which is derived from OutputListener and writes all output to a list.
+
+        This list can be used to re-send old output to other instances of
+        OutputListener, e.g. if they were newly created or to re-write the
+        log-file.
+
+        Since MemoryWriter receives output of all levels, this means also that
+        all possible output needs to be generated as long as MemoryWriter stays
+        active. Hence disable() should be called as soon as possible.
+    */
     class _UtilExport MemoryWriter : public OutputListener
     {
+        /// @brief A helper struct which is used to store output and its properties.
         struct Message
         {
+            /// @brief Constructor, assigns all values.
             Message(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
                 : level(level), context(&context), lines(lines) {}
 
-            OutputLevel level;
-            const OutputContextContainer* context;
-            std::vector<std::string> lines;
+            OutputLevel level;                      ///< The level of the output message
+            const OutputContextContainer* context;  ///< The context of the output message
+            std::vector<std::string> lines;         ///< The lines of text of the output message
         };
 
         public:
@@ -60,7 +79,7 @@
             MemoryWriter(const MemoryWriter&);
             virtual ~MemoryWriter();
 
-            std::vector<Message> messages_;
+            std::vector<Message> messages_; ///< Stores all output messages from the creation of this instance until disable() is called.
     };
 }
 

Modified: code/branches/output/src/libraries/util/output/OutputDefinitions.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputDefinitions.h	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/OutputDefinitions.h	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,15 +26,39 @@
  *
  */
 
+/**
+    @file
+    @ingroup Output
+    @brief Defines output levels and output contexts.
+*/
+
 #ifndef _OutputDefinitions_H__
 #define _OutputDefinitions_H__
 
 #include "util/UtilPrereqs.h"
 #include <string>
 
+/**
+    @brief Defines a context function with a given name.
+    @param name Name of the context
+
+    Context functions return a reference to a OutputContextContainer. Context
+    functions (or the containers they return) can be passed to orxout() as
+    context argument.
+*/
 #define REGISTER_OUTPUT_CONTEXT(name) \
     const OutputContextContainer& name() { static const OutputContextContainer& context = registerContext(#name); return context; }
 
+/**
+    @brief Defines a sub-context.
+    @param name Name of the main-context
+    @param subname Name of the sub-context
+
+    Sub-contexts act like normal contexts, except that multiple sub-contexts
+    share the context mask of their main-context. This allows contexts with
+    more descriptive names (e.g. input::keyboard) and they can be filtered
+    individually by derivatives of orxonox::BaseWriter.
+*/
 #define REGISTER_OUTPUT_SUBCONTEXT(name, subname) \
     const OutputContextContainer& subname() { static const OutputContextContainer& context = registerContext(#name, #subname); return context; }
 
@@ -43,54 +67,63 @@
 {
     namespace level
     {
+        /**
+            @brief Output levels define type and importance of an output message.
+            They can be passed to the orxout() function as level argument.
+        */
         enum OutputLevel
         {
-            all              = 0xFFFF,
-            none             = 0x0000,
+            all              = 0xFFFF, ///< Level mask with all bits set to 1
+            none             = 0x0000, ///< Level mask with all bits set to 0
 
-            message          = 0x0001,
-            debug_output     = 0x0002,
-            user_error       = 0x0004,
-            user_warning     = 0x0008,
-            user_status      = 0x0010,
-            user_info        = 0x0020,
-            internal_error   = 0x0040,
-            internal_warning = 0x0080,
-            internal_status  = 0x0100,
-            internal_info    = 0x0200,
-            verbose          = 0x0400,
-            verbose_more     = 0x0800,
-            verbose_ultra    = 0x1000
+            message          = 0x0001, ///< Output level, used for messages directed to the user (e.g. "Press any key to continue")
+            debug_output     = 0x0002, ///< Output level, used for temporary debug output while writing code
+            user_error       = 0x0004, ///< Output level, used for error messages which are important for the user
+            user_warning     = 0x0008, ///< Output level, used for warnings which are important for the user
+            user_status      = 0x0010, ///< Output level, used to notify the user about the program's state
+            user_info        = 0x0020, ///< Output level, used to provide the user with additional progress information
+            internal_error   = 0x0040, ///< Output level, used for error messages which are important for developers
+            internal_warning = 0x0080, ///< Output level, used for warnings which are important for developers
+            internal_status  = 0x0100, ///< Output level, used to log the program's internal state in the log file
+            internal_info    = 0x0200, ///< Output level, used to log information about the program's progress in the log file
+            verbose          = 0x0400, ///< Output level, usually not visible, used for unimportant debug information
+            verbose_more     = 0x0800, ///< Output level, usually not visible, used for unimportant debug information (less important than verbose)
+            verbose_ultra    = 0x1000  ///< Output level, usually not visible, used for unimportant debug information (even less important than verbose_more)
         };
     }
 // tolua_end
 
     using namespace level;
 
-    typedef uint64_t OutputContextMask;
-    typedef uint16_t OutputContextSubID;
+    typedef uint64_t OutputContextMask;  ///< Used to store the context masks. Each bit defines a context.
+    typedef uint16_t OutputContextSubID; ///< Used to store the IDs of sub-contexts. Each number except context::no_subcontext defines a sub-context.
 
+    /// @brief Stores all information about a context.
     struct OutputContextContainer
     {
-        OutputContextMask mask;
-        OutputContextSubID sub_id;
-        std::string name;
+        OutputContextMask mask;     ///< The mask of the context (or the mask of the main-context if this container defines a sub-context)
+        OutputContextSubID sub_id;  ///< The id of the sub-context (or context::no_subcontext if this container doesn't define a sub-context)
+        std::string name;           ///< The name of this context
     };
 
     typedef const OutputContextContainer& (OutputContextFunction)();
 
+    /**
+        @brief Registers a context.
+        This is a shortcut to OutputManager::registerContext() to avoid the inclusion of its header file.
+    */
     extern _UtilExport const OutputContextContainer& registerContext(const std::string& name, const std::string& subname = "");
 
     namespace context
     {
-        static const OutputContextMask all       = 0xFFFFFFFFFFFFFFFF;
-        static const OutputContextMask none      = 0x0000000000000000;
+        static const OutputContextMask all       = 0xFFFFFFFFFFFFFFFF; ///< Context mask, all bits set to 1
+        static const OutputContextMask none      = 0x0000000000000000; ///< Context mask, all bits set to 0
 
-        static const OutputContextSubID no_subcontext = 0;
+        static const OutputContextSubID no_subcontext = 0; ///< Used as ID for contexts which are not sub-contexts
 
         namespace
         {
-            REGISTER_OUTPUT_CONTEXT(undefined);
+            REGISTER_OUTPUT_CONTEXT(undefined); ///< "undefined" context which is implicitly used for all output that has no explicit context
 
             REGISTER_OUTPUT_CONTEXT(ogre);
             REGISTER_OUTPUT_CONTEXT(cegui);

Modified: code/branches/output/src/libraries/util/output/OutputListener.cc
===================================================================
--- code/branches/output/src/libraries/util/output/OutputListener.cc	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/OutputListener.cc	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,12 +26,22 @@
  *
  */
 
+/**
+    @file
+    @brief Implementation of the OutputListener class.
+*/
+
 #include "OutputListener.h"
 
 #include "OutputManager.h"
 
 namespace orxonox
 {
+    /**
+        @brief Constructor, initializes the values and registers the instance at OutputManager if requested.
+        @param bRegister If \c true, the instance is automatically registered at OutputManager.
+                         Should be \c false if the constructor of the derived class generates output.
+    */
     OutputListener::OutputListener(bool bRegister)
     {
         this->levelMask_ = level::none;
@@ -42,16 +52,25 @@
             OutputManager::getInstance().registerListener(this);
     }
 
+    /**
+        @brief Destructor, unregisters the instance from OutputManager.
+    */
     OutputListener::~OutputListener()
     {
         OutputManager::getInstance().unregisterListener(this);
     }
 
+    /**
+        @brief Defines the level mask in a way which accepts all output up to the level \c max.
+    */
     void OutputListener::setLevelMax(OutputLevel max)
     {
         this->setLevelRange(static_cast<OutputLevel>(0x1), max);
     }
 
+    /**
+        @brief Defines the level mask in a way which accepts all output between the levels \c min and \c max.
+    */
     void OutputListener::setLevelRange(OutputLevel min, OutputLevel max)
     {
         int mask = 0;
@@ -61,6 +80,9 @@
         this->setLevelMask(static_cast<OutputLevel>(mask));
     }
 
+    /**
+        @brief Defines the level mask.
+    */
     void OutputListener::setLevelMask(OutputLevel mask)
     {
         this->levelMask_ = mask;
@@ -68,11 +90,17 @@
         OutputManager::getInstance().updateCombinedLevelMask();
     }
 
+    /**
+        @brief Defines the level mask of additional contexts in a way which accepts all output up to the level \c max.
+    */
     void OutputListener::setAdditionalContextsLevelMax(OutputLevel max)
     {
         this->setAdditionalContextsLevelRange(static_cast<OutputLevel>(0x1), max);
     }
 
+    /**
+        @brief Defines the level mask of additional contexts in a way which accepts all output between the levels \c min and \c max.
+    */
     void OutputListener::setAdditionalContextsLevelRange(OutputLevel min, OutputLevel max)
     {
         int mask = 0;
@@ -82,6 +110,9 @@
         this->setAdditionalContextsLevelMask(static_cast<OutputLevel>(mask));
     }
 
+    /**
+        @brief Defines the level mask of additional contexts.
+    */
     void OutputListener::setAdditionalContextsLevelMask(OutputLevel mask)
     {
         this->additionalContextsLevelMask_ = mask;
@@ -89,6 +120,9 @@
         OutputManager::getInstance().updateCombinedAdditionalContextsLevelMask();
     }
 
+    /**
+        @brief Defines the mask of additional contexts.
+    */
     void OutputListener::setAdditionalContextsMask(OutputContextMask mask)
     {
         this->additionalContextsMask_ = mask;

Modified: code/branches/output/src/libraries/util/output/OutputListener.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputListener.h	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/OutputListener.h	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,13 @@
  *
  */
 
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the OutputListener interface which receives output
+    from orxonox::OutputManager.
+*/
+
 #ifndef _OutputListener_H__
 #define _OutputListener_H__
 
@@ -37,6 +44,10 @@
 
 namespace orxonox
 {
+    /**
+        @brief OutputListener is an interface which is used to receive output of a certain level and context from OutputManager.
+    */
+    //  See below the class declaration for a more detailed description.
     class _UtilExport OutputListener
     {
         public:
@@ -53,29 +64,115 @@
 
             void setAdditionalContextsMask(OutputContextMask mask);
 
+            /// @brief Returns the level mask.
             inline OutputLevel getLevelMask() const
                 { return this->levelMask_; }
+            /// @brief Returns the additional contexts mask.
+            inline OutputContextMask getAdditionalContextsMask() const
+                { return this->additionalContextsMask_; }
+            /// @brief Returns the additional contexts level mask.
             inline OutputLevel getAdditionalContextsLevelMask() const
                 { return this->additionalContextsLevelMask_; }
-            inline OutputContextMask getAdditionalContextsMask() const
-                { return this->additionalContextsMask_; }
 
+            /// @brief Returns true if this listener accepts output of the given level and context, based on the levels and contexts masks.
             inline bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const
             {
                 return (this->levelMask_ & level) ||
                        ((this->additionalContextsLevelMask_ & level) && (this->additionalContextsMask_ & context.mask)); }
 
+            /// @brief Called by OutputManager for each line of output, checks if this listener actually accepts this output before it calls the output() function.
             inline void unfilteredOutput(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
                 { if (this->acceptsOutput(level, context)) this->output(level, context, lines); }
 
         protected:
+            /// @brief Pure virtual function, needs to be implemented in order to receive output.
             virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines) = 0;
 
         private:
-            OutputLevel       levelMask_;
-            OutputLevel       additionalContextsLevelMask_;
-            OutputContextMask additionalContextsMask_;
+            OutputLevel       levelMask_;                   ///< Mask of accepted output levels, independent of contexts
+            OutputContextMask additionalContextsMask_;      ///< Mask of accepted additional contexts
+            OutputLevel       additionalContextsLevelMask_; ///< Mask of accepted output levels of the additional contexts
     };
+
+    /**
+        @class OutputListener
+
+        An instance of OutputListener registers itself at OutputManager and
+        declares the desired output levels and contexts. OutputManager will
+        then send output to it by calling the output() function.
+
+        OutputListener has 3 masks to define the desired output. These masks
+        can be used in two different ways (or as a combination of both):
+        \li 1. By defining the \a "level mask": The OutputListener will then
+               receive all output of these levels independent of the context.
+        \li 2. By defining the \a "additional contexts mask" and the
+               \a "additional contexts level mask": This way the listener
+               receives only output of a particular context and level.
+        \li 3. By using all 3 masks which combines the output defined by the
+               first two ways.
+
+        This can be illustrated as follows:
+
+        1. Only level mask:
+        \li level-mask = error | warning;
+
+        @verbatim
+                |   Contexts:   |
+                | A | B | C | D |
+        --------|---|---|---|---|
+        debug   | - | - | - | - |
+        --------|---|---|---|---|
+        error   | x | x | x | x |
+        --------|---|---|---|---|       [x] Receives output
+        warning | x | x | x | x |       [-] Does not receive output
+        --------|---|---|---|---|
+        status  | - | - | - | - |
+        --------|---|---|---|---|
+        verbose | - | - | - | - |
+        --------|---|---|---|---|
+        @endverbatim
+
+        2. Only additional contexts:
+        \li additional-contexts-mask = B | D;
+        \li additional-contexts-level-mask = debug | verbose;
+
+        @verbatim
+                |   Contexts:   |
+                | A | B | C | D |
+        --------|---|---|---|---|
+        debug   | - | x | - | x |
+        --------|---|---|---|---|
+        error   | - | - | - | - |
+        --------|---|---|---|---|       [x] Receives output
+        warning | - | - | - | - |       [-] Does not receive output
+        --------|---|---|---|---|
+        status  | - | - | - | - |
+        --------|---|---|---|---|
+        verbose | - | x | - | x |
+        --------|---|---|---|---|
+        @endverbatim
+
+        3. Both level mask plus additional contexts:
+        \li level-mask = error | warning;
+        \li additional-contexts-mask = B | D;
+        \li additional-contexts-level-mask = debug | verbose;
+
+        @verbatim
+                |   Contexts:   |
+                | A | B | C | D |
+        --------|---|---|---|---|
+        debug   | - | x | - | x |
+        --------|---|---|---|---|
+        error   | x | x | x | x |
+        --------|---|---|---|---|       [x] Receives output
+        warning | x | x | x | x |       [-] Does not receive output
+        --------|---|---|---|---|
+        status  | - | - | - | - |
+        --------|---|---|---|---|
+        verbose | - | x | - | x |
+        --------|---|---|---|---|
+        @endverbatim
+    */
 }
 
 #endif /* _OutputListener_H__ */

Modified: code/branches/output/src/libraries/util/output/OutputManager.cc
===================================================================
--- code/branches/output/src/libraries/util/output/OutputManager.cc	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/OutputManager.cc	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,11 @@
  *
  */
 
+/**
+    @file
+    @brief Implementation of the OutputManager singleton.
+*/
+
 #include "OutputManager.h"
 
 #include "MemoryWriter.h"
@@ -36,6 +41,9 @@
 
 namespace orxonox
 {
+    /**
+        @brief Constructor, initializes all values.
+    */
     OutputManager::OutputManager()
     {
         this->combinedLevelMask_ = level::none;
@@ -45,16 +53,30 @@
         this->subcontextCounter_ = 0;
     }
 
+    /**
+        @brief Destructor.
+    */
     OutputManager::~OutputManager()
     {
     }
 
+    /**
+        @brief Returns the only existing instance of the OutputManager singleton.
+    */
     /*static*/ OutputManager& OutputManager::getInstance()
     {
         static OutputManager instance;
         return instance;
     }
 
+    /**
+        @brief Returns the only existing instance of the OutputManager singleton
+        and ensures that the most important output listeners exist.
+
+        You should use this function if you send output to OutputManager and want
+        to be sure that the most important output listeners exist. Don't use it
+        elsewhere inside the output system to avoid circular calls.
+    */
     /*static*/ OutputManager& OutputManager::getInstanceAndCreateListeners()
     {
         static OutputManager& instance = OutputManager::getInstance();
@@ -66,6 +88,16 @@
         return instance;
     }
 
+    /**
+        @brief Sends an output message to all output listeners.
+        @param level The level of the message
+        @param context The context of the message
+        @param message The output message (may contain '\\n')
+
+        This function splits the message into lines (if it contains '\\n') and
+        sends it to the output listeners. They may ignore the message if it
+        doesn't match their level- and context-masks.
+    */
     void OutputManager::pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message)
     {
         std::vector<std::string> lines;
@@ -75,12 +107,18 @@
             this->listeners_[i]->unfilteredOutput(level, context, lines);
     }
 
+    /**
+        @brief Adds an output listener to the list of listeners.
+    */
     void OutputManager::registerListener(OutputListener* listener)
     {
         this->listeners_.push_back(listener);
         this->updateMasks();
     }
 
+    /**
+        @brief Removes an output listener from the list of listeners.
+    */
     void OutputManager::unregisterListener(OutputListener* listener)
     {
         for (std::vector<OutputListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
@@ -94,6 +132,9 @@
         this->updateMasks();
     }
 
+    /**
+        @brief Updates all three combined level- and context-masks.
+    */
     void OutputManager::updateMasks()
     {
         this->updateCombinedLevelMask();
@@ -101,6 +142,9 @@
         this->updateCombinedAdditionalContextsMask();
     }
 
+    /**
+        @brief Updates the combined level mask. The masks of all listeners are ORed to form the combined mask.
+    */
     void OutputManager::updateCombinedLevelMask()
     {
         int mask = 0;
@@ -109,6 +153,9 @@
         this->combinedLevelMask_ = static_cast<OutputLevel>(mask);
     }
 
+    /**
+        @brief Updates the combined additional contexts level mask. The masks of all listeners are ORed to form the combined mask.
+    */
     void OutputManager::updateCombinedAdditionalContextsLevelMask()
     {
         int mask = 0;
@@ -117,6 +164,9 @@
         this->combinedAdditionalContextsLevelMask_ = static_cast<OutputLevel>(mask);
     }
 
+    /**
+        @brief Updates the combined additional contexts mask. The masks of all listeners are ORed to form the combined mask.
+    */
     void OutputManager::updateCombinedAdditionalContextsMask()
     {
         this->combinedAdditionalContextsMask_ = 0;
@@ -124,26 +174,39 @@
             this->combinedAdditionalContextsMask_ |= this->listeners_[i]->getAdditionalContextsMask();
     }
 
+    /**
+        @brief Registers a context (or sub-context) and returns the container which identifies the context.
+        @param name The name of the context
+        @param subname The name of the sub-context (or "" if it is not a sub-context)
+
+        If the context doesn't exist, it gets created. Otherwise the existing instance is returned.
+    */
     const OutputContextContainer& OutputManager::registerContext(const std::string& name, const std::string& subname)
     {
+        // the full name of a context is a combination of name and subname with "::" in between
         std::string full_name = name;
         if (subname != "")
             full_name += "::" + subname;
 
+        // check if the context already exists (and return it if it does)
         std::map<std::string, OutputContextContainer>::iterator it_container = this->contextContainers_.find(full_name);
         if (it_container != this->contextContainers_.end())
             return it_container->second;
 
+        // create a new context container
         OutputContextContainer container;
         container.name = full_name;
 
+        // check if the mask of the main-context already exists
         std::map<std::string, OutputContextMask>::iterator it_mask = this->contextMasks_.find(name);
         if (it_mask != this->contextMasks_.end())
         {
+            // the mask exists, assign it to the container
             container.mask = it_mask->second;
         }
         else
         {
+            // the mask doesn't exist, create it. It's a binary mask. The n-th main-context is defined by the n-th bit in the mask.
             container.mask = static_cast<OutputContextMask>(0x1) << this->contextMasks_.size();
             this->contextMasks_[name] = container.mask;
 
@@ -151,23 +214,33 @@
                 orxout(internal_warning) << "More than " << sizeof(OutputContextMask) * 8 << " output contexts defined. Context '" << name << "' might not get filtered correctly" << endl;
         }
 
+        // if the context is a sub-context, assign a unique ID.
         if (subname == "")
             container.sub_id = context::no_subcontext;
         else
             container.sub_id = ++this->subcontextCounter_; // start with 1
 
+        // add the new context to the map and return it
         return (this->contextContainers_[full_name] = container);
     }
 
+    /**
+        @brief Static function, shortcut to OutputManager::registerContext().
+        The function is declared in OutputDefinitions.h.
+    */
     const OutputContextContainer& registerContext(const std::string& name, const std::string& subname)
     {
         return OutputManager::getInstance().registerContext(name, subname);
     }
 
+    /**
+        @brief Returns a human readable string for each output level.
+    */
     const std::string& OutputManager::getLevelName(OutputLevel level) const
     {
         switch (level)
         {
+            // using static cache variables for speed
             case level::none:               { static std::string name = "None"; return name; }
             case level::message:            { static std::string name = "Message"; return name; }
             case level::debug_output:       { static std::string name = "Debug"; return name; }
@@ -186,8 +259,13 @@
         }
     }
 
+    /**
+        @brief Returns a string containing the name of the level and the context (if any) which
+        can be prepended to an output message if it is written to the console or the log file.
+    */
     std::string OutputManager::getDefaultPrefix(OutputLevel level, const OutputContextContainer& context) const
     {
+        // "undefined" context is ignored because it's used implicitly if no explicit context is defined
         static OutputContextMask undefined_mask = context::undefined().mask;
 
         std::string prefix = this->getLevelName(level) + ": ";

Modified: code/branches/output/src/libraries/util/output/OutputManager.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputManager.h	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/OutputManager.h	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,13 @@
  *
  */
 
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the OutputManager class which receives output from orxonox::OutputStream
+    and distributes it to all instances of orxonox::OutputListener.
+*/
+
 #ifndef _OutputManager_H__
 #define _OutputManager_H__
 
@@ -38,6 +45,21 @@
 
 namespace orxonox
 {
+    /**
+        @brief OutputManager acts as the center of the output system and is implemented as a singleton.
+
+        All instances of OutputStream (and hence also the orxout() function)
+        send their buffered output to OutputManager. OutputManager then
+        distributes this output to all registered instances of OutputListener.
+
+        For each listener OutputManager checks if it wants to receive output
+        with the given level and context. OutputManager itself also maintains
+        masks that define the accepted levels and concept. They are a
+        combination of the masks of all output listeners. See the description
+        of OutputListener for a more conclusive description of these masks.
+
+        Additionally OutputManager is used to register output contexts.
+    */
     class _UtilExport OutputManager
     {
         public:
@@ -54,6 +76,13 @@
             void updateCombinedAdditionalContextsLevelMask();
             void updateCombinedAdditionalContextsMask();
 
+            /**
+                @brief Returns true if at least one of the output listeners will accept output with the given level and context.
+
+                For the sake of performance, output messages with levels or
+                contexts that are not accepted should be ignored or, even
+                better, not generated at all.
+            */
             inline bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const
             {
                 return (this->combinedLevelMask_ & level) ||
@@ -70,15 +99,15 @@
             OutputManager(const OutputManager&);
             ~OutputManager();
 
-            std::vector<OutputListener*> listeners_;
+            std::vector<OutputListener*> listeners_;                            ///< List of all registered output listeners
 
-            OutputLevel       combinedLevelMask_;
-            OutputLevel       combinedAdditionalContextsLevelMask_;
-            OutputContextMask combinedAdditionalContextsMask_;
+            OutputLevel       combinedLevelMask_;                               ///< The combined mask of accepted levels of all listeners
+            OutputLevel       combinedAdditionalContextsLevelMask_;             ///< The combined mask of accepted additional contexts levels of all listeners
+            OutputContextMask combinedAdditionalContextsMask_;                  ///< The combined mask of accepted additional contexts of all listeners
 
-            std::map<std::string, OutputContextMask> contextMasks_;
-            std::map<std::string, OutputContextContainer> contextContainers_;
-            OutputContextSubID subcontextCounter_;
+            std::map<std::string, OutputContextMask> contextMasks_;             ///< Contains all main-contexts and their masks
+            std::map<std::string, OutputContextContainer> contextContainers_;   ///< Contains all contexts including sub-contexts and their containers
+            OutputContextSubID subcontextCounter_;                              ///< Counts the number of sub-contexts (and generates their IDs)
     };
 }
 

Modified: code/branches/output/src/libraries/util/output/OutputStream.cc
===================================================================
--- code/branches/output/src/libraries/util/output/OutputStream.cc	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/OutputStream.cc	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,28 +26,47 @@
  *
  */
 
+/**
+    @file
+    @brief Implementation of the non-generic functions of the OutputStream class.
+*/
+
 #include "OutputStream.h"
 
 #include "OutputManager.h"
 
 namespace orxonox
 {
+    /**
+        @brief Default constructor, initializes level and context with default values.
+    */
     OutputStream::OutputStream()
     {
         this->setOutputAttributes(level::debug_output, context::undefined());
     }
 
+    /**
+        @brief Constructor, initializes level and context with the provided values.
+    */
     OutputStream::OutputStream(OutputLevel level, const OutputContextContainer& context)
     {
         this->setOutputAttributes(level, context);
     }
 
+    /**
+        @brief Sends the buffered message to OutputManager together with the stored level and context.
+        Additionally empties the buffer.
+    */
     void OutputStream::sendMessage()
     {
         OutputManager::getInstanceAndCreateListeners().pushMessage(this->level_, *this->context_, this->str());
         this->str("");
     }
 
+    /**
+        @brief Defines level and context of the following output.
+        Also sets the bAcceptsOutput_ flag according to the masks defined in OutputManager.
+    */
     void OutputStream::setOutputAttributes(OutputLevel level, const OutputContextContainer& context)
     {
         this->level_ = level;

Modified: code/branches/output/src/libraries/util/output/OutputStream.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputStream.h	2011-08-18 20:48:28 UTC (rev 8847)
+++ code/branches/output/src/libraries/util/output/OutputStream.h	2011-08-21 14:04:54 UTC (rev 8848)
@@ -26,6 +26,12 @@
  *
  */
 
+/**
+    @file
+    @ingroup Output
+    @brief Declaration of the OutputStream class which is used to send output to orxonox::OutputManager.
+*/
+
 #ifndef _OutputStream_H__
 #define _OutputStream_H__
 
@@ -37,6 +43,33 @@
 
 namespace orxonox
 {
+    /**
+        @brief This class is used to buffer output and send it to OutputManager whenever std::endl is passed to it.
+
+        OutputStream inherits from std::ostringstream and acts like std::cout.
+        This means you can use the << operator to write output to the stream.
+        This class is used by the orxout() function.
+
+        @attention
+        You must end an output message with std::endl, otherwise the message
+        won't be flushed. '\\n' only adds a new line to the message.
+
+        The following code samples are all equivalent:
+        @code
+        OutputStream stream;
+        stream.setOutputAttributes(user_info, context::example());
+        stream << "Hello World" << endl;
+        @endcode
+
+        @code
+        OutputStream stream(user_info, context::example());
+        stream << "Hello World" << endl;
+        @endcode
+
+        @code
+        orxout(user_info, context::example) << "Hello World" << endl;
+        @endcode
+    */
     class OutputStream : public std::ostringstream
     {
         typedef std::ostream& (*EndlType)(std::ostream&);
@@ -47,23 +80,28 @@
 
             void _UtilExport setOutputAttributes(OutputLevel level, const OutputContextContainer& context);
 
+            /// @brief Generic << operator which adds output to the stream.
             template <class T>
             inline OutputStream& operator<<(const T& val) { return this->output(val); }
+            /// @brief Sends a manipulator to the output stream.
             inline OutputStream& operator<<(std::ios_base& (*manipulator)(std::ios_base&)) { return this->output(manipulator); }
+            /// @brief Sends a manipulator to the output stream.
             inline OutputStream& operator<<(std::ios&      (*manipulator)(std::ios&))      { return this->output(manipulator); }
+            /// @brief Sends a manipulator to the output stream and flushes the message if the manipulator is std::endl.
             inline OutputStream& operator<<(std::ostream&  (*manipulator)(std::ostream&))
             {
                 if (this->bAcceptsOutput_)
                 {
                     if (manipulator == static_cast<EndlType>(std::endl))
-                        this->sendMessage();
+                        this->sendMessage(); // send the message to OutputManager
                     else
-                        return this->output(manipulator);
+                        return this->output(manipulator); // apply the manipulator
                 }
                 return *this;
             }
 
         private:
+            /// @brief Generic function to add values to the output stream, using the inherited << operator from std::ostringstream.
             template <class T>
             inline OutputStream& output(const T& val)
             {
@@ -74,9 +112,9 @@
 
             void _UtilExport sendMessage();
 
-            OutputLevel level_;
-            const OutputContextContainer* context_;
-            bool bAcceptsOutput_;
+            OutputLevel level_;                     ///< The output level of the current message
+            const OutputContextContainer* context_; ///< The output context of the current message
+            bool bAcceptsOutput_;                   ///< After defining level and context of the following message, this flag is set according to the masks defined in OutputManager. If it is false, the OutputStream will throw away every output sent using the << operator.
     };
 }
 




More information about the Orxonox-commit mailing list