[Orxonox-commit 4162] r8833 - in code/branches/output/src/libraries: core core/command util util/output

landauf at orxonox.net landauf at orxonox.net
Thu Aug 11 23:20:39 CEST 2011


Author: landauf
Date: 2011-08-11 23:20:39 +0200 (Thu, 11 Aug 2011)
New Revision: 8833

Modified:
   code/branches/output/src/libraries/core/Core.cc
   code/branches/output/src/libraries/core/command/Shell.cc
   code/branches/output/src/libraries/util/Output.h
   code/branches/output/src/libraries/util/output/BaseWriter.cc
   code/branches/output/src/libraries/util/output/BaseWriter.h
   code/branches/output/src/libraries/util/output/LogWriter.cc
   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:
A context is now defined by a struct instead of only a mask.

Introduced sub-contexts. Sub-contexts of the same main-context share the same mask, but have a different ID.
Main-contexts are filtered using a bitmask which happens for every line of output and is very fast.
Sub-contexts are filtered using a set which is slow but happens only if a specific sub-context is enabled in the config file which is usually not the case.

The concept of filtering normal output + additional contexts was moved from BaseWriter directly to OutputListener and OutputManager which makes the whole system faster.
BaseWriter now calls registerContext() for each configured output context, which basically allows the usage of more than 64 contexts as long as these contexts are not used before loading the config file. Though by design it's not recommended.

Modified: code/branches/output/src/libraries/core/Core.cc
===================================================================
--- code/branches/output/src/libraries/core/Core.cc	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/core/Core.cc	2011-08-11 21:20:39 UTC (rev 8833)
@@ -262,19 +262,19 @@
                                LogWriter::getInstance().getConfigurableMaxLevelName(),
                                LogWriter::getInstance().configurableMaxLevel_)
             .description("The maximum level of output shown in the log file")
-            .callback(static_cast<BaseWriter*>(&LogWriter::getInstance()), &BaseWriter::changedConfigurableLevels);
-        SetConfigValueExternal(LogWriter::getInstance().configurableContextsMaxLevel_,
+            .callback(static_cast<BaseWriter*>(&LogWriter::getInstance()), &BaseWriter::changedConfigurableLevel);
+        SetConfigValueExternal(LogWriter::getInstance().configurableAdditionalContextsMaxLevel_,
                                LogWriter::getInstance().getConfigurableSectionName(),
-                               LogWriter::getInstance().getConfigurableContextsMaxLevelName(),
-                               LogWriter::getInstance().configurableContextsMaxLevel_)
+                               LogWriter::getInstance().getConfigurableAdditionalContextsMaxLevelName(),
+                               LogWriter::getInstance().configurableAdditionalContextsMaxLevel_)
             .description("The maximum level of output shown in the log file for additional contexts")
-            .callback(static_cast<BaseWriter*>(&LogWriter::getInstance()), &BaseWriter::changedConfigurableLevels);
-        SetConfigValueExternal(LogWriter::getInstance().configurableContexts_,
+            .callback(static_cast<BaseWriter*>(&LogWriter::getInstance()), &BaseWriter::changedConfigurableAdditionalContextsLevel);
+        SetConfigValueExternal(LogWriter::getInstance().configurableAdditionalContexts_,
                                LogWriter::getInstance().getConfigurableSectionName(),
-                               LogWriter::getInstance().getConfigurableContextsName(),
-                               LogWriter::getInstance().configurableContexts_)
+                               LogWriter::getInstance().getConfigurableAdditionalContextsName(),
+                               LogWriter::getInstance().configurableAdditionalContexts_)
             .description("Additional output contexts shown in the log file")
-            .callback(static_cast<BaseWriter*>(&LogWriter::getInstance()), &BaseWriter::changedConfigurableContexts);
+            .callback(static_cast<BaseWriter*>(&LogWriter::getInstance()), &BaseWriter::changedConfigurableAdditionalContexts);
 
         SetConfigValue(bDevMode_, PathConfig::buildDirectoryRun())
             .description("Developer mode. If not set, hides some things from the user to not confuse him.")

Modified: code/branches/output/src/libraries/core/command/Shell.cc
===================================================================
--- code/branches/output/src/libraries/core/command/Shell.cc	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/core/command/Shell.cc	2011-08-11 21:20:39 UTC (rev 8833)
@@ -122,19 +122,19 @@
                                this->getConfigurableMaxLevelName(),
                                this->configurableMaxLevel_)
             .description("The maximum level of output shown in the " + this->getName())
