Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Mar 12, 2013, 11:13:03 PM (12 years ago)
Author:
landauf
Message:

merged testing branch back to trunk. unbelievable it took me 13 months to finish this chore…

Location:
code/trunk
Files:
14 edited
1 copied

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/util/output/ConsoleWriter.cc

    r9348 r9550  
    3434#include "ConsoleWriter.h"
    3535
    36 #include <iostream>
    3736
    3837#include "OutputManager.h"
     
    4847        After creation, the instance is enabled.
    4948    */
    50     ConsoleWriter::ConsoleWriter() : BaseWriter("Console")
     49    ConsoleWriter::ConsoleWriter(std::ostream& outputStream) : BaseWriter("Console"), outputStream_(outputStream)
    5150    {
    5251#ifdef ORXONOX_RELEASE
     
    6665
    6766    /**
    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     /**
    7767        @brief Inherited function from BaseWriter, writes output to the console using std::cout.
    7868    */
    7969    void ConsoleWriter::printLine(const std::string& line, OutputLevel)
    8070    {
    81         std::cout << line << std::endl;
     71        this->outputStream_ << line << std::endl;
    8272    }
    8373
  • code/trunk/src/libraries/util/output/ConsoleWriter.h

    r8858 r9550  
    3737
    3838#include "util/UtilPrereqs.h"
     39
     40#include <ostream>
     41
    3942#include "BaseWriter.h"
    4043
     
    4447        @brief ConsoleWriter inherits from BaseWriter and writes output to the console.
    4548
    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.
    4850    */
    4951    class _UtilExport ConsoleWriter : public BaseWriter
    5052    {
    5153        public:
    52             static ConsoleWriter& getInstance();
     54            ConsoleWriter(std::ostream& outputStream);
     55            ConsoleWriter(const ConsoleWriter&);
     56            virtual ~ConsoleWriter();
    5357
    5458            void enable();
    5559            void disable();
     60
     61            inline const std::ostream& getOutputStream() const
     62                { return this->outputStream_; }
    5663
    5764        protected:
     
    5966
    6067        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.
    6670    };
    6771}
  • code/trunk/src/libraries/util/output/LogWriter.cc

    r8858 r9550  
    3939#include "OutputManager.h"
    4040#include "MemoryWriter.h"
     41#include "util/Convert.h"
    4142
    4243namespace orxonox
    4344{
     45    static const int MAX_ARCHIVED_FILES = 9;
     46
    4447    /**
    4548        @brief Constructor, initializes the desired output levels and the name and path of the log-file, and opens the log-file.
     
    5861        // get the path for a temporary file, depending on the system
    5962#ifdef ORXONOX_PLATFORM_WINDOWS
    60         this->path_ = getenv("TEMP");
     63        this->directory_ = getenv("TEMP");
    6164#else
    62         this->path_ = "/tmp";
     65        this->directory_ = "/tmp";
    6366#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());
    6570
    6671        this->openFile();
     
    7681
    7782    /**
    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     /**
    8783        @brief Opens the log-file in order to write output to it.
    8884    */
    8985    void LogWriter::openFile()
    9086    {
    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();
    9789
    9890        // open the file
    99         this->file_.open(name.c_str(), std::fstream::out);
     91        this->file_.open(this->getPath().c_str(), std::fstream::out);
    10092
    10193        // check if it worked and print some output
     
    119111
    120112    /**
     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    /**
    121157        @brief Changes the path of the log-file. Re-writes the log-file by using MemoryWriter.
    122158    */
    123     void LogWriter::setLogPath(const std::string& path)
     159    void LogWriter::setLogDirectory(const std::string& directory)
    124160    {
    125161        // 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);
    127163
    128164        // close the old file, update the path and open the new file
    129165        this->closeFile();
    130         this->path_ = path;
    131         this->bDefaultPath_ = false;
     166        this->directory_ = directory;
    132167        this->openFile();
    133168
    134169        // request old output from MemoryWriter
    135         MemoryWriter::getInstance().resendOutput(this);
     170        if (OutputManager::getInstance().getMemoryWriter())
     171            OutputManager::getInstance().getMemoryWriter()->resendOutput(this);
    136172    }
    137173
  • code/trunk/src/libraries/util/output/LogWriter.h

    r8858 r9550  
    4747        @brief The LogWriter class inherits from BaseWriter and writes output to a log-file.
    4848
    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
    5150        is rewritten by using the output stored by MemoryWriter. This adds the
    5251        possibility to change the desired output levels before changing the
     
    5756    {
    5857        public:
    59             static LogWriter& getInstance();
     58            LogWriter();
     59            LogWriter(const LogWriter&);
     60            virtual ~LogWriter();
    6061
    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_; }
    6270
    6371        protected:
     
    6573
    6674        private:
    67             LogWriter();
    68             LogWriter(const LogWriter&);
    69             virtual ~LogWriter();
    70 
    7175            void openFile();
    7276            void closeFile();
    7377
    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;
    7780
     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)
    7883            std::ofstream file_;    ///< The output file stream.
    7984    };
  • code/trunk/src/libraries/util/output/MemoryWriter.cc

    r8858 r9550  
    5353
    5454    /**
    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     /**
    6455        @brief Implementation of the output() function inherited from OutputListener, stores the received output in memory.
    6556    */
  • code/trunk/src/libraries/util/output/MemoryWriter.h

    r8858 r9550  
    6767
    6868        public:
    69             static MemoryWriter& getInstance();
     69            MemoryWriter();
     70            MemoryWriter(const MemoryWriter&);
     71            virtual ~MemoryWriter();
    7072
    7173            void resendOutput(OutputListener* listener) const;
     
    7678
    7779        private:
    78             MemoryWriter();
    79             MemoryWriter(const MemoryWriter&);
    80             virtual ~MemoryWriter();
    81 
    8280            std::vector<Message> messages_; ///< Stores all output messages from the creation of this instance until disable() is called.
    8381    };
  • code/trunk/src/libraries/util/output/OutputDefinitions.h

    r8879 r9550  
    4747    context argument.
    4848*/
    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
    5156
    5257/**
     
    6065    individually by derivatives of orxonox::SubcontextOutputListener.
    6166*/
    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
    6474
    6575// tolua_begin
     
    105115        OutputContextSubID sub_id;  ///< The id of the sub-context (or context::no_subcontext if this container doesn't define a sub-context)
    106116        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        }
    107122    };
    108123
  • code/trunk/src/libraries/util/output/OutputListener.cc

    r8858 r9550  
    6262
    6363    /**
     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    /**
    6487        @brief Defines the level mask in a way which accepts all output up to the level \c max.
    6588    */
     
    88111        this->levelMask_ = mask;
    89112
    90         OutputManager::getInstance().updateCombinedLevelMask();
     113        for (size_t i = 0; i < this->listeners_.size(); ++i)
     114            this->listeners_[i]->updatedLevelMask(this);
    91115    }
    92116
     
    118142        this->additionalContextsLevelMask_ = mask;
    119143
    120         OutputManager::getInstance().updateCombinedAdditionalContextsLevelMask();
     144        for (size_t i = 0; i < this->listeners_.size(); ++i)
     145            this->listeners_[i]->updatedAdditionalContextsLevelMask(this);
    121146    }
    122147
     
    128153        this->additionalContextsMask_ = mask;
    129154
    130         OutputManager::getInstance().updateCombinedAdditionalContextsMask();
     155        for (size_t i = 0; i < this->listeners_.size(); ++i)
     156            this->listeners_[i]->updatedAdditionalContextsMask(this);
    131157    }
    132158
  • code/trunk/src/libraries/util/output/OutputListener.h

    r8858 r9550  
    5555            virtual ~OutputListener();
    5656
     57            void registerListener(AdditionalContextListener* listener);
     58            void unregisterListener(AdditionalContextListener* listener);
     59
    5760            void setLevelMax(OutputLevel max);
    5861            void setLevelRange(OutputLevel min, OutputLevel max);
     
    6366            void setAdditionalContextsLevelMask(OutputLevel mask);
    6467
    65             void setAdditionalContextsMask(OutputContextMask mask);
     68            virtual void setAdditionalContextsMask(OutputContextMask mask);
    6669
    6770            /// @brief Returns the level mask.
     
    7881
    7982            /// @brief Called by OutputManager for each line of output, checks if this listener actually accepts this output before it calls the output() function.
    80             inline void 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)
    8184                { if (this->acceptsOutput(level, context)) this->output(level, context, lines); }
    8285
     
    8588            virtual void output(OutputLevel level, const OutputContextContainer& context, const std::vector<std::string>& lines) = 0;
    8689
     90            inline const std::vector<AdditionalContextListener*>& getListeners() const
     91                { return this->listeners_; }
     92
    8793        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
    9199    };
    92100
  • code/trunk/src/libraries/util/output/OutputManager.cc

    r8858 r9550  
    3333
    3434#include "OutputManager.h"
     35
     36#include <iostream>
    3537
    3638#include "MemoryWriter.h"
     
    3941#include "util/Output.h"
    4042#include "util/StringUtils.h"
     43#include "util/SharedPtr.h"
    4144
    4245namespace orxonox
     
    5255
    5356        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");
    5465    }
    5566
     
    5970    OutputManager::~OutputManager()
    6071    {
     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;
    6187    }
    6288
     
    6692    /*static*/ OutputManager& OutputManager::getInstance()
    6793    {
    68         static OutputManager instance;
    69         return instance;
     94        return *OutputManager::Testing::getInstancePointer();
    7095    }
    7196
     
    80105    /*static*/ OutputManager& OutputManager::getInstanceAndCreateListeners()
    81106    {
    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        }
    87115
    88116        return instance;
     
    113141    void OutputManager::registerListener(OutputListener* listener)
    114142    {
     143        listener->registerListener(this);
    115144        this->listeners_.push_back(listener);
    116145        this->updateMasks();
     
    122151    void OutputManager::unregisterListener(OutputListener* listener)
    123152    {
     153        listener->unregisterListener(this);
    124154        for (std::vector<OutputListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
    125155        {
     
    267297    {
    268298        // "undefined" context is ignored because it's used implicitly if no explicit context is defined
    269         static OutputContextMask undefined_mask = context::undefined().mask;
     299        OutputContextMask undefined_mask = context::undefined().mask;
    270300
    271301        std::string prefix = this->getLevelName(level) + ": ";
  • code/trunk/src/libraries/util/output/OutputManager.h

    r8858 r9550  
    4343
    4444#include "OutputDefinitions.h"
     45#include "AdditionalContextListener.h"
    4546
    4647namespace orxonox
     
    6162        Additionally OutputManager is used to register output contexts.
    6263    */
    63     class _UtilExport OutputManager
     64    class _UtilExport OutputManager : public AdditionalContextListener
    6465    {
    6566        public:
     67            OutputManager();
     68            OutputManager(const OutputManager&);
     69            virtual ~OutputManager();
     70
    6671            static OutputManager& getInstance();
    6772            static OutputManager& getInstanceAndCreateListeners();
    6873
    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_; }
    7077
    71             void registerListener(OutputListener* listener);
    72             void unregisterListener(OutputListener* listener);
     78            virtual void pushMessage(OutputLevel level, const OutputContextContainer& context, const std::string& message);
    7379
    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(); }
    7889
    7990            /**
     
    95106            std::string getDefaultPrefix(OutputLevel level, const OutputContextContainer& context) const;
    96107
     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
    97115        private:
    98             OutputManager();
    99             OutputManager(const OutputManager&);
    100             ~OutputManager();
     116            void updateMasks();
     117            void updateCombinedLevelMask();
     118            void updateCombinedAdditionalContextsLevelMask();
     119            void updateCombinedAdditionalContextsMask();
    101120
    102121            std::vector<OutputListener*> listeners_;                            ///< List of all registered output listeners
     
    109128            std::map<std::string, OutputContextContainer> contextContainers_;   ///< Contains all contexts including sub-contexts and their containers
    110129            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            };
    111141    };
    112142}
  • code/trunk/src/libraries/util/output/OutputStream.h

    r8858 r9550  
    102102            }
    103103
     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
    104108        private:
    105109            /// @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  
    7373            virtual ~SubcontextOutputListener();
    7474
    75             void setAdditionalContextsMask(OutputContextMask mask);
     75            virtual void setAdditionalContextsMask(OutputContextMask mask);
    7676            void setAdditionalSubcontexts(const std::set<const OutputContextContainer*>& subcontexts);
    7777
    7878            virtual bool acceptsOutput(OutputLevel level, const OutputContextContainer& context) const;
     79
     80            inline const std::set<OutputContextSubID>& getSubcontexts() const
     81                { return this->subcontexts_; }
    7982
    8083        private:
Note: See TracChangeset for help on using the changeset viewer.