Changeset 9550 for code/trunk/src/libraries/util/output
- Timestamp:
- Mar 12, 2013, 11:13:03 PM (12 years ago)
- Location:
- code/trunk
- Files:
-
- 14 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/testing (added) merged: 9015,9017,9020-9022,9025-9026,9047,9076-9078,9114-9115,9221-9226,9356,9473-9480,9524,9529-9531,9533-9545,9547-9549
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/util/output/ConsoleWriter.cc
r9348 r9550 34 34 #include "ConsoleWriter.h" 35 35 36 #include <iostream>37 36 38 37 #include "OutputManager.h" … … 48 47 After creation, the instance is enabled. 49 48 */ 50 ConsoleWriter::ConsoleWriter( ) : BaseWriter("Console")49 ConsoleWriter::ConsoleWriter(std::ostream& outputStream) : BaseWriter("Console"), outputStream_(outputStream) 51 50 { 52 51 #ifdef ORXONOX_RELEASE … … 66 65 67 66 /** 68 @brief Returns the only existing instance of this class.69 */70 /*static*/ ConsoleWriter& ConsoleWriter::getInstance()71 {72 static ConsoleWriter instance;73 return instance;74 }75 76 /**77 67 @brief Inherited function from BaseWriter, writes output to the console using std::cout. 78 68 */ 79 69 void ConsoleWriter::printLine(const std::string& line, OutputLevel) 80 70 { 81 std::cout<< line << std::endl;71 this->outputStream_ << line << std::endl; 82 72 } 83 73 -
code/trunk/src/libraries/util/output/ConsoleWriter.h
r8858 r9550 37 37 38 38 #include "util/UtilPrereqs.h" 39 40 #include <ostream> 41 39 42 #include "BaseWriter.h" 40 43 … … 44 47 @brief ConsoleWriter inherits from BaseWriter and writes output to the console. 45 48 46 This class can be seen as an equivalent to std::cout within the output 47 system. It is implemented as a singleton for static acces. 49 This class can be seen as an equivalent to std::cout within the output system. 48 50 */ 49 51 class _UtilExport ConsoleWriter : public BaseWriter 50 52 { 51 53 public: 52 static ConsoleWriter& getInstance(); 54 ConsoleWriter(std::ostream& outputStream); 55 ConsoleWriter(const ConsoleWriter&); 56 virtual ~ConsoleWriter(); 53 57 54 58 void enable(); 55 59 void disable(); 60 61 inline const std::ostream& getOutputStream() const 62 { return this->outputStream_; } 56 63 57 64 protected: … … 59 66 60 67 private: 61 ConsoleWriter(); 62 ConsoleWriter(const ConsoleWriter&); 63 virtual ~ConsoleWriter(); 64 65 bool bEnabled_; ///< If false, the instance will not write output to the console. 68 std::ostream& outputStream_; ///< The ostream to which the console writer writes its output 69 bool bEnabled_; ///< If false, the instance will not write output to the console. 66 70 }; 67 71 } -
code/trunk/src/libraries/util/output/LogWriter.cc
r8858 r9550 39 39 #include "OutputManager.h" 40 40 #include "MemoryWriter.h" 41 #include "util/Convert.h" 41 42 42 43 namespace orxonox 43 44 { 45 static const int MAX_ARCHIVED_FILES = 9; 46 44 47 /** 45 48 @brief Constructor, initializes the desired output levels and the name and path of the log-file, and opens the log-file. … … 58 61 // get the path for a temporary file, depending on the system 59 62 #ifdef ORXONOX_PLATFORM_WINDOWS 60 this-> path_ = getenv("TEMP");63 this->directory_ = getenv("TEMP"); 61 64 #else 62 this-> path_ = "/tmp";65 this->directory_ = "/tmp"; 63 66 #endif 64 this->bDefaultPath_ = true; 67 68 // send a message to the user so that he can find the file in the case of a crash. 69 OutputManager::getInstance().pushMessage(level::user_info, context::undefined(), "Opening log file " + this->getPath()); 65 70 66 71 this->openFile(); … … 76 81 77 82 /** 78 @brief Returns the only existing instance of this class.79 */80 /*static*/ LogWriter& LogWriter::getInstance()81 {82 static LogWriter instance;83 return instance;84 }85 86 /**87 83 @brief Opens the log-file in order to write output to it. 88 84 */ 89 85 void LogWriter::openFile() 90 86 { 91 // get the full file-name 92 std::string name = this->path_ + '/' + this->filename_; 93 94 // 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. 95 if (this->bDefaultPath_) 96 OutputManager::getInstance().pushMessage(level::user_info, context::undefined(), "Opening log file " + name); 87 // archive the old log file 88 this->archive(); 97 89 98 90 // open the file 99 this->file_.open( name.c_str(), std::fstream::out);91 this->file_.open(this->getPath().c_str(), std::fstream::out); 100 92 101 93 // check if it worked and print some output … … 119 111 120 112 /** 113 * @brief Archives old copies of the log file by adding increasing numbers to the filename. 114 */ 115 void LogWriter::archive(int index) 116 { 117 std::string oldPath = this->getArchivedPath(index); 118 119 // see if the file already exists, otherwise return 120 std::ifstream stream(oldPath.c_str()); 121 bool exists = stream.is_open(); 122 stream.close(); 123 124 if (!exists) 125 return; 126 127 if (index < MAX_ARCHIVED_FILES) 128 { 129 // increment the index and archive the file with the next higher index 130 this->archive(++index); 131 132 // create the new path based on the incremented index 133 std::string newPath = this->getArchivedPath(index); 134 135 // move the file 136 std::rename(oldPath.c_str(), newPath.c_str()); 137 } 138 else 139 { 140 // delete the file 141 std::remove(oldPath.c_str()); 142 } 143 } 144 145 /** 146 * @brief Returns the path for archived copies of the logfile (based on the archive index) 147 */ 148 std::string LogWriter::getArchivedPath(int index) const 149 { 150 std::string path = this->getPath(); 151 if (index > 0) 152 path += '.' + multi_cast<std::string>(index); 153 return path; 154 } 155 156 /** 121 157 @brief Changes the path of the log-file. Re-writes the log-file by using MemoryWriter. 122 158 */ 123 void LogWriter::setLog Path(const std::string& path)159 void LogWriter::setLogDirectory(const std::string& directory) 124 160 { 125 161 // notify about the change of the log-file (because the old file will no longer be updated) 126 OutputManager::getInstance().pushMessage(level::internal_info, context::undefined(), "Migrating log file from " + this-> path_ + "\nto " + path);162 OutputManager::getInstance().pushMessage(level::internal_info, context::undefined(), "Migrating log file from " + this->directory_ + "\nto " + directory); 127 163 128 164 // close the old file, update the path and open the new file 129 165 this->closeFile(); 130 this->path_ = path; 131 this->bDefaultPath_ = false; 166 this->directory_ = directory; 132 167 this->openFile(); 133 168 134 169 // request old output from MemoryWriter 135 MemoryWriter::getInstance().resendOutput(this); 170 if (OutputManager::getInstance().getMemoryWriter()) 171 OutputManager::getInstance().getMemoryWriter()->resendOutput(this); 136 172 } 137 173 -
code/trunk/src/libraries/util/output/LogWriter.h
r8858 r9550 47 47 @brief The LogWriter class inherits from BaseWriter and writes output to a log-file. 48 48 49 It is implemented as singleton because we (currently) use only one 50 log-file. The path of the file can be changed, in which case the file 49 The path of the file can be changed, in which case the file 51 50 is rewritten by using the output stored by MemoryWriter. This adds the 52 51 possibility to change the desired output levels before changing the … … 57 56 { 58 57 public: 59 static LogWriter& getInstance(); 58 LogWriter(); 59 LogWriter(const LogWriter&); 60 virtual ~LogWriter(); 60 61 61 void setLogPath(const std::string& path); 62 void setLogDirectory(const std::string& directory); 63 64 /** @brief Returns the path to the logfile. */ 65 inline std::string getPath() const 66 { return this->directory_ + '/' + this->filename_; } 67 /** @brief Returns the open file stream. */ 68 inline const std::ofstream& getFile() const 69 { return this->file_; } 62 70 63 71 protected: … … 65 73 66 74 private: 67 LogWriter();68 LogWriter(const LogWriter&);69 virtual ~LogWriter();70 71 75 void openFile(); 72 76 void closeFile(); 73 77 74 std::string filename_; ///< The name of the log-file (without directories) 75 std::string path_; ///< The path of the log-file (without file-name) 76 bool bDefaultPath_; ///< If true, the log-file resides at the default path (which is usually a temporary directory) 78 void archive(int index = 0); 79 std::string getArchivedPath(int index) const; 77 80 81 std::string filename_; ///< The name of the log-file (without directory) 82 std::string directory_; ///< The directory where the log-file resided (without file-name) 78 83 std::ofstream file_; ///< The output file stream. 79 84 }; -
code/trunk/src/libraries/util/output/MemoryWriter.cc
r8858 r9550 53 53 54 54 /** 55 @brief Returns the only existing instance of this singleton class.56 */57 /*static*/ MemoryWriter& MemoryWriter::getInstance()58 {59 static MemoryWriter instance;60 return instance;61 }62 63 /**64 55 @brief Implementation of the output() function inherited from OutputListener, stores the received output in memory. 65 56 */ -
code/trunk/src/libraries/util/output/MemoryWriter.h
r8858 r9550 67 67 68 68 public: 69 static MemoryWriter& getInstance(); 69 MemoryWriter(); 70 MemoryWriter(const MemoryWriter&); 71 virtual ~MemoryWriter(); 70 72 71 73 void resendOutput(OutputListener* listener) const; … … 76 78 77 79 private: 78 MemoryWriter();79 MemoryWriter(const MemoryWriter&);80 virtual ~MemoryWriter();81 82 80 std::vector<Message> messages_; ///< Stores all output messages from the creation of this instance until disable() is called. 83 81 }; -
code/trunk/src/libraries/util/output/OutputDefinitions.h
r8879 r9550 47 47 context argument. 48 48 */ 49 #define REGISTER_OUTPUT_CONTEXT(name) \ 50 const OutputContextContainer& name() { static const OutputContextContainer& context = registerContext(#name); return context; } 49 #ifndef DISABLE_OUTPUT_CONTEXT_STATIC_CACHE 50 #define REGISTER_OUTPUT_CONTEXT(name) \ 51 const OutputContextContainer& name() { static OutputContextContainer context = registerContext(#name); return context; } 52 #else 53 #define REGISTER_OUTPUT_CONTEXT(name) \ 54 const OutputContextContainer& name() { return registerContext(#name); } 55 #endif 51 56 52 57 /** … … 60 65 individually by derivatives of orxonox::SubcontextOutputListener. 61 66 */ 62 #define REGISTER_OUTPUT_SUBCONTEXT(name, subname) \ 63 const OutputContextContainer& subname() { static const OutputContextContainer& context = registerContext(#name, #subname); return context; } 67 #ifndef DISABLE_OUTPUT_CONTEXT_STATIC_CACHE 68 #define REGISTER_OUTPUT_SUBCONTEXT(name, subname) \ 69 const OutputContextContainer& subname() { static const OutputContextContainer context = registerContext(#name, #subname); return context; } 70 #else 71 #define REGISTER_OUTPUT_SUBCONTEXT(name, subname) \ 72 const OutputContextContainer& subname() { return registerContext(#name, #subname); } 73 #endif 64 74 65 75 // tolua_begin … … 105 115 OutputContextSubID sub_id; ///< The id of the sub-context (or context::no_subcontext if this container doesn't define a sub-context) 106 116 std::string name; ///< The name of this context 117 118 inline bool operator==(const OutputContextContainer& other) const 119 { 120 return this->mask == other.mask && this->sub_id == other.sub_id && this->name == other.name; 121 } 107 122 }; 108 123 -
code/trunk/src/libraries/util/output/OutputListener.cc
r8858 r9550 62 62 63 63 /** 64 @brief Adds a listener to the list. 65 */ 66 void OutputListener::registerListener(AdditionalContextListener* listener) 67 { 68 this->listeners_.push_back(listener); 69 } 70 71 /** 72 @brief Removes a listener from the list. 73 */ 74 void OutputListener::unregisterListener(AdditionalContextListener* listener) 75 { 76 for (std::vector<AdditionalContextListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 77 { 78 if (*it == listener) 79 { 80 this->listeners_.erase(it); 81 break; 82 } 83 } 84 } 85 86 /** 64 87 @brief Defines the level mask in a way which accepts all output up to the level \c max. 65 88 */ … … 88 111 this->levelMask_ = mask; 89 112 90 OutputManager::getInstance().updateCombinedLevelMask(); 113 for (size_t i = 0; i < this->listeners_.size(); ++i) 114 this->listeners_[i]->updatedLevelMask(this); 91 115 } 92 116 … … 118 142 this->additionalContextsLevelMask_ = mask; 119 143 120 OutputManager::getInstance().updateCombinedAdditionalContextsLevelMask(); 144 for (size_t i = 0; i < this->listeners_.size(); ++i) 145 this->listeners_[i]->updatedAdditionalContextsLevelMask(this); 121 146 } 122 147 … … 128 153 this->additionalContextsMask_ = mask; 129 154 130 OutputManager::getInstance().updateCombinedAdditionalContextsMask(); 155 for (size_t i = 0; i < this->listeners_.size(); ++i) 156 this->listeners_[i]->updatedAdditionalContextsMask(this); 131 157 } 132 158 -
code/trunk/src/libraries/util/output/OutputListener.h
r8858 r9550 55 55 virtual ~OutputListener(); 56 56 57 void registerListener(AdditionalContextListener* listener); 58 void unregisterListener(AdditionalContextListener* listener); 59 57 60 void setLevelMax(OutputLevel max); 58 61 void setLevelRange(OutputLevel min, OutputLevel max); … … 63 66 void setAdditionalContextsLevelMask(OutputLevel mask); 64 67 65 v oid setAdditionalContextsMask(OutputContextMask mask);68 virtual void setAdditionalContextsMask(OutputContextMask mask); 66 69 67 70 /// @brief Returns the level mask. … … 78 81 79 82 /// @brief Called by OutputManager for each line of output, checks if this listener actually accepts this output before it calls the output() function. 80 inlinevoid unfilteredOutput(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines)83 virtual void unfilteredOutput(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines) 81 84 { if (this->acceptsOutput(level, context)) this->output(level, context, lines); } 82 85 … … 85 88 virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines) = 0; 86 89 90 inline const std::vector<AdditionalContextListener*>& getListeners() const 91 { return this->listeners_; } 92 87 93 private: 88 OutputLevel levelMask_; ///< Mask of accepted output levels, independent of contexts 89 OutputContextMask additionalContextsMask_; ///< Mask of accepted additional contexts 90 OutputLevel additionalContextsLevelMask_; ///< Mask of accepted output levels of the additional contexts 94 std::vector<AdditionalContextListener*> listeners_; ///< List of all registered additional context listeners 95 96 OutputLevel levelMask_; ///< Mask of accepted output levels, independent of contexts 97 OutputContextMask additionalContextsMask_; ///< Mask of accepted additional contexts 98 OutputLevel additionalContextsLevelMask_; ///< Mask of accepted output levels of the additional contexts 91 99 }; 92 100 -
code/trunk/src/libraries/util/output/OutputManager.cc
r8858 r9550 33 33 34 34 #include "OutputManager.h" 35 36 #include <iostream> 35 37 36 38 #include "MemoryWriter.h" … … 39 41 #include "util/Output.h" 40 42 #include "util/StringUtils.h" 43 #include "util/SharedPtr.h" 41 44 42 45 namespace orxonox … … 52 55 53 56 this->subcontextCounter_ = 0; 57 58 this->isInitialized_ = false; 59 this->memoryWriterInstance_ = 0; 60 this->consoleWriterInstance_ = 0; 61 this->logWriterInstance_ = 0; 62 63 // register 'undefined' context in order to give it always the first context-ID 64 this->registerContext("undefined"); 54 65 } 55 66 … … 59 70 OutputManager::~OutputManager() 60 71 { 72 while (!this->listeners_.empty()) 73 this->unregisterListener(this->listeners_[0]); 74 75 if (this->memoryWriterInstance_) 76 delete this->memoryWriterInstance_; 77 if (this->consoleWriterInstance_) 78 delete this->consoleWriterInstance_; 79 if (this->logWriterInstance_) 80 delete this->logWriterInstance_; 81 } 82 83 /*static*/ SharedPtr<OutputManager>& OutputManager::Testing::getInstancePointer() 84 { 85 static SharedPtr<OutputManager> instance(new OutputManager()); 86 return instance; 61 87 } 62 88 … … 66 92 /*static*/ OutputManager& OutputManager::getInstance() 67 93 { 68 static OutputManager instance; 69 return instance; 94 return *OutputManager::Testing::getInstancePointer(); 70 95 } 71 96 … … 80 105 /*static*/ OutputManager& OutputManager::getInstanceAndCreateListeners() 81 106 { 82 static OutputManager& instance = OutputManager::getInstance(); 83 84 static MemoryWriter& memoryWriterInstance = MemoryWriter::getInstance(); (void)memoryWriterInstance; 85 static ConsoleWriter& consoleWriterInstance = ConsoleWriter::getInstance(); (void)consoleWriterInstance; 86 static LogWriter& logWriterInstance = LogWriter::getInstance(); (void)logWriterInstance; 107 OutputManager& instance = *OutputManager::Testing::getInstancePointer(); 108 109 if (!instance.isInitialized_) { 110 instance.isInitialized_ = true; 111 instance.memoryWriterInstance_ = new MemoryWriter(); 112 instance.consoleWriterInstance_ = new ConsoleWriter(std::cout); 113 instance.logWriterInstance_ = new LogWriter(); 114 } 87 115 88 116 return instance; … … 113 141 void OutputManager::registerListener(OutputListener* listener) 114 142 { 143 listener->registerListener(this); 115 144 this->listeners_.push_back(listener); 116 145 this->updateMasks(); … … 122 151 void OutputManager::unregisterListener(OutputListener* listener) 123 152 { 153 listener->unregisterListener(this); 124 154 for (std::vector<OutputListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it) 125 155 { … … 267 297 { 268 298 // "undefined" context is ignored because it's used implicitly if no explicit context is defined 269 staticOutputContextMask undefined_mask = context::undefined().mask;299 OutputContextMask undefined_mask = context::undefined().mask; 270 300 271 301 std::string prefix = this->getLevelName(level) + ": "; -
code/trunk/src/libraries/util/output/OutputManager.h
r8858 r9550 43 43 44 44 #include "OutputDefinitions.h" 45 #include "AdditionalContextListener.h" 45 46 46 47 namespace orxonox … … 61 62 Additionally OutputManager is used to register output contexts. 62 63 */ 63 class _UtilExport OutputManager 64 class _UtilExport OutputManager : public AdditionalContextListener 64 65 { 65 66 public: 67 OutputManager(); 68 OutputManager(const OutputManager&); 69 virtual ~OutputManager(); 70 66 71 static OutputManager& getInstance(); 67 72 static OutputManager& getInstanceAndCreateListeners(); 68 73 69 void pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message); 74 inline MemoryWriter* getMemoryWriter() { return this->memoryWriterInstance_; } 75 inline ConsoleWriter* getConsoleWriter() { return this->consoleWriterInstance_; } 76 inline LogWriter* getLogWriter() { return this->logWriterInstance_; } 70 77 71 void registerListener(OutputListener* listener); 72 void unregisterListener(OutputListener* listener); 78 virtual void pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message); 73 79 74 void updateMasks(); 75 void updateCombinedLevelMask(); 76 void updateCombinedAdditionalContextsLevelMask(); 77 void updateCombinedAdditionalContextsMask(); 80 virtual void registerListener(OutputListener* listener); 81 virtual void unregisterListener(OutputListener* listener); 82 83 virtual void updatedLevelMask(const OutputListener* listener) 84 { this->updateCombinedLevelMask(); } 85 virtual void updatedAdditionalContextsLevelMask(const OutputListener* listener) 86 { this->updateCombinedAdditionalContextsLevelMask(); } 87 virtual void updatedAdditionalContextsMask(const OutputListener* listener) 88 { this->updateCombinedAdditionalContextsMask(); } 78 89 79 90 /** … … 95 106 std::string getDefaultPrefix(OutputLevel level, const OutputContextContainer& context) const; 96 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 97 115 private: 98 OutputManager(); 99 OutputManager(const OutputManager&); 100 ~OutputManager(); 116 void updateMasks(); 117 void updateCombinedLevelMask(); 118 void updateCombinedAdditionalContextsLevelMask(); 119 void updateCombinedAdditionalContextsMask(); 101 120 102 121 std::vector<OutputListener*> listeners_; ///< List of all registered output listeners … … 109 128 std::map<std::string, OutputContextContainer> contextContainers_; ///< Contains all contexts including sub-contexts and their containers 110 129 OutputContextSubID subcontextCounter_; ///< Counts the number of sub-contexts (and generates their IDs) 130 131 bool isInitialized_; ///< Becomes true once the following instances were created 132 MemoryWriter* memoryWriterInstance_; ///< The main instance of MemoryWriter, managed by OutputManager 133 ConsoleWriter* consoleWriterInstance_; ///< The main instance of ConsoleWriter, managed by OutputManager 134 LogWriter* logWriterInstance_; ///< The main instance of LogWriter, managed by OutputManager 135 136 public: 137 struct _UtilExport Testing 138 { 139 static SharedPtr<OutputManager>& getInstancePointer(); 140 }; 111 141 }; 112 142 } -
code/trunk/src/libraries/util/output/OutputStream.h
r8858 r9550 102 102 } 103 103 104 inline const OutputLevel getOutputLevel() const { return this->level_; } 105 inline const OutputContextContainer* getOutputContext() const { return this->context_; } 106 inline bool acceptsOutput() const { return this->bAcceptsOutput_; } 107 104 108 private: 105 109 /// @brief Generic function to add values to the output stream, using the inherited << operator from std::ostringstream. -
code/trunk/src/libraries/util/output/SubcontextOutputListener.h
r8858 r9550 73 73 virtual ~SubcontextOutputListener(); 74 74 75 v oid setAdditionalContextsMask(OutputContextMask mask);75 virtual void setAdditionalContextsMask(OutputContextMask mask); 76 76 void setAdditionalSubcontexts(const std::set<const OutputContextContainer*>& subcontexts); 77 77 78 78 virtual bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const; 79 80 inline const std::set<OutputContextSubID>& getSubcontexts() const 81 { return this->subcontexts_; } 79 82 80 83 private:
Note: See TracChangeset
for help on using the changeset viewer.