Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Aug 23, 2011, 12:45:53 AM (13 years ago)
Author:
landauf
Message:

merged output branch back to trunk.

Changes:

  • you have to include util/Output.h instead of util/Debug.h
  • COUT(x) is now called orxout(level)
  • output levels are now defined by an enum instead of numbers. see util/Output.h for the definition
  • it's possible to use output contexts with orxout(level, context). see util/Output.h for some common contexts. you can define more contexts
  • you must use 'endl' at the end of an output message, '\n' does not flush the message

Output levels:

  • instead of COUT(0) use orxout()
  • instead of COUT(1) use orxout(user_error) or orxout(internal_error)
  • instead of COUT(2) use orxout(user_warning) or orxout(internal_warning)
  • instead of COUT(3) use orxout(user_status/user_info) or orxout(internal_status/internal_info)
  • instead of COUT(4) use orxout(verbose)
  • instead of COUT(5) use orxout(verbose_more)
  • instead of COUT(6) use orxout(verbose_ultra)

Guidelines:

  • user_* levels are for the user, visible in the console and the log-file
  • internal_* levels are for developers, visible in the log-file
  • verbose_* levels are for debugging, only visible if the context of the output is activated

Usage in C++:

  • orxout() << "message" << endl;
  • orxout(level) << "message" << endl;
  • orxout(level, context) << "message" << endl;

Usage in Lua:

  • orxout("message")
  • orxout(orxonox.level.levelname, "message")
  • orxout(orxonox.level.levelname, "context", "message")

Usage in Tcl (and in the in-game-console):

  • orxout levelname message
  • orxout_context levelname context message
  • shortcuts: log message, error message, warning message, status message, info message, debug message
