| 1 | /* | 
|---|
| 2 | *   ORXONOX - the hottest 3D action shooter ever to exist | 
|---|
| 3 | *                    > www.orxonox.net < | 
|---|
| 4 | * | 
|---|
| 5 | * | 
|---|
| 6 | *   License notice: | 
|---|
| 7 | * | 
|---|
| 8 | *   This program is free software; you can redistribute it and/or | 
|---|
| 9 | *   modify it under the terms of the GNU General Public License | 
|---|
| 10 | *   as published by the Free Software Foundation; either version 2 | 
|---|
| 11 | *   of the License, or (at your option) any later version. | 
|---|
| 12 | * | 
|---|
| 13 | *   This program is distributed in the hope that it will be useful, | 
|---|
| 14 | *   but WITHOUT ANY WARRANTY; without even the implied warranty of | 
|---|
| 15 | *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
|---|
| 16 | *   GNU General Public License for more details. | 
|---|
| 17 | * | 
|---|
| 18 | *   You should have received a copy of the GNU General Public License | 
|---|
| 19 | *   along with this program; if not, write to the Free Software | 
|---|
| 20 | *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA. | 
|---|
| 21 | * | 
|---|
| 22 | *   Author: | 
|---|
| 23 | *      Fabian 'x3n' Landau | 
|---|
| 24 | *   Co-authors: | 
|---|
| 25 | *      ... | 
|---|
| 26 | * | 
|---|
| 27 | */ | 
|---|
| 28 |  | 
|---|
| 29 | /** | 
|---|
| 30 | @file | 
|---|
| 31 | @ingroup Output | 
|---|
| 32 | @brief Declaration of the OutputManager class which receives output from orxonox::OutputStream | 
|---|
| 33 | and distributes it to all instances of orxonox::OutputListener. | 
|---|
| 34 | */ | 
|---|
| 35 |  | 
|---|
| 36 | #ifndef _OutputManager_H__ | 
|---|
| 37 | #define _OutputManager_H__ | 
|---|
| 38 |  | 
|---|
| 39 | #include "util/UtilPrereqs.h" | 
|---|
| 40 |  | 
|---|
| 41 | #include <vector> | 
|---|
| 42 | #include <map> | 
|---|
| 43 | #include <memory> | 
|---|
| 44 |  | 
|---|
| 45 | #include "OutputDefinitions.h" | 
|---|
| 46 | #include "AdditionalContextListener.h" | 
|---|
| 47 |  | 
|---|
| 48 | namespace orxonox | 
|---|
| 49 | { | 
|---|
| 50 | /** | 
|---|
| 51 | @brief OutputManager acts as the center of the output system and is implemented as a singleton. | 
|---|
| 52 |  | 
|---|
| 53 | All instances of OutputStream (and hence also the orxout() function) | 
|---|
| 54 | send their buffered output to OutputManager. OutputManager then | 
|---|
| 55 | distributes this output to all registered instances of OutputListener. | 
|---|
| 56 |  | 
|---|
| 57 | For each listener OutputManager checks if it wants to receive output | 
|---|
| 58 | with the given level and context. OutputManager itself also maintains | 
|---|
| 59 | masks that define the accepted levels and concept. They are a | 
|---|
| 60 | combination of the masks of all output listeners. See the description | 
|---|
| 61 | of OutputListener for a more conclusive description of these masks. | 
|---|
| 62 |  | 
|---|
| 63 | Additionally OutputManager is used to register output contexts. | 
|---|
| 64 | */ | 
|---|
| 65 | class _UtilExport OutputManager : public AdditionalContextListener | 
|---|
| 66 | { | 
|---|
| 67 | public: | 
|---|
| 68 | OutputManager(); | 
|---|
| 69 | virtual ~OutputManager(); | 
|---|
| 70 |  | 
|---|
| 71 | static OutputManager& getInstance(); | 
|---|
| 72 | static OutputManager& getInstanceAndCreateListeners(); | 
|---|
| 73 |  | 
|---|
| 74 | inline MemoryWriter* getMemoryWriter()   { return this->memoryWriterInstance_; } | 
|---|
| 75 | inline ConsoleWriter* getConsoleWriter() { return this->consoleWriterInstance_; } | 
|---|
| 76 | inline LogWriter* getLogWriter()         { return this->logWriterInstance_; } | 
|---|
| 77 |  | 
|---|
| 78 | virtual void pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message); | 
|---|
| 79 |  | 
|---|
| 80 | virtual void registerListener(OutputListener* listener); | 
|---|
| 81 | virtual void unregisterListener(OutputListener* listener); | 
|---|
| 82 |  | 
|---|
| 83 | virtual void updatedLevelMask(const OutputListener* listener) override | 
|---|
| 84 | { this->updateCombinedLevelMask(); } | 
|---|
| 85 | virtual void updatedAdditionalContextsLevelMask(const OutputListener* listener) override | 
|---|
| 86 | { this->updateCombinedAdditionalContextsLevelMask(); } | 
|---|
| 87 | virtual void updatedAdditionalContextsMask(const OutputListener* listener) override | 
|---|
| 88 | { this->updateCombinedAdditionalContextsMask(); } | 
|---|
| 89 |  | 
|---|
| 90 | /** | 
|---|
| 91 | @brief Returns true if at least one of the output listeners will accept output with the given level and context. | 
|---|
| 92 |  | 
|---|
| 93 | For the sake of performance, output messages with levels or | 
|---|
| 94 | contexts that are not accepted should be ignored or, even | 
|---|
| 95 | better, not generated at all. | 
|---|
| 96 | */ | 
|---|
| 97 | inline bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const | 
|---|
| 98 | { | 
|---|
| 99 | return (this->combinedLevelMask_ & level) || | 
|---|
| 100 | ((this->combinedAdditionalContextsLevelMask_ & level) && (this->combinedAdditionalContextsMask_ & context.mask)); | 
|---|
| 101 | } | 
|---|
| 102 |  | 
|---|
| 103 | const OutputContextContainer& registerContext(const std::string& name, const std::string& subname = ""); | 
|---|
| 104 |  | 
|---|
| 105 | const std::string& getLevelName(OutputLevel level) const; | 
|---|
| 106 | std::string getDefaultPrefix(OutputLevel level, const OutputContextContainer& context) const; | 
|---|
| 107 |  | 
|---|
| 108 | inline const std::vector<OutputListener*>& getListeners() const | 
|---|
| 109 | { return this->listeners_; } | 
|---|
| 110 |  | 
|---|
| 111 | inline OutputLevel getCombinedLevelMask() const { return this->combinedLevelMask_; } | 
|---|
| 112 | inline OutputLevel getCombinedAdditionalContextsLevelMask() const { return this->combinedAdditionalContextsLevelMask_; } | 
|---|
| 113 | inline OutputContextMask getCombinedAdditionalContextsMask() const { return this->combinedAdditionalContextsMask_; } | 
|---|
| 114 |  | 
|---|
| 115 | private: | 
|---|
| 116 | // non-copyable: | 
|---|
| 117 | OutputManager(const OutputManager&) = delete; | 
|---|
| 118 | OutputManager& operator=(const OutputManager&) = delete; | 
|---|
| 119 |  | 
|---|
| 120 | void updateMasks(); | 
|---|
| 121 | void updateCombinedLevelMask(); | 
|---|
| 122 | void updateCombinedAdditionalContextsLevelMask(); | 
|---|
| 123 | void updateCombinedAdditionalContextsMask(); | 
|---|
| 124 |  | 
|---|
| 125 | std::vector<OutputListener*> listeners_;                            ///< List of all registered output listeners | 
|---|
| 126 |  | 
|---|
| 127 | OutputLevel       combinedLevelMask_;                               ///< The combined mask of accepted levels of all listeners | 
|---|
| 128 | OutputLevel       combinedAdditionalContextsLevelMask_;             ///< The combined mask of accepted additional contexts levels of all listeners | 
|---|
| 129 | OutputContextMask combinedAdditionalContextsMask_;                  ///< The combined mask of accepted additional contexts of all listeners | 
|---|
| 130 |  | 
|---|
| 131 | std::map<std::string, OutputContextMask> contextMasks_;             ///< Contains all main-contexts and their masks | 
|---|
| 132 | std::map<std::string, OutputContextContainer> contextContainers_;   ///< Contains all contexts including sub-contexts and their containers | 
|---|
| 133 | OutputContextSubID subcontextCounter_;                              ///< Counts the number of sub-contexts (and generates their IDs) | 
|---|
| 134 |  | 
|---|
| 135 | bool isInitialized_;                                                ///< Becomes true once the following instances were created | 
|---|
| 136 | MemoryWriter*  memoryWriterInstance_;                               ///< The main instance of MemoryWriter, managed by OutputManager | 
|---|
| 137 | ConsoleWriter* consoleWriterInstance_;                              ///< The main instance of ConsoleWriter, managed by OutputManager | 
|---|
| 138 | LogWriter*     logWriterInstance_;                                  ///< The main instance of LogWriter, managed by OutputManager | 
|---|
| 139 |  | 
|---|
| 140 | public: | 
|---|
| 141 | struct _UtilExport Testing | 
|---|
| 142 | { | 
|---|
| 143 | static std::shared_ptr<OutputManager>& getInstancePointer(); | 
|---|
| 144 | }; | 
|---|
| 145 | }; | 
|---|
| 146 | } | 
|---|
| 147 |  | 
|---|
| 148 | #endif /* _OutputManager_H__ */ | 
|---|