-            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableLevels);
-        SetConfigValueExternal(this->configurableContextsMaxLevel_,
+            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableLevel);
+        SetConfigValueExternal(this->configurableAdditionalContextsMaxLevel_,
                                this->getConfigurableSectionName(),
-                               this->getConfigurableContextsMaxLevelName(),
-                               this->configurableContextsMaxLevel_)
+                               this->getConfigurableAdditionalContextsMaxLevelName(),
+                               this->configurableAdditionalContextsMaxLevel_)
             .description("The maximum level of output shown in the " + this->getName() + " for additional contexts")
-            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableLevels);
-        SetConfigValueExternal(this->configurableContexts_,
+            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableAdditionalContextsLevel);
+        SetConfigValueExternal(this->configurableAdditionalContexts_,
                                this->getConfigurableSectionName(),
-                               this->getConfigurableContextsName(),
-                               this->configurableContexts_)
+                               this->getConfigurableAdditionalContextsName(),
+                               this->configurableAdditionalContexts_)
             .description("Additional output contexts shown in the " + this->getName())
-            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableContexts);
+            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableAdditionalContexts);
     }
 
     /**

Modified: code/branches/output/src/libraries/util/Output.h
===================================================================
--- code/branches/output/src/libraries/util/Output.h	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/Output.h	2011-08-11 21:20:39 UTC (rev 8833)
@@ -37,7 +37,7 @@
     // Just for convenience
     using std::endl;
 
-    inline OutputStream& orxout(OutputLevel level = level::debug_output, OutputContext context = context::undefined())
+    inline OutputStream& orxout(OutputLevel level = level::debug_output, const OutputContextContainer& context = context::undefined())
     {
         static OutputStream stream;
         stream.setOutputAttributes(level, context);

Modified: code/branches/output/src/libraries/util/output/BaseWriter.cc
===================================================================
--- code/branches/output/src/libraries/util/output/BaseWriter.cc	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/BaseWriter.cc	2011-08-11 21:20:39 UTC (rev 8833)
@@ -37,18 +37,23 @@
         this->name_ = name;
 
         this->configurableMaxLevel_ = level::none;
-        this->configurableContextsMaxLevel_ = level::verbose;
-        this->configurableContexts_.push_back("example");
-        this->changedConfigurableLevels();
+        this->configurableAdditionalContextsMaxLevel_ = level::verbose;
+        this->configurableAdditionalContexts_.push_back("example");
+
+        this->subcontextsCheckMask_ = context::none;
+
+        this->changedConfigurableLevel();
+        this->changedConfigurableAdditionalContextsLevel();
+        this->changedConfigurableAdditionalContexts();
     }
 
     BaseWriter::~BaseWriter()
     {
     }
 
-    void BaseWriter::output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
+    void BaseWriter::output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
     {
-        if (level <= this->configurableMaxLevel_ || (level <= this->configurableContextsMaxLevel_ && this->isAdditionalContext(context)))
+        if (((this->subcontextsCheckMask_ & context.mask) == 0) || (this->subcontexts_.find(context.sub_id) != this->subcontexts_.end()))
         {
             const std::string& prefix = OutputManager::getInstance().getDefaultPrefix(level, context);
             std::string blanks(prefix.length(), ' ');
@@ -61,26 +66,58 @@
     void BaseWriter::setLevelMax(OutputLevel max)
     {
         this->configurableMaxLevel_ = max;
-        this->changedConfigurableLevels();
+        this->changedConfigurableLevel();
     }
 
-    void BaseWriter::changedConfigurableLevels()
+    void BaseWriter::setAdditionalContextsLevelMax(OutputLevel max)
     {
-        int max_level = std::max(this->configurableMaxLevel_, this->configurableContextsMaxLevel_);
-        OutputListener::setLevelMax(static_cast<OutputLevel>(max_level));
+        this->configurableAdditionalContextsMaxLevel_ = max;
+        this->changedConfigurableAdditionalContextsLevel();
     }
 
-    void BaseWriter::changedConfigurableContexts()
+    void BaseWriter::changedConfigurableLevel()
     {
-        this->configurableContextsSet_.clear();
-        for (size_t i = 0; i < this->configurableContexts_.size(); ++i)
-            this->configurableContextsSet_.insert(this->configurableContexts_[i]);
+        OutputListener::setLevelMax(static_cast<OutputLevel>(this->configurableMaxLevel_));
     }
 
-    bool BaseWriter::isAdditionalContext(OutputContext context) const
+    void BaseWriter::changedConfigurableAdditionalContextsLevel()
     {
-        const std::string& name = OutputManager::getInstance().getContextName(context);
-        std::set<std::string>::const_iterator it = this->configurableContextsSet_.find(name);
-        return (it != this->configurableContextsSet_.end());
+        OutputListener::setAdditionalContextsLevelMax(static_cast<OutputLevel>(this->configurableAdditionalContextsMaxLevel_));
     }
+
+    void BaseWriter::changedConfigurableAdditionalContexts()
+    {
+        OutputContextMask context_mask = context::none;
+        this->subcontextsCheckMask_ = context::none;
+
+        this->subcontexts_.clear();
+        this->subcontexts_.insert(context::no_subcontext);
+
+        for (size_t i = 0; i < this->configurableAdditionalContexts_.size(); ++i)
+        {
+            const std::string& full_name = this->configurableAdditionalContexts_[i];
+
+            std::string name = full_name;
+            std::string subname;
+
+            size_t pos = full_name.find("::");
+            if (pos != std::string::npos)
+            {
+                name = full_name.substr(0, pos);
+                subname = full_name.substr(pos + 2);
+            }
+
+            const OutputContextContainer& container = OutputManager::getInstance().registerContext(name, subname);
+
+            context_mask |= container.mask;
+
+            if (container.sub_id != context::no_subcontext)
+            {
+                this->subcontexts_.insert(container.sub_id);
+                this->subcontextsCheckMask_ |= container.mask;
+            }
+        }
+
+        this->setAdditionalContextsMask(context_mask);
+    }
 }

Modified: code/branches/output/src/libraries/util/output/BaseWriter.h
===================================================================
--- code/branches/output/src/libraries/util/output/BaseWriter.h	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/BaseWriter.h	2011-08-11 21:20:39 UTC (rev 8833)
@@ -44,31 +44,33 @@
             BaseWriter(const std::string& name);
             virtual ~BaseWriter();
 
+            void setLevelMax(OutputLevel max);
+            void setAdditionalContextsLevelMax(OutputLevel max);
+
             const std::string& getName() const
                 { return this->name_; }
 
-            void setLevelMax(OutputLevel max);
-
             int configurableMaxLevel_;
             inline std::string getConfigurableMaxLevelName() const
-                { return "outputLevel" + this->name_; }
+                { return this->name_ + "Level"; }
 
-            int configurableContextsMaxLevel_;
-            inline std::string getConfigurableContextsMaxLevelName() const
-                { return "outputContextsLevel" + this->name_; }
+            int configurableAdditionalContextsMaxLevel_;
+            inline std::string getConfigurableAdditionalContextsMaxLevelName() const
+                { return this->name_ + "AdditionalContextsLevel"; }
 
-            std::vector<std::string> configurableContexts_;
-            inline std::string getConfigurableContextsName() const
-                { return "outputContexts" + this->name_; }
+            std::vector<std::string> configurableAdditionalContexts_;
+            inline std::string getConfigurableAdditionalContextsName() const
+                { return this->name_ + "AdditionalContexts"; }
 
-            void changedConfigurableLevels();
-            void changedConfigurableContexts();
+            void changedConfigurableLevel();
+            void changedConfigurableAdditionalContextsLevel();
+            void changedConfigurableAdditionalContexts();
 
             static inline std::string getConfigurableSectionName()
                 { return "Output"; }
 
         protected:
-            virtual void output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines);
+            virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines);
 
         private:
             virtual void printLine(const std::string& line, OutputLevel level) = 0;
@@ -76,10 +78,13 @@
             void setLevelRange(OutputLevel min, OutputLevel max);
             void setLevelMask(OutputLevel mask);
 
-            bool isAdditionalContext(OutputContext context) const;
+            void setAdditionalContextsLevelRange(OutputLevel min, OutputLevel max);
+            void setAdditionalContextsLevelMask(OutputLevel mask);
 
             std::string name_;
-            std::set<std::string> configurableContextsSet_;
+
+            OutputContextMask subcontextsCheckMask_;
+            std::set<OutputContextSubID> subcontexts_;
     };
 }
 

Modified: code/branches/output/src/libraries/util/output/LogWriter.cc
===================================================================
--- code/branches/output/src/libraries/util/output/LogWriter.cc	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/LogWriter.cc	2011-08-11 21:20:39 UTC (rev 8833)
@@ -29,6 +29,7 @@
 #include "LogWriter.h"
 
 #include <ctime>
+#include <cstdlib>
 
 #include "OutputManager.h"
 #include "MemoryWriter.h"

Modified: code/branches/output/src/libraries/util/output/MemoryWriter.cc
===================================================================
--- code/branches/output/src/libraries/util/output/MemoryWriter.cc	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/MemoryWriter.cc	2011-08-11 21:20:39 UTC (rev 8833)
@@ -47,7 +47,7 @@
         return instance;
     }
 
-    void MemoryWriter::output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
+    void MemoryWriter::output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
     {
         this->messages_.push_back(Message(level, context, lines));
     }
@@ -57,7 +57,7 @@
         for (size_t i = 0; i < this->messages_.size(); ++i)
         {
             const Message& message = this->messages_[i];
-            listener->unfilteredOutput(message.level, message.context, message.lines);
+            listener->unfilteredOutput(message.level, *message.context, message.lines);
         }
     }
 

Modified: code/branches/output/src/libraries/util/output/MemoryWriter.h
===================================================================
--- code/branches/output/src/libraries/util/output/MemoryWriter.h	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/MemoryWriter.h	2011-08-11 21:20:39 UTC (rev 8833)
@@ -38,11 +38,11 @@
     {
         struct Message
         {
-            Message(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
-                : level(level), context(context), lines(lines) {}
+            Message(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)
+                : level(level), context(&context), lines(lines) {}
 
             OutputLevel level;
-            OutputContext context;
+            const OutputContextContainer* context;
             std::vector<std::string> lines;
         };
 
@@ -53,7 +53,7 @@
             void disable();
 
         protected:
-            virtual void output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines);
+            virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines);
 
         private:
             MemoryWriter();

Modified: code/branches/output/src/libraries/util/output/OutputDefinitions.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputDefinitions.h	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/OutputDefinitions.h	2011-08-11 21:20:39 UTC (rev 8833)
@@ -33,8 +33,11 @@
 #include <string>
 
 #define REGISTER_OUTPUT_CONTEXT(name) \
-    OutputContext name() { static OutputContext context = registerContext(#name); return context; }
+    const OutputContextContainer& name() { static const OutputContextContainer& context = registerContext(#name); return context; }
 
+#define REGISTER_OUTPUT_SUBCONTEXT(name, subname) \
+    const OutputContextContainer& subname() { static const OutputContextContainer& context = registerContext(#name, #subname); return context; }
+
 namespace orxonox
 {
     namespace level
@@ -62,16 +65,27 @@
 
     using namespace level;
 
-    typedef uint64_t OutputContext;
-    typedef OutputContext (OutputContextFunction)();
+    typedef uint64_t OutputContextMask;
+    typedef uint16_t OutputContextSubID;
 
-    extern _UtilExport OutputContext registerContext(const std::string& name);
+    struct OutputContextContainer
+    {
+        OutputContextMask mask;
+        OutputContextSubID sub_id;
+        std::string name;
+    };
 
+    typedef const OutputContextContainer& (OutputContextFunction)();
+
+    extern _UtilExport const OutputContextContainer& registerContext(const std::string& name, const std::string& subname = "");
+
     namespace context
     {
-        static const OutputContext all       = 0xFFFFFFFFFFFFFFFF;
-        static const OutputContext none      = 0x0000000000000000;
+        static const OutputContextMask all       = 0xFFFFFFFFFFFFFFFF;
+        static const OutputContextMask none      = 0x0000000000000000;
 
+        static const OutputContextSubID no_subcontext = 0;
+
         namespace
         {
             REGISTER_OUTPUT_CONTEXT(undefined);
@@ -102,6 +116,52 @@
             REGISTER_OUTPUT_CONTEXT(notifications);
             REGISTER_OUTPUT_CONTEXT(triggers);
             REGISTER_OUTPUT_CONTEXT(docking);
+
+            namespace misc
+            {
+                REGISTER_OUTPUT_SUBCONTEXT(misc, testcontext1);
+                REGISTER_OUTPUT_SUBCONTEXT(misc, testcontext2);
+                REGISTER_OUTPUT_SUBCONTEXT(misc, testcontext3);
+                REGISTER_OUTPUT_SUBCONTEXT(misc, testcontext4);
+            }
+
+            REGISTER_OUTPUT_CONTEXT(c30);
+            REGISTER_OUTPUT_CONTEXT(c31);
+            REGISTER_OUTPUT_CONTEXT(c32);
+            REGISTER_OUTPUT_CONTEXT(c33);
+            REGISTER_OUTPUT_CONTEXT(c34);
+            REGISTER_OUTPUT_CONTEXT(c35);
+            REGISTER_OUTPUT_CONTEXT(c36);
+            REGISTER_OUTPUT_CONTEXT(c37);
+            REGISTER_OUTPUT_CONTEXT(c38);
+            REGISTER_OUTPUT_CONTEXT(c39);
+            REGISTER_OUTPUT_CONTEXT(c40);
+            REGISTER_OUTPUT_CONTEXT(c41);
+            REGISTER_OUTPUT_CONTEXT(c42);
+            REGISTER_OUTPUT_CONTEXT(c43);
+            REGISTER_OUTPUT_CONTEXT(c44);
+            REGISTER_OUTPUT_CONTEXT(c45);
+            REGISTER_OUTPUT_CONTEXT(c46);
+            REGISTER_OUTPUT_CONTEXT(c47);
+            REGISTER_OUTPUT_CONTEXT(c48);
+            REGISTER_OUTPUT_CONTEXT(c49);
+            REGISTER_OUTPUT_CONTEXT(c50);
+            REGISTER_OUTPUT_CONTEXT(c51);
+            REGISTER_OUTPUT_CONTEXT(c52);
+            REGISTER_OUTPUT_CONTEXT(c53);
+            REGISTER_OUTPUT_CONTEXT(c54);
+            REGISTER_OUTPUT_CONTEXT(c55);
+            REGISTER_OUTPUT_CONTEXT(c56);
+            REGISTER_OUTPUT_CONTEXT(c57);
+            REGISTER_OUTPUT_CONTEXT(c58);
+            REGISTER_OUTPUT_CONTEXT(c59);
+            REGISTER_OUTPUT_CONTEXT(c60);
+            REGISTER_OUTPUT_CONTEXT(c61);
+            REGISTER_OUTPUT_CONTEXT(c62);
+            REGISTER_OUTPUT_CONTEXT(c63);
+            REGISTER_OUTPUT_CONTEXT(c64);
+            REGISTER_OUTPUT_CONTEXT(c65);
+            REGISTER_OUTPUT_CONTEXT(c66);
         }
     }
 }

Modified: code/branches/output/src/libraries/util/output/OutputListener.cc
===================================================================
--- code/branches/output/src/libraries/util/output/OutputListener.cc	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/OutputListener.cc	2011-08-11 21:20:39 UTC (rev 8833)
@@ -35,7 +35,8 @@
     OutputListener::OutputListener()
     {
         this->levelMask_ = level::none;
-        this->contextMask_ = context::all;
+        this->additionalContextsLevelMask_ = level::none;
+        this->additionalContextsMask_ = context::none;
 
         OutputManager::getInstance().registerListener(this);
     }
@@ -66,10 +67,31 @@
         OutputManager::getInstance().updateCombinedLevelMask();
     }
 
-    void OutputListener::setContextMask(OutputContext mask)
+    void OutputListener::setAdditionalContextsLevelMax(OutputLevel max)
     {
-        this->contextMask_ = mask;
+        this->setAdditionalContextsLevelRange(static_cast<OutputLevel>(0x1), max);
+    }
 
-        OutputManager::getInstance().updateCombinedContextMask();
+    void OutputListener::setAdditionalContextsLevelRange(OutputLevel min, OutputLevel max)
+    {
+        int mask = 0;
+        for (int level = min; level <= max; level = level << 1)
+            mask |= level;
+
+        this->setAdditionalContextsLevelMask(static_cast<OutputLevel>(mask));
     }
+
+    void OutputListener::setAdditionalContextsLevelMask(OutputLevel mask)
+    {
+        this->additionalContextsLevelMask_ = mask;
+
+        OutputManager::getInstance().updateCombinedAdditionalContextsLevelMask();
+    }
+
+    void OutputListener::setAdditionalContextsMask(OutputContextMask mask)
+    {
+        this->additionalContextsMask_ = mask;
+
+        OutputManager::getInstance().updateCombinedAdditionalContextsMask();
+    }
 }

Modified: code/branches/output/src/libraries/util/output/OutputListener.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputListener.h	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/OutputListener.h	2011-08-11 21:20:39 UTC (rev 8833)
@@ -47,26 +47,34 @@
             void setLevelRange(OutputLevel min, OutputLevel max);
             void setLevelMask(OutputLevel mask);
 
+            void setAdditionalContextsLevelMax(OutputLevel max);
+            void setAdditionalContextsLevelRange(OutputLevel min, OutputLevel max);
+            void setAdditionalContextsLevelMask(OutputLevel mask);
+
+            void setAdditionalContextsMask(OutputContextMask mask);
+
             inline OutputLevel getLevelMask() const
                 { return this->levelMask_; }
+            inline OutputLevel getAdditionalContextsLevelMask() const
+                { return this->additionalContextsLevelMask_; }
+            inline OutputContextMask getAdditionalContextsMask() const
+                { return this->additionalContextsMask_; }
 
-            void setContextMask(OutputContext mask);
+            inline bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const
+            {
+                return (this->levelMask_ & level) ||
+                       ((this->additionalContextsLevelMask_ & level) && (this->additionalContextsMask_ & context.mask)); }
 
-            inline OutputContext getContextMask() const
-                { return this->contextMask_; }
-
-            inline bool acceptsOutput(OutputLevel level, OutputContext context) const
-                { return ((this->levelMask_ & level) && (this->contextMask_ & context)); }
-
-            inline void unfilteredOutput(OutputLevel level, OutputContext context, const std::vector<std::string>& lines)
+            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:
-            virtual void output(OutputLevel level, OutputContext context, const std::vector<std::string>& lines) = 0;
+            virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines) = 0;
 
         private:
-            OutputLevel   levelMask_;
-            OutputContext contextMask_;
+            OutputLevel       levelMask_;
+            OutputLevel       additionalContextsLevelMask_;
+            OutputContextMask additionalContextsMask_;
     };
 }
 

Modified: code/branches/output/src/libraries/util/output/OutputManager.cc
===================================================================
--- code/branches/output/src/libraries/util/output/OutputManager.cc	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/OutputManager.cc	2011-08-11 21:20:39 UTC (rev 8833)
@@ -31,6 +31,7 @@
 #include "MemoryWriter.h"
 #include "ConsoleWriter.h"
 #include "LogWriter.h"
+#include "util/Output.h"
 #include "util/StringUtils.h"
 
 namespace orxonox
@@ -38,7 +39,10 @@
     OutputManager::OutputManager()
     {
         this->combinedLevelMask_ = level::none;
-        this->combinedContextMask_ = 0;
+        this->combinedAdditionalContextsLevelMask_ = level::none;
+        this->combinedAdditionalContextsMask_ = context::none;
+
+        this->subcontextCounter_ = 0;
     }
 
     OutputManager::~OutputManager()
@@ -62,7 +66,7 @@
         return instance;
     }
 
-    void OutputManager::pushMessage(OutputLevel level, OutputContext context, const std::string& message)
+    void OutputManager::pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message)
     {
         std::vector<std::string> lines;
         vectorize(message, '\n', &lines);
@@ -93,7 +97,8 @@
     void OutputManager::updateMasks()
     {
         this->updateCombinedLevelMask();
-        this->updateCombinedContextMask();
+        this->updateCombinedAdditionalContextsLevelMask();
+        this->updateCombinedAdditionalContextsMask();
     }
 
     void OutputManager::updateCombinedLevelMask()
@@ -104,31 +109,59 @@
         this->combinedLevelMask_ = static_cast<OutputLevel>(mask);
     }
 
-    void OutputManager::updateCombinedContextMask()
+    void OutputManager::updateCombinedAdditionalContextsLevelMask()
     {
-        this->combinedContextMask_ = 0;
+        int mask = 0;
         for (size_t i = 0; i < this->listeners_.size(); ++i)
-            this->combinedContextMask_ |= this->listeners_[i]->getContextMask();
+            mask |= this->listeners_[i]->getAdditionalContextsLevelMask();
+        this->combinedAdditionalContextsLevelMask_ = static_cast<OutputLevel>(mask);
     }
 
-    OutputContext OutputManager::registerContext(const std::string& name)
+    void OutputManager::updateCombinedAdditionalContextsMask()
     {
-        boost::bimap<OutputContext, std::string>::right_map::iterator it = this->contexts_.right.find(name);
-        if (it == this->contexts_.right.end())
+        this->combinedAdditionalContextsMask_ = 0;
+        for (size_t i = 0; i < this->listeners_.size(); ++i)
+            this->combinedAdditionalContextsMask_ |= this->listeners_[i]->getAdditionalContextsMask();
+    }
+
+    const OutputContextContainer& OutputManager::registerContext(const std::string& name, const std::string& subname)
+    {
+        std::string full_name = name;
+        if (subname != "")
+            full_name += "::" + subname;
+
+        std::map<std::string, OutputContextContainer>::iterator it_container = this->contextContainers_.find(full_name);
+        if (it_container != this->contextContainers_.end())
+            return it_container->second;
+
+        OutputContextContainer container;
+        container.name = full_name;
+
+        std::map<std::string, OutputContextMask>::iterator it_mask = this->contextMasks_.find(name);
+        if (it_mask != this->contextMasks_.end())
         {
-            OutputContext context = 0x1 << this->contexts_.size();
-            this->contexts_.insert(boost::bimap<OutputContext, std::string>::value_type(context, name));
-            return context;
+            container.mask = it_mask->second;
         }
         else
         {
-            return it->second;
+            container.mask = static_cast<OutputContextMask>(0x1) << this->contextMasks_.size();
+            this->contextMasks_[name] = container.mask;
+
+            if (container.mask == 0)
+                orxout(internal_warning) << "More than " << sizeof(OutputContextMask) * 8 << " output contexts defined. Context '" << name << "' might not get filtered correctly" << endl;
         }
+
+        if (subname == "")
+            container.sub_id = context::no_subcontext;
+        else
+            container.sub_id = ++this->subcontextCounter_; // start with 1
+
+        return (this->contextContainers_[full_name] = container);
     }
 
-    OutputContext registerContext(const std::string& name)
+    const OutputContextContainer& registerContext(const std::string& name, const std::string& subname)
     {
-        return OutputManager::getInstance().registerContext(name);
+        return OutputManager::getInstance().registerContext(name, subname);
     }
 
     const std::string& OutputManager::getLevelName(OutputLevel level) const
@@ -153,58 +186,14 @@
         }
     }
 
-    const std::string& OutputManager::getContextName(OutputContext context) const
+    std::string OutputManager::getDefaultPrefix(OutputLevel level, const OutputContextContainer& context) const
     {
-        if (context != context::undefined())
-        {
-            boost::bimap<OutputContext, std::string>::left_map::const_iterator it = this->contexts_.left.find(context);
-            if (it != this->contexts_.left.end())
-                return it->second;
-        }
-        return BLANKSTRING;
-    }
+        static OutputContextMask undefined_mask = context::undefined().mask;
 
-    OutputContext OutputManager::getContextValue(const std::string& name) const
-    {
-        boost::bimap<OutputContext, std::string>::right_map::const_iterator it = this->contexts_.right.find(name);
-        if (it != this->contexts_.right.end())
-            return it->second;
-        else
-            return context::none;
-    }
-
-    std::string OutputManager::getComposedContextName(OutputContext context) const
-    {
-        std::string name;
-        size_t counter = 0;
-        for (OutputContext context_test = 0x1; context_test != 0x0; context_test = context_test << 1)
-        {
-            if (context & context_test)
-            {
-                boost::bimap<OutputContext, std::string>::left_map::const_iterator it = this->contexts_.left.find(context_test);
-                if (it != this->contexts_.left.end())
-                {
-                    if (counter)
-                        name += ", ";
-
-                    name += it->second;
-                    ++counter;
-                }
-            }
-        }
-        return name;
-    }
-
-    std::string OutputManager::getDefaultPrefix(OutputLevel level, OutputContext context) const
-    {
         std::string prefix = this->getLevelName(level) + ": ";
-        if (context != context::undefined())
-        {
-            std::string context_name = this->getContextName(context);
-            if (context_name == "")
-                context_name = this->getComposedContextName(context);
-            prefix += "[" + context_name + "] ";
-        }
+        if (context.mask != undefined_mask)
+            prefix += "[" + context.name + "] ";
+
         return prefix;
     }
 }

Modified: code/branches/output/src/libraries/util/output/OutputManager.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputManager.h	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/OutputManager.h	2011-08-11 21:20:39 UTC (rev 8833)
@@ -32,7 +32,7 @@
 #include "util/UtilPrereqs.h"
 
 #include <vector>
-#include <boost/bimap.hpp>
+#include <map>
 
 #include "OutputDefinitions.h"
 
@@ -44,32 +44,27 @@
             static OutputManager& getInstance();
             static OutputManager& getInstanceAndCreateListeners();
 
-            void pushMessage(OutputLevel level, OutputContext context, const std::string& message);
+            void pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message);
 
             void registerListener(OutputListener* listener);
             void unregisterListener(OutputListener* listener);
 
             void updateMasks();
             void updateCombinedLevelMask();
-            void updateCombinedContextMask();
+            void updateCombinedAdditionalContextsLevelMask();
+            void updateCombinedAdditionalContextsMask();
 
-            inline OutputLevel getCombinedLevelMask() const
-                { return this->combinedLevelMask_; }
-            inline OutputContext getCombinedContextMask() const
-                { return this->combinedContextMask_; }
+            inline bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const
+            {
+                return (this->combinedLevelMask_ & level) ||
+                       ((this->combinedAdditionalContextsLevelMask_ & level) && (this->combinedAdditionalContextsMask_ & context.mask));
+            }
 
-            inline bool acceptsOutput(OutputLevel level, OutputContext context) const
-                { return ((this->combinedLevelMask_ & level) && (this->combinedContextMask_ & context)); }
+            const OutputContextContainer& registerContext(const std::string& name, const std::string& subname = "");
 
-            OutputContext registerContext(const std::string& name);
-
             const std::string& getLevelName(OutputLevel level) const;
-            const std::string& getContextName(OutputContext context) const;
-            OutputContext getContextValue(const std::string& name) const;
+            std::string getDefaultPrefix(OutputLevel level, const OutputContextContainer& context) const;
 
-            std::string getComposedContextName(OutputContext context) const;
-            std::string getDefaultPrefix(OutputLevel level, OutputContext context) const;
-
         private:
             OutputManager();
             OutputManager(const OutputManager&);
@@ -77,10 +72,13 @@
 
             std::vector<OutputListener*> listeners_;
 
-            OutputLevel   combinedLevelMask_;
-            OutputContext combinedContextMask_;
+            OutputLevel       combinedLevelMask_;
+            OutputLevel       combinedAdditionalContextsLevelMask_;
+            OutputContextMask combinedAdditionalContextsMask_;
 
-            boost::bimap<OutputContext, std::string> contexts_;
+            std::map<std::string, OutputContextMask> contextMasks_;
+            std::map<std::string, OutputContextContainer> contextContainers_;
+            OutputContextSubID subcontextCounter_;
     };
 }
 

Modified: code/branches/output/src/libraries/util/output/OutputStream.cc
===================================================================
--- code/branches/output/src/libraries/util/output/OutputStream.cc	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/OutputStream.cc	2011-08-11 21:20:39 UTC (rev 8833)
@@ -37,21 +37,21 @@
         this->setOutputAttributes(level::debug_output, context::undefined());
     }
 
-    OutputStream::OutputStream(OutputLevel level, OutputContext context)
+    OutputStream::OutputStream(OutputLevel level, const OutputContextContainer& context)
     {
         this->setOutputAttributes(level, context);
     }
 
     void OutputStream::sendMessage()
     {
-        OutputManager::getInstanceAndCreateListeners().pushMessage(this->level_, this->context_, this->str());
+        OutputManager::getInstanceAndCreateListeners().pushMessage(this->level_, *this->context_, this->str());
         this->str("");
     }
 
-    void OutputStream::setOutputAttributes(OutputLevel level, OutputContext context)
+    void OutputStream::setOutputAttributes(OutputLevel level, const OutputContextContainer& context)
     {
         this->level_ = level;
-        this->context_ = context;
+        this->context_ = &context;
 
         this->bAcceptsOutput_ = OutputManager::getInstanceAndCreateListeners().acceptsOutput(level, context);
     }

Modified: code/branches/output/src/libraries/util/output/OutputStream.h
===================================================================
--- code/branches/output/src/libraries/util/output/OutputStream.h	2011-08-08 22:37:21 UTC (rev 8832)
+++ code/branches/output/src/libraries/util/output/OutputStream.h	2011-08-11 21:20:39 UTC (rev 8833)
@@ -43,9 +43,9 @@
 
         public:
             _UtilExport OutputStream();
-            _UtilExport OutputStream(OutputLevel level, OutputContext context);
+            _UtilExport OutputStream(OutputLevel level, const OutputContextContainer& context);
 
-            void _UtilExport setOutputAttributes(OutputLevel level, OutputContext context);
+            void _UtilExport setOutputAttributes(OutputLevel level, const OutputContextContainer& context);
 
             template <class T>
             inline OutputStream& operator<<(const T& val) { return this->output(val); }
@@ -75,7 +75,7 @@
             void _UtilExport sendMessage();
 
             OutputLevel level_;
-            OutputContext context_;
+            const OutputContextContainer* context_;
             bool bAcceptsOutput_;
     };
 }




More information about the Orxonox-commit mailing list