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:
21 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

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

    r8351 r8858  
    9090            ArgumentCompletionList _groupsandcommands(const std::string& fragment, bool bOnlyShowHidden)
    9191            {
    92                 // note: this function returns only arguments that begin with "fragment", which would't be necessary for the
     92                // note: this function returns only arguments that begin with "fragment", which wouldn't be necessary for the
    9393                //       auto-completion, but it's necessary to place the line-break "\n" between groups and commands
    9494                //       only if both groups AND commands are in the list.
     
    100100                const std::map<std::string, std::map<std::string, ConsoleCommand*> >& commands = ConsoleCommand::getCommands();
    101101                for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = commands.begin(); it_group != commands.end(); ++it_group)
    102                     if (groupIsVisible(it_group->second, bOnlyShowHidden) && it_group->first != "" && (fragmentLC == "" || getLowercase(it_group->first).find_first_of(fragmentLC) == 0))
     102                    if (groupIsVisible(it_group->second, bOnlyShowHidden) && it_group->first != "" && (fragmentLC == "" || getLowercase(it_group->first).find(fragmentLC) == 0))
    103103                        groupList.push_back(ArgumentCompletionListElement(it_group->first, getLowercase(it_group->first)));
    104104
     
    113113                    // add the shortcuts
    114114                    for (std::map<std::string, ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command)
    115                         if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden && (fragmentLC == "" || getLowercase(it_command->first).find_first_of(fragmentLC) == 0))
     115                        if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden && (fragmentLC == "" || getLowercase(it_command->first).find(fragmentLC) == 0))
    116116                            groupList.push_back(ArgumentCompletionListElement(it_command->first, getLowercase(it_command->first)));
    117117                }
  • code/trunk/src/libraries/core/command/CommandEvaluation.cc

    r7401 r8858  
    131131
    132132            if (!this->execCommand_)
    133                 *error = CommandExecutor::Error;
     133                *error = CommandExecutor::Inexistent;
    134134            else if (!this->execCommand_->isActive())
    135135                *error = CommandExecutor::Deactivated;
     
    151151            if (this->bEvaluatedArguments_)
    152152            {
    153                 COUT(6) << "CE_execute (evaluation): " << this->execCommand_->getName() << " with " << this->numberOfEvaluatedArguments_ << " arguments: " << this->arguments_[0] << ' ' << this->arguments_[1] << ' ' << this->arguments_[2] << ' ' << this->arguments_[3] << ' ' << this->arguments_[4] << std::endl;
     153                orxout(verbose, context::commands) << "CE_execute (evaluation): " << this->execCommand_->getName() << " with " << this->numberOfEvaluatedArguments_ << " arguments: " << this->arguments_[0] << ' ' << this->arguments_[1] << ' ' << this->arguments_[2] << ' ' << this->arguments_[3] << ' ' << this->arguments_[4] << endl;
    154154
    155155                // pass as many arguments to the executor as were evaluated (thus the executor can still use additional default values)
     
    186186        {
    187187            if (bPrintError)
    188                 COUT(1) << "Error: Can't evaluate arguments, no console command assigned." << std::endl;
    189             return CommandExecutor::Error;
     188                orxout(internal_error, context::commands) << "Can't evaluate arguments, no console command assigned." << endl;
     189            return CommandExecutor::Inexistent;
    190190        }
    191191
     
    200200            this->bEvaluatedArguments_ = true;
    201201        else if (bPrintError)
    202             COUT(1) << "Error: Can't evaluate arguments, not enough arguments given." << std::endl;
     202            orxout(internal_error, context::commands) << "Can't evaluate arguments, not enough arguments given." << endl;
    203203
    204204        return error;
  • code/trunk/src/libraries/core/command/CommandExecutor.cc

    r7401 r8858  
    6969        @return Returns the error-code (see @ref CommandExecutorErrorCodes "error codes")
    7070    */
    71     /* static */ int CommandExecutor::execute(const std::string& command, bool useTcl)
     71    /* static */ int CommandExecutor::execute(const std::string& command, bool useTcl, bool printErrors)
    7272    {
    7373        int error;
    7474        CommandExecutor::queryMT(command, &error, useTcl);
     75        if (error && printErrors)
     76            orxout(user_error) << "Can't execute \"" << command << "\", " << CommandExecutor::getErrorDescription(error) << ". (execute)" << endl;
    7577        return error;
    7678    }
     
    8587    /* static */ MultiType CommandExecutor::queryMT(const std::string& command, int* error, bool useTcl)
    8688    {
     89        MultiType result;
     90        int error_internal;
     91
    8792        if (useTcl)
    8893        {
    8994            // pass the command to tcl
    90             return TclBind::eval(command, error);
     95            result = TclBind::eval(command, &error_internal);
    9196        }
    9297        else
     
    108113
    109114            // query the command and return its return-value
    110             return evaluation.query(error);
    111         }
     115            result = evaluation.query(&error_internal);
     116        }
     117
     118        if (error)
     119            *error = error_internal;
     120        else if (error_internal)
     121            orxout(user_error) << "Can't execute \"" << command << "\", " << CommandExecutor::getErrorDescription(error_internal) << ". (query)" << endl;
     122
     123        return result;
    112124    }
    113125
     
    172184
    173185    /**
     186        @brief Returns a description of the error code.
     187        @param error The error code
     188    */
     189    /* static */ std::string CommandExecutor::getErrorDescription(int error)
     190    {
     191        switch (error)
     192        {
     193            case CommandExecutor::Inexistent:  return "command doesn't exist";
     194            case CommandExecutor::Incomplete:  return "not enough arguments given";
     195            case CommandExecutor::Deactivated: return "command is not active";
     196            case CommandExecutor::Denied:      return "access denied";
     197            case CommandExecutor::Error:       return "an error occurred";
     198            default: return "";
     199        }
     200    }
     201
     202    /**
    174203        @brief Gets an evaluated command from the cache.
    175204        @param command The command that should be looked up in the cache
     
    261290            if ((tokens.size() == 1 && ConsoleCommand::getCommand(tokens[0])) || (tokens.size() == 2 && ConsoleCommand::getCommand(tokens[0], tokens[1])))
    262291            {
    263                 COUT(1) << "Error: A command with name \"" << alias << "\" already exists." << std::endl;
     292                orxout(user_error) << "A command with name \"" << alias << "\" already exists." << endl;
    264293                return;
    265294            }
     
    271300                createConsoleCommand(tokens[0], tokens[1], executor);
    272301            else
    273                 COUT(1) << "Error: \"" << alias << "\" is not a valid alias name (must have one or two words)." << std::endl;
     302                orxout(user_error) << "\"" << alias << "\" is not a valid alias name (must have one or two words)." << endl;
    274303        }
    275304        else
    276             COUT(1) << "Error: \"" << command << "\" is not a valid command (did you mean \"" << evaluation.getCommandSuggestion() << "\"?)." << std::endl;
     305            orxout(user_error) << "\"" << command << "\" is not a valid command (did you mean \"" << evaluation.getCommandSuggestion() << "\"?)." << endl;
    277306    }
    278307}
  • code/trunk/src/libraries/core/command/CommandExecutor.h

    r7401 r8858  
    111111// tolua_end
    112112        public:
    113             static int execute(const std::string& command, bool useTcl = true); // tolua_export
     113            static int execute(const std::string& command, bool useTcl = true, bool printErrors = true); // tolua_export
    114114
    115115            static MultiType queryMT(const std::string& command, int* error = 0, bool useTcl = true);
     
    119119
    120120            static const int Success = 0;       ///< Error code for "success" (or no error)
    121             static const int Error = 1;         ///< Error code if the command doesn't exist
     121            static const int Inexistent = 1;    ///< Error code if the command doesn't exist
    122122            static const int Incomplete = 2;    ///< Error code if the command needs more arguments
    123123            static const int Deactivated = 3;   ///< Error code if the command is not active
    124124            static const int Denied = 4;        ///< Error code if the command needs a different access level
     125            static const int Error = 5;         ///< Error code if the command returned an error
     126
     127            static std::string getErrorDescription(int error);
    125128
    126129            static MultiType unhide(const std::string& command);
  • code/trunk/src/libraries/core/command/ConsoleCommand.cc

    r8316 r8858  
    172172                if (!this->executor_->defaultValueSet(i))
    173173                {
    174                     COUT(2) << "Default value " << i << " is missing" << std::endl;
     174                    orxout(internal_warning, context::commands) << "Default value " << i << " is missing" << endl;
    175175                    return false;
    176176                }
     
    202202                if (!executor->defaultValueSet(i))
    203203                {
    204                     COUT(2) << "Default value " << i << " is missing" << std::endl;
     204                    orxout(internal_warning, context::commands) << "Default value " << i << " is missing" << endl;
    205205                    return false;
    206206                }
     
    229229        else
    230230        {
    231             COUT(1) << "Error: Couldn't assign new executor to console command \"" << this->baseName_ << "\", headers don't match." << std::endl;
     231            orxout(internal_error, context::commands) << "Couldn't assign new executor to console command \"" << this->baseName_ << "\", headers don't match." << endl;
    232232            return false;
    233233        }
     
    256256        else
    257257        {
    258             COUT(1) << "Error: Couldn't assign new functor to console command \"" << this->baseName_ << "\", headers don't match." << std::endl;
     258            orxout(internal_error, context::commands) << "Couldn't assign new functor to console command \"" << this->baseName_ << "\", headers don't match." << endl;
    259259            return false;
    260260        }
     
    307307            this->pushFunction(new Executor(*this->executor_.get()));
    308308        else
    309             COUT(1) << "Error: Couldn't push copy of executor in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     309            orxout(internal_error, context::commands) << "Couldn't push copy of executor in console command \"" << this->baseName_ << "\", no executor set." << endl;
    310310    }
    311311
     
    367367            }
    368368            else if (object)
    369                 COUT(1) << "Error: Can't assign object to console command \"" << this->baseName_ << "\", no functor set." << std::endl;
     369                orxout(internal_error, context::commands) << "Can't assign object to console command \"" << this->baseName_ << "\", no functor set." << endl;
    370370        }
    371371        else if (object)
    372             COUT(1) << "Error: Can't assign object to console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     372            orxout(internal_error, context::commands) << "Can't assign object to console command \"" << this->baseName_ << "\", no executor set." << endl;
    373373
    374374        return false;
     
    418418            this->executor_->setDefaultValues(arg1);
    419419        else
    420             COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     420            orxout(internal_error, context::commands) << "Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << endl;
    421421
    422422        return *this;
     
    431431            this->executor_->setDefaultValues(arg1, arg2);
    432432        else
    433             COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     433            orxout(internal_error, context::commands) << "Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << endl;
    434434
    435435        return *this;
     
    444444            this->executor_->setDefaultValues(arg1, arg2, arg3);
    445445        else
    446             COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     446            orxout(internal_error, context::commands) << "Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << endl;
    447447
    448448        return *this;
     
    457457            this->executor_->setDefaultValues(arg1, arg2, arg3, arg4);
    458458        else
    459             COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     459            orxout(internal_error, context::commands) << "Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << endl;
    460460
    461461        return *this;
     
    470470            this->executor_->setDefaultValues(arg1, arg2, arg3, arg4, arg5);
    471471        else
    472             COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     472            orxout(internal_error, context::commands) << "Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << endl;
    473473
    474474        return *this;
     
    485485            this->executor_->setDefaultValue(index, arg);
    486486        else
    487             COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     487            orxout(internal_error, context::commands) << "Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << endl;
    488488
    489489        return *this;
     
    500500            this->argumentCompleter_[index] = completer;
    501501        else
    502             COUT(2) << "Warning: Couldn't add autocompletion-function for index " << index << " in console command \"" << this->baseName_ << "\": index out of bound." << std::endl;
     502            orxout(internal_warning, context::commands) << "Couldn't add autocompletion-function for index " << index << " in console command \"" << this->baseName_ << "\": index out of bound." << endl;
    503503
    504504        return *this;
     
    611611        {
    612612            if (group == "")
    613                 COUT(1) << "Error: Couldn't find console command with shortcut \"" << name << "\"" << std::endl;
     613                orxout(internal_error, context::commands) << "Couldn't find console command with shortcut \"" << name << "\"" << endl;
    614614            else
    615                 COUT(1) << "Error: Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << std::endl;
     615                orxout(internal_error, context::commands) << "Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << endl;
    616616        }
    617617        return 0;
     
    644644        {
    645645            if (group == "")
    646                 COUT(1) << "Error: Couldn't find console command with shortcut \"" << name << "\"" << std::endl;
     646                orxout(internal_error, context::commands) << "Couldn't find console command with shortcut \"" << name << "\"" << endl;
    647647            else
    648                 COUT(1) << "Error: Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << std::endl;
     648                orxout(internal_error, context::commands) << "Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << endl;
    649649        }
    650650        return 0;
     
    681681        {
    682682            if (group == "")
    683                 COUT(2) << "Warning: A console command with shortcut \"" << name << "\" already exists." << std::endl;
     683                orxout(internal_warning, context::commands) << "A console command with shortcut \"" << name << "\" already exists." << endl;
    684684            else
    685                 COUT(2) << "Warning: A console command with name \"" << name << "\" already exists in group \"" << group << "\"." << std::endl;
     685                orxout(internal_warning, context::commands) << "A console command with name \"" << name << "\" already exists in group \"" << group << "\"." << endl;
    686686        }
    687687        else
  • code/trunk/src/libraries/core/command/ConsoleCommand.h

    r8418 r8858  
    5353    void myCoutFunction(const std::string& text)        // Define a static function
    5454    {
    55         COUT(0) << "Text: " << text << std::endl;       // Print the text to the console
     55        orxout() << "Text: " << text << endl;           // Print the text to the console
    5656    }
    5757
     
    125125    void myOtherCoutFunction(const std::string& text)                       // Define a new static function
    126126    {
    127         COUT(0) << "Uppercase: " << getUppercase(text) << std::endl;        // Print the text in uppercase to the console
     127        orxout() << "Uppercase: " << getUppercase(text) << endl;            // Print the text in uppercase to the console
    128128    }
    129129
  • code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc

    r8079 r8858  
    3838#include <string>
    3939
    40 #include "util/Debug.h"
     40#include "util/Output.h"
    4141#include "util/ExprParser.h"
    4242#include "util/StringUtils.h"
     
    4646namespace orxonox
    4747{
     48    SetConsoleCommand("echo", echo);
     49
     50    SetConsoleCommand("orxout", orxout_level);
     51    SetConsoleCommand("orxout_context", orxout_level_context);
     52
     53    SetConsoleCommand("log"    , log    );
     54    SetConsoleCommand("error"  , error  ).hide();
     55    SetConsoleCommand("warning", warning).hide();
     56    SetConsoleCommand("status" , status ).hide();
     57    SetConsoleCommand("info"   , info   ).hide();
     58    SetConsoleCommand("debug"  , debug  ).hide();
     59
    4860//    SetConsoleCommand("source", source).argumentCompleter(0, autocompletion::files());  // disabled because we use the implementation in Tcl
    49     SetConsoleCommand("echo", echo);
    50 //    SetConsoleCommand("puts", puts);                                                    // disabled because we use the implementation in Tcl
    51 
    5261//    SetConsoleCommand("read", read).argumentCompleter(0, autocompletion::files());      // disabled because we use the implementation in Tcl
    5362//    SetConsoleCommand("append", append).argumentCompleter(0, autocompletion::files());  // disabled because we use the implementation in Tcl
     
    5766
    5867    /**
     68        @brief Simply returns the arguments.
     69    */
     70    std::string echo(const std::string& text)
     71    {
     72        return text;
     73    }
     74
     75    /**
     76        @brief Builds a map that maps the levels of all output levels to their ID.
     77    */
     78    std::map<std::string, OutputLevel> getOutputLevelsMap()
     79    {
     80        std::map<std::string, OutputLevel> levels;
     81
     82        levels["message"]          = level::message;
     83        levels["debug_output"]     = level::debug_output;
     84        levels["user_error"]       = level::user_error;
     85        levels["user_warning"]     = level::user_warning;
     86        levels["user_status"]      = level::user_status;
     87        levels["user_info"]        = level::user_info;
     88        levels["internal_error"]   = level::internal_error;
     89        levels["internal_warning"] = level::internal_warning;
     90        levels["internal_status"]  = level::internal_status;
     91        levels["internal_info"]    = level::internal_info;
     92        levels["verbose"]          = level::verbose;
     93        levels["verbose_more"]     = level::verbose_more;
     94        levels["verbose_ultra"]    = level::verbose_ultra;
     95
     96        return levels;
     97    }
     98
     99    /**
     100        @brief Prints text to the console.
     101        @param level_name The name of the output level
     102    */
     103    void orxout_level(const std::string& level_name, const std::string& text)
     104    {
     105        static std::map<std::string, OutputLevel> levels = getOutputLevelsMap();
     106
     107        OutputLevel level = level::debug_output;
     108        std::map<std::string, OutputLevel>::iterator it = levels.find(level_name);
     109        if (it != levels.end())
     110            level = it->second;
     111        else
     112            orxout(internal_warning) << "'" << level_name << "' is not a valid output level" << endl;
     113
     114        orxout(level) << text << endl;
     115    }
     116
     117    /**
     118        @brief Prints text to the console.
     119        @param level_name The name of the output level
     120        @param context_name The name of the output context
     121    */
     122    void orxout_level_context(const std::string& level_name, const std::string& context_name, const std::string& text)
     123    {
     124        static std::map<std::string, OutputLevel> levels = getOutputLevelsMap();
     125
     126        OutputLevel level = level::debug_output;
     127        std::map<std::string, OutputLevel>::iterator it = levels.find(level_name);
     128        if (it != levels.end())
     129            level = it->second;
     130        else
     131            orxout(internal_warning) << "'" << level_name << "' is not a valid output level" << endl;
     132
     133        OutputContextContainer context = registerContext(context_name);
     134
     135        orxout(level, context) << text << endl;
     136    }
     137
     138    /// @brief Prints text to the console and the logfile.
     139    void log(const std::string& text)
     140    { orxout() << text << endl; }
     141
     142    /// @brief Prints output with error level.
     143    void error(const std::string& text)
     144    { orxout(user_error) << text << endl; }
     145
     146    /// @brief Prints output with warning level.
     147    void warning(const std::string& text)
     148    { orxout(user_warning) << text << endl; }
     149
     150    /// @brief Prints output with status level.
     151    void status(const std::string& text)
     152    { orxout(user_status) << text << endl; }
     153
     154    /// @brief Prints output with info level.
     155    void info(const std::string& text)
     156    { orxout(user_info) << text << endl; }
     157
     158    /// @brief Prints debug output with verbose level.
     159    void debug(const std::string& text)
     160    { orxout(verbose, context::tcl) << text << endl; }
     161
     162    /**
    59163        @brief Reads the content of a file and executes the commands in it line by line.
    60164    */
     
    66170        if (it != executingFiles.end())
    67171        {
    68             COUT(1) << "Error: Recurring source command in \"" << filename << "\". Stopped execution." << std::endl;
     172            orxout(user_error) << "Recurring source command in \"" << filename << "\". Stopped execution." << endl;
    69173            return;
    70174        }
     
    76180        if (!file.is_open())
    77181        {
    78             COUT(1) << "Error: Couldn't open file \"" << filename << "\"." << std::endl;
     182            orxout(user_error) << "Couldn't open file \"" << filename << "\"." << endl;
    79183            return;
    80184        }
     
    95199
    96200    /**
    97         @brief Simply returns the arguments.
    98     */
    99     std::string echo(const std::string& text)
    100     {
    101         return text;
    102     }
    103 
    104     /**
    105         @brief Writes text to the console, depending on the first argument with or without a line-break after it.
    106     */
    107     void puts(bool newline, const std::string& text)
    108     {
    109         if (newline)
    110         {
    111             COUT(0) << stripEnclosingBraces(text) << std::endl;
    112         }
    113         else
    114         {
    115             COUT(0) << stripEnclosingBraces(text);
    116         }
    117     }
    118 
    119     /**
    120201        @brief Writes text to a file.
    121202    */
     
    127208        if (!file.is_open())
    128209        {
    129             COUT(1) << "Error: Couldn't write to file \"" << filename << "\"." << std::endl;
    130             return;
    131         }
    132 
    133         file << text << std::endl;
     210            orxout(user_error) << "Couldn't write to file \"" << filename << "\"." << endl;
     211            return;
     212        }
     213
     214        file << text << endl;
    134215        file.close();
    135216    }
     
    145226        if (!file.is_open())
    146227        {
    147             COUT(1) << "Error: Couldn't append to file \"" << filename << "\"." << std::endl;
    148             return;
    149         }
    150 
    151         file << text << std::endl;
     228            orxout(user_error) << "Couldn't append to file \"" << filename << "\"." << endl;
     229            return;
     230        }
     231
     232        file << text << endl;
    152233        file.close();
    153234    }
     
    163244        if (!file.is_open())
    164245        {
    165             COUT(1) << "Error: Couldn't read from file \"" << filename << "\"." << std::endl;
     246            orxout(user_error) << "Couldn't read from file \"" << filename << "\"." << endl;
    166247            return "";
    167248        }
     
    192273            if (expr.getResult() == 42.0)
    193274            {
    194                 COUT(3) << "Greetings from the restaurant at the end of the universe." << std::endl;
     275                orxout(user_info) << "Greetings from the restaurant at the end of the universe." << endl;
    195276            }
    196277            if (!expr.getRemains().empty())
    197278            {
    198                 COUT(2) << "Warning: Expression could not be parsed to the end! Remains: '" << expr.getRemains() << '\'' << std::endl;
     279                orxout(user_warning) << "Expression could not be parsed to the end! Remains: '" << expr.getRemains() << '\'' << endl;
    199280            }
    200281            return static_cast<float>(expr.getResult());
     
    202283        else
    203284        {
    204             COUT(1) << "Error: Cannot calculate expression: Parse error." << std::endl;
     285            orxout(user_error) << "Cannot calculate expression: Parse error." << endl;
    205286            return 0;
    206287        }
  • code/trunk/src/libraries/core/command/ConsoleCommandCompilation.h

    r7401 r8858  
    4242    _CoreExport void source(const std::string& filename);
    4343    _CoreExport std::string echo(const std::string& text);
    44     _CoreExport void puts(bool newline, const std::string& test);
     44
     45    _CoreExport void orxout_level(const std::string& level_name, const std::string& text);
     46    _CoreExport void orxout_level_context(const std::string& level_name, const std::string& context_name, const std::string& text);
     47
     48    _CoreExport void log(const std::string& text);
     49    _CoreExport void error(const std::string& text);
     50    _CoreExport void warning(const std::string& text);
     51    _CoreExport void status(const std::string& text);
     52    _CoreExport void info(const std::string& text);
     53    _CoreExport void debug(const std::string& text);
    4554
    4655    _CoreExport void write(const std::string& filename, const std::string& text);
  • code/trunk/src/libraries/core/command/Executor.cc

    r7401 r8858  
    3838
    3939#include "util/Convert.h"
    40 #include "util/Debug.h"
     40#include "util/Output.h"
    4141#include "util/StringUtils.h"
    4242#include "util/SubString.h"
     
    104104        {
    105105            if (bPrintError)
    106                 COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough arguments or default values given (input: " << arguments.join() << ")." << std::endl;
     106                orxout(internal_warning) << "Can't call executor " << this->name_ << " through parser: Not enough arguments or default values given (input: " << arguments.join() << ")." << endl;
    107107            return MT_Type::Null;
    108108        }
    109109
    110         COUT(5) << "Executor::parse: \"" << arguments.join(delimiter) << "\" -> " << argCount << " arguments: " << arg[0] << " / " << arg[1] << " / " << arg[2] << " / " << arg[3] << " / " << arg[4] << std::endl;
     110        orxout(verbose, context::misc::executor) << "Executor::parse: \"" << arguments.join(delimiter) << "\" -> " << argCount << " arguments: " << arg[0] << " / " << arg[1] << " / " << arg[2] << " / " << arg[3] << " / " << arg[4] << endl;
    111111
    112112        // execute the function with the evaluated arguments (the default values of the executor are also included in these arguments)
  • code/trunk/src/libraries/core/command/Executor.h

    r7401 r8858  
    5757    void myFunction(int a, int b)                           // declare a static function
    5858    {
    59         COUT(0) << "The sum is " << (a + b) << std::endl;   // print the sum of a and b to the console
     59        orxout() << "The sum is " << (a + b) << endl;       // print the sum of a and b to the console
    6060    }
    6161
  • code/trunk/src/libraries/core/command/Functor.h

    r8729 r8858  
    118118#include <typeinfo>
    119119
    120 #include "util/Debug.h"
     120#include "util/Output.h"
    121121#include "util/MultiType.h"
    122122#include "core/OrxonoxClass.h"
     
    256256                else
    257257                {
    258                     COUT(1) << "Error: Can't execute FunctorMember, no object set." << std::endl;
     258                    orxout(internal_error) << "Can't execute FunctorMember, no object set." << endl;
    259259                    return MT_Type::Null;
    260260                }
     
    339339            // see Functor::setRawObjectPointer()
    340340            inline void setRawObjectPointer(void*)
    341                 { COUT(2) << "Warning: Can't assign an object pointer to a static functor" << std::endl; }
     341                { orxout(internal_warning) << "Can't assign an object pointer to a static functor" << endl; }
    342342            // see Functor::getRawObjectPointer()
    343343            inline void* getRawObjectPointer() const
  • code/trunk/src/libraries/core/command/IOConsolePOSIX.cc

    r8729 r8858  
    3737#include "util/Clock.h"
    3838#include "util/Math.h"
     39#include "util/output/ConsoleWriter.h"
    3940#include "core/Game.h"
    4041#include "core/input/InputBuffer.h"
     
    5556
    5657    IOConsole::IOConsole()
    57         : shell_(new Shell("IOConsole", false))
     58        : shell_(new Shell("Console", false))
    5859        , buffer_(shell_->getInputBuffer())
    5960        , cout_(std::cout.rdbuf())
     
    7475
    7576        // Disable standard std::cout logging
    76         OutputHandler::getInstance().disableCout();
     77        ConsoleWriter::getInstance().disable();
    7778        // Redirect std::cout to an ostringstream
    7879        // (Other part is in the initialiser list)
     
    8889        std::cout.flush();
    8990        if (!this->origCout_.str().empty())
    90             this->shell_->addOutput(this->origCout_.str(), Shell::None);
     91            this->shell_->addOutput(this->origCout_.str(), Shell::Cout);
    9192        // Erase input and status lines
    9293        this->cout_ << "\033[1G\033[J";
     
    102103        std::cout.rdbuf(this->cout_.rdbuf());
    103104        // Enable standard std::cout logging again
    104         OutputHandler::getInstance().enableCout();
     105        ConsoleWriter::getInstance().enable();
    105106    }
    106107
     
    229230        if (!this->origCout_.str().empty())
    230231        {
    231             this->shell_->addOutput(this->origCout_.str(), Shell::None);
     232            this->shell_->addOutput(this->origCout_.str(), Shell::Cout);
    232233            this->origCout_.str("");
    233234        }
     
    239240        switch (type)
    240241        {
    241         case Shell::Error:   this->cout_ << "\033[91m"; break;
    242         case Shell::Warning: this->cout_ << "\033[93m"; break;
    243         case Shell::Info:    this->cout_ << "\033[90m"; break;
    244         case Shell::Debug:   this->cout_ << "\033[90m"; break;
    245         case Shell::Verbose: this->cout_ << "\033[90m"; break;
    246         case Shell::Ultra:   this->cout_ << "\033[90m"; break;
    247         case Shell::Command: this->cout_ << "\033[36m"; break;
    248         case Shell::Hint:    this->cout_ << "\033[33m"; break;
    249         case Shell::TDebug:  this->cout_ << "\033[95m"; break;
    250         default: break;
     242            case Shell::Message:
     243            case Shell::DebugOutput:     this->cout_ << "\033[0m"; break;
     244
     245            case Shell::UserError:       this->cout_ << "\033[91m"; break;
     246            case Shell::UserWarning:     this->cout_ << "\033[93m"; break;
     247            case Shell::UserStatus:      this->cout_ << "\033[92m"; break;
     248            case Shell::UserInfo:        this->cout_ << "\033[96m"; break;
     249
     250            case Shell::InternalError:   this->cout_ << "\033[31m"; break;
     251            case Shell::InternalWarning: this->cout_ << "\033[33m"; break;
     252            case Shell::InternalStatus:  this->cout_ << "\033[32m"; break;
     253            case Shell::InternalInfo:    this->cout_ << "\033[36m"; break;
     254
     255            case Shell::Verbose:         this->cout_ << "\033[94m"; break;
     256            case Shell::VerboseMore:     this->cout_ << "\033[34m"; break;
     257            case Shell::VerboseUltra:    this->cout_ << "\033[34m"; break;
     258
     259            case Shell::Command:         this->cout_ << "\033[95m"; break;
     260            case Shell::Hint:            this->cout_ << "\033[35m"; break;
     261
     262            default:                     this->cout_ << "\033[37m"; break;
    251263        }
    252264
     
    371383    void IOConsole::executed()
    372384    {
    373         this->shell_->addOutput(this->promptString_ + this->shell_->getInput() + '\n', Shell::Command);
     385        this->shell_->addOutput(this->promptString_ + this->shell_->getInput(), Shell::Command);
    374386    }
    375387
     
    378390    {
    379391        // Exit is not an option, just do nothing (Shell doesn't really exit too)
    380     }
    381 
    382     //! Called if only the last output-line has changed
    383     void IOConsole::onlyLastLineChanged()
    384     {
    385         // Save cursor position and move it to the beginning of the first output line
    386         this->cout_ << "\033[s\033[1A\033[1G";
    387         // Erase the line
    388         this->cout_ << "\033[K";
    389         // Reprint the last output line
    390         this->printOutputLine(this->shell_->getNewestLineIterator()->first, this->shell_->getNewestLineIterator()->second);
    391         // Restore cursor
    392         this->cout_ << "\033[u";
    393         this->cout_.flush();
    394392    }
    395393
  • code/trunk/src/libraries/core/command/IOConsolePOSIX.h

    r7401 r8858  
    6666        // Methods from ShellListener
    6767        void linesChanged();
    68         void onlyLastLineChanged();
    6968        void lineAdded();
    7069        void inputChanged();
  • code/trunk/src/libraries/core/command/IOConsoleWindows.cc

    r8729 r8858  
    3434#include "util/Clock.h"
    3535#include "util/Math.h"
     36#include "util/output/ConsoleWriter.h"
    3637#include "core/Game.h"
    3738#include "core/input/InputBuffer.h"
     
    4344    //! Redirects std::cout, creates the corresponding Shell and changes the terminal mode
    4445    IOConsole::IOConsole()
    45         : shell_(new Shell("IOConsole", false))
     46        : shell_(new Shell("Console", false))
    4647        , buffer_(shell_->getInputBuffer())
    4748        , cout_(std::cout.rdbuf())
     
    5253    {
    5354        // Disable standard this->cout_ logging
    54         OutputHandler::getInstance().disableCout();
     55        ConsoleWriter::getInstance().disable();
    5556        // Redirect std::cout to an ostringstream
    5657        // (Other part is in the initialiser list)
     
    9596        std::cout.flush();
    9697        if (!this->origCout_.str().empty())
    97             this->shell_->addOutput(this->origCout_.str(), Shell::None);
     98            this->shell_->addOutput(this->origCout_.str(), Shell::Cout);
    9899
    99100        this->shell_->unregisterListener(this);
     
    108109        std::cout.rdbuf(this->cout_.rdbuf());
    109110        // Enable standard this->cout_ logging again
    110         OutputHandler::getInstance().enableCout();
     111        ConsoleWriter::getInstance().enable();
    111112
    112113        resetTerminalMode();
     
    188189        if (!this->origCout_.str().empty())
    189190        {
    190             this->shell_->addOutput(this->origCout_.str(), Shell::None);
     191            this->shell_->addOutput(this->origCout_.str(), Shell::Cout);
    191192            this->origCout_.str("");
    192193        }
     
    200201        switch (type)
    201202        {
    202         case Shell::Error:   colour = FOREGROUND_INTENSITY                    | FOREGROUND_RED; break;
    203         case Shell::Warning: colour = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED; break;
    204         case Shell::Info:
    205         case Shell::Debug:
    206         case Shell::Verbose:
    207         case Shell::Ultra:   colour = FOREGROUND_INTENSITY                                     ; break;
    208         case Shell::Command: colour =                        FOREGROUND_GREEN                  | FOREGROUND_BLUE; break;
    209         case Shell::Hint:    colour =                        FOREGROUND_GREEN | FOREGROUND_RED                  ; break;
    210         case Shell::TDebug:  colour = FOREGROUND_INTENSITY                    | FOREGROUND_RED | FOREGROUND_BLUE; break;
    211         default:             colour =                        FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE; break;
     203            case Shell::Message:
     204            case Shell::DebugOutput:     colour = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
     205
     206            case Shell::UserError:       colour = FOREGROUND_INTENSITY | FOREGROUND_RED | 0                | 0              ; break;
     207            case Shell::UserWarning:     colour = FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN | 0              ; break;
     208            case Shell::UserStatus:      colour = FOREGROUND_INTENSITY | 0              | FOREGROUND_GREEN | 0              ; break;
     209            case Shell::UserInfo:        colour = FOREGROUND_INTENSITY | 0              | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
     210
     211            case Shell::InternalError:   colour = 0                    | FOREGROUND_RED | 0                | 0              ; break;
     212            case Shell::InternalWarning: colour = 0                    | FOREGROUND_RED | FOREGROUND_GREEN | 0              ; break;
     213            case Shell::InternalStatus:  colour = 0                    | 0              | FOREGROUND_GREEN | 0              ; break;
     214            case Shell::InternalInfo:    colour = 0                    | 0              | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
     215
     216            case Shell::Verbose:         colour = FOREGROUND_INTENSITY | 0              | 0                | FOREGROUND_BLUE; break;
     217            case Shell::VerboseMore:     colour = FOREGROUND_INTENSITY | 0              | 0                | FOREGROUND_BLUE; break;
     218            case Shell::VerboseUltra:    colour = FOREGROUND_INTENSITY | 0              | 0                | FOREGROUND_BLUE; break;
     219
     220            case Shell::Command:         colour = FOREGROUND_INTENSITY | FOREGROUND_RED | 0                | FOREGROUND_BLUE; break;
     221            case Shell::Hint:            colour = 0                    | FOREGROUND_RED | 0                | FOREGROUND_BLUE; break;
     222
     223            default:                     colour = 0                    | FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; break;
    212224        }
    213225
     
    238250            || !SetConsoleMode(this->stdInHandle_, 0))
    239251        {
    240             COUT(1) << "Error: Could not set Windows console settings" << std::endl;
     252            orxout(user_error) << "Could not set Windows console settings" << endl;
    241253            return;
    242254        }
     
    318330    void IOConsole::executed()
    319331    {
    320         this->shell_->addOutput(this->promptString_ + this->shell_->getInput() + '\n', Shell::Command);
     332        this->shell_->addOutput(this->promptString_ + this->shell_->getInput(), Shell::Command);
    321333    }
    322334
     
    377389    }
    378390
    379     //! Called if only the last output-line has changed
    380     void IOConsole::onlyLastLineChanged()
    381     {
    382         int newLineHeight = 1 + this->shell_->getNewestLineIterator()->first.size() / this->terminalWidth_;
    383         // Compute the number of new lines needed
    384         int newLines = newLineHeight - this->lastOutputLineHeight_;
    385         this->lastOutputLineHeight_ = newLineHeight;
    386         // Scroll console if necessary
    387         if (newLines > 0) // newLines < 0 is assumed impossible
    388             this->createNewOutputLines(newLines);
    389         Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
    390         this->printOutputLine(it->first, it->second, makeCOORD(0, this->inputLineRow_ - newLineHeight));
    391     }
    392 
    393391    //! Called if a new output line was added
    394392    void IOConsole::lineAdded()
  • code/trunk/src/libraries/core/command/IOConsoleWindows.h

    r8729 r8858  
    6868        // Methods from ShellListener
    6969        void linesChanged();
    70         void onlyLastLineChanged();
    7170        void lineAdded();
    7271        void inputChanged();
  • code/trunk/src/libraries/core/command/IRC.cc

    r7401 r8858  
    8585        }
    8686        catch (Tcl::tcl_error const &e)
    87         {   COUT(1) << "Tcl (IRC) error: " << e.what();   }
     87        {   orxout(user_error, context::tcl) << "Tcl (IRC) error: " << e.what() << endl;   }
    8888
    8989        this->nickname_ = "orx" + multi_cast<std::string>(static_cast<unsigned int>(rand()));
     
    100100        {
    101101            IRC::getInstance().initialize();
    102             COUT(1) << "Error: IRC client wasn't yet initialized, please try again." << std::endl;
     102            orxout(user_error) << "IRC client wasn't yet initialized, please try again." << endl;
    103103            return false;
    104104        }
     
    110110        }
    111111        catch (Tcl::tcl_error const &e)
    112         {   COUT(1) << "Tcl (IRC) error: " << e.what();   }
     112        {   orxout(user_error, context::tcl) << "Tcl (IRC) error: " << e.what() << endl;   }
    113113
    114114        return false;
     
    139139    void IRC::tcl_say(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
    140140    {
    141         COUT(0) << "IRC> " << nick.get() << ": " << stripEnclosingBraces(args.get()) << std::endl;
     141        orxout(message) << "IRC> " << nick.get() << ": " << stripEnclosingBraces(args.get()) << endl;
    142142    }
    143143
     
    145145    void IRC::tcl_privmsg(Tcl::object const &query, Tcl::object const &nick, Tcl::object const &args)
    146146    {
    147         COUT(0) << "IRC (" << query.get() << ")> " << nick.get() << ": " << stripEnclosingBraces(args.get()) << std::endl;
     147        orxout(message) << "IRC (" << query.get() << ")> " << nick.get() << ": " << stripEnclosingBraces(args.get()) << endl;
    148148    }
    149149
     
    151151    void IRC::tcl_action(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
    152152    {
    153         COUT(0) << "IRC> * " << nick.get() << ' ' << stripEnclosingBraces(args.get()) << std::endl;
     153        orxout(message) << "IRC> * " << nick.get() << ' ' << stripEnclosingBraces(args.get()) << endl;
    154154    }
    155155
     
    157157    void IRC::tcl_info(Tcl::object const &channel, Tcl::object const &args)
    158158    {
    159         COUT(0) << "IRC> --> " << stripEnclosingBraces(args.get()) << std::endl;
     159        orxout(message) << "IRC> --> " << stripEnclosingBraces(args.get()) << endl;
    160160    }
    161161}
  • 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();
  • code/trunk/src/libraries/core/command/Shell.h

    r8729 r8858  
    4848#include <vector>
    4949
    50 #include "util/OutputHandler.h"
     50#include "util/output/BaseWriter.h"
    5151#include "core/Core.h"
    5252#include "core/OrxonoxClass.h"
     
    6666        private:
    6767            virtual void linesChanged() {}          ///< Called if all output-lines have changed
    68             virtual void onlyLastLineChanged() {}   ///< Called if only the last output-line has changed
    6968            virtual void lineAdded() {}             ///< Called if a new line was added to the output
    7069            virtual void inputChanged() {}          ///< Called if the input has changed
     
    7877        @brief The Shell is the logical component of the console that displays output to the user and allows him to enter commands.
    7978
    80         The Shell gathers output sent from OutputHandler by inheriting from OutputListener.
     79        The Shell gathers output sent from OutputManager by inheriting from BaseWriter.
    8180        The output-lines are stored in the shell, so they can be displayed in a graphical
    8281        console. Additionally the Shell has an InputBuffer which is needed by the user to
     
    8584        Different graphical consoles build upon a Shell, for example InGameConsole and IOConsole.
    8685    */
    87     class _CoreExport Shell : public OutputListener, public DevModeListener
     86    class _CoreExport Shell : public BaseWriter, public DevModeListener
    8887    {
    8988        public:
     
    9190            enum LineType
    9291            {
    93                 TDebug  = OutputLevel::TDebug,
    94                 None    = OutputLevel::None,
    95                 Warning = OutputLevel::Warning,
    96                 Error   = OutputLevel::Error,
    97                 Info    = OutputLevel::Info,
    98                 Debug   = OutputLevel::Debug,
    99                 Verbose = OutputLevel::Verbose,
    100                 Ultra   = OutputLevel::Ultra,
     92                DebugOutput     = debug_output,
     93                Message         = message,
     94                UserError       = user_error,
     95                UserWarning     = user_warning,
     96                UserStatus      = user_status,
     97                UserInfo        = user_info,
     98                InternalError   = internal_error,
     99                InternalWarning = internal_warning,
     100                InternalStatus  = internal_status,
     101                InternalInfo    = internal_info,
     102                Verbose         = verbose,
     103                VerboseMore     = verbose_more,
     104                VerboseUltra    = verbose_ultra,
     105                Cout,
    101106                Input,
    102107                Command,
     108                Result,
    103109                Hint
    104110            };
     
    127133            LineList::const_iterator getEndIterator() const;
    128134
    129             void addOutput(const std::string& text, LineType type = None);
     135            void addOutput(const std::string& text, LineType type = DebugOutput);
     136            void addLine(const std::string& line, LineType type = DebugOutput);
    130137            void clearOutput();
    131138
     
    150157            const std::string& getFromHistory() const;
    151158            void clearInput();
    152             // OutputListener
    153             void outputChanged(int level);
     159            // BaseWriter
     160            virtual void printLine(const std::string& line, OutputLevel level);
    154161
    155162            void configureInputBuffer();
     
    183190            std::list<ShellListener*> listeners_;           ///< The registered shell listeners
    184191            InputBuffer*              inputBuffer_;         ///< The input buffer that is needed by the user to enter text
    185             std::stringstream         outputBuffer_;        ///< The output buffer that is used to retrieve lines of output from OutputListener
    186             bool                      bFinishedLastLine_;   ///< Stores if the most recent output-line was terminated with a line-break or if more output is expected for this line
    187192            LineList                  outputLines_;         ///< A list of all output-lines that were displayed in the shell so far
    188193            LineList::const_iterator  scrollIterator_;      ///< An iterator to an entry of the list of output-lines, changes if the user scrolls through the output in the shell
    189194            unsigned int              scrollPosition_;      ///< The number of the line that is currently being referenced by scrollIterator_
    190195            unsigned int              historyPosition_;     ///< If the user scrolls through the history of entered commands (stored in commandHistory_), this contains the currently viewed history entry
    191 
    192             const std::string         consoleName_;         ///< The name of this shell - used to define the name of the soft-debug-level config-value
    193196            const bool                bScrollable_;         ///< If true, the user can scroll through the output-lines
    194197
     
    197200            unsigned int              historyOffset_;       ///< The command history is a circular buffer, this variable defines the current write-offset
    198201            std::vector<std::string>  commandHistory_;      ///< The history of commands that were entered by the user
    199             int                       debugLevel_;          //!< The maximum level of output that is displayed in the shell (will be passed to OutputListener to filter output)
    200202            static unsigned int       cacheSize_s;          ///< The maximum cache size of the CommandExecutor - this is stored here for better readability of the config file and because CommandExecutor is no OrxonoxClass
    201203    };
  • code/trunk/src/libraries/core/command/TclBind.cc

    r8366 r8858  
    3434
    3535#include "SpecialConfig.h"
    36 #include "util/Debug.h"
     36#include "util/Output.h"
    3737#include "util/Exception.h"
    3838#include "util/StringUtils.h"
     
    106106            }
    107107            catch (Tcl::tcl_error const &e)
    108             {   COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl;   }
     108            {   orxout(internal_error, context::tcl) << "Tcl error while creating Tcl-interpreter: " << e.what() << endl;   }
    109109        }
    110110    }
     
    129129        }
    130130        catch (Tcl::tcl_error const &e)
    131         {   COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl; COUT(1) << "Error: Tcl isn't properly initialized. Orxonox might possibly not work like that." << std::endl;   }
     131        {
     132            orxout(internal_error, context::tcl) << "Tcl error while creating Tcl-interpreter: " << e.what() << endl;
     133            orxout(user_error, context::tcl) << "Tcl isn't properly initialized. Orxonox might possibly not work like that." << endl;
     134        }
    132135
    133136        return interpreter;
     
    154157    std::string TclBind::tcl_query(Tcl::object const &args)
    155158    {
    156         COUT(4) << "Tcl_query: " << args.get() << std::endl;
     159        orxout(verbose, context::commands) << "Tcl_query: " << args.get() << endl;
    157160        return TclBind::tcl_helper(args, true);
    158161    }
     
    163166    void TclBind::tcl_execute(Tcl::object const &args)
    164167    {
    165         COUT(4) << "Tcl_execute: " << args.get() << std::endl;
     168        orxout(verbose, context::commands) << "Tcl_execute: " << args.get() << endl;
    166169        TclBind::tcl_helper(args, false);
    167170    }
     
    184187            error = evaluation.execute();
    185188
    186         switch (error)
    187         {
    188             case CommandExecutor::Error:       COUT(1) << "Error: Can't execute command \"" << command << "\", command doesn't exist. (B)" << std::endl; break;
    189             case CommandExecutor::Incomplete:  COUT(1) << "Error: Can't execute command \"" << command << "\", not enough arguments given. (B)" << std::endl; break;
    190             case CommandExecutor::Deactivated: COUT(1) << "Error: Can't execute command \"" << command << "\", command is not active. (B)" << std::endl; break;
    191             case CommandExecutor::Denied:      COUT(1) << "Error: Can't execute command \"" << command << "\", access denied. (B)" << std::endl; break;
    192         }
    193 
    194         if (error == CommandExecutor::Error)
    195             COUT(3) << "Did you mean \"" << evaluation.getCommandSuggestion() << "\"?" << std::endl;
     189        if (error)
     190        {
     191            orxout(user_error) << "Can't execute command \"" << command << "\", " + CommandExecutor::getErrorDescription(error) + ". (TclBind)" << endl;
     192            if (error == CommandExecutor::Inexistent)
     193                orxout(user_info) << "Did you mean \"" << evaluation.getCommandSuggestion() << "\"?" << endl;
     194        }
    196195
    197196        return result;
     
    211210            }
    212211            catch (Tcl::tcl_error const &e)
    213             {   COUT(1) << "Tcl error: " << e.what() << std::endl;   }
     212            {   orxout(user_error, context::tcl) << "Tcl error: " << e.what() << endl;   }
    214213        }
    215214
     
    223222    void TclBind::bgerror(const std::string& error)
    224223    {
    225         COUT(1) << "Tcl background error: " << stripEnclosingBraces(error) << std::endl;
     224        orxout(user_error, context::tcl) << "Tcl background error: " << stripEnclosingBraces(error) << endl;
    226225    }
    227226
     
    243242        }
    244243        catch (Tcl::tcl_error const &e)
    245         {   COUT(1) << "Tcl error: " << e.what() << std::endl;   }
     244        {   orxout(user_error, context::tcl) << "Tcl error: " << e.what() << endl;   }
    246245
    247246        if (error)
  • code/trunk/src/libraries/core/command/TclThreadManager.cc

    r8351 r8858  
    225225        TclThreadManager::getInstance().numInterpreterBundles_++;
    226226        TclThreadManager::createWithId(TclThreadManager::getInstance().numInterpreterBundles_);
    227         COUT(0) << "Created new Tcl-interpreter with ID " << TclThreadManager::getInstance().numInterpreterBundles_ << std::endl;
     227        orxout(user_info) << "Created new Tcl-interpreter with ID " << TclThreadManager::getInstance().numInterpreterBundles_ << endl;
    228228        return TclThreadManager::getInstance().numInterpreterBundles_;
    229229    }
     
    288288        }
    289289        catch (const Tcl::tcl_error& e)
    290         {   bundle->interpreter_ = 0; COUT(1) << "Tcl error while creating Tcl-interpreter (" << id_string << "): " << e.what() << std::endl;   }
     290        {
     291            bundle->interpreter_ = 0;
     292            orxout(user_error, context::tcl) << "Tcl error while creating Tcl-interpreter (" << id_string << "): " << e.what() << endl;
     293        }
    291294    }
    292295
     
    407410            {
    408411                // This query would lead to a deadlock - return with an error
    409                 TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + ' ' + multi_cast<std::string>(source_bundle->id_) \
     412                TclThreadManager::error("Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + ' ' + multi_cast<std::string>(source_bundle->id_) \
    410413                            + " -> " + multi_cast<std::string>(target_bundle->id_) \
    411414                            + "), couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(target_bundle->id_) \
     
    446449                        int error;
    447450                        output = CommandExecutor::query(command, &error, false);
    448                         switch (error)
    449                         {
    450                             case CommandExecutor::Error:       TclThreadManager::error("Error: Can't execute command \"" + command + "\", command doesn't exist. (T)"); break;
    451                             case CommandExecutor::Incomplete:  TclThreadManager::error("Error: Can't execute command \"" + command + "\", not enough arguments given. (T)"); break;
    452                             case CommandExecutor::Deactivated: TclThreadManager::error("Error: Can't execute command \"" + command + "\", command is not active. (T)"); break;
    453                             case CommandExecutor::Denied:      TclThreadManager::error("Error: Can't execute command \"" + command + "\", access denied. (T)"); break;
    454                         }
     451                        if (error)
     452                            TclThreadManager::error("Can't execute command \"" + command + "\", " + CommandExecutor::getErrorDescription(error) + ". (TclThreadManager)");
    455453                    }
    456454                    else
     
    476474                    // This happens if the main thread tries to query a busy interpreter
    477475                    // To avoid a lock of the main thread, we simply don't proceed with the query in this case
    478                     TclThreadManager::error("Error: Couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(target_bundle->id_) + ", interpreter is busy right now.");
     476                    TclThreadManager::error("Couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(target_bundle->id_) + ", interpreter is busy right now.");
    479477                }
    480478            }
     
    522520        else
    523521        {
    524             TclThreadManager::error("Error: No Tcl-interpreter with ID " + multi_cast<std::string>(id) + " existing.");
     522            TclThreadManager::error("No Tcl-interpreter with ID " + multi_cast<std::string>(id) + " existing.");
    525523            return 0;
    526524        }
Note: See TracChangeset for help on using the changeset viewer.