Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Jul 4, 2011, 2:47:44 AM (13 years ago)
Author:
rgrieder
Message:

Merged unity_build branch back to trunk.

Features:

  • Implemented fully automatic build units to speed up compilation if requested
  • Added DOUT macro for quick debug output
  • Activated text colouring in the POSIX IOConsole
  • DeclareToluaInterface is not necessary anymore

Improvements:

  • Output levels now change appropriately when switch back and forth from dev mode
  • Log level for the file output is now also correct during startup
  • Removed some header file dependencies in core and tools to speed up compilation

no more file for command line options

  • Improved util::tribool by adapting some concepts from boost::tribool

Regressions:

  • It is not possible anymore to specify command line arguments in an extra file because we've got config values for that purpose.
Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/util/OutputHandler.cc

    r7401 r8729  
    6969        */
    7070        LogFileWriter()
    71             : OutputListener(OutputHandler::logFileOutputListenerName_s)
     71            : OutputListener("LogFile")
    7272        {
    7373            // Get path for a temporary file
     
    8585            timeinfo = localtime(&rawtime);
    8686
    87             this->logFile_.open(this->logFilename_.c_str(), std::fstream::out);
    88             this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl;
    89             this->logFile_.flush();
    90 
    91             this->outputStream_ = &this->logFile_;
     87            this->openFile();
     88            if (this->logFile_.is_open())
     89            {
     90                this->logFile_ << "Started log on " << asctime(timeinfo) << std::endl;
     91                this->logFile_.flush();
     92            }
    9293        }
    9394
     
    9596        ~LogFileWriter()
    9697        {
    97             this->logFile_ << "Closed log" << std::endl;
    98             this->logFile_.close();
     98            if (this->logFile_.is_open())
     99            {
     100                this->logFile_ << "Closed log" << std::endl;
     101                this->logFile_.close();
     102            }
    99103        }
    100104
     
    102106        void setLogPath(const std::string& path)
    103107        {
    104             this->logFile_.close();
    105             // Read old file into a buffer
    106             std::ifstream old(this->logFilename_.c_str());
     108            if (this->logFile_.is_open())
     109                this->logFile_.close();
     110
     111            // Open the new file
    107112            this->logFilename_ = path + logFileBaseName_g;
    108             // Open the new file and feed it the content of the old one
     113            this->openFile();
     114        }
     115
     116        //! Erases the log file
     117        void clearFile()
     118        {
     119            if (this->logFile_.is_open())
     120            {
     121                this->logFile_.close();
     122                this->openFile();
     123            }
     124        }
     125
     126    private:
     127        void openFile()
     128        {
    109129            this->logFile_.open(this->logFilename_.c_str(), std::fstream::out);
    110             this->logFile_ << old.rdbuf();
    111             this->logFile_.flush();
    112             old.close();
    113         }
    114 
    115     private:
     130
     131            if (this->logFile_.is_open())
     132                this->outputStream_ = &this->logFile_;
     133            else
     134            {
     135                COUT(2) << "Warning: Failed to open log file. File logging disabled." << std::endl;
     136                this->outputStream_ = NULL;
     137            }
     138        }
     139
    116140        std::ofstream logFile_;     //!< File handle for the log file
    117141        std::string   logFilename_; //!< Filename of the log file
     
    133157        //! Only assigns the output stream with std::cout
    134158        ConsoleWriter()
    135             : OutputListener("consoleLog")
     159            : OutputListener("Console")
    136160        {
    137161            this->outputStream_ = &std::cout;
     
    147171        OutputListener that writes all the output piece by piece to an array
    148172        associated with the corresponding output level.
     173        Used as buffer until all output devices have been initialised.
    149174    @note
    150         Only output below or equal to the current soft debug level is written
    151         to minimise huge arrays for the normal run.
     175        At some point, OutputHandler::disableMemoryLog() has to be called in
     176        order to avoid large memory footprints of this class.
    152177    */
    153178    class MemoryLogWriter : public OutputListener
     
    156181        friend class OutputHandler;
    157182
    158         /**
    159         @brief
    160             Sets the right soft debug level and registers itself
    161         */
    162183        MemoryLogWriter()
    163184            : OutputListener("memoryLog")
     
    166187        }
    167188
    168         //! Pushed the just written output to the internal array
     189        //! Push the just written output to the internal array
    169190        void outputChanged(int level)
    170191        {
     
    180201
    181202    private:
    182         std::ostringstream                        buffer_; //!< Stream object used to process the output
    183         std::vector<std::pair<int, std::string> > output_; //!< Vector containing ALL output
     203        std::ostringstream          buffer_; //!< Stream object used to process the output
     204        OutputHandler::OutputVector output_; //!< Vector containing ALL output
    184205    };
    185206
     
    188209    ///// OutputHandler /////
    189210    /////////////////////////
    190     const std::string OutputHandler::logFileOutputListenerName_s = "logFile";
    191           int         OutputHandler::softDebugLevel_s = hardDebugLevel;
     211    int OutputHandler::softDebugLevel_s = hardDebugLevel;
    192212
    193213    //! Creates the LogFileWriter and the MemoryLogWriter
     
    195215        : outputLevel_(OutputLevel::Verbose)
    196216    {
     217        // Note: These levels only concern startup before orxonox.ini is read.
    197218#ifdef ORXONOX_RELEASE
    198         const OutputLevel::Value defaultLevelConsole = OutputLevel::Error;
    199         const OutputLevel::Value defaultLevelLogFile = OutputLevel::Info;
     219        const OutputLevel::Value initialLevelConsole = OutputLevel::Error;
    200220#else
    201         const OutputLevel::Value defaultLevelConsole = OutputLevel::Info;
    202         const OutputLevel::Value defaultLevelLogFile = OutputLevel::Debug;
     221        const OutputLevel::Value initialLevelConsole = OutputLevel::Info;
    203222#endif
     223        // Use high log level because we rewrite the log file anyway with the
     224        // correct level. But if Orxonox were to crash before that, we might be
     225        // grateful to have a high debug level, esp. for releases.
     226        const OutputLevel::Value intialLevelLogFile = OutputLevel::Debug;
    204227
    205228        this->logFile_ = new LogFileWriter();
    206229        // Use default level until we get the configValue from the Core
    207         this->logFile_->softDebugLevel_ = defaultLevelLogFile;
     230        this->logFile_->softDebugLevel_ = intialLevelLogFile;
    208231        this->registerOutputListener(this->logFile_);
    209232
    210233        this->consoleWriter_ = new ConsoleWriter();
    211         this->consoleWriter_->softDebugLevel_ = defaultLevelConsole;
     234        this->consoleWriter_->softDebugLevel_ = initialLevelConsole;
    212235        this->registerOutputListener(this->consoleWriter_);
    213236
    214         this->output_ = new MemoryLogWriter();
    215         // We capture as much input as the listener with the highest level
    216         this->output_->softDebugLevel_ = getSoftDebugLevel();
    217         this->registerOutputListener(this->output_);
     237        this->memoryBuffer_ = new MemoryLogWriter();
     238        // Write everything, e.g. use hardDebugLevel
     239        this->memoryBuffer_->softDebugLevel_ = hardDebugLevel;
     240        this->registerOutputListener(this->memoryBuffer_);
    218241    }
    219242
     
    223246        delete this->logFile_;
    224247        delete this->consoleWriter_;
    225         delete this->output_;
     248        delete this->memoryBuffer_; // Might already be NULL
    226249    }
    227250
     
    234257    void OutputHandler::registerOutputListener(OutputListener* listener)
    235258    {
    236         for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
     259        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
    237260        {
    238261            if ((*it)->name_ == listener->name_)
     
    243266        }
    244267        this->listeners_.push_back(listener);
    245         // Update global soft debug level
    246         this->setSoftDebugLevel(listener->getOutputListenerName(), listener->getSoftDebugLevel());
     268        this->updateGlobalDebugLevel();
    247269    }
    248270
    249271    void OutputHandler::unregisterOutputListener(OutputListener* listener)
    250272    {
    251         this->listeners_.remove(listener);
     273        for (std::vector<OutputListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
     274        {
     275            if ((*it)->name_ == listener->name_)
     276            {
     277                this->listeners_.erase(it);
     278                break;
     279            }
     280        }
     281        this->updateGlobalDebugLevel();
    252282    }
    253283
     
    255285    {
    256286        this->logFile_->setLogPath(path);
     287        this->rewriteLogFile();
     288    }
     289
     290    void OutputHandler::rewriteLogFile()
     291    {
     292        logFile_->clearFile();
     293
     294        if (logFile_->outputStream_ == NULL)
     295            return;
     296
     297        for (OutputVector::const_iterator it = this->getOutput().begin(); it != this->getOutput().end(); ++it)
     298        {
     299            if (it->first <= logFile_->softDebugLevel_)
     300                (*logFile_->outputStream_) << it->second;
     301        }
     302        logFile_->outputStream_->flush();
    257303    }
    258304
     
    267313    }
    268314
    269     OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorBegin() const
    270     {
    271         return this->output_->output_.begin();
    272     }
    273 
    274     OutputHandler::OutputVectorIterator OutputHandler::getOutputVectorEnd() const
    275     {
    276         return this->output_->output_.end();
     315    void OutputHandler::disableMemoryLog()
     316    {
     317        this->unregisterOutputListener(this->memoryBuffer_);
     318        // Only clear the buffer so we can still reference the vector
     319        this->memoryBuffer_->output_.clear();
     320    }
     321
     322    const OutputHandler::OutputVector& OutputHandler::getOutput() const
     323    {
     324        return this->memoryBuffer_->output_;
    277325    }
    278326
    279327    int OutputHandler::getSoftDebugLevel(const std::string& name) const
    280328    {
    281         for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
     329        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
    282330        {
    283331            if ((*it)->name_ == name)
     
    289337    void OutputHandler::setSoftDebugLevel(const std::string& name, int level)
    290338    {
    291         int globalSoftDebugLevel = -1;
    292         for (std::list<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
     339        for (std::vector<OutputListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
    293340        {
    294341            if ((*it)->name_ == name)
    295342                (*it)->softDebugLevel_ = level;
    296             if ((*it)->softDebugLevel_ > globalSoftDebugLevel)
    297                 globalSoftDebugLevel = (*it)->softDebugLevel_;
    298         }
    299         // Update global soft debug level
     343        }
     344        this->updateGlobalDebugLevel();
     345    }
     346
     347    void OutputHandler::updateGlobalDebugLevel()
     348    {
     349        int globalSoftDebugLevel = -1;
     350        std::vector<OutputListener*>::const_iterator it = this->listeners_.begin();
     351        for (; it != this->listeners_.end(); ++it)
     352            globalSoftDebugLevel = std::max(globalSoftDebugLevel, (*it)->softDebugLevel_);
     353
    300354        OutputHandler::softDebugLevel_s = globalSoftDebugLevel;
    301355    }
Note: See TracChangeset for help on using the changeset viewer.