Location:
code/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/command/Shell.cc

    r8729 r8858  
    3535
    3636#include "util/Math.h"
    37 #include "util/OutputHandler.h"
    3837#include "util/StringUtils.h"
    3938#include "util/SubString.h"
     39#include "util/output/OutputManager.h"
     40#include "util/output/MemoryWriter.h"
    4041#include "core/CoreIncludes.h"
    4142#include "core/ConfigFileManager.h"
     
    4445#include "core/input/InputBuffer.h"
    4546#include "CommandExecutor.h"
    46 #include "ConsoleCommand.h"
    4747
    4848namespace orxonox
    4949{
    50     SetConsoleCommand("log",     OutputHandler::log    );
    51     SetConsoleCommand("error",   OutputHandler::error  ).hide();
    52     SetConsoleCommand("warning", OutputHandler::warning).hide();
    53     SetConsoleCommand("info",    OutputHandler::info   ).hide();
    54     SetConsoleCommand("debug",   OutputHandler::debug  ).hide();
    55 
    5650    unsigned int Shell::cacheSize_s;
    5751
    58     /**
    59         @brief Constructor: Initializes the values and registers itself at OutputHandler.
     52    namespace DefaultLogLevel
     53    {
     54        const OutputLevel Dev  = level::internal_warning;
     55        const OutputLevel User = level::user_info;
     56    }
     57
     58    /**
     59        @brief Constructor: Initializes the values.
    6060        @param consoleName The name of the shell - used to define the name of the soft-debug-level config-value
    6161        @param bScrollable If true, the user is allowed to scroll through the output-lines
    6262    */
    6363    Shell::Shell(const std::string& consoleName, bool bScrollable)
    64         : OutputListener(consoleName)
     64        : BaseWriter(consoleName, false)
    6565        , inputBuffer_(new InputBuffer())
    66         , consoleName_(consoleName)
    6766        , bScrollable_(bScrollable)
    6867    {
    6968        RegisterRootObject(Shell);
     69
     70        OutputManager::getInstance().registerListener(this);
    7071
    7172        this->scrollPosition_ = 0;
     
    7374        this->historyPosition_ = 0;
    7475        this->historyOffset_ = 0;
    75         this->bFinishedLastLine_ = true;
    7676
    7777        this->clearOutput();
     
    8181        ConfigFileManager::getInstance().setFilename(ConfigFileType::CommandHistory, "commandHistory.ini");
    8282
    83         // Use a stringstream object to buffer the output
    84         this->outputStream_ = &this->outputBuffer_;
     83        // Choose the default level according to the path Orxonox was started (build directory or not)
     84        OutputLevel defaultDebugLevel = (PathConfig::buildDirectoryRun() ? DefaultLogLevel::Dev : DefaultLogLevel::User);
     85        this->setLevelMax(defaultDebugLevel);
    8586
    8687        this->setConfigValues();
    8788
    8889        // Get the previous output and add it to the Shell
    89         OutputHandler::OutputVector::const_iterator it = OutputHandler::getInstance().getOutput().begin();
    90         for (;it != OutputHandler::getInstance().getOutput().end(); ++it)
    91         {
    92             if (it->first <= debugLevel_)
    93             {
    94                 this->outputBuffer_ << it->second;
    95                 this->outputChanged(it->first);
    96             }
    97         }
    98 
    99         // Register the shell as output listener
    100         OutputHandler::getInstance().registerOutputListener(this);
    101         OutputHandler::getInstance().setSoftDebugLevel(consoleName_, debugLevel_);
    102     }
    103 
    104     /**
    105         @brief Destructor: Unregisters the shell from OutputHandler.
     90        MemoryWriter::getInstance().resendOutput(this);
     91    }
     92
     93    /**
     94        @brief Destructor
    10695    */
    10796    Shell::~Shell()
    10897    {
    109         OutputHandler::getInstance().unregisterOutputListener(this);
    11098        this->inputBuffer_->destroy();
    111     }
    112 
    113     namespace DefaultLogLevel
    114     {
    115         const OutputLevel::Value Dev  = OutputLevel::Info;
    116         const OutputLevel::Value User = OutputLevel::Error;
     99
     100        OutputManager::getInstance().unregisterListener(this);
    117101    }
    118102
     
    129113        SetConfigValue(cacheSize_s, 32);
    130114
    131         // Choose the default level according to the path Orxonox was started (build directory or not)
    132         OutputLevel::Value defaultDebugLevel = (PathConfig::buildDirectoryRun() ? DefaultLogLevel::Dev : DefaultLogLevel::User);
    133         SetConfigValueExternal(debugLevel_, "OutputHandler", "debugLevel" + consoleName_, defaultDebugLevel)
    134             .description("The maximum level of debug output shown in the " + consoleName_);
    135         OutputHandler::getInstance().setSoftDebugLevel(consoleName_, debugLevel_);
     115        SetConfigValueExternal(this->configurableMaxLevel_,
     116                               this->getConfigurableSectionName(),
     117                               this->getConfigurableMaxLevelName(),
     118                               this->configurableMaxLevel_)
     119            .description("The maximum level of output shown in the " + this->getName())
     120            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableLevel);
     121        SetConfigValueExternal(this->configurableAdditionalContextsMaxLevel_,
     122                               this->getConfigurableSectionName(),
     123                               this->getConfigurableAdditionalContextsMaxLevelName(),
     124                               this->configurableAdditionalContextsMaxLevel_)
     125            .description("The maximum level of output shown in the " + this->getName() + " for additional contexts")
     126            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableAdditionalContextsLevel);
     127        SetConfigValueExternal(this->configurableAdditionalContexts_,
     128                               this->getConfigurableSectionName(),
     129                               this->getConfigurableAdditionalContextsName(),
     130                               this->configurableAdditionalContexts_)
     131            .description("Additional output contexts shown in the " + this->getName())
     132            .callback(static_cast<BaseWriter*>(this), &BaseWriter::changedConfigurableAdditionalContexts);
    136133    }
    137134
     
    168165        if (isNormal)
    169166        {
    170             ModifyConfigValueExternal(debugLevel_, "debugLevel" + consoleName_, update);
     167            ModifyConfigValueExternal(this->configurableMaxLevel_, this->getConfigurableMaxLevelName(), update);
    171168        }
    172169        else
    173170        {
    174             OutputLevel::Value level = (value ? DefaultLogLevel::Dev : DefaultLogLevel::User);
    175             ModifyConfigValueExternal(debugLevel_, "debugLevel" + consoleName_, tset, level);
     171            OutputLevel level = (value ? DefaultLogLevel::Dev : DefaultLogLevel::User);
     172            ModifyConfigValueExternal(this->configurableMaxLevel_, this->getConfigurableMaxLevelName(), tset, level);
    176173        }
    177174    }
     
    252249
    253250    /**
    254         @brief Sends output to the internal output buffer.
     251        @brief Adds multiple lines to the internal output buffer.
    255252    */
    256253    void Shell::addOutput(const std::string& text, LineType type)
    257254    {
    258         this->outputBuffer_ << text;
    259         this->outputChanged(type);
     255        std::vector<std::string> lines;
     256        vectorize(text, '\n', &lines);
     257
     258        for (size_t i = 0; i < lines.size(); ++i)
     259            this->addLine(lines[i], type);
     260    }
     261
     262    /**
     263        @brief Adds a line to the internal output buffer.
     264    */
     265    void Shell::addLine(const std::string& line, LineType type)
     266    {
     267        // yes it was - push the new line to the list
     268        this->outputLines_.push_front(std::make_pair(line, static_cast<LineType>(type)));
     269
     270        // adjust the scroll position if needed
     271        if (this->scrollPosition_)
     272            this->scrollPosition_++;
     273        else
     274            this->scrollIterator_ = this->outputLines_.begin();
     275
     276        if (!this->scrollPosition_)
     277            this->updateListeners<&ShellListener::lineAdded>();
    260278    }
    261279
     
    269287
    270288        this->scrollPosition_ = 0;
    271         this->bFinishedLastLine_ = true;
    272289
    273290        this->updateListeners<&ShellListener::linesChanged>();
     291    }
     292
     293    /**
     294        @brief Inherited from BaseWriter (LogListener), called if a new line of output was sent.
     295    */
     296    void Shell::printLine(const std::string& line, OutputLevel level)
     297    {
     298        this->addLine(line, static_cast<LineType>(level));
    274299    }
    275300
     
    323348
    324349    /**
    325         @brief Called by OutputHandler or internally whenever output was sent to the output buffer. Reads from the buffer and writes the new output-lines to the list.
    326     */
    327     void Shell::outputChanged(int lineType)
    328     {
    329         bool newline = false;
    330         do
    331         {
    332             // get the first line from the buffer
    333             std::string output;
    334             std::getline(this->outputBuffer_, output);
    335 
    336             // check the state of the buffer
    337             bool eof = this->outputBuffer_.eof();
    338             bool fail = this->outputBuffer_.fail();
    339             if (eof)
    340                 this->outputBuffer_.flush(); // check if more output was received in the meantime
    341             if (eof || fail)
    342                 this->outputBuffer_.clear(); // clear the error flags
    343 
    344             // the line is terminated with a line-break if neither an error occurred nor the end of the file was reached
    345             newline = (!eof && !fail);
    346 
    347             // no output retrieved - break the loop
    348             if (!newline && output.empty())
    349                 break;
    350 
    351             // check if the last line was terminated with a line-break
    352             if (this->bFinishedLastLine_)
    353             {
    354                 // yes it was - push the new line to the list
    355                 this->outputLines_.push_front(std::make_pair(output, static_cast<LineType>(lineType)));
    356 
    357                 // adjust the scroll position if needed
    358                 if (this->scrollPosition_)
    359                     this->scrollPosition_++;
    360                 else
    361                     this->scrollIterator_ = this->outputLines_.begin();
    362 
    363                 if (!this->scrollPosition_)
    364                     this->updateListeners<&ShellListener::lineAdded>();
    365             }
    366             else
    367             {
    368                 // no it wasn't - add the new output to the last line
    369                 this->outputLines_.front().first += output;
    370                 this->updateListeners<&ShellListener::onlyLastLineChanged>();
    371             }
    372 
    373             // remember if the last line was terminated with a line-break
    374             this->bFinishedLastLine_ = newline;
    375 
    376         } while (newline); // loop as long as more lines are in the buffer
    377     }
    378 
    379     /**
    380350        @brief Clears the text in the input buffer.
    381351    */
     
    409379        const std::string& result = CommandExecutor::query(this->inputBuffer_->get(), &error);
    410380        if (error)
    411         {
    412             switch (error)
    413             {
    414                 case CommandExecutor::Error:       this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\", command doesn't exist. (S)" << std::endl; break;
    415                 case CommandExecutor::Incomplete:  this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\", not enough arguments given. (S)" << std::endl; break;
    416                 case CommandExecutor::Deactivated: this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\", command is not active. (S)" << std::endl; break;
    417                 case CommandExecutor::Denied:      this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\", access denied. (S)" << std::endl; break;
    418             }
    419             this->outputChanged(Error);
    420         }
     381            this->addOutput("Error: Can't execute \"" + this->inputBuffer_->get() + "\", " + CommandExecutor::getErrorDescription(error) + ". (Shell)", UserError);
    421382        else if (result != "")
    422         {
    423             this->outputBuffer_ << result << std::endl;
    424             this->outputChanged(Command);
    425         }
     383            this->addOutput(result, Result);
    426384
    427385        this->clearInput();
     
    432390    {
    433391        this->inputBuffer_->set(CommandExecutor::evaluate(this->inputBuffer_->get()).complete());
    434         this->outputBuffer_ << CommandExecutor::evaluate(this->inputBuffer_->get()).hint() << std::endl;
    435         this->outputChanged(Hint);
     392        this->addOutput(CommandExecutor::evaluate(this->inputBuffer_->get()).hint(), Hint);
    436393
    437394        this->inputChanged();
Note: See TracChangeset for help on using the changeset viewer.