Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Changeset 1502 for code/trunk/src/core


Ignore:
Timestamp:
Jun 1, 2008, 3:54:20 PM (17 years ago)
Author:
rgrieder
Message:
  • @everyone: Do not create a branch until I've added the svn:eol-style property correctly. Otherwise this would cost me another 4 hours or so when we want to merge back.
  • merged network branch back to trunk
  • I had to omit the changes from last evening concerning the line endings
  • might not work yet because of the line endings
  • @beni: script branch is the only branch still open. you probably will have to apply a patch because of inconsistent new lines
Location:
code/trunk/src/core
Files:
2 deleted
34 edited
19 copied

Legend:

Unmodified
Added
Removed
  • code/trunk/src/core/CMakeLists.txt

    r1224 r1502  
    22  BaseObject.cc
    33  ClassTreeMask.cc
    4   CommandExecutor.cc
    54  ConfigFileManager.cc
    65  ConfigValueContainer.cc
     
    1110  Identifier.cc
    1211  IdentifierDistributor.cc
     12  InputManager.cc
     13  KeyBinder.cc
     14  OutputBuffer.cc
    1315  InputBuffer.cc
    14   InputHandler.cc
    15   InputManager.cc
     16  Shell.cc
     17  CommandExecutor.cc
     18  CommandEvaluation.cc
     19  ConsoleCommand.cc
     20  ArgumentCompletionFunctions.cc
     21  ConsoleCommandCompilation.cc
    1622  Language.cc
    1723  Loader.cc
     
    2632  Tickable.cc
    2733  XMLPort.cc
     34  TclThreadManager.cc
     35  IRC.cc
    2836  tolua/tolua_bind.cc
    2937)
     
    4755  ois
    4856  util
     57  ${Boost_thread_LIBRARIES}
     58  ${Boost_filesystem_LIBRARIES}
    4959)
  • code/trunk/src/core/ClassManager.h

    r1062 r1502  
    4949#include "Identifier.h"
    5050#include "IdentifierDistributor.h"
     51#include "Debug.h"
    5152
    5253namespace orxonox
  • code/trunk/src/core/CommandExecutor.cc

    r1349 r1502  
    3131#include "util/String.h"
    3232#include "util/Convert.h"
    33 #include "util/SubString.h"
    3433#include "Identifier.h"
    3534#include "Language.h"
    3635#include "Debug.h"
    37 #include "Executor.h"
    38 #include "ConfigValueContainer.h"
    3936#include "TclBind.h"
    40 
    41 #define COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE "set"
    42 #define COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY "tset"
    43 #define COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND "bind"
    4437
    4538namespace orxonox
    4639{
    47     ConsoleCommandShortcutGeneric(keyword1, createExecutor((FunctorStatic*)0, "set", AccessLevel::User));
    48     ConsoleCommandShortcutGeneric(keyword2, createExecutor((FunctorStatic*)0, "tset", AccessLevel::User));
    49     ConsoleCommandShortcutGeneric(keyword3, createExecutor((FunctorStatic*)0, "bind", AccessLevel::User));
    50 
    51     ConsoleCommandShortcutExtern(exec, AccessLevel::None);
    52     ConsoleCommandShortcutExtern(echo, AccessLevel::None);
    53 
    54     ConsoleCommandShortcutExtern(read, AccessLevel::None);
    55     ConsoleCommandShortcutExtern(append, AccessLevel::None);
    56     ConsoleCommandShortcutExtern(write, AccessLevel::None);
    57 
    58     void exec(const std::string& filename)
    59     {
    60         static std::set<std::string> executingFiles;
    61 
    62         std::set<std::string>::const_iterator it = executingFiles.find(filename);
    63         if (it != executingFiles.end())
    64         {
    65             COUT(1) << "Error: Recurring exec command in \"" << filename << "\". Stopped execution." << std::endl;
    66             return;
    67         }
    68 
    69         // Open the file
    70         std::ifstream file;
    71         file.open(filename.c_str(), std::fstream::in);
    72 
    73         if (!file.is_open())
    74         {
    75             COUT(1) << "Error: Couldn't execute file \"" << filename << "\"." << std::endl;
    76             return;
    77         }
    78 
    79         executingFiles.insert(filename);
    80 
    81         // Iterate through the file and put the lines into the CommandExecutor
    82         char line[1024];
    83         while (file.good() && !file.eof())
    84         {
    85             file.getline(line, 1024);
    86             CommandExecutor::execute(line);
    87         }
    88 
    89         executingFiles.erase(filename);
    90         file.close();
    91     }
    92 
    93     std::string echo(const std::string& text)
    94     {
    95         return text;
    96     }
    97 
    98     void write(const std::string& filename, const std::string& text)
    99     {
    100         std::ofstream file;
    101         file.open(filename.c_str(), std::fstream::out);
    102 
    103         if (!file.is_open())
    104         {
    105             COUT(1) << "Error: Couldn't write to file \"" << filename << "\"." << std::endl;
    106             return;
    107         }
    108 
    109         file << text << std::endl;
    110         file.close();
    111     }
    112 
    113     void append(const std::string& filename, const std::string& text)
    114     {
    115         std::ofstream file;
    116         file.open(filename.c_str(), std::fstream::app);
    117 
    118         if (!file.is_open())
    119         {
    120             COUT(1) << "Error: Couldn't append to file \"" << filename << "\"." << std::endl;
    121             return;
    122         }
    123 
    124         file << text << std::endl;
    125         file.close();
    126     }
    127 
    128     std::string read(const std::string& filename)
    129     {
    130         std::ifstream file;
    131         file.open(filename.c_str(), std::fstream::in);
    132 
    133         if (!file.is_open())
    134         {
    135             COUT(1) << "Error: Couldn't read from file \"" << filename << "\"." << std::endl;
    136             return "";
    137         }
    138 
    139         std::string output = "";
    140         char line[1024];
    141         while (file.good() && !file.eof())
    142         {
    143             file.getline(line, 1024);
    144             output += line;
    145             output += "\n";
    146         }
    147 
    148         file.close();
    149 
    150         return output;
    151     }
    152 
    153 
    154     ///////////////////////
    155     // CommandEvaluation //
    156     ///////////////////////
    157     CommandEvaluation::CommandEvaluation()
    158     {
    159         this->processedCommand_ = "";
    160         this->additionalParameter_ = "";
    161 
    162         this->functionclass_ = 0;
    163         this->configvalueclass_ = 0;
    164         this->shortcut_ = 0;
    165         this->function_ = 0;
    166         this->configvalue_ = 0;
    167         this->key_ = 0;
    168 
    169         this->errorMessage_ = "";
    170         this->state_ = CS_Uninitialized;
    171 
    172         this->bEvaluatedParams_ = false;
    173         this->evaluatedExecutor_ = 0;
    174     }
    175 
    176     KeybindMode::Enum CommandEvaluation::getKeybindMode()
    177     {
    178         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    179         {
    180 //            if (this->shortcut_ != 0)
    181 //                return this->shortcut_->getKeybindMode();
    182         }
    183         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    184         {
    185 //            if (this->function_ != 0)
    186 //                return this->function_->getKeybindMode();
    187         }
    188         else if (this->state_ == CS_ConfigValueType || this->state_ == CS_ConfigValueFinished)
    189         {
    190 //            return KeybindMode::onPress;
    191         }
    192         else if (this->state_ == CS_KeybindCommand || this->state_ == CS_KeybindFinished)
    193         {
    194 //            return KeybindMode::onPress;
    195         }
    196         else
    197         {
    198 //            return KeybindMode::onPress;
    199         }
    200         // FIXME: Had to insert a return statement
    201         return (KeybindMode::Enum)0;
    202     }
    203 
    204     bool CommandEvaluation::isValid() const
    205     {
    206         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    207         {
    208             return this->shortcut_;
    209         }
    210         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    211         {
    212             return (this->functionclass_ && this->function_);
    213         }
    214         else if (this->state_ == CS_ConfigValueType || this->state_ == CS_ConfigValueFinished)
    215         {
    216             return (this->configvalueclass_ && this->configvalue_);
    217         }
    218         else if (this->state_ == CS_KeybindCommand || this->state_ == CS_KeybindFinished)
    219         {
    220             return this->key_;
    221         }
    222         else
    223         {
    224             return false;
    225         }
    226     }
    227 
    228     void CommandEvaluation::evaluateParams()
    229     {
    230         this->bEvaluatedParams_ = false;
    231         this->evaluatedExecutor_ = 0;
    232 
    233         for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++)
    234             this->param_[i] = MT_null;
    235 
    236         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    237         {
    238             if (this->shortcut_)
    239             {
    240                 if (this->tokens_.size() <= 1)
    241                 {
    242                     if (this->shortcut_->evaluate(this->getAdditionalParameter(), this->param_, " "))
    243                     {
    244                         this->bEvaluatedParams_ = true;
    245                         this->evaluatedExecutor_ = this->shortcut_;
    246                     }
    247                 }
    248                 else if (this->tokens_.size() > 1)
    249                 {
    250                     if (this->shortcut_->evaluate(this->tokens_.subSet(1).join() + this->getAdditionalParameter(), this->param_, " "))
    251                     {
    252                         this->bEvaluatedParams_ = true;
    253                         this->evaluatedExecutor_ = this->shortcut_;
    254                     }
    255                 }
    256             }
    257         }
    258         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    259         {
    260             if (this->function_)
    261             {
    262                 if (this->tokens_.size() <= 2)
    263                 {
    264                     if (this->function_->evaluate(this->getAdditionalParameter(), this->param_, " "))
    265                     {
    266                         this->bEvaluatedParams_ = true;
    267                         this->evaluatedExecutor_ = this->function_;
    268                     }
    269                 }
    270                 else if (this->tokens_.size() > 2)
    271                 {
    272                     if (this->function_->evaluate(this->tokens_.subSet(2).join() + this->getAdditionalParameter(), this->param_, " "))
    273                     {
    274                         this->bEvaluatedParams_ = true;
    275                         this->evaluatedExecutor_ = this->function_;
    276                     }
    277                 }
    278             }
    279         }
    280     }
    281 
    282     void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiTypeMath param)
    283     {
    284         if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS)
    285             this->param_[index] = param;
    286     }
    287 
    288     MultiTypeMath CommandEvaluation::getEvaluatedParameter(unsigned int index) const
    289     {
    290         if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS)
    291             return this->param_[index];
    292 
    293         return MT_null;
    294     }
    295 
    296     bool CommandEvaluation::hasReturnvalue() const
    297     {
    298         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    299         {
    300             if (this->shortcut_)
    301                 return this->shortcut_->hasReturnvalue();
    302         }
    303         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    304         {
    305             if (this->function_)
    306                 return this->function_->hasReturnvalue();
    307         }
    308 
    309         return MT_null;
    310     }
    311 
    312     MultiTypeMath CommandEvaluation::getReturnvalue() const
    313     {
    314         if (this->state_ == CS_Shortcut_Params || this->state_ == CS_Shortcut_Finished)
    315         {
    316             if (this->shortcut_)
    317                 return this->shortcut_->getReturnvalue();
    318         }
    319         else if (this->state_ == CS_Function_Params || this->state_ == CS_Function_Finished)
    320         {
    321             if (this->function_)
    322                 return this->function_->getReturnvalue();
    323         }
    324 
    325         return MT_null;
    326     }
    327 
    328 
    329     /////////////////////
    330     // CommandExecutor //
    331     /////////////////////
    33240    CommandExecutor& CommandExecutor::getInstance()
    33341    {
     
    34654    }
    34755
    348     Executor& CommandExecutor::addConsoleCommandShortcut(ExecutorStatic* executor)
    349     {
    350         CommandExecutor::getInstance().consoleCommandShortcuts_[executor->getName()] = executor;
    351         CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(executor->getName())] = executor;
    352         return (*executor);
     56    ConsoleCommand& CommandExecutor::addConsoleCommandShortcut(ConsoleCommand* command)
     57    {
     58        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(command->getName());
     59        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
     60        {
     61            COUT(2) << "Warning: Overwriting console-command shortcut with name " << command->getName() << "." << std::endl;
     62        }
     63
     64
     65        CommandExecutor::getInstance().consoleCommandShortcuts_[command->getName()] = command;
     66        CommandExecutor::getInstance().consoleCommandShortcuts_LC_[getLowercase(command->getName())] = command;
     67        return (*command);
    35368    }
    35469
     
    35873        @return The executor of the requested console command shortcut
    35974    */
    360     ExecutorStatic* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
    361     {
    362         std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
     75    ConsoleCommand* CommandExecutor::getConsoleCommandShortcut(const std::string& name)
     76    {
     77        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
    36378        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
    36479            return (*it).second;
     
    37287        @return The executor of the requested console command shortcut
    37388    */
    374     ExecutorStatic* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
    375     {
    376         std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
     89    ConsoleCommand* CommandExecutor::getLowercaseConsoleCommandShortcut(const std::string& name)
     90    {
     91        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
    37792        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end())
    37893            return (*it).second;
     
    38499    {
    385100        if (useTcl)
    386         {
    387101            return TclBind::eval(command);
    388         }
    389         else
    390         {
    391             if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
    392                 CommandExecutor::parse(command);
    393 
    394             return CommandExecutor::execute(CommandExecutor::getEvaluation());
    395         }
    396     }
    397 
    398 
    399     bool CommandExecutor::execute(const CommandEvaluation& evaluation)
    400     {
    401         SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    402 
    403         if (evaluation.bEvaluatedParams_ && evaluation.evaluatedExecutor_)
    404         {
    405 std::cout << "CE_execute (evaluation): " << evaluation.evaluatedExecutor_->getName() << " " << evaluation.param_[0] << " " << evaluation.param_[1] << " " << evaluation.param_[2] << " " << evaluation.param_[3] << " " << evaluation.param_[4] << std::endl;
    406             (*evaluation.evaluatedExecutor_)(evaluation.param_[0], evaluation.param_[1], evaluation.param_[2], evaluation.param_[3], evaluation.param_[4]);
    407             return true;
    408         }
    409 
    410 std::cout << "CE_execute: " << evaluation.processedCommand_ << "\n";
    411         switch (evaluation.state_)
    412         {
    413             case CS_Uninitialized:
    414                 break;
    415             case CS_Empty:
    416                 break;
    417             case CS_FunctionClass_Or_Shortcut_Or_Keyword:
    418                 break;
    419             case CS_Shortcut_Params:
    420                 // not enough parameters but lets hope there are some additional parameters and go on
    421             case CS_Shortcut_Finished:
    422                 // call the shortcut
    423                 if (evaluation.shortcut_)
    424                 {
    425                     if (tokens.size() >= 2)
    426                         return evaluation.shortcut_->parse(removeSlashes(tokens.subSet(1).join() + evaluation.getAdditionalParameter()));
    427                     else
    428                         return evaluation.shortcut_->parse(removeSlashes(evaluation.additionalParameter_));
    429                 }
    430                 break;
    431             case CS_Function:
    432                 break;
    433             case CS_Function_Params:
    434                 // not enough parameters but lets hope there are some additional parameters and go on
    435             case CS_Function_Finished:
    436                 // call the shortcut
    437                 if (evaluation.function_)
    438                 {
    439                     if (tokens.size() >= 3)
    440                         return evaluation.function_->parse(removeSlashes(tokens.subSet(2).join() + evaluation.getAdditionalParameter()));
    441                     else
    442                         return evaluation.function_->parse(removeSlashes(evaluation.additionalParameter_));
    443                 }
    444                 break;
    445             case CS_ConfigValueClass:
    446                 break;
    447             case CS_ConfigValue:
    448                 break;
    449             case CS_ConfigValueType:
    450                 // not enough parameters but lets hope there are some additional parameters and go on
    451             case CS_ConfigValueFinished:
    452                 // set the config value
    453                 if (evaluation.configvalue_)
    454                 {
    455                     if ((tokens.size() >= 1) && (tokens[0] == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE))
    456                     {
    457                         if (tokens.size() >= 4)
    458                             return evaluation.configvalue_->set(removeSlashes(tokens.subSet(3).join() + evaluation.getAdditionalParameter()));
    459                         else
    460                             return evaluation.configvalue_->set(removeSlashes(evaluation.additionalParameter_));
    461                     }
    462                     else if ((tokens.size() >= 1) && (tokens[0] == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
    463                     {
    464                         if (tokens.size() >= 4)
    465                             return evaluation.configvalue_->tset(removeSlashes(tokens.subSet(3).join() + evaluation.getAdditionalParameter()));
    466                         else
    467                             return evaluation.configvalue_->tset(removeSlashes(evaluation.additionalParameter_));
    468                     }
    469                 }
    470                 break;
    471             case CS_KeybindKey:
    472                 break;
    473             case CS_KeybindCommand:
    474                 // not enough parameters but lets hope there are some additional parameters and go on
    475             case CS_KeybindFinished:
    476                 // set the keybind
    477                 // ...todo
    478                 break;
    479             case CS_Error:
    480                 break;
    481         }
    482 
    483         return false;
     102
     103        CommandExecutor::parseIfNeeded(command);
     104        return CommandExecutor::getEvaluation().execute();
    484105    }
    485106
    486107    std::string CommandExecutor::complete(const std::string& command)
    487108    {
    488         if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
    489             CommandExecutor::parse(command);
    490 
    491         return CommandExecutor::complete(CommandExecutor::getEvaluation());
    492     }
    493 
    494     std::string CommandExecutor::complete(const CommandEvaluation& evaluation)
    495     {
    496         SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    497 
    498         std::list<std::pair<const std::string*, const std::string*> > temp;
    499         if (evaluation.state_ == CS_Empty)
    500         {
    501             temp.insert(temp.end(), evaluation.listOfPossibleShortcuts_.begin(), evaluation.listOfPossibleShortcuts_.end());
    502             temp.insert(temp.end(), evaluation.listOfPossibleFunctionClasses_.begin(), evaluation.listOfPossibleFunctionClasses_.end());
    503         }
    504 
    505         switch (evaluation.state_)
    506         {
    507             case CS_Uninitialized:
    508                 break;
    509             case CS_Empty:
    510                 return (CommandExecutor::getCommonBegin(temp));
    511                 break;
    512             case CS_FunctionClass_Or_Shortcut_Or_Keyword:
    513                 break;
    514             case CS_Shortcut_Params:
    515                 if (evaluation.shortcut_)
    516                     return (evaluation.shortcut_->getName() + " ");
    517                 break;
    518             case CS_Shortcut_Finished:
    519                 if (evaluation.shortcut_)
    520                 {
    521                     if (evaluation.shortcut_->getParamCount() == 0)
    522                         return (evaluation.shortcut_->getName());
    523                     else if (tokens.size() >= 2)
    524                         return (evaluation.shortcut_->getName() + " " + tokens.subSet(1).join());
    525                 }
    526                 break;
    527             case CS_Function:
    528                 if (evaluation.functionclass_)
    529                     return (evaluation.functionclass_->getName() + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleFunctions_));
    530                 break;
    531             case CS_Function_Params:
    532                 if (evaluation.functionclass_ && evaluation.function_)
    533                     return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName() + " ");
    534                 break;
    535             case CS_Function_Finished:
    536                 if (evaluation.functionclass_ && evaluation.function_)
    537                 {
    538                     if (evaluation.function_->getParamCount() == 0)
    539                         return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName());
    540                     else if (tokens.size() >= 3)
    541                         return (evaluation.functionclass_->getName() + " " + evaluation.function_->getName() + " " + tokens.subSet(2).join());
    542                 }
    543                 break;
    544             case CS_ConfigValueClass:
    545                 if (tokens.size() >= 1)
    546                     return (tokens[0] + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleConfigValueClasses_));
    547                 break;
    548             case CS_ConfigValue:
    549                 if ((tokens.size() >= 1) && evaluation.configvalueclass_)
    550                     return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleConfigValues_));
    551                 break;
    552             case CS_ConfigValueType:
    553                 if ((tokens.size() >= 1) && evaluation.configvalueclass_ && evaluation.configvalue_)
    554                     return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + evaluation.configvalue_->getName() + " ");
    555                 break;
    556             case CS_ConfigValueFinished:
    557                 if ((tokens.size() >= 1) && evaluation.configvalueclass_ && evaluation.configvalue_ && (tokens.size() >= 4))
    558                     return (tokens[0] + " " + evaluation.configvalueclass_->getName() + " " + evaluation.configvalue_->getName() + " " + tokens.subSet(3).join());
    559                 break;
    560             case CS_KeybindKey:
    561                 if (tokens.size() >= 1)
    562                     return (tokens[0] + " " + CommandExecutor::getCommonBegin(evaluation.listOfPossibleKeys_));
    563                 break;
    564             case CS_KeybindCommand:
    565                 if ((evaluation.processedCommand_.size() >= 1) && (evaluation.processedCommand_[evaluation.processedCommand_.size() - 1] != ' '))
    566                     return (evaluation.processedCommand_ + " ");
    567                 break;
    568             case CS_KeybindFinished:
    569                 break;
    570             case CS_Error:
    571                 break;
    572         }
    573 
    574         return evaluation.processedCommand_;
     109        CommandExecutor::parseIfNeeded(command);
     110        return CommandExecutor::getEvaluation().complete();
    575111    }
    576112
    577113    std::string CommandExecutor::hint(const std::string& command)
    578114    {
    579         if ((CommandExecutor::getEvaluation().processedCommand_ != command) || (CommandExecutor::getEvaluation().state_ == CS_Uninitialized))
    580             CommandExecutor::parse(command);
    581 
    582         return CommandExecutor::hint(CommandExecutor::getEvaluation());
    583     }
    584 
    585     std::string CommandExecutor::hint(const CommandEvaluation& evaluation)
    586     {
    587         SubString tokens(evaluation.processedCommand_, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    588 
    589         switch (evaluation.state_)
    590         {
    591             case CS_Uninitialized:
    592                 break;
    593             case CS_Empty:
    594                 return (CommandExecutor::dump(evaluation.listOfPossibleShortcuts_) + "\n" + CommandExecutor::dump(evaluation.listOfPossibleFunctionClasses_));
    595                 break;
    596             case CS_FunctionClass_Or_Shortcut_Or_Keyword:
    597                 break;
    598             case CS_Shortcut_Params:
    599                 if (evaluation.shortcut_)
    600                     return CommandExecutor::dump(evaluation.shortcut_);
    601                 break;
    602             case CS_Shortcut_Finished:
    603                 if (evaluation.shortcut_)
    604                     return CommandExecutor::dump(evaluation.shortcut_);
    605                 break;
    606             case CS_Function:
    607                 return CommandExecutor::dump(evaluation.listOfPossibleFunctions_);
    608                 break;
    609             case CS_Function_Params:
    610                 if (evaluation.function_)
    611                     return CommandExecutor::dump(evaluation.function_);
    612                 break;
    613             case CS_Function_Finished:
    614                 if (evaluation.function_)
    615                     return CommandExecutor::dump(evaluation.function_);
    616                 break;
    617             case CS_ConfigValueClass:
    618                 return CommandExecutor::dump(evaluation.listOfPossibleConfigValueClasses_);
    619                 break;
    620             case CS_ConfigValue:
    621                 return CommandExecutor::dump(evaluation.listOfPossibleConfigValues_);
    622                 break;
    623             case CS_ConfigValueType:
    624                 if (evaluation.configvalue_)
    625                     return CommandExecutor::dump(evaluation.configvalue_);
    626                 break;
    627             case CS_ConfigValueFinished:
    628                 if (evaluation.configvalue_)
    629                     return CommandExecutor::dump(evaluation.configvalue_);
    630                 break;
    631             case CS_KeybindKey:
    632                 return CommandExecutor::dump(evaluation.listOfPossibleKeys_);
    633                 break;
    634             case CS_KeybindCommand:
    635                 if (evaluation.key_)
    636                     return CommandExecutor::dump(evaluation.key_);
    637                 break;
    638             case CS_KeybindFinished:
    639                 if (evaluation.key_)
    640                     return CommandExecutor::dump(evaluation.key_);
    641                 break;
    642             case CS_Error:
    643                 return CommandExecutor::getEvaluation().errorMessage_;
    644                 break;
    645         }
    646 
    647         return "";
     115        CommandExecutor::parseIfNeeded(command);
     116        return CommandExecutor::getEvaluation().hint();
    648117    }
    649118
    650119    CommandEvaluation CommandExecutor::evaluate(const std::string& command)
    651120    {
    652         CommandExecutor::parse(command, true);
    653 
    654         if (CommandExecutor::getEvaluation().tokens_.size() > 0)
    655         {
    656             std::string lastToken;
    657             lastToken = CommandExecutor::getEvaluation().tokens_[CommandExecutor::getEvaluation().tokens_.size() - 1];
    658             lastToken = lastToken.substr(0, lastToken.size() - 1);
    659             CommandExecutor::getEvaluation().tokens_.pop_back();
    660             CommandExecutor::getEvaluation().tokens_.append(SubString(lastToken, " ", "", true, '\0', false, '\0', false, '\0', '\0', false, '\0'));
    661         }
    662 
     121        CommandExecutor::parse(command);
    663122        CommandExecutor::getEvaluation().evaluateParams();
    664123        return CommandExecutor::getEvaluation();
    665124    }
    666125
     126    void CommandExecutor::parseIfNeeded(const std::string& command)
     127    {
     128        if (CommandExecutor::getEvaluation().state_ == CS_Uninitialized)
     129        {
     130            CommandExecutor::parse(command);
     131        }
     132        else if (CommandExecutor::getEvaluation().originalCommand_ != command)
     133        {
     134            if (CommandExecutor::getEvaluation().command_ == command)
     135            {
     136                CommandExecutor::parse(command);
     137                CommandExecutor::getEvaluation().bNewCommand_ = false;
     138            }
     139            else
     140            {
     141                CommandExecutor::parse(command);
     142            }
     143        }
     144    }
     145
    667146    void CommandExecutor::parse(const std::string& command, bool bInitialize)
    668147    {
    669         CommandExecutor::getEvaluation().tokens_.split((command + COMMAND_EXECUTOR_CURSOR), " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    670         CommandExecutor::getEvaluation().processedCommand_ = command;
    671 
    672148        if (bInitialize)
    673             CommandExecutor::initialize(command);
     149            CommandExecutor::getEvaluation().initialize(command);
     150
     151        CommandExecutor::getEvaluation().commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
     152        CommandExecutor::getEvaluation().command_ = command;
    674153
    675154        switch (CommandExecutor::getEvaluation().state_)
    676155        {
    677156            case CS_Uninitialized:
     157            {
    678158                // Impossible
    679159                break;
     160            }
    680161            case CS_Empty:
     162            {
    681163                if (CommandExecutor::argumentsGiven() == 0)
    682164                {
    683                     // We want a hint for the first token
    684                     // Check if there is already a perfect match
    685                     CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0));
    686                     CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0));
    687 
    688                     if ((CommandExecutor::getEvaluation().functionclass_) || (CommandExecutor::getEvaluation().shortcut_))
    689                     {
    690                         // Yes, there is a class or a shortcut with the searched name
    691                         // Add a whitespace and continue parsing
    692                         CommandExecutor::getEvaluation().state_ = CS_FunctionClass_Or_Shortcut_Or_Keyword;
    693                         CommandExecutor::parse(command + " ", false);
     165                    CommandExecutor::createListOfPossibleFunctions("");
     166                    CommandExecutor::createListOfPossibleIdentifiers("");
     167                    break;
     168                }
     169                else
     170                {
     171                    CommandExecutor::getEvaluation().state_ = CS_ShortcutOrIdentifier;
     172                    // Move on to next case
     173                }
     174            }
     175            case CS_ShortcutOrIdentifier:
     176            {
     177                if (CommandExecutor::argumentsGiven() > 1)
     178                {
     179                    // There's a finished first argument - check if it's a shortcut or a classname
     180                    CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
     181                    CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
     182
     183                    if (CommandExecutor::getEvaluation().function_)
     184                    {
     185                        // It's a shortcut
     186                        CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     187                        CommandExecutor::getEvaluation().functionclass_ = 0;
     188                        // Move on to next case
     189                    }
     190                    else if (CommandExecutor::getEvaluation().functionclass_)
     191                    {
     192                        // It's a functionname
     193                        CommandExecutor::getEvaluation().state_ = CS_Function;
     194                        CommandExecutor::getEvaluation().function_ = 0;
     195                        // Move on to next case
     196                    }
     197                    else
     198                    {
     199                        // The first argument is bad
     200                        CommandExecutor::getEvaluation().state_ = CS_Error;
     201                        AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname");
     202                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + " " + GetLocalisation("commandexecutorunknownfirstargument") + ".";
    694203                        return;
    695204                    }
    696 
    697                     // No perfect match: Create the lists of all possible classes and shortcuts and return
    698                     CommandExecutor::createListOfPossibleFunctionClasses(CommandExecutor::getToken(0));
    699                     CommandExecutor::createListOfPossibleShortcuts(CommandExecutor::getToken(0));
    700 
    701                     // Check if there's only one possiblility
    702                     if ((CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.size() == 1) && (CommandExecutor::getEvaluation().listOfPossibleShortcuts_.size() == 0))
    703                     {
    704                         // There's only one possible class
     205                }
     206                else
     207                {
     208                    // There's no finished first argument - search possible shortcuts or classnames
     209                    CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(0));
     210                    CommandExecutor::createListOfPossibleIdentifiers(CommandExecutor::getArgument(0));
     211
     212                    unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
     213                    unsigned int num_identifiers = CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.size();
     214
     215                    if (num_functions == 1 && num_identifiers == 0)
     216                    {
     217                        // It's a shortcut
     218                        std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
     219                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname);
     220                        if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(0)))
     221                        {
     222                            // Unfinished shortcut
     223                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     224                        }
     225                        CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     226                        CommandExecutor::getEvaluation().functionclass_ = 0;
     227                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().function_->getName();
     228                        if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
     229                        {
     230                            CommandExecutor::getEvaluation().command_ += " ";
     231                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     232                        }
     233                        // Move on to next case
     234                    }
     235                    else if (num_identifiers == 1 && num_functions == 0)
     236                    {
     237                        // It's a classname
     238                        std::string classname = *(*CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()).first;
     239                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(classname);
     240                        if (getLowercase(classname) != getLowercase(CommandExecutor::getArgument(0)))
     241                        {
     242                            // Unfinished classname
     243                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     244                        }
    705245                        CommandExecutor::getEvaluation().state_ = CS_Function;
    706                         CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(*(*CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.begin()).first);
    707                         CommandExecutor::parse(*(*CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.begin()).first + " ", false);
     246                        CommandExecutor::getEvaluation().function_ = 0;
     247                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " ";
     248                        // Move on to next case
     249                    }
     250                    else if (num_identifiers == 0 && num_functions == 0)
     251                    {
     252                        // No possibilities
     253                        CommandExecutor::getEvaluation().state_ = CS_Error;
     254                        AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with");
     255                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + " " + CommandExecutor::getArgument(0) + ".";
    708256                        return;
    709257                    }
    710                     else if ((CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.size() == 0) && (CommandExecutor::getEvaluation().listOfPossibleShortcuts_.size() == 1))
    711                     {
    712                         if ((*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE)
    713                          && (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)
    714                          && (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND))
    715                         {
    716                             // There's only one possible shortcut
    717                             CommandExecutor::getEvaluation().state_ = CS_Shortcut_Params;
    718                             CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first);
    719                         }
    720                         else if ((*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE)
    721                               || (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
    722                         {
    723                             // It's the 'set' or 'tset' keyword
    724                             CommandExecutor::getEvaluation().state_ = CS_ConfigValueClass;
    725                         }
    726                         else if (*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first != COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)
    727                         {
    728                             // It's the 'bind' keyword
    729                             CommandExecutor::getEvaluation().state_ = CS_KeybindKey;
    730                         }
    731 
    732                         CommandExecutor::parse(*(*CommandExecutor::getEvaluation().listOfPossibleShortcuts_.begin()).first + " ", false);
     258                    else
     259                    {
     260                        // There are several possiblilities
     261                        std::list<std::pair<const std::string*, const std::string*> > temp;
     262                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin(), CommandExecutor::getEvaluation().listOfPossibleFunctions_.end());
     263                        temp.insert(temp.end(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin(), CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.end());
     264                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getCommonBegin(temp);
     265                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(0));
     266                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(CommandExecutor::getArgument(0));
     267                        CommandExecutor::getEvaluation().bCommandChanged_ = true;
    733268                        return;
    734269                    }
    735 
    736                     // It's ambiguous
     270                }
     271            }
     272            case CS_Function:
     273            {
     274                if (CommandExecutor::getEvaluation().functionclass_)
     275                {
     276                    // There is a classname - search for the commandname
     277                    if (CommandExecutor::argumentsGiven() > 2)
     278                    {
     279                        // There is a finished second argument - check if it's a commandname
     280                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
     281
     282                        if (CommandExecutor::getEvaluation().function_)
     283                        {
     284                            // It's a function
     285                            CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     286                            // Move on to next case
     287                        }
     288                        else
     289                        {
     290                            // The second argument is bad
     291                            CommandExecutor::getEvaluation().state_ = CS_Error;
     292                            AddLanguageEntry("commandexecutorunknownsecondargument", "is not a function of");
     293                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(1) + " " + GetLocalisation("commandexecutorunknownsecondargument") + " " + CommandExecutor::getEvaluation().functionclass_->getName() + ".";
     294                            return;
     295                        }
     296                    }
     297                    else
     298                    {
     299                        // There is no finished second argument - search for possibilities
     300                        CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
     301                        unsigned int num_functions = CommandExecutor::getEvaluation().listOfPossibleFunctions_.size();
     302
     303                        if (num_functions == 1)
     304                        {
     305                            // It's a function
     306                            std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
     307                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname, CommandExecutor::getEvaluation().functionclass_);
     308                            if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(1)))
     309                            {
     310                                // Unfinished function
     311                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
     312                            }
     313                            CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     314                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getEvaluation().function_->getName();
     315                            if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
     316                            {
     317                                CommandExecutor::getEvaluation().command_ += " ";
     318                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
     319                            }
     320                            // Move on to next case
     321                        }
     322                        else if (num_functions == 0)
     323                        {
     324                            // No possibilities
     325                            CommandExecutor::getEvaluation().state_ = CS_Error;
     326                            AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with");
     327                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + " " + GetLocalisation("commandexecutorunknownsecondargumentstart") + " " + CommandExecutor::getArgument(1) + ".";
     328                            return;
     329                        }
     330                        else
     331                        {
     332                            // There are several possibilities
     333                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_);
     334                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
     335                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     336                            return;
     337                        }
     338                    }
     339                }
     340                else
     341                {
     342                    // There is no classname - move on to CS_ParamPreparation
     343                }
     344            }
     345            case CS_ParamPreparation:
     346            {
     347                if (CommandExecutor::getEvaluation().function_->getParamCount() == 0 || CommandExecutor::enoughArgumentsGiven(CommandExecutor::getEvaluation().function_))
     348                {
     349                    CommandExecutor::getEvaluation().state_ = CS_Finished;
    737350                    return;
    738351                }
    739352                else
    740353                {
    741                     // There is at least one argument: Check if it's a shortcut, a classname or a special keyword
    742                     CommandExecutor::getEvaluation().state_ = CS_FunctionClass_Or_Shortcut_Or_Keyword;
    743                     CommandExecutor::parse(command, false);
     354                    unsigned int argumentNumber = CommandExecutor::argumentsGiven() - 2;
     355                    if (CommandExecutor::getEvaluation().functionclass_)
     356                        argumentNumber -= 1;
     357
     358                    CommandExecutor::createListOfPossibleArguments(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
     359                    CommandExecutor::getEvaluation().state_ = CS_Params;
     360
     361                    if (CommandExecutor::getEvaluation().bCommandChanged_)
     362                    {
     363                        // Don't do more than one change
     364                        return;
     365                    }
     366                }
     367            }
     368            case CS_Params:
     369            {
     370                if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 1)
     371                {
     372                    // There is exactly one possible argument
     373                    CommandExecutor::getEvaluation().argument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
     374                    CommandExecutor::getEvaluation().possibleArgument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
     375                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
    744376                    return;
    745377                }
     378                else if (CommandExecutor::getEvaluation().listOfPossibleArguments_.size() == 0)
     379                {
     380                    // The user tries something new - we let him do
     381                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     382                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getLastArgument();
     383                    return;
     384                }
     385                else
     386                {
     387                    // There are several possibilities
     388                    unsigned int argumentNumber = CommandExecutor::argumentsGiven();
     389                    if (argumentNumber > 0)
     390                        --argumentNumber;
     391                    if (CommandExecutor::getEvaluation().functionclass_ && argumentNumber > 0)
     392                        --argumentNumber;
     393
     394                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleArguments_);
     395                    CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getPossibleArgument(CommandExecutor::getLastArgument(), CommandExecutor::getEvaluation().function_, argumentNumber);
     396                    CommandExecutor::getEvaluation().state_ = CS_ParamPreparation;
     397                    return;
     398                }
     399            }
     400            case CS_Finished:
     401            {
     402                // Nothing more to do
    746403                break;
    747             case CS_FunctionClass_Or_Shortcut_Or_Keyword:
    748                 if (CommandExecutor::argumentsGiven() >= 1)
    749                 {
    750                     if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY))
    751                     {
    752                         // We want to set a config value
    753                         CommandExecutor::getEvaluation().state_ = CS_ConfigValueClass;
    754                         CommandExecutor::parse(command, false);
    755                         return;
    756                     }
    757                     else if (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND)
    758                     {
    759                         // We want to set a keybinding
    760                         CommandExecutor::getEvaluation().state_ = CS_KeybindKey;
    761                         CommandExecutor::parse(command, false);
    762                         return;
    763                     }
    764 
    765                     if (!CommandExecutor::getEvaluation().functionclass_)
    766                         CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getIdentifierOfPossibleFunctionClass(CommandExecutor::getToken(0));
    767                     if (!CommandExecutor::getEvaluation().shortcut_)
    768                         CommandExecutor::getEvaluation().shortcut_ = CommandExecutor::getExecutorOfPossibleShortcut(CommandExecutor::getToken(0));
    769 
    770                     if ((!CommandExecutor::getEvaluation().functionclass_) && (!CommandExecutor::getEvaluation().shortcut_))
    771                     {
    772                         // Argument 1 seems to be wrong
    773                         AddLanguageEntry("CommandExecutor::NoSuchCommandOrClassName", "No such command or classname");
    774                         CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(0) + ": " + GetLocalisation("CommandExecutor::NoSuchCommandOrClassName"));
    775                         CommandExecutor::getEvaluation().state_ = CS_Error;
    776                         return;
    777                     }
    778                     else if (CommandExecutor::getEvaluation().shortcut_)
    779                     {
    780                         // Argument 1 is a shortcut: Return the needed parameter types
    781                         CommandExecutor::getEvaluation().state_ = CS_Shortcut_Params;
    782                         CommandExecutor::parse(command, false);
    783                         return;
    784                     }
    785                     else
    786                     {
    787                         // Argument 1 is a classname: Return the possible functions
    788                         CommandExecutor::getEvaluation().state_ = CS_Function;
    789                         CommandExecutor::parse(command, false);
    790                         return;
    791                     }
    792                 }
    793                 else
    794                 {
    795                     CommandExecutor::getEvaluation().state_ = CS_Error;
    796                     return;
    797                 }
     404            }
     405            case CS_Error:
     406            {
     407                // Bad, very bad
    798408                break;
    799             case CS_Shortcut_Params:
    800                 if (CommandExecutor::getEvaluation().shortcut_)
    801                 {
    802                     // Valid command
    803                     // Check if there are enough parameters
    804                     if (CommandExecutor::enoughParametersGiven(1, CommandExecutor::getEvaluation().shortcut_))
    805                     {
    806                         CommandExecutor::getEvaluation().state_ = CS_Shortcut_Finished;
    807                         return;
    808                     }
    809                 }
    810                 else
    811                 {
    812                     // Something is wrong
    813                     CommandExecutor::getEvaluation().state_ = CS_Error;
    814                     return;
    815                 }
    816                 break;
    817             case CS_Function:
    818                 if (CommandExecutor::getEvaluation().functionclass_)
    819                 {
    820                     // We have a valid classname
    821                     // Check if there is a second argument
    822                     if (CommandExecutor::argumentsGiven() >= 2)
    823                     {
    824                         // There is a second argument: Check if it's a valid functionname
    825                         CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
    826                         if (!CommandExecutor::getEvaluation().function_)
    827                         {
    828                             // Argument 2 seems to be wrong
    829                             AddLanguageEntry("CommandExecutor::NoSuchFunctionnameIn", "No such functionname in");
    830                             CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchFunctionnameIn") + " " + CommandExecutor::getEvaluation().functionclass_->getName());
    831                             CommandExecutor::getEvaluation().state_ = CS_Error;
    832                             return;
    833                         }
    834                         else
    835                         {
    836                             // Argument 2 seems to be a valid functionname: Get the parameters
    837                             CommandExecutor::getEvaluation().state_ = CS_Function_Params;
    838                             CommandExecutor::parse(command, false);
    839                             return;
    840                         }
    841                     }
    842                     else
    843                     {
    844                         // There is no finished second argument
    845                         // Check if there's already a perfect match
    846                         if (CommandExecutor::getEvaluation().tokens_.size() >= 2)
    847                         {
    848                             CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
    849                             if (CommandExecutor::getEvaluation().function_)
    850                             {
    851                                 // There is a perfect match: Add a whitespace and continue parsing
    852                                 CommandExecutor::getEvaluation().state_ = CS_Function_Params;
    853                                 CommandExecutor::parse(command + " ", false);
    854                                 return;
    855                             }
    856                         }
    857 
    858                         // No perfect match: Create the list of all possible functions and return
    859                         CommandExecutor::createListOfPossibleFunctions(CommandExecutor::getToken(1), CommandExecutor::getEvaluation().functionclass_);
    860 
    861                         // Check if there's only one possiblility
    862                         if (CommandExecutor::getEvaluation().listOfPossibleFunctions_.size() == 1)
    863                         {
    864                             // There's only one possible function
    865                             CommandExecutor::getEvaluation().state_ = CS_Function_Params;
    866                             CommandExecutor::getEvaluation().function_ = CommandExecutor::getExecutorOfPossibleFunction(*(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first, CommandExecutor::getEvaluation().functionclass_);
    867                             CommandExecutor::parse(CommandExecutor::getToken(0) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first + " ", false);
    868                             return;
    869                         }
    870 
    871                         // It's ambiguous
    872                         return;
    873                     }
    874                 }
    875                 else
    876                 {
    877                     CommandExecutor::getEvaluation().state_ = CS_Error;
    878                     return;
    879                 }
    880                 break;
    881             case CS_Function_Params:
    882                 if (CommandExecutor::getEvaluation().functionclass_ && CommandExecutor::getEvaluation().function_)
    883                 {
    884                     // Valid command
    885                     // Check if there are enough parameters
    886                     if (CommandExecutor::enoughParametersGiven(2, CommandExecutor::getEvaluation().function_))
    887                     {
    888                         CommandExecutor::getEvaluation().state_ = CS_Function_Finished;
    889                         return;
    890                     }
    891                 }
    892                 else
    893                 {
    894                     // Something is wrong
    895                     CommandExecutor::getEvaluation().state_ = CS_Error;
    896                     return;
    897                 }
    898                 break;
    899             case CS_ConfigValueClass:
    900                 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)))
    901                 {
    902                     // We want to set a config value
    903                     // Check if there is a second argument
    904                     if (CommandExecutor::argumentsGiven() >= 2)
    905                     {
    906                         // There is a second argument: Check if it's a valid classname
    907                         CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1));
    908                         if (!CommandExecutor::getEvaluation().configvalueclass_)
    909                         {
    910                             // Argument 2 seems to be wrong
    911                             AddLanguageEntry("CommandExecutor::NoSuchClassWithConfigValues", "No such class with config values");
    912                             CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(1) + ": " + GetLocalisation("CommandExecutor::NoSuchClassWithConfigValues"));
    913                             CommandExecutor::getEvaluation().state_ = CS_Error;
    914                             return;
    915                         }
    916                         else
    917                         {
    918                             // Argument 2 seems to be a valid classname: Search for possible config values
    919                             CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
    920                             CommandExecutor::parse(command, false);
    921                             return;
    922                         }
    923                     }
    924                     else
    925                     {
    926                         // There's no finished second argument
    927                         // Check if there's already a perfect match
    928                         if (CommandExecutor::getEvaluation().tokens_.size() >= 2)
    929                         {
    930                             CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(CommandExecutor::getToken(1));
    931                             if (CommandExecutor::getEvaluation().configvalueclass_)
    932                             {
    933                                 // There is a perfect match: Add a whitespace and continue parsing
    934                                 CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
    935                                 CommandExecutor::parse(command + " ", false);
    936                                 return;
    937                             }
    938                         }
    939 
    940                         // No perfect match: Create the list of all possible classnames and return
    941                         CommandExecutor::createListOfPossibleConfigValueClasses(CommandExecutor::getToken(1));
    942 
    943                         // Check if there's only one possiblility
    944                         if (CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.size() == 1)
    945                         {
    946                             // There's only one possible classname
    947                             CommandExecutor::getEvaluation().state_ = CS_ConfigValue;
    948                             CommandExecutor::getEvaluation().configvalueclass_ = CommandExecutor::getIdentifierOfPossibleConfigValueClass(*(*CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.begin()).first);
    949                             CommandExecutor::parse(CommandExecutor::getToken(0) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.begin()).first + " ", false);
    950                             return;
    951                         }
    952 
    953                         // It's ambiguous
    954                         return;
    955                     }
    956                 }
    957                 else
    958                 {
    959                     // Something is wrong
    960                     CommandExecutor::getEvaluation().state_ = CS_Error;
    961                     return;
    962                 }
    963                 break;
    964             case CS_ConfigValue:
    965                 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && (CommandExecutor::getEvaluation().configvalueclass_))
    966                 {
    967                     // Check if there is a third argument
    968                     if (CommandExecutor::argumentsGiven() >= 3)
    969                     {
    970                         // There is a third argument: Check if it's a valid config value
    971                         CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
    972                         if (!CommandExecutor::getEvaluation().configvalue_)
    973                         {
    974                             // Argument 3 seems to be wrong
    975                             AddLanguageEntry("CommandExecutor::NoSuchConfigValueIn", "No such config value in");
    976                             CommandExecutor::getEvaluation().errorMessage_ = (CommandExecutor::getToken(2) + ": " + GetLocalisation("CommandExecutor::NoSuchConfigValueIn") + " " + CommandExecutor::getEvaluation().configvalueclass_->getName());
    977                             CommandExecutor::getEvaluation().state_ = CS_Error;
    978                             return;
    979                         }
    980                         else
    981                         {
    982                             // Argument 3 seems to be a valid config value: Get the type
    983                             CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
    984                             CommandExecutor::parse(command, false);
    985                             return;
    986                         }
    987                     }
    988                     else
    989                     {
    990                         // There is no finished third argument
    991                         // Check if there's already a perfect match
    992                         if (CommandExecutor::getEvaluation().tokens_.size() >= 3)
    993                         {
    994                             CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
    995                             if (CommandExecutor::getEvaluation().configvalue_)
    996                             {
    997                                 // There is a perfect match: Add a whitespace and continue parsing
    998                                 CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
    999                                 CommandExecutor::parse(command + " ", false);
    1000                                 return;
    1001                             }
    1002                         }
    1003 
    1004                         // No perfect match: Create the list of all possible config values
    1005                         CommandExecutor::createListOfPossibleConfigValues(CommandExecutor::getToken(2), CommandExecutor::getEvaluation().configvalueclass_);
    1006 
    1007                         // Check if there's only one possiblility
    1008                         if (CommandExecutor::getEvaluation().listOfPossibleConfigValues_.size() == 1)
    1009                         {
    1010                             // There's only one possible config value
    1011                             CommandExecutor::getEvaluation().state_ = CS_ConfigValueType;
    1012                             CommandExecutor::getEvaluation().configvalue_ = CommandExecutor::getContainerOfPossibleConfigValue(*(*CommandExecutor::getEvaluation().listOfPossibleConfigValues_.begin()).first, CommandExecutor::getEvaluation().configvalueclass_);
    1013                             CommandExecutor::parse(CommandExecutor::getToken(0) + " " + CommandExecutor::getToken(1) + " " + *(*CommandExecutor::getEvaluation().listOfPossibleConfigValues_.begin()).first + " ", false);
    1014                             return;
    1015                         }
    1016 
    1017                         // It's ambiguous
    1018                         return;
    1019                     }
    1020                 }
    1021                 else
    1022                 {
    1023                     // Something is wrong
    1024                     CommandExecutor::getEvaluation().state_ = CS_Error;
    1025                     return;
    1026                 }
    1027                 break;
    1028             case CS_ConfigValueType:
    1029                 if (((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE) || (CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_CONFIG_VALUE_TEMPORARY)) && CommandExecutor::getEvaluation().configvalueclass_ && CommandExecutor::getEvaluation().configvalue_)
    1030                 {
    1031                     // Valid command
    1032                     // Check if there are enough parameters
    1033                     if ((CommandExecutor::getEvaluation().tokens_.size() >= 4) && (CommandExecutor::getEvaluation().tokens_[3] != COMMAND_EXECUTOR_CURSOR))
    1034                     {
    1035                         CommandExecutor::getEvaluation().state_ = CS_ConfigValueFinished;
    1036                         return;
    1037                     }
    1038                 }
    1039                 else
    1040                 {
    1041                     // Something is wrong
    1042                     CommandExecutor::getEvaluation().state_ = CS_Error;
    1043                     return;
    1044                 }
    1045                 break;
    1046             case CS_KeybindKey:
    1047                 if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND))
    1048                 {
    1049                     // todo
    1050                 }
    1051                 else
    1052                 {
    1053                     // Something is wrong
    1054                     CommandExecutor::getEvaluation().state_ = CS_Error;
    1055                     return;
    1056                 }
    1057                 break;
    1058             case CS_KeybindCommand:
    1059                 if ((CommandExecutor::getToken(0) == COMMAND_EXECUTOR_KEYWORD_SET_KEYBIND) && (false)) // todo
    1060                 {
    1061                     // Valid command
    1062                     // Check if there are enough parameters
    1063                     if (CommandExecutor::getEvaluation().tokens_.size() >= 3)
    1064                     {
    1065                         CommandExecutor::getEvaluation().state_ = CS_KeybindFinished;
    1066                         return;
    1067                     }
    1068 
    1069                 }
    1070                 else
    1071                 {
    1072                     // Something is wrong
    1073                     CommandExecutor::getEvaluation().state_ = CS_Error;
    1074                     return;
    1075                 }
    1076                 break;
    1077             case CS_Shortcut_Finished:
    1078                 // Nothing to do
    1079                 break;
    1080             case CS_Function_Finished:
    1081                 // Nothing to do
    1082                 break;
    1083             case CS_ConfigValueFinished:
    1084                 // Nothing to do
    1085                 break;
    1086             case CS_KeybindFinished:
    1087                 // Nothing to do
    1088                 break;
    1089             case CS_Error:
    1090                 // This is bad
    1091                 break;
    1092         }
    1093     }
    1094 
    1095     void CommandExecutor::initialize(const std::string& command)
    1096     {
    1097         CommandExecutor::getEvaluation().processedCommand_ = command;
    1098         CommandExecutor::getEvaluation().additionalParameter_ = "";
    1099 
    1100         CommandExecutor::getEvaluation().bEvaluatedParams_ = false;
    1101         CommandExecutor::getEvaluation().evaluatedExecutor_ = 0;
    1102 
    1103         CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.clear();
    1104         CommandExecutor::getEvaluation().listOfPossibleShortcuts_.clear();
     409            }
     410        }
     411    }
     412
     413    unsigned int CommandExecutor::argumentsFinished()
     414    {
     415        unsigned int argumentsGiven = CommandExecutor::argumentsGiven();
     416        if (argumentsGiven > 0)
     417            return argumentsGiven - 1;
     418        else
     419            return 0;
     420    }
     421
     422    unsigned int CommandExecutor::argumentsGiven()
     423    {
     424        if (CommandExecutor::getEvaluation().command_.size() > 0 && CommandExecutor::getEvaluation().command_[CommandExecutor::getEvaluation().command_.size() - 1] == ' ')
     425            return CommandExecutor::getEvaluation().commandTokens_.size() + 1;
     426        else
     427            return CommandExecutor::getEvaluation().commandTokens_.size();
     428    }
     429
     430    bool CommandExecutor::enoughArgumentsGiven(ConsoleCommand* command)
     431    {
     432        if (CommandExecutor::getEvaluation().functionclass_)
     433            return (CommandExecutor::argumentsGiven() > (2 + command->getParamCount()));
     434        else
     435            return (CommandExecutor::argumentsGiven() > (1 + command->getParamCount()));
     436    }
     437
     438    std::string CommandExecutor::getArgument(unsigned int index)
     439    {
     440        if (index < (CommandExecutor::getEvaluation().commandTokens_.size()))
     441            return CommandExecutor::getEvaluation().commandTokens_[index];
     442        else
     443            return "";
     444    }
     445
     446    std::string CommandExecutor::getLastArgument()
     447    {
     448        return CommandExecutor::getArgument(CommandExecutor::argumentsGiven() - 1);
     449    }
     450
     451    void CommandExecutor::createListOfPossibleIdentifiers(const std::string& fragment)
     452    {
     453        CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.clear();
     454        std::string lowercase = getLowercase(fragment);
     455        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
     456            if ((*it).second->hasConsoleCommands())
     457                if ((*it).first.find(lowercase) == 0 || fragment == "")
     458                    CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     459    }
     460
     461    void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
     462    {
    1105463        CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear();
    1106         CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.clear();
    1107         CommandExecutor::getEvaluation().listOfPossibleConfigValues_.clear();
    1108         CommandExecutor::getEvaluation().listOfPossibleKeys_.clear();
    1109 
    1110         CommandExecutor::getEvaluation().functionclass_ = 0;
    1111         CommandExecutor::getEvaluation().configvalueclass_ = 0;
    1112         CommandExecutor::getEvaluation().shortcut_ = 0;
    1113         CommandExecutor::getEvaluation().function_ = 0;
    1114         CommandExecutor::getEvaluation().configvalue_ = 0;
    1115         CommandExecutor::getEvaluation().key_ = 0;
    1116 
    1117         CommandExecutor::getEvaluation().errorMessage_ = "";
    1118         CommandExecutor::getEvaluation().state_ = CS_Empty;
    1119     }
    1120 
    1121     bool CommandExecutor::argumentsGiven(unsigned int num)
    1122     {
    1123         // Because we added a cursor we have +1 arguments
    1124         // There are num arguments given if there are at least num arguments + one cursor
    1125         return (CommandExecutor::getEvaluation().tokens_.size() >= (num + 1));
    1126     }
    1127 
    1128     unsigned int CommandExecutor::argumentsGiven()
    1129     {
    1130         // Because we added a cursor we have +1 arguments
    1131         if (CommandExecutor::getEvaluation().tokens_.size() >= 1)
    1132             return (CommandExecutor::getEvaluation().tokens_.size() - 1);
    1133         else
    1134             return 0;
    1135     }
    1136 
    1137     std::string CommandExecutor::getToken(unsigned int index)
    1138     {
    1139         if ((index >= 0) && (index < (CommandExecutor::getEvaluation().tokens_.size() - 1)))
    1140             return CommandExecutor::getEvaluation().tokens_[index];
    1141         else if (index == (CommandExecutor::getEvaluation().tokens_.size() - 1))
    1142             return CommandExecutor::getEvaluation().tokens_[index].substr(0, CommandExecutor::getEvaluation().tokens_[index].size() - 1);
    1143         else
    1144             return "";
    1145     }
    1146 
    1147     bool CommandExecutor::enoughParametersGiven(unsigned int head, Executor* executor)
    1148     {
    1149         unsigned int neededParams = head + executor->getParamCount();
    1150         /*
    1151         for (unsigned int i = executor->getParamCount() - 1; i >= 0; i--)
    1152         {
    1153             if (executor->defaultValueSet(i))
    1154                 neededParams--;
     464        std::string lowercase = getLowercase(fragment);
     465        if (!identifier)
     466        {
     467            for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
     468                if ((*it).first.find(lowercase) == 0 || fragment == "")
     469                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     470        }
     471        else
     472        {
     473            for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
     474                if ((*it).first.find(lowercase) == 0 || fragment == "")
     475                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     476        }
     477    }
     478
     479    void CommandExecutor::createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param)
     480    {
     481        CommandExecutor::createArgumentCompletionList(command, param);
     482
     483        CommandExecutor::getEvaluation().listOfPossibleArguments_.clear();
     484        std::string lowercase = getLowercase(fragment);
     485        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
     486        {
     487            if ((*it).lowercaseComparison())
     488            {
     489                if ((*it).getComparable().find(lowercase) == 0 || fragment == "")
     490                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
     491            }
    1155492            else
    1156                 break;
    1157         }
    1158         */
    1159         return ((CommandExecutor::getEvaluation().tokens_.size() >= neededParams) && (CommandExecutor::getEvaluation().tokens_[neededParams - 1] != COMMAND_EXECUTOR_CURSOR));
    1160     }
    1161 
    1162     void CommandExecutor::createListOfPossibleFunctionClasses(const std::string& fragment)
    1163     {
    1164         for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
    1165         {
    1166             if ((*it).second->hasConsoleCommands())
    1167             {
    1168                 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1169                 {
    1170                     CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1171                 }
    1172             }
    1173         }
    1174 
    1175         CommandExecutor::getEvaluation().listOfPossibleFunctionClasses_.sort(CommandExecutor::compareStringsInList);
    1176     }
    1177 
    1178     void CommandExecutor::createListOfPossibleShortcuts(const std::string& fragment)
    1179     {
    1180         for (std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
    1181         {
    1182             if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1183             {
    1184                 CommandExecutor::getEvaluation().listOfPossibleShortcuts_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1185             }
    1186         }
    1187 
    1188         CommandExecutor::getEvaluation().listOfPossibleShortcuts_.sort(CommandExecutor::compareStringsInList);
    1189     }
    1190 
    1191     void CommandExecutor::createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier)
    1192     {
    1193         for (std::map<std::string, ExecutorStatic*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
    1194         {
    1195             if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1196             {
    1197                 CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1198             }
    1199         }
    1200 
    1201         CommandExecutor::getEvaluation().listOfPossibleFunctions_.sort(CommandExecutor::compareStringsInList);
    1202     }
    1203 
    1204     void CommandExecutor::createListOfPossibleConfigValueClasses(const std::string& fragment)
    1205     {
    1206         for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMapBegin(); it != Identifier::getLowercaseIdentifierMapEnd(); ++it)
    1207         {
    1208             if ((*it).second->hasConfigValues())
    1209             {
    1210                 if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1211                 {
    1212                     CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1213                 }
    1214             }
    1215         }
    1216 
    1217         CommandExecutor::getEvaluation().listOfPossibleConfigValueClasses_.sort(CommandExecutor::compareStringsInList);
    1218     }
    1219 
    1220     void CommandExecutor::createListOfPossibleConfigValues(const std::string& fragment, Identifier* identifier)
    1221     {
    1222         for (std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMapBegin(); it != identifier->getLowercaseConfigValueMapEnd(); ++it)
    1223         {
    1224             if ((*it).first.find(getLowercase(fragment)) == 0 || fragment == "")
    1225             {
    1226                 CommandExecutor::getEvaluation().listOfPossibleConfigValues_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
    1227             }
    1228         }
    1229 
    1230         CommandExecutor::getEvaluation().listOfPossibleConfigValues_.sort(CommandExecutor::compareStringsInList);
    1231     }
    1232 
    1233     void CommandExecutor::createListOfPossibleKeys(const std::string& fragment)
    1234     {
    1235         // todo
    1236 
    1237         CommandExecutor::getEvaluation().listOfPossibleKeys_.sort(CommandExecutor::compareStringsInList);
    1238     }
    1239 
    1240     bool CommandExecutor::compareStringsInList(const std::pair<const std::string*, const std::string*>& first, const std::pair<const std::string*, const std::string*>& second)
    1241     {
    1242         return ((*first.first) < (*second.first));
    1243     }
    1244 
    1245     Identifier* CommandExecutor::getIdentifierOfPossibleFunctionClass(const std::string& name)
    1246     {
    1247         std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name));
     493            {
     494                if ((*it).getComparable().find(fragment) == 0 || fragment == "")
     495                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
     496            }
     497        }
     498    }
     499
     500    Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name)
     501    {
     502        std::string lowercase = getLowercase(name);
     503        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(lowercase);
    1248504        if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConsoleCommands())
    1249505            return (*it).second;
     
    1252508    }
    1253509
    1254     ExecutorStatic* CommandExecutor::getExecutorOfPossibleShortcut(const std::string& name)
    1255     {
    1256         std::map<std::string, ExecutorStatic*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(getLowercase(name));
    1257         if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
    1258             return (*it).second;
    1259 
     510    ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier)
     511    {
     512        std::string lowercase = getLowercase(name);
     513        if (!identifier)
     514        {
     515            std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(lowercase);
     516            if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
     517                return (*it).second;
     518        }
     519        else
     520        {
     521            std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(lowercase);
     522            if (it != identifier->getLowercaseConsoleCommandMapEnd())
     523                return (*it).second;
     524        }
    1260525        return 0;
    1261526    }
    1262527
    1263     ExecutorStatic* CommandExecutor::getExecutorOfPossibleFunction(const std::string& name, Identifier* identifier)
    1264     {
    1265         std::map<std::string, ExecutorStatic*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(getLowercase(name));
    1266         if (it != identifier->getLowercaseConsoleCommandMapEnd())
    1267             return (*it).second;
    1268 
    1269         return 0;
    1270     }
    1271 
    1272     Identifier* CommandExecutor::getIdentifierOfPossibleConfigValueClass(const std::string& name)
    1273     {
    1274         std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseIdentifierMap().find(getLowercase(name));
    1275         if ((it != Identifier::getLowercaseIdentifierMapEnd()) && (*it).second->hasConfigValues())
    1276             return (*it).second;
    1277 
    1278         return 0;
    1279     }
    1280 
    1281     ConfigValueContainer* CommandExecutor::getContainerOfPossibleConfigValue(const std::string& name, Identifier* identifier)
    1282     {
    1283         std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->getLowercaseConfigValueMap().find(getLowercase(name));
    1284         if (it != identifier->getLowercaseConfigValueMapEnd())
    1285         {
    1286             return (*it).second;
    1287         }
    1288 
    1289         return 0;
    1290     }
    1291 
    1292     ConfigValueContainer* CommandExecutor::getContainerOfPossibleKey(const std::string& name)
    1293     {
    1294         // todo
    1295 
    1296         return 0;
    1297     }
    1298 
    1299     std::string CommandExecutor::dump(const std::list<std::pair<const std::string*, const std::string*> >& list)
    1300     {
    1301         std::string output = "";
    1302         for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
    1303         {
    1304             if (it != list.begin())
    1305                 output += " ";
    1306 
    1307             output += *(*it).second;
    1308         }
    1309         return output;
    1310     }
    1311 
    1312     std::string CommandExecutor::dump(const ExecutorStatic* executor)
    1313     {
    1314         std::string output = "";
    1315         for (unsigned int i = 0; i < executor->getParamCount(); i++)
    1316         {
    1317             if (i != 0)
    1318                 output += " ";
    1319 
    1320             if (executor->defaultValueSet(i))
    1321                 output += "[";
     528    std::string CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
     529    {
     530        CommandExecutor::createArgumentCompletionList(command, param);
     531
     532        std::string lowercase = getLowercase(name);
     533        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
     534        {
     535            if ((*it).lowercaseComparison())
     536            {
     537                if ((*it).getComparable() == lowercase)
     538                    return (*it).getString();
     539            }
    1322540            else
    1323                 output += "{";
    1324 
    1325             output += executor->getTypenameParam(i);
    1326 
    1327             if (executor->defaultValueSet(i))
    1328                 output += "=" + executor->getDefaultValue(i).toString() + "]";
    1329             else
    1330                 output += "}";
    1331         }
    1332         return output;
    1333     }
    1334 
    1335     std::string CommandExecutor::dump(const ConfigValueContainer* container)
    1336     {
    1337         AddLanguageEntry("CommandExecutor::oldvalue", "old value");
    1338         if (!container->isVector())
    1339             return ("{" + container->getTypename() + "} (" + GetLocalisation("CommandExecutor::oldvalue") + ": " + container->toString() + ")");
    1340         else
    1341             return ("(vector<" + container->getTypename() + ">) (size: " + getConvertedValue<unsigned int, std::string>(container->getVectorSize()) + ")");
     541            {
     542                if ((*it).getComparable() == name)
     543                    return (*it).getString();
     544            }
     545        }
     546
     547        return "";
     548    }
     549
     550    void CommandExecutor::createArgumentCompletionList(ConsoleCommand* command, unsigned int param)
     551    {
     552        std::string params[5];
     553
     554        unsigned int index = 0;
     555        unsigned int lowestIndex = 1 + (CommandExecutor::getEvaluation().functionclass_ != 0);
     556
     557        for (unsigned int i = CommandExecutor::argumentsGiven() - 1; i >= lowestIndex; --i)
     558        {
     559            params[index] = CommandExecutor::getArgument(i);
     560            ++index;
     561            if (index >= 5)
     562                break;
     563        }
     564
     565        command->createArgumentCompletionList(param, params[0], params[1], params[2], params[3], params[4]);
    1342566    }
    1343567
     
    1382606        }
    1383607    }
     608
     609    std::string CommandExecutor::getCommonBegin(const ArgumentCompletionList& list)
     610    {
     611        if (list.size() == 0)
     612        {
     613            return "";
     614        }
     615        else if (list.size() == 1)
     616        {
     617            return ((*list.begin()).getComparable() + " ");
     618        }
     619        else
     620        {
     621            std::string output = "";
     622            for (unsigned int i = 0; true; i++)
     623            {
     624                char temp = 0;
     625                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
     626                {
     627                    std::string argument = (*it).getComparable();
     628                    if (argument.size() > i)
     629                    {
     630                        if (it == list.begin())
     631                        {
     632                            temp = argument[i];
     633                        }
     634                        else
     635                        {
     636                            if (temp != argument[i])
     637                                return output;
     638                        }
     639                    }
     640                    else
     641                    {
     642                        return output;
     643                    }
     644                }
     645                output += temp;
     646            }
     647            return output;
     648        }
     649    }
    1384650}
  • code/trunk/src/core/CommandExecutor.h

    r1349 r1502  
    3232#include "CorePrereqs.h"
    3333
    34 #include <string>
    3534#include <map>
    36 #include <list>
    3735
    38 #include "util/SubString.h"
    39 #include "util/MultiTypeMath.h"
    40 
    41 #define COMMAND_EXECUTOR_CURSOR "$"
     36#include "CommandEvaluation.h"
    4237
    4338namespace orxonox
    4439{
    45     enum CommandState
    46     {
    47         CS_Uninitialized,
    48         CS_Empty,
    49         CS_FunctionClass_Or_Shortcut_Or_Keyword,
    50         CS_Shortcut_Params,
    51         CS_Shortcut_Finished,
    52         CS_Function,
    53         CS_Function_Params,
    54         CS_Function_Finished,
    55         CS_ConfigValueClass,
    56         CS_ConfigValue,
    57         CS_ConfigValueType,
    58         CS_ConfigValueFinished,
    59         CS_KeybindKey,
    60         CS_KeybindCommand,
    61         CS_KeybindFinished,
    62         CS_Error
    63     };
    64 
    65     void exec(const std::string& filename);
    66     std::string echo(const std::string& text);
    67 
    68     void write(const std::string& filename, const std::string& text);
    69     void append(const std::string& filename, const std::string& text);
    70     std::string read(const std::string& filename);
    71 
    72     ///////////////////////
    73     // CommandEvaluation //
    74     ///////////////////////
    75     class _CoreExport CommandEvaluation
    76     {
    77         friend class CommandExecutor;
    78 
    79         public:
    80             CommandEvaluation();
    81 
    82             KeybindMode::Enum getKeybindMode();
    83             bool isValid() const;
    84 
    85             inline void setAdditionalParameter(const std::string& param)
    86                 { this->additionalParameter_ = param; this->bEvaluatedParams_ = false; }
    87             inline std::string getAdditionalParameter() const
    88                 { return (this->additionalParameter_ != "") ? (" " + this->additionalParameter_) : ""; }
    89             inline ExecutorStatic* getEvaluatedExecutor() { return evaluatedExecutor_; }
    90             inline std::string getCommandString() { return this->processedCommand_; }
    91 
    92             void setEvaluatedParameter(unsigned int index, MultiTypeMath param);
    93             MultiTypeMath getEvaluatedParameter(unsigned int index) const;
    94 
    95             void evaluateParams();
    96 
    97             bool hasReturnvalue() const;
    98             MultiTypeMath getReturnvalue() const;
    99 
    100         private:
    101             std::string processedCommand_;
    102             SubString tokens_;
    103             std::string additionalParameter_;
    104 
    105             std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctionClasses_;
    106             std::list<std::pair<const std::string*, const std::string*> > listOfPossibleShortcuts_;
    107             std::list<std::pair<const std::string*, const std::string*> > listOfPossibleFunctions_;
    108             std::list<std::pair<const std::string*, const std::string*> > listOfPossibleConfigValueClasses_;
    109             std::list<std::pair<const std::string*, const std::string*> > listOfPossibleConfigValues_;
    110             std::list<std::pair<const std::string*, const std::string*> > listOfPossibleKeys_;
    111 
    112             Identifier* functionclass_;
    113             Identifier* configvalueclass_;
    114             ExecutorStatic* shortcut_;
    115             ExecutorStatic* function_;
    116             ConfigValueContainer* configvalue_;
    117             ConfigValueContainer* key_;
    118 
    119             std::string errorMessage_;
    120             CommandState state_;
    121 
    122             bool bEvaluatedParams_;
    123             MultiTypeMath param_[5];
    124             ExecutorStatic* evaluatedExecutor_;
    125     };
    126 
    127     /////////////////////
    128     // CommandExecutor //
    129     /////////////////////
    13040    class _CoreExport CommandExecutor
    13141    {
    13242        public:
    13343            static bool execute(const std::string& command, bool useTcl = true);
    134             static bool execute(const CommandEvaluation& evaluation);
    135 
    13644            static std::string complete(const std::string& command);
    137             static std::string complete(const CommandEvaluation& evaluation);
    138 
    13945            static std::string hint(const std::string& command);
    140             static std::string hint(const CommandEvaluation& evaluation);
    14146
    14247            static CommandEvaluation evaluate(const std::string& command);
    143 
    14448            static const CommandEvaluation& getLastEvaluation();
    14549
    146             static Executor& addConsoleCommandShortcut(ExecutorStatic* executor);
    147             static ExecutorStatic* getConsoleCommandShortcut(const std::string& name);
    148             static ExecutorStatic* getLowercaseConsoleCommandShortcut(const std::string& name);
     50            static ConsoleCommand& addConsoleCommandShortcut(ConsoleCommand* command);
     51            static ConsoleCommand* getConsoleCommandShortcut(const std::string& name);
     52            static ConsoleCommand* getLowercaseConsoleCommandShortcut(const std::string& name);
    14953
    15054            /** @brief Returns the map that stores all console commands. @return The const_iterator */
    151             static inline const std::map<std::string, ExecutorStatic*>& getConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_; }
     55            static inline const std::map<std::string, ConsoleCommand*>& getConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_; }
    15256            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands. @return The const_iterator */
    153             static inline std::map<std::string, ExecutorStatic*>::const_iterator getConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_.begin(); }
     57            static inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_.begin(); }
    15458            /** @brief Returns a const_iterator to the end of the map that stores all console commands. @return The const_iterator */
    155             static inline std::map<std::string, ExecutorStatic*>::const_iterator getConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_.end(); }
     59            static inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_.end(); }
    15660
    15761            /** @brief Returns the map that stores all console commands with their names in lowercase. @return The const_iterator */
    158             static inline const std::map<std::string, ExecutorStatic*>& getLowercaseConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_; }
     62            static inline const std::map<std::string, ConsoleCommand*>& getLowercaseConsoleCommandShortcutMap() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_; }
    15963            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands with their names in lowercase. @return The const_iterator */
    160             static inline std::map<std::string, ExecutorStatic*>::const_iterator getLowercaseConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.begin(); }
     64            static inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandShortcutMapBegin() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.begin(); }
    16165            /** @brief Returns a const_iterator to the end of the map that stores all console commands with their names in lowercase. @return The const_iterator */
    162             static inline std::map<std::string, ExecutorStatic*>::const_iterator getLowercaseConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end(); }
     66            static inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandShortcutMapEnd() { return CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end(); }
    16367
    16468        private:
     
    17074            static CommandEvaluation& getEvaluation();
    17175
     76            static void parseIfNeeded(const std::string& command);
    17277            static void parse(const std::string& command, bool bInitialize = true);
    173             static void initialize(const std::string& command);
    17478
    175             static bool argumentsGiven(unsigned int num);
     79            static unsigned int argumentsFinished();
    17680            static unsigned int argumentsGiven();
     81            static bool enoughArgumentsGiven(ConsoleCommand* command);
     82            static std::string getArgument(unsigned int index);
     83            static std::string getLastArgument();
    17784
    178             static std::string getToken(unsigned int index);
     85            static void createListOfPossibleIdentifiers(const std::string& fragment);
     86            static void createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier = 0);
     87            static void createListOfPossibleArguments(const std::string& fragment, ConsoleCommand* command, unsigned int param);
    17988
    180             static bool enoughParametersGiven(unsigned int head, Executor* executor);
     89            static Identifier* getPossibleIdentifier(const std::string& name);
     90            static ConsoleCommand* getPossibleCommand(const std::string& name, Identifier* identifier = 0);
     91            static std::string getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param);
    18192
    182             static void createListOfPossibleShortcuts(const std::string& fragment);
    183             static void createListOfPossibleFunctionClasses(const std::string& fragment);
    184             static void createListOfPossibleFunctions(const std::string& fragment, Identifier* identifier);
    185             static void createListOfPossibleConfigValueClasses(const std::string& fragment);
    186             static void createListOfPossibleConfigValues(const std::string& fragment, Identifier* identifier);
    187             static void createListOfPossibleKeys(const std::string& fragment);
    188 
    189             static bool compareStringsInList(const std::pair<const std::string*, const std::string*>& first, const std::pair<const std::string*, const std::string*>& second);
    190 
    191             static std::string dump(const std::list<std::pair<const std::string*, const std::string*> >& list);
    192             static std::string dump(const ExecutorStatic* executor);
    193             static std::string dump(const ConfigValueContainer* container);
    194 
     93            static void createArgumentCompletionList(ConsoleCommand* command, unsigned int param);
    19594            static std::string getCommonBegin(const std::list<std::pair<const std::string*, const std::string*> >& list);
    196 
    197             static Identifier* getIdentifierOfPossibleFunctionClass(const std::string& name);
    198             static ExecutorStatic* getExecutorOfPossibleShortcut(const std::string& name);
    199             static ExecutorStatic* getExecutorOfPossibleFunction(const std::string& name, Identifier* identifier);
    200             static Identifier* getIdentifierOfPossibleConfigValueClass(const std::string& name);
    201             static ConfigValueContainer* getContainerOfPossibleConfigValue(const std::string& name, Identifier* identifier);
    202             static ConfigValueContainer* getContainerOfPossibleKey(const std::string& name);
     95            static std::string getCommonBegin(const ArgumentCompletionList& list);
    20396
    20497            CommandEvaluation evaluation_;
    205 
    206             std::map<std::string, ExecutorStatic*> consoleCommandShortcuts_;
    207             std::map<std::string, ExecutorStatic*> consoleCommandShortcuts_LC_;
     98            std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_;
     99            std::map<std::string, ConsoleCommand*> consoleCommandShortcuts_LC_;
    208100    };
    209101}
  • code/trunk/src/core/ConfigFileManager.cc

    r1056 r1502  
    3838namespace orxonox
    3939{
    40     ConsoleCommandShortcutExtern(reloadConfig, AccessLevel::None);
    41     ConsoleCommandShortcutExtern(cleanConfig, AccessLevel::None);
    42     ConsoleCommandShortcutExtern(loadSettings, AccessLevel::None);
    43     ConsoleCommandShortcutExtern(loadKeybindings, AccessLevel::None);
     40    SetConsoleCommandShortcutExtern(config).setArgumentCompleter(0, autocompletion::configvalueclasses()).setArgumentCompleter(1, autocompletion::configvalues()).setArgumentCompleter(2, autocompletion::configvalue());
     41    SetConsoleCommandShortcutExtern(tconfig).setArgumentCompleter(0, autocompletion::configvalueclasses()).setArgumentCompleter(1, autocompletion::configvalues()).setArgumentCompleter(2, autocompletion::configvalue());
     42    SetConsoleCommandShortcutExtern(reloadConfig);
     43    SetConsoleCommandShortcutExtern(cleanConfig);
     44    SetConsoleCommandShortcutExtern(loadSettings).setArgumentCompleter(0, autocompletion::files());
     45    SetConsoleCommandShortcutExtern(loadKeybindings).setArgumentCompleter(0, autocompletion::files());
     46
     47    bool config(const std::string& classname, const std::string& varname, const std::string& value)
     48    {
     49        std::map<std::string, Identifier*>::const_iterator identifier = Identifier::getLowercaseIdentifierMap().find(getLowercase(classname));
     50        if (identifier != Identifier::getLowercaseIdentifierMapEnd())
     51        {
     52            std::map<std::string, ConfigValueContainer*>::const_iterator variable = (*identifier).second->getLowercaseConfigValueMap().find(getLowercase(varname));
     53            if (variable != (*identifier).second->getLowercaseConfigValueMapEnd())
     54                return (*variable).second->set(value);
     55        }
     56        return false;
     57    }
     58
     59    bool tconfig(const std::string& classname, const std::string& varname, const std::string& value)
     60    {
     61        std::map<std::string, Identifier*>::const_iterator identifier = Identifier::getLowercaseIdentifierMap().find(getLowercase(classname));
     62        if (identifier != Identifier::getLowercaseIdentifierMapEnd())
     63        {
     64            std::map<std::string, ConfigValueContainer*>::const_iterator variable = (*identifier).second->getLowercaseConfigValueMap().find(getLowercase(varname));
     65            if (variable != (*identifier).second->getLowercaseConfigValueMapEnd())
     66                return (*variable).second->tset(value);
     67        }
     68        return false;
     69    }
    4470
    4571    void reloadConfig()
     
    336362
    337363        COUT(4) << "Saved config file \"" << this->filename_ << "\"." << std::endl;
     364    }
     365
     366    void ConfigFile::save(const std::string& filename)
     367    {
     368        std::string temp = this->filename_;
     369        this->filename_ = filename;
     370        this->save();
     371        this->filename_ = temp;
    338372    }
    339373
     
    473507    }
    474508
     509    void ConfigFileManager::save(ConfigFileType type, const std::string& filename)
     510    {
     511        this->getFile(type)->save(filename);
     512    }
     513
    475514    void ConfigFileManager::clean(ConfigFileType type, bool bCleanComments)
    476515    {
  • code/trunk/src/core/ConfigFileManager.h

    r1116 r1502  
    5050
    5151
     52    bool config(const std::string& classname, const std::string& varname, const std::string& value);
     53    bool tconfig(const std::string& classname, const std::string& varname, const std::string& value);
    5254    void reloadConfig();
    5355    void saveConfig();
     
    222224            void load(bool bCreateIfNotExisting = true);
    223225            void save() const;
     226            void save(const std::string& filename);
    224227            void clean(bool bCleanComments = false);
    225228
     
    265268            void load(ConfigFileType type, bool bCreateIfNotExisting = true);
    266269            void save(ConfigFileType type);
     270            void save(ConfigFileType type, const std::string& filename);
    267271            void clean(ConfigFileType type, bool bCleanComments = false);
    268272
  • code/trunk/src/core/ConfigValueContainer.cc

    r1062 r1502  
    8787
    8888        if (defvalue.size() > 0)
    89             this->value_ = defvalue[0];
    90 
    91         for (unsigned int i = 0; i < defvalue.size(); i++)
    92             ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, defvalue[i].toString(), this->value_.isA(MT_string));
    93 
    94         for (unsigned int i = 0; i < defvalue.size(); i++)
    95             this->defvalueStringVector_.push_back(defvalue[i].toString());
    96 
    97         this->update();
     89        {
     90                this->value_ = defvalue[0];
     91
     92            for (unsigned int i = 0; i < defvalue.size(); i++)
     93            {
     94                ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, defvalue[i].toString(), this->value_.isA(MT_string));
     95                this->defvalueStringVector_.push_back(defvalue[i].toString());
     96            }
     97
     98            this->update();
     99        }
     100    }
     101
     102    /**
     103        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
     104        @param input The new value
     105        @return True if the new value was successfully assigned
     106    */
     107    bool ConfigValueContainer::set(const MultiTypeMath& input)
     108    {
     109        if (this->bIsVector_)
     110        {
     111            return this->callFunctionWithIndex(&ConfigValueContainer::set, input.toString());
     112        }
     113        else
     114        {
     115            if (this->tset(input))
     116            {
     117                ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, input.toString(), this->value_.isA(MT_string));
     118                return true;
     119            }
     120        }
     121        return false;
     122    }
     123
     124    /**
     125        @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
     126        @param index The index in the vector
     127        @param input The new value
     128        @return True if the new value was successfully assigned
     129    */
     130    bool ConfigValueContainer::set(unsigned int index, const MultiTypeMath& input)
     131    {
     132        if (this->bIsVector_)
     133        {
     134            if (this->tset(index, input))
     135            {
     136                ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, index, input.toString(), this->value_.isA(MT_string));
     137                return true;
     138            }
     139        }
     140        else
     141        {
     142            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
     143        }
     144        return false;
     145    }
     146
     147    /**
     148        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
     149        @param input The new value. If bIsVector_ then write "index value"
     150        @return True if the new value was successfully assigned
     151    */
     152    bool ConfigValueContainer::tset(const MultiTypeMath& input)
     153    {
     154        if (this->bIsVector_)
     155        {
     156            return this->callFunctionWithIndex(&ConfigValueContainer::tset, input.toString());
     157        }
     158        else
     159        {
     160            MultiTypeMath temp = this->value_;
     161            if (temp.assimilate(input))
     162            {
     163                this->value_ = temp;
     164                if (this->identifier_)
     165                    this->identifier_->updateConfigValues();
     166
     167                return true;
     168            }
     169        }
     170        return false;
     171    }
     172
     173    /**
     174        @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
     175        @param index The index in the vector
     176        @param input The new value
     177        @return True if the new value was successfully assigned
     178    */
     179    bool ConfigValueContainer::tset(unsigned int index, const MultiTypeMath& input)
     180    {
     181        if (this->bIsVector_)
     182        {
     183            if (index > MAX_VECTOR_INDEX)
     184            {
     185                COUT(1) << "Error: Index " << index << " is too large." << std::endl;
     186                return false;
     187            }
     188
     189            if (index >= this->valueVector_.size())
     190            {
     191                for (unsigned int i = this->valueVector_.size(); i <= index; i++)
     192                {
     193                    this->valueVector_.push_back(MultiTypeMath());
     194                }
     195            }
     196
     197            MultiTypeMath temp = this->value_;
     198            if (temp.assimilate(input))
     199            {
     200                this->valueVector_[index] = temp;
     201
     202                if (this->identifier_)
     203                    this->identifier_->updateConfigValues();
     204
     205                return true;
     206            }
     207        }
     208        else
     209        {
     210            COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
     211        }
     212        return false;
    98213    }
    99214
     
    103218        @return True if the new entry was successfully added
    104219    */
    105     bool ConfigValueContainer::add(const std::string& input)
     220    bool ConfigValueContainer::add(const MultiTypeMath& input)
    106221    {
    107222        if (this->bIsVector_)
     
    123238            if (index < this->valueVector_.size())
    124239            {
     240                // Erase the entry from the vector, change (shift) all entries beginning with index in the config file, remove the last entry from the file
    125241                this->valueVector_.erase(this->valueVector_.begin() + index);
    126242                for (unsigned int i = index; i < this->valueVector_.size(); i++)
     
    131247            }
    132248            COUT(1) << "Error: Invalid vector-index." << std::endl;
    133         }
    134 
    135         COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
    136         return false;
    137     }
    138 
    139     /**
    140         @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
    141         @param input The new value
    142         @return True if the new value was successfully assigned
    143     */
    144     bool ConfigValueContainer::set(const std::string& input)
    145     {
    146         if (this->bIsVector_)
    147         {
    148             SubString token(input, " ", "", true, '"', false, '(', ')', false, '\0');
    149             int index = -1;
    150             bool success = false;
    151 
    152             if (token.size() > 0)
    153                 success = ConvertValue(&index, token[0]);
    154 
    155             if (!success || index < 0 || index > MAX_VECTOR_INDEX)
    156             {
    157                 if (!success)
    158                 {
    159                     COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
    160                 }
    161                 else
    162                 {
    163                     COUT(1) << "Error: Invalid vector-index." << std::endl;
    164                 }
    165                 return false;
    166             }
    167 
    168             if (token.size() >= 2)
    169                 return this->set(index, token.subSet(1).join());
    170             else
    171                 return this->set(index, "");
    172         }
    173 
    174         bool success = this->tset(input);
    175         ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, input, this->value_.isA(MT_string));
    176         return success;
    177     }
    178 
    179     /**
    180         @brief Assigns a new value to the config-value of all objects and writes the change into the config-file.
    181         @param index The index in the vector
    182         @param input The new value
    183         @return True if the new value was successfully assigned
    184     */
    185     bool ConfigValueContainer::set(unsigned int index, const std::string& input)
    186     {
    187         if (this->bIsVector_)
    188         {
    189             bool success = this->tset(index, input);
    190             ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, index, input, this->value_.isA(MT_string));
    191             return success;
    192         }
    193 
    194         COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
    195         return false;
    196     }
    197 
    198     /**
    199         @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
    200         @param input The new value
    201         @return True if the new value was successfully assigned
    202     */
    203     bool ConfigValueContainer::tset(const std::string& input)
    204     {
    205         bool success = this->parse(input);
    206         if (this->identifier_)
    207             this->identifier_->updateConfigValues();
    208         return success;
    209     }
    210 
    211     /**
    212         @brief Assigns a new value to the config-value of all objects, but doesn't change the config-file (t stands for temporary).
    213         @param index The index in the vector
    214         @param input The new value
    215         @return True if the new value was successfully assigned
    216     */
    217     bool ConfigValueContainer::tset(unsigned int index, const std::string& input)
    218     {
    219         if (this->bIsVector_)
    220         {
    221             bool success = this->parse(index, input);
    222             if (this->identifier_)
    223                 this->identifier_->updateConfigValues();
    224             return success;
    225249        }
    226250
     
    259283            for (unsigned int i = 0; i < ConfigFileManager::getSingleton()->getVectorSize(this->type_, this->sectionname_, this->varname_); i++)
    260284            {
    261                 this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isA(MT_string)));
    262                 this->valueVector_.push_back(this->value_);
    263             }
    264         }
    265     }
    266 
    267     /**
    268         @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
    269         @param input The string to convert
    270         @return True if the string was successfully parsed
    271     */
    272     bool ConfigValueContainer::parse(const std::string& input)
    273     {
    274         if (this->bIsVector_)
    275         {
    276             SubString token(input, " ", "", true, '"', false, '(', ')', false, '\0');
    277             int index = -1;
    278             bool success = false;
    279 
    280             if (token.size() > 0)
    281                 success = ConvertValue(&index, token[0]);
    282 
    283             if (!success || index < 0 || index > MAX_VECTOR_INDEX)
    284             {
    285                 if (!success)
     285                if (i < this->defvalueStringVector_.size())
    286286                {
    287                     COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
     287                    this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, this->defvalueStringVector_[i], this->value_.isA(MT_string)));
    288288                }
    289289                else
    290290                {
    291                     COUT(1) << "Error: Invalid vector-index." << std::endl;
     291                    this->value_.fromString(ConfigFileManager::getSingleton()->getValue(this->type_, this->sectionname_, this->varname_, i, MultiTypeMath(), this->value_.isA(MT_string)));
    292292                }
    293                 return false;
    294             }
    295 
    296             if (token.size() >= 2)
    297                 return this->parse(index, token.subSet(1).join());
     293
     294                this->valueVector_.push_back(this->value_);
     295            }
     296        }
     297    }
     298
     299    /**
     300        @brief Calls the given function with parsed index and the parsed argument from the input string.
     301        @param function The function to call
     302        @param input The input string
     303        @return The returnvalue of the functioncall
     304    */
     305    bool ConfigValueContainer::callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiTypeMath&), const std::string& input)
     306    {
     307        SubString token(input, " ", SubString::WhiteSpaces, true, '\\', false, '"', false, '(', ')', false, '\0');
     308        int index = -1;
     309        bool success = false;
     310
     311        if (token.size() > 0)
     312            success = ConvertValue(&index, token[0]);
     313
     314        if (!success || index < 0 || index > MAX_VECTOR_INDEX)
     315        {
     316            if (!success)
     317            {
     318                COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is a vector." << std::endl;
     319            }
    298320            else
    299                 return this->parse(index, "");
    300         }
    301 
    302         MultiTypeMath temp = this->value_;
    303         if (temp.fromString(input))
    304         {
    305             this->value_ = temp;
    306             return true;
    307         }
    308         return false;
    309     }
    310 
    311     /**
    312         @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
    313         @param index The index in the vector
    314         @param input The string to convert
    315         @return True if the string was successfully parsed
    316     */
    317     bool ConfigValueContainer::parse(unsigned int index, const std::string& input)
    318     {
    319         if (this->bIsVector_)
    320         {
    321             if (index >= this->valueVector_.size())
    322             {
    323                 for (unsigned int i = this->valueVector_.size(); i <= index; i++)
    324                 {
    325                     this->valueVector_.push_back(MultiTypeMath());
    326                     ConfigFileManager::getSingleton()->setValue(this->type_, this->sectionname_, this->varname_, i, this->valueVector_[i], this->value_.isA(MT_string));
    327                 }
    328             }
    329 
    330             MultiTypeMath temp = this->value_;
    331             if (temp.fromString(input))
    332             {
    333                 this->valueVector_[index] = temp;
    334                 return true;
     321            {
     322                COUT(1) << "Error: Invalid vector-index." << std::endl;
    335323            }
    336324            return false;
    337325        }
    338326
    339         COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
    340         return false;
    341     }
    342 
    343     /**
    344         @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
    345         @param input The string to convert
    346         @param defvalue The default value to assign if the parsing fails
    347         @return True if the string was successfully parsed
    348     */
    349     bool ConfigValueContainer::parse(const std::string& input, const MultiTypeMath& defvalue)
    350     {
    351         if (this->parse(input))
    352             return true;
    353 
    354         this->value_ = defvalue;
    355         return false;
    356     }
    357 
    358     /**
    359         @brief Parses a given std::string into a value of the type of the associated variable and assigns it.
    360         @param index The index in the vector
    361         @param input The string to convert
    362         @param defvalue The default value to assign if the parsing fails
    363         @return True if the string was successfully parsed
    364     */
    365     bool ConfigValueContainer::parse(unsigned int index, const std::string& input, const MultiTypeMath& defvalue)
    366     {
    367         if (this->bIsVector_)
    368         {
    369             if (this->parse(index, input))
    370                 return true;
    371 
    372             this->valueVector_[index] = defvalue;
    373             return false;
    374         }
    375 
    376         COUT(1) << "Error: Config-value '" << this->varname_ << "' in " << this->sectionname_ << " is not a vector." << std::endl;
    377         return false;
     327        if (token.size() >= 2)
     328            return (this->*function)(index, token.subSet(1).join());
     329        else
     330            return (this->*function)(index, "");
    378331    }
    379332
  • code/trunk/src/core/ConfigValueContainer.h

    r1062 r1502  
    9090            }
    9191
     92            template <typename T>
     93            inline void setVectorType(const std::vector<T>& value)
     94            {
     95                this->value_ = T();
     96                this->update();
     97            }
     98
    9299            inline const std::string& getName() const
    93100                { return this->varname_; }
     
    100107            const std::string& getDescription() const;
    101108
    102             bool add(const std::string& input);
     109            bool set(const MultiTypeMath& input);
     110            bool tset(const MultiTypeMath& input);
     111
     112            bool set(unsigned int index, const MultiTypeMath& input);
     113            bool tset(unsigned int index, const MultiTypeMath& input);
     114            bool add(const MultiTypeMath& input);
    103115            bool remove(unsigned int index);
    104             bool set(const std::string& input);
    105             bool tset(const std::string& input);
     116
    106117            bool reset();
    107118            void update();
     
    115126
    116127        private:
    117             bool parse(const std::string& input);
    118             bool parse(const std::string& input, const MultiTypeMath& defvalue);
    119 
    120             bool set(unsigned int index, const std::string& input);
    121             bool tset(unsigned int index, const std::string& input);
    122             bool parse(unsigned int index, const std::string& input);
    123             bool parse(unsigned int index, const std::string& input, const MultiTypeMath& defvalue);
     128            bool callFunctionWithIndex(bool (ConfigValueContainer::* function) (unsigned int, const MultiTypeMath&), const std::string& input);
    124129
    125130            bool                       bIsVector_;                  //!< True if the container contains a std::vector
  • code/trunk/src/core/ConfigValueIncludes.h

    r1062 r1502  
    5757
    5858/**
     59    @brief Assigns the value, defined in the config-file, to the variable (or the default-value, if there is no entry in the file).
     60    @param classname name in which the config value should be stored
     61    @param varname The name of the variable
     62    @param defvalue The default-value of the variable
     63*/
     64#define SetConfigValueGeneric(classname, varname, defvalue) \
     65    orxonox::ConfigValueContainer* container##varname = ClassManager<classname>::getIdentifier()->getConfigValueContainer(#varname); \
     66    if (!container##varname) \
     67    { \
     68        container##varname = new orxonox::ConfigValueContainer(CFT_Settings, ClassManager<classname>::getIdentifier(), #varname, varname = defvalue); \
     69        ClassManager<classname>::getIdentifier()->addConfigValueContainer(#varname, container##varname); \
     70    } \
     71    container##varname->getValue(&varname)
     72
     73/**
    5974    @brief Assigns the vector-values, defined in the config-file, to the vector (or the default-value, if there are no entries in the file).
    6075    @param varname The name of the std::vector
     
    6984            temp.push_back(MultiTypeMath(defvalue[i])); \
    7085        container##varname = new orxonox::ConfigValueContainer(CFT_Settings, this->getIdentifier(), #varname, temp); \
     86        container##varname->setVectorType(varname); \
    7187        this->getIdentifier()->addConfigValueContainer(#varname, container##varname); \
    7288    } \
     
    106122    }
    107123
    108 /**
    109     @brief Assigns the command, defined in the keybind-file, to the key-variable (or an empty string, if there is no entry in the file).
    110     @param varname The name of the key-variable
    111 */
    112 #define SetKeybind(keyname) \
    113     orxonox::ConfigValueContainer* container##keyname = this->getIdentifier()->getConfigValueContainer(#keyname); \
    114     if (!container##keyname) \
    115     { \
    116         container##keyname = new orxonox::ConfigValueContainer(CFT_Keybindings, this->getIdentifier(), #keyname, keyname = ""); \
    117         this->getIdentifier()->addConfigValueContainer(#keyname, container##keyname); \
    118     } \
    119     container##keyname->getValue(&varname)
    120 
    121124#endif /* _ConfigValueIncludes_H__ */
  • code/trunk/src/core/ConsoleCommand.h

    r1062 r1502  
    3434#include "Executor.h"
    3535#include "ClassManager.h"
    36 #include "Identifier.h"
    3736#include "CommandExecutor.h"
     37#include "ArgumentCompletionFunctions.h"
    3838
    3939
     40#define SetConsoleCommand(classname, function,  bCreateShortcut) \
     41    SetConsoleCommandGeneric(classname##function##consolecommand__, classname, orxonox::createConsoleCommand(orxonox::createFunctor(&classname::function), #function), bCreateShortcut)
    4042
    41 #define ConsoleCommand(classname, function, accesslevel, bCreateShortcut) \
    42     ConsoleCommandGeneric(classname##function##consolecommand__, classname, orxonox::createExecutor(orxonox::createFunctor(&classname::function), #function, accesslevel), bCreateShortcut)
    43 
    44 #define ConsoleCommandGeneric(fakevariable, classname, executor, bCreateShortcut) \
    45     Executor& fakevariable = ClassManager<classname>::getIdentifier()->addConsoleCommand((ExecutorStatic*)executor, bCreateShortcut)
     43#define SetConsoleCommandGeneric(fakevariable, classname, command, bCreateShortcut) \
     44    ConsoleCommand& fakevariable = ClassManager<classname>::getIdentifier()->addConsoleCommand(command, bCreateShortcut)
    4645
    4746
    48 #define ConsoleCommandShortcut(classname, function, accesslevel) \
    49     ConsoleCommandShortcutGeneric(function##consolecommand__, orxonox::createExecutor(orxonox::createFunctor(&classname::function), #function, accesslevel))
     47#define SetConsoleCommandShortcut(classname, function) \
     48    SetConsoleCommandShortcutGeneric(function##consolecommand__, orxonox::createConsoleCommand(orxonox::createFunctor(&classname::function), #function))
    5049
    51 #define ConsoleCommandShortcutExtern(function, accesslevel) \
    52     ConsoleCommandShortcutGeneric(function##consolecommand__, orxonox::createExecutor(orxonox::createFunctor(&function), #function, accesslevel))
     50#define SetConsoleCommandShortcutExtern(function) \
     51    SetConsoleCommandShortcutGeneric(function##consolecommand__, orxonox::createConsoleCommand(orxonox::createFunctor(&function), #function))
    5352
    54 #define ConsoleCommandShortcutGeneric(fakevariable, executor) \
    55     Executor& fakevariable = CommandExecutor::addConsoleCommandShortcut((ExecutorStatic*)executor)
     53#define SetConsoleCommandShortcutGeneric(fakevariable, command) \
     54    ConsoleCommand& fakevariable = CommandExecutor::addConsoleCommandShortcut(command)
    5655
    5756
     57namespace orxonox
     58{
     59    namespace AccessLevel
     60    {
     61        enum Level
     62        {
     63            None,
     64            User,
     65            Admin,
     66            Offline,
     67            Debug,
     68            Disabled
     69        };
     70    }
     71
     72    class _CoreExport ConsoleCommand : public ExecutorStatic
     73    {
     74        public:
     75            ConsoleCommand(FunctorStatic* functor, const std::string& name = "");
     76
     77            inline ConsoleCommand& setDescription(const std::string& description)
     78                { this->ExecutorStatic::setDescription(description); return (*this); }
     79            inline ConsoleCommand& setDescriptionParam(int param, const std::string& description)
     80                { this->ExecutorStatic::setDescriptionParam(param, description); return (*this); }
     81            inline ConsoleCommand& setDescriptionReturnvalue(const std::string& description)
     82                { this->ExecutorStatic::setDescriptionReturnvalue(description); return (*this); }
     83            inline ConsoleCommand& setDefaultValues(const MultiTypeMath& param1)
     84                { this->ExecutorStatic::setDefaultValues(param1); return (*this); }
     85            inline ConsoleCommand& setDefaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2)
     86                { this->ExecutorStatic::setDefaultValues(param1, param2); return (*this); }
     87            inline ConsoleCommand& setDefaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3)
     88                { this->ExecutorStatic::setDefaultValues(param1, param2, param3); return (*this); }
     89            inline ConsoleCommand& setDefaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4)
     90                { this->ExecutorStatic::setDefaultValues(param1, param2, param3, param4); return (*this); }
     91            inline ConsoleCommand& setDefaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2, const MultiTypeMath& param3, const MultiTypeMath& param4, const MultiTypeMath& param5)
     92                { this->ExecutorStatic::setDefaultValues(param1, param2, param3, param4, param5); return (*this); }
     93            inline ConsoleCommand& setDefaultValue(unsigned int index, const MultiTypeMath& param)
     94                { this->ExecutorStatic::setDefaultValue(index, param); return (*this); }
     95
     96            inline ConsoleCommand& setAccessLevel(AccessLevel::Level level)
     97                { this->accessLevel_ = level; return (*this); }
     98            inline AccessLevel::Level getAccessLevel() const
     99                { return this->accessLevel_; }
     100
     101            ConsoleCommand& setArgumentCompleter(unsigned int param, ArgumentCompleter* completer);
     102            ArgumentCompleter* getArgumentCompleter(unsigned int param) const;
     103
     104            void createArgumentCompletionList(unsigned int param, const std::string& param1 = "", const std::string& param2 = "", const std::string& param3 = "", const std::string& param4 = "", const std::string& param5 = "");
     105            const ArgumentCompletionList& getArgumentCompletionList() const
     106                { return this->argumentList_; }
     107            ArgumentCompletionList::const_iterator getArgumentCompletionListBegin() const
     108                { return this->argumentList_.begin(); }
     109            ArgumentCompletionList::const_iterator getArgumentCompletionListEnd() const
     110                { return this->argumentList_.end(); }
     111
     112            inline ConsoleCommand& setKeybindMode(KeybindMode::Enum mode)
     113                { this->keybindMode_ = mode; return *this; }
     114            inline KeybindMode::Enum getKeybindMode() const
     115                { return this->keybindMode_; }
     116
     117            inline ConsoleCommand& setAxisParamIndex(int index)
     118                { this->axisParamIndex_ = index; return *this; }
     119            inline int getAxisParamIndex() const
     120                { return this->axisParamIndex_; }
     121
     122            inline ConsoleCommand& setIsAxisRelative(bool val)
     123                { this->bAxisRelative_ = val; return *this; }
     124            inline int getIsAxisRelative() const
     125                { return this->bAxisRelative_; }
     126
     127        private:
     128            AccessLevel::Level accessLevel_;
     129            ArgumentCompleter* argumentCompleter_[5];
     130            ArgumentCompletionList argumentList_;
     131
     132            KeybindMode::Enum keybindMode_;
     133            int axisParamIndex_;
     134            bool bAxisRelative_;
     135    };
     136
     137    inline ConsoleCommand* createConsoleCommand(FunctorStatic* functor, const std::string& name = "")
     138    {
     139        return new ConsoleCommand(functor, name);
     140    }
     141}
     142
    58143#endif /* _ConsoleCommand_H__ */
  • code/trunk/src/core/CorePrereqs.h

    r1349 r1502  
    3535#define _CorePrereqs_H__
    3636
    37 #include "OrxonoxPlatform.h"
     37#include "util/OrxonoxPlatform.h"
    3838
    3939#include <string>
     
    6666namespace orxonox
    6767{
    68 #ifndef _XMLPort_Mode__
    69 #define _XMLPort_Mode__
    7068  namespace XMLPort
    7169  {
     
    7674    };
    7775  }
    78 #endif
    7976
    8077  namespace KeybindMode
     
    9188  typedef std::string LanguageEntryLabel;
    9289
     90  class ArgumentCompleter;
     91  class ArgumentCompletionListElement;
    9392  class BaseFactory;
    9493  class BaseMetaObjectListElement;
     
    112111  class ConfigFileSection;
    113112  class ConfigValueContainer;
     113  class ConsoleCommand;
    114114  class CoreSettings;
    115115  class Error;
     
    125125  class Identifier;
    126126  class IdentifierDistributor;
     127  class IRC;
    127128  template <class T>
    128129  class Iterator;
     
    141142  class ObjectListElement;
    142143  class OrxonoxClass;
     144  class OutputBuffer;
     145  class OutputBufferListener;
    143146  class OutputHandler;
    144147  class Shell;
     148  class ShellListener;
    145149  template <class T>
    146150  class SubclassIdentifier;
    147151  class TclBind;
     152  struct TclInterpreterBundle;
     153  class TclThreadManager;
    148154  class Tickable;
    149155  template <class T, class O>
     
    156162  // input
    157163  //class GUIInputHandler;
     164  class Calibrator;
     165  class CalibratorCallback;
    158166  class InputBuffer;
    159167  class InputBufferListener;
     
    161169  class JoyStickHandler;
    162170  class KeyBinder;
    163   class KeyHandler;
     171  class KeyDetector;
    164172  class MouseHandler;
    165173
  • code/trunk/src/core/CoreSettings.cc

    r1058 r1502  
    117117
    118118    /**
    119         @brief Static function that holds the singleton.
     119        @brief Returns the softDebugLevel for the given device (returns a default-value if the class ist right about to be created).
     120        @param device The device
     121        @return The softDebugLevel
    120122    */
    121123    int CoreSettings::getSoftDebugLevel(OutputHandler::OutputDevice device)
     
    136138        return 2;
    137139    }
     140
     141     /**
     142        @brief Sets the softDebugLevel for the given device. Please use this only temporary and restore the value afterwards, as it overrides the configured value.
     143        @param device The device
     144        @param level The level
     145    */
     146     void CoreSettings::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
     147     {
     148        if (!CoreSettings::isCreatingCoreSettings())
     149        {
     150            if (device == OutputHandler::LD_All)
     151                CoreSettings::getInstance().softDebugLevel_ = level;
     152            else if (device == OutputHandler::LD_Console)
     153                CoreSettings::getInstance().softDebugLevelConsole_ = level;
     154            else if (device == OutputHandler::LD_Logfile)
     155                CoreSettings::getInstance().softDebugLevelLogfile_ = level;
     156            else if (device == OutputHandler::LD_Shell)
     157                CoreSettings::getInstance().softDebugLevelShell_ = level;
     158        }
     159     }
    138160
    139161    /**
  • code/trunk/src/core/CoreSettings.h

    r1064 r1502  
    5454
    5555            static int getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All);
     56            static void setSoftDebugLevel(OutputHandler::OutputDevice device, int level);
    5657            static const std::string& getLanguage();
    5758            static void resetLanguage();
  • code/trunk/src/core/Debug.h

    r1293 r1502  
    206206   COUT ## x
    207207
     208  #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE
     209   #define COUT0  \
     210    if (getSoftDebugLevel() >= ORX_NONE)  \
     211     COUT_EXEC(0)
     212  #else
     213   #define COUT0 if (ORX_NONE)\
     214    COUT_EXEC(0)
     215  #endif
     216
    208217  #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR
    209218   #define COUT1  \
     
    256265 #endif /* if ORX_PRINT_DEBUG_OUTPUT */
    257266
    258  #define COUT0 \
    259   COUT_EXEC(0)
    260267#endif /* ifndef COUT */
    261268
     
    280287   CCOUT ## x
    281288
     289  #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE
     290   #define CCOUT0  \
     291    if (getSoftDebugLevel() >= ORX_NONE)  \
     292     CCOUT_EXEC(0)
     293  #else
     294   #define CCOUT0 if (ORX_NONE)\
     295    CCOUT_EXEC(0)
     296  #endif
     297
    282298  #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR
    283299   #define CCOUT1  \
     
    330346 #endif /* if ORX_PRINT_DEBUG_OUTPUT */
    331347
    332  #define CCOUT0 \
    333   CCOUT_EXEC(0)
    334348#endif /* ifndef CCOUT */
    335349
  • code/trunk/src/core/Executor.cc

    r1349 r1502  
    3434namespace orxonox
    3535{
    36     Executor::Executor(Functor* functor, const std::string& name, AccessLevel::Level level)
     36    Executor::Executor(Functor* functor, const std::string& name)
    3737    {
    3838        this->functor_ = functor;
    3939        this->name_ = name;
    40         this->accessLevel_ = level;
    41         this->keybindMode_ = KeybindMode::OnPress;
    42         this->axisParamIndex_ = -1;
    43         this->bAxisRelative_ = false;
    4440
    4541        this->bAddedDescription_ = false;
  • code/trunk/src/core/Executor.h

    r1349 r1502  
    3535#include "util/SubString.h"
    3636#include "util/String.h"
     37#include "util/Math.h"
    3738#include "Functor.h"
    3839#include "Debug.h"
     
    100101            COUT(5) << tokens[i]; \
    101102        } \
    102         COUT(5) << ") and " << (paramCount - tokens.size()) << " default values ("; \
     103        COUT(5) << ") and " << max((int)paramCount - (int)tokens.size(), 0) << " default values ("; \
    103104        for (unsigned int i = tokens.size(); i < paramCount; i++) \
    104105        { \
     
    134135    return true
    135136
    136 namespace AccessLevel
    137 {
    138     enum Level
    139     {
    140         None,
    141         User,
    142         Admin,
    143         Offline,
    144         Debug,
    145         Disabled
    146     };
    147 }
    148 
    149137namespace orxonox
    150138{
     
    152140    {
    153141        public:
    154             Executor(Functor* functor, const std::string& name = "", AccessLevel::Level level = AccessLevel::None);
     142            Executor(Functor* functor, const std::string& name = "");
    155143            virtual ~Executor();
    156144
     
    181169            const std::string& getDescriptionReturnvalue(int param) const;
    182170
     171            inline Functor* getFunctor() const
     172                { return this->functor_; }
    183173            inline unsigned int getParamCount() const
    184174                { return this->functor_->getParamCount(); }
     
    199189                { return this->name_; }
    200190
    201             inline void setAccessLevel(AccessLevel::Level level)
    202                 { this->accessLevel_ = level; }
    203             inline AccessLevel::Level getAccessLevel() const
    204                 { return this->accessLevel_; }
    205 
    206             inline Executor& setKeybindMode(KeybindMode::Enum mode)
    207                 { this->keybindMode_ = mode; return *this; }
    208             inline KeybindMode::Enum getKeybindMode() const
    209                 { return this->keybindMode_; }
    210 
    211             inline Executor& setAxisParamIndex(int index)
    212                 { this->axisParamIndex_ = index; return *this; }
    213             inline int getAxisParamIndex() const
    214                 { return this->axisParamIndex_; }
    215 
    216             inline Executor& setIsAxisRelative(bool val)
    217                 { this->bAxisRelative_ = val; return *this; }
    218             inline int getIsAxisRelative() const
    219                 { return this->bAxisRelative_; }
    220 
    221191            Executor& setDefaultValues(const MultiTypeMath& param1);
    222192            Executor& setDefaultValues(const MultiTypeMath& param1, const MultiTypeMath& param2);
     
    249219            bool bAddedDefaultValue_[MAX_FUNCTOR_ARGUMENTS];
    250220
    251             KeybindMode::Enum keybindMode_;
    252             int axisParamIndex_;
    253             bool bAxisRelative_;
    254 
    255221        private:
    256222            LanguageEntryLabel description_;
     
    261227            bool bAddedDescriptionReturnvalue_;
    262228            bool bAddedDescriptionParam_[MAX_FUNCTOR_ARGUMENTS];
    263 
    264             AccessLevel::Level accessLevel_;
    265229    };
    266230
     
    268232    {
    269233        public:
    270             ExecutorStatic(FunctorStatic* functor, const std::string& name = "", AccessLevel::Level level = AccessLevel::None) : Executor(functor, name, level) {}
     234            ExecutorStatic(FunctorStatic* functor, const std::string& name = "") : Executor(functor, name) {}
    271235            virtual ~ExecutorStatic() {}
    272236    };
     
    276240    {
    277241        public:
    278             ExecutorMember(FunctorMember<T>* functor, const std::string& name = "", AccessLevel::Level level = AccessLevel::None) : Executor(functor, name, level) {}
     242            ExecutorMember(FunctorMember<T>* functor, const std::string& name = "") : Executor(functor, name) {}
    279243            virtual ~ExecutorMember() {}
    280244
     
    322286    };
    323287
    324     inline Executor* createExecutor(Functor* functor, const std::string& name = "", AccessLevel::Level level = AccessLevel::None)
    325     {
    326         return new Executor(functor, name, level);
     288    inline Executor* createExecutor(Functor* functor, const std::string& name = "")
     289    {
     290        return new Executor(functor, name);
    327291    }
    328292
    329293    template <class T>
    330     inline ExecutorMember<T>* createExecutor(FunctorMember<T>* functor, const std::string& name = "", AccessLevel::Level level = AccessLevel::None)
    331     {
    332         return new ExecutorMember<T>(functor, name, level);
     294    inline ExecutorMember<T>* createExecutor(FunctorMember<T>* functor, const std::string& name = "")
     295    {
     296        return new ExecutorMember<T>(functor, name);
    333297    }
    334298
    335     inline ExecutorStatic* createExecutor(FunctorStatic* functor, const std::string& name = "", AccessLevel::Level level = AccessLevel::None)
    336     {
    337         return new ExecutorStatic(functor, name, level);
     299    inline ExecutorStatic* createExecutor(FunctorStatic* functor, const std::string& name = "")
     300    {
     301        return new ExecutorStatic(functor, name);
    338302    }
    339303}
  • code/trunk/src/core/Identifier.cc

    r1062 r1502  
    3737
    3838#include "Factory.h"
    39 #include "Executor.h"
     39#include "ConsoleCommand.h"
    4040#include "CommandExecutor.h"
    4141
     
    231231    void Identifier::addConfigValueContainer(const std::string& varname, ConfigValueContainer* container)
    232232    {
     233        std::map<std::string, ConfigValueContainer*>::const_iterator it = this->configValues_.find(varname);
     234        if (it != this->configValues_.end())
     235        {
     236            COUT(2) << "Warning: Overwriting config-value with name " << varname << " in class " << this->getName() << "." << std::endl;
     237        }
     238
    233239        this->bHasConfigValues_ = true;
    234240        this->configValues_[varname] = container;
     
    270276        @return The executor of the command
    271277    */
    272     ExecutorStatic& Identifier::addConsoleCommand(ExecutorStatic* executor, bool bCreateShortcut)
    273     {
     278    ConsoleCommand& Identifier::addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut)
     279    {
     280        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(command->getName());
     281        if (it != this->consoleCommands_.end())
     282        {
     283            COUT(2) << "Warning: Overwriting console-command with name " << command->getName() << " in class " << this->getName() << "." << std::endl;
     284        }
     285
    274286        this->bHasConsoleCommands_ = true;
    275         this->consoleCommands_[executor->getName()] = executor;
    276         this->consoleCommands_LC_[getLowercase(executor->getName())] = executor;
     287        this->consoleCommands_[command->getName()] = command;
     288        this->consoleCommands_LC_[getLowercase(command->getName())] = command;
    277289
    278290        if (bCreateShortcut)
    279             CommandExecutor::addConsoleCommandShortcut(executor);
    280 
    281         return (*executor);
     291            CommandExecutor::addConsoleCommandShortcut(command);
     292
     293        return (*command);
    282294    }
    283295
     
    287299        @return The executor of the requested console command
    288300    */
    289     ExecutorStatic* Identifier::getConsoleCommand(const std::string& name) const
    290     {
    291         std::map<std::string, ExecutorStatic*>::const_iterator it = this->consoleCommands_.find(name);
     301    ConsoleCommand* Identifier::getConsoleCommand(const std::string& name) const
     302    {
     303        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_.find(name);
    292304        if (it != this->consoleCommands_.end())
    293305            return (*it).second;
     
    301313        @return The executor of the requested console command
    302314    */
    303     ExecutorStatic* Identifier::getLowercaseConsoleCommand(const std::string& name) const
    304     {
    305         std::map<std::string, ExecutorStatic*>::const_iterator it = this->consoleCommands_LC_.find(name);
     315    ConsoleCommand* Identifier::getLowercaseConsoleCommand(const std::string& name) const
     316    {
     317        std::map<std::string, ConsoleCommand*>::const_iterator it = this->consoleCommands_LC_.find(name);
    306318        if (it != this->consoleCommands_LC_.end())
    307319            return (*it).second;
  • code/trunk/src/core/Identifier.h

    r1064 r1502  
    6363#include "Debug.h"
    6464#include "Iterator.h"
     65#include "MetaObjectList.h"
    6566#include "util/String.h"
    6667
     
    175176
    176177            /** @brief Returns the map that stores all console commands. @return The const_iterator */
    177             inline const std::map<std::string, ExecutorStatic*>& getConsoleCommandMap() const { return this->consoleCommands_; }
     178            inline const std::map<std::string, ConsoleCommand*>& getConsoleCommandMap() const { return this->consoleCommands_; }
    178179            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands. @return The const_iterator */
    179             inline std::map<std::string, ExecutorStatic*>::const_iterator getConsoleCommandMapBegin() const { return this->consoleCommands_.begin(); }
     180            inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandMapBegin() const { return this->consoleCommands_.begin(); }
    180181            /** @brief Returns a const_iterator to the end of the map that stores all console commands. @return The const_iterator */
    181             inline std::map<std::string, ExecutorStatic*>::const_iterator getConsoleCommandMapEnd() const { return this->consoleCommands_.end(); }
     182            inline std::map<std::string, ConsoleCommand*>::const_iterator getConsoleCommandMapEnd() const { return this->consoleCommands_.end(); }
    182183
    183184            /** @brief Returns the map that stores all console commands with their names in lowercase. @return The const_iterator */
    184             inline const std::map<std::string, ExecutorStatic*>& getLowercaseConsoleCommandMap() const { return this->consoleCommands_LC_; }
     185            inline const std::map<std::string, ConsoleCommand*>& getLowercaseConsoleCommandMap() const { return this->consoleCommands_LC_; }
    185186            /** @brief Returns a const_iterator to the beginning of the map that stores all console commands with their names in lowercase. @return The const_iterator */
    186             inline std::map<std::string, ExecutorStatic*>::const_iterator getLowercaseConsoleCommandMapBegin() const { return this->consoleCommands_LC_.begin(); }
     187            inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandMapBegin() const { return this->consoleCommands_LC_.begin(); }
    187188            /** @brief Returns a const_iterator to the end of the map that stores all console commands with their names in lowercase. @return The const_iterator */
    188             inline std::map<std::string, ExecutorStatic*>::const_iterator getLowercaseConsoleCommandMapEnd() const { return this->consoleCommands_LC_.end(); }
     189            inline std::map<std::string, ConsoleCommand*>::const_iterator getLowercaseConsoleCommandMapEnd() const { return this->consoleCommands_LC_.end(); }
    189190
    190191
     
    213214            virtual XMLPortObjectContainer* getXMLPortObjectContainer(const std::string& sectionname) = 0;
    214215
    215             ExecutorStatic& addConsoleCommand(ExecutorStatic* executor, bool bCreateShortcut);
    216             ExecutorStatic* getConsoleCommand(const std::string& name) const;
    217             ExecutorStatic* getLowercaseConsoleCommand(const std::string& name) const;
     216            ConsoleCommand& addConsoleCommand(ConsoleCommand* command, bool bCreateShortcut);
     217            ConsoleCommand* getConsoleCommand(const std::string& name) const;
     218            ConsoleCommand* getLowercaseConsoleCommand(const std::string& name) const;
    218219
    219220        protected:
     
    270271
    271272            bool bHasConsoleCommands_;                                     //!< True if this class has at least one assigned console command
    272             std::map<std::string, ExecutorStatic*> consoleCommands_;       //!< All console commands of this class
    273             std::map<std::string, ExecutorStatic*> consoleCommands_LC_;    //!< All console commands of this class with their names in lowercase
     273            std::map<std::string, ConsoleCommand*> consoleCommands_;       //!< All console commands of this class
     274            std::map<std::string, ConsoleCommand*> consoleCommands_LC_;    //!< All console commands of this class with their names in lowercase
    274275    };
    275276
  • code/trunk/src/core/InputBuffer.cc

    r1349 r1502  
    3737namespace orxonox
    3838{
    39   InputBuffer::InputBuffer(const std::string allowedChars) :
    40     buffer_(""),
    41     allowedChars_(allowedChars),
    42     lastKey_(KeyCode::Unassigned),
    43     timeSinceKeyPressed_(0.0f),
    44     timeSinceKeyRepeated_(0.0f),
    45     keysToRepeat_(0)
    46   {
    47     RegisterObject(InputBuffer);
    48     setConfigValues();
    49   }
    50 
    51   void InputBuffer::setConfigValues()
    52   {
    53     SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat deleay of the input buffer");
    54     SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
    55     if (keyRepeatDeleay_ < 0.0)
    56     {
    57       ResetConfigValue(keyRepeatDeleay_);
    58     }
    59     if (keyRepeatTime_ < 0.0)
    60     {
    61       ResetConfigValue(keyRepeatTime_);
    62     }
    63   }
    64   /*
    65   void InputBuffer::registerListener(InputBufferListener* listener, void (InputBufferListener::*function)(), bool bOnlySingleInput)
    66   {
    67     struct InputBufferListenerTuple newListener = {listener, function, true, bOnlySingleInput, ' '};
    68     listeners_.insert(listeners_.end(), newListener);
    69   }
    70 
    71   void InputBuffer::registerListener(InputBufferListener* listener, void (InputBufferListener::*function)(), char char_, bool bOnlySingleInput)
    72   {
    73     struct InputBufferListenerTuple newListener = {listener, function, false, bOnlySingleInput, char_};
    74     listeners_.insert(listeners_.end(), newListener);
    75   }
    76   */
    77   void InputBuffer::set(const std::string& input)
    78   {
    79     buffer_ = "";
    80     append(input);
    81   }
    82 
    83   void InputBuffer::append(const std::string& input)
    84   {
    85     for (unsigned int i = 0; i < input.size(); i++)
    86     {
    87       if (charIsAllowed(input[i]))
    88         buffer_ += input[i];
    89 
    90       updated(input[i], false);
    91     }
    92     updated();
    93   }
    94 
    95   void InputBuffer::append(const char& input)
    96   {
    97     if (charIsAllowed(input))
    98       buffer_ += input;
    99 
    100     updated(input, true);
    101   }
    102 
    103   void InputBuffer::clear()
    104   {
    105     buffer_ = "";
    106     updated();
    107   }
    108 
    109   void InputBuffer::removeLast()
    110   {
    111     buffer_ = buffer_.substr(0, buffer_.size() - 1);
    112     updated();
    113   }
    114 
    115   void InputBuffer::updated()
    116   {
    117     for (std::list<InputBufferListenerTuple>::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
    118     {
    119       if ((*it).bListenToAllChanges_)
    120         (*(*it).listener_.*(*it).function_)();
    121     }
    122   }
    123 
    124   void InputBuffer::updated(const char& update, bool bSingleInput)
    125   {
    126     for (std::list<InputBufferListenerTuple>::iterator it = listeners_.begin(); it != listeners_.end(); ++it)
    127     {
    128       if (((*it).bListenToAllChanges_ || ((*it).char_ == update)) && (!(*it).bOnlySingleInput_ || bSingleInput))
    129         (*(*it).listener_.*(*it).function_)();
    130     }
    131   }
    132 
    133   bool InputBuffer::charIsAllowed(const char& input)
    134   {
    135     if (allowedChars_ == "")
    136       return true;
    137     else
    138       return (allowedChars_.find(input) != std::string::npos);
    139   }
    140 
    141 
    142   void InputBuffer::processKey(const KeyEvent &evt)
    143   {
    144     if (evt.isModifierDown(KeyboardModifier::Ctrl))
    145     {
    146       if (evt.key == KeyCode::V)
    147         append(fromClipboard());
    148       else if (evt.key == KeyCode::C)
    149         toClipboard(buffer_);
    150       else if (evt.key == KeyCode::X)
    151       {
    152         toClipboard(buffer_);
    153         clear();
    154       }
    155     }
    156     else if (evt.isModifierDown(KeyboardModifier::Shift))
    157     {
    158       if (evt.key == KeyCode::Insert)
    159       {
    160         append(fromClipboard());
    161       }
    162       else if (evt.key == KeyCode::Delete)
    163       {
    164         toClipboard(buffer_);
    165         clear();
    166       }
    167     }
    168     //std::string input = keyboard_->getAsString(e.key);
    169     /*if (input.size() >= 1)
    170     append(input[0]);*/
    171 
    172     append((char)evt.text);
    173   }
    174 
    175   /**
    176   * This tick() function is called by the InputManager if the InputBuffer is active.
    177   * @param dt Delta time
    178   */
    179   void InputBuffer::tick(float dt)
    180   {
    181     timeSinceKeyPressed_ += dt;
    182     if (keysToRepeat_ < 10 && timeSinceKeyPressed_ > keyRepeatDeleay_)
    183     {
    184       // initial time out has gone by, start repeating keys
    185       while (timeSinceKeyPressed_ - timeSinceKeyRepeated_ > keyRepeatTime_)
    186       {
    187         timeSinceKeyRepeated_ += keyRepeatTime_;
    188         keysToRepeat_++;
    189       }
    190     }
    191   }
    192 
    193   void InputBuffer::keyPressed(const KeyEvent &evt)
    194   {
    195     lastKey_ = evt.key;
    196     timeSinceKeyPressed_ = 0.0;
    197     timeSinceKeyRepeated_ = keyRepeatDeleay_;
    198     keysToRepeat_ = 0;
    199 
    200     processKey(evt);
    201   }
    202 
    203   void InputBuffer::keyHeld(const KeyEvent& evt)
    204   {
    205     if (evt.key == lastKey_)
    206     {
    207       while (keysToRepeat_)
    208       {
     39    InputBuffer::InputBuffer()
     40    {
     41        RegisterObject(InputBuffer);
     42
     43        this->buffer_ = "";
     44        this->cursor_ = 0;
     45        this->allowedChars_ = "abcdefghijklmnopqrstuvwxyz \
     46                               ABCDEFGHIJKLMNOPQRSTUVWXYZ \
     47                               äëïöüÄËÏÖÜáâàéêèíîìóôòúûù \
     48                               0123456789 \
     49                               \\\"(){}[]<>.:,;_-+*/=!?|$&%^~#";
     50
     51        this->lastKey_ = KeyCode::Unassigned;
     52        this->timeSinceKeyPressed_ = 0.0f;
     53        this->timeSinceKeyRepeated_ = 0.0f;
     54        this->keysToRepeat_ = 0;
     55
     56        setConfigValues();
     57    }
     58
     59    InputBuffer::InputBuffer(const std::string allowedChars)
     60    {
     61        RegisterObject(InputBuffer);
     62
     63        this->allowedChars_ = allowedChars;
     64        this->buffer_ = "";
     65        this->cursor_ = 0;
     66
     67        this->lastKey_ = KeyCode::Unassigned;
     68        this->timeSinceKeyPressed_ = 0.0f;
     69        this->timeSinceKeyRepeated_ = 0.0f;
     70        this->keysToRepeat_ = 0;
     71
     72        setConfigValues();
     73    }
     74
     75    void InputBuffer::setConfigValues()
     76    {
     77        SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat deleay of the input buffer");
     78        SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
     79
     80        if (keyRepeatDeleay_ < 0.0)
     81        {
     82            ResetConfigValue(keyRepeatDeleay_);
     83        }
     84        if (keyRepeatTime_ < 0.0)
     85        {
     86            ResetConfigValue(keyRepeatTime_);
     87        }
     88    }
     89
     90    void InputBuffer::set(const std::string& input, bool update)
     91    {
     92        this->clear(false);
     93        this->insert(input, update);
     94    }
     95
     96    void InputBuffer::insert(const std::string& input, bool update)
     97    {
     98        for (unsigned int i = 0; i < input.size(); ++i)
     99        {
     100            this->insert(input[i], false);
     101
     102            if (update)
     103                this->updated(input[i], false);
     104        }
     105
     106        if (update)
     107            this->updated();
     108    }
     109
     110    void InputBuffer::insert(const char& input, bool update)
     111    {
     112        if (this->charIsAllowed(input))
     113        {
     114            this->buffer_.insert(this->cursor_, 1, input);
     115            ++this->cursor_;
     116        }
     117
     118        if (update)
     119            this->updated(input, true);
     120    }
     121
     122    void InputBuffer::clear(bool update)
     123    {
     124        this->buffer_ = "";
     125        this->cursor_ = 0;
     126
     127        if (update)
     128            this->updated();
     129    }
     130
     131    void InputBuffer::removeBehindCursor(bool update)
     132    {
     133        if (this->cursor_ > 0)
     134        {
     135            --this->cursor_;
     136            this->buffer_.erase(this->cursor_, 1);
     137
     138            if (update)
     139                this->updated();
     140        }
     141    }
     142
     143    void InputBuffer::removeAtCursor(bool update)
     144    {
     145        if (this->cursor_ < this->buffer_.size())
     146        {
     147            this->buffer_.erase(this->cursor_, 1);
     148
     149            if (update)
     150                this->updated();
     151        }
     152    }
     153
     154    void InputBuffer::updated()
     155    {
     156        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
     157        {
     158            if ((*it)->bListenToAllChanges_)
     159                (*it)->callFunction();
     160        }
     161    }
     162
     163    void InputBuffer::updated(const char& update, bool bSingleInput)
     164    {
     165        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
     166        {
     167            if ((!(*it)->trueKeyFalseChar_) && ((*it)->bListenToAllChanges_ || ((*it)->char_ == update)) && (!(*it)->bOnlySingleInput_ || bSingleInput))
     168                (*it)->callFunction();
     169        }
     170    }
     171
     172    bool InputBuffer::charIsAllowed(const char& input)
     173    {
     174        if (this->allowedChars_ == "")
     175            return true;
     176        else
     177            return (this->allowedChars_.find(input) != std::string::npos);
     178    }
     179
     180
     181    void InputBuffer::processKey(const KeyEvent &evt)
     182    {
     183        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.key == KeyCode::Tab)
     184            return;
     185
     186        for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ++it)
     187        {
     188            if ((*it)->trueKeyFalseChar_ && ((*it)->key_ == evt.key))
     189                (*it)->callFunction();
     190        }
     191
     192        if (evt.isModifierDown(KeyboardModifier::Ctrl))
     193        {
     194            if (evt.key == KeyCode::V)
     195                this->insert(fromClipboard());
     196            else if (evt.key == KeyCode::C)
     197                toClipboard(this->buffer_);
     198            else if (evt.key == KeyCode::X)
     199            {
     200                toClipboard(this->buffer_);
     201                this->clear();
     202            }
     203        }
     204        else if (evt.isModifierDown(KeyboardModifier::Shift))
     205        {
     206            if (evt.key == KeyCode::Insert)
     207                this->insert(fromClipboard());
     208            else if (evt.key == KeyCode::Delete)
     209            {
     210                toClipboard(this->buffer_);
     211                this->clear();
     212            }
     213        }
     214
     215        this->insert((char)evt.text);
     216    }
     217
     218    /**
     219        @brief This tick() function is called by the InputManager if the InputBuffer is active.
     220        @param dt Delta time
     221    */
     222    void InputBuffer::tickInput(float dt, const HandlerState& state)
     223    {
     224        timeSinceKeyPressed_ += dt;
     225        if (keysToRepeat_ < 10 && timeSinceKeyPressed_ > keyRepeatDeleay_)
     226        {
     227            // initial time out has gone by, start repeating keys
     228            while (timeSinceKeyPressed_ - timeSinceKeyRepeated_ > keyRepeatTime_)
     229            {
     230                timeSinceKeyRepeated_ += keyRepeatTime_;
     231                keysToRepeat_++;
     232            }
     233        }
     234    }
     235
     236    void InputBuffer::keyPressed(const KeyEvent &evt)
     237    {
     238        lastKey_ = evt.key;
     239        timeSinceKeyPressed_ = 0.0;
     240        timeSinceKeyRepeated_ = keyRepeatDeleay_;
     241        keysToRepeat_ = 0;
     242
    209243        processKey(evt);
    210         keysToRepeat_--;
    211       }
    212     }
    213   }
    214 
     244    }
     245
     246    void InputBuffer::keyHeld(const KeyEvent& evt)
     247    {
     248        if (evt.key == lastKey_)
     249        {
     250            while (keysToRepeat_)
     251            {
     252                processKey(evt);
     253                keysToRepeat_--;
     254            }
     255        }
     256    }
    215257}
  • code/trunk/src/core/InputBuffer.h

    r1349 r1502  
    3636
    3737#include "InputInterfaces.h"
    38 #include "Tickable.h"
     38#include "OrxonoxClass.h"
    3939
    4040namespace orxonox
    4141{
    42   class _CoreExport InputBufferListener
    43   {};
    44 
    45   class _CoreExport InputBuffer : public KeyHandler, public OrxonoxClass
    46   {
    47     struct InputBufferListenerTuple
     42    class BaseInputBufferListenerTuple
    4843    {
    49       InputBufferListener* listener_;
    50       void (InputBufferListener::*function_)();
    51       bool bListenToAllChanges_;
    52       bool bOnlySingleInput_;
    53       char char_;
     44    public:
     45        BaseInputBufferListenerTuple(bool bListenToAllChanges, bool bOnlySingleInput,
     46            bool trueKeyFalseChar, char _char, KeyCode::Enum key)
     47            : bListenToAllChanges_(bListenToAllChanges), bOnlySingleInput_(bOnlySingleInput),
     48              trueKeyFalseChar_(trueKeyFalseChar), char_(_char), key_(key)
     49        { }
     50        virtual ~BaseInputBufferListenerTuple() { }
     51        virtual void callFunction() = 0;
     52        bool bListenToAllChanges_;
     53        bool bOnlySingleInput_;
     54        bool trueKeyFalseChar_;
     55        char char_;
     56        KeyCode::Enum key_;
    5457    };
    5558
    56   public:
    57     InputBuffer(const std::string allowedChars =
    58       "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZäöüÄÖÜ0123456789 \\\"(){}[]<>.:,;_-+*/=!?|$&%^");
     59    template <class T>
     60    class InputBufferListenerTuple : public BaseInputBufferListenerTuple
     61    {
     62    public:
     63        InputBufferListenerTuple(T* listener, void (T::*function)(), bool bListenToAllChanges,
     64            bool bOnlySingleInput, bool trueKeyFalseChar, char _char, KeyCode::Enum key)
     65            : BaseInputBufferListenerTuple(bListenToAllChanges, bOnlySingleInput, trueKeyFalseChar, _char, key),
     66              listener_(listener), function_(function)
     67        { }
     68        virtual ~InputBufferListenerTuple() { }
     69        void callFunction()
     70        {
     71            (listener_->*function_)();
     72        }
     73        T* listener_;
     74        void (T::*function_)();
     75    };
    5976
    60     void setConfigValues();
     77    class _CoreExport InputBuffer : public KeyHandler, public OrxonoxClass
     78    {
     79        public:
     80            InputBuffer();
     81            InputBuffer(const std::string allowedChars);
    6182
    62     template <class T>
    63     void registerListener(T* listener, void (T::*function)(), bool bOnlySingleInput)
    64     {
    65       struct InputBufferListenerTuple newListener = {listener, (void (InputBufferListener::*)())function, true, bOnlySingleInput, ' '};
    66       this->listeners_.insert(this->listeners_.end(), newListener);
    67     }
    68     template <class T>
    69     void registerListener(T* listener, void (T::*function)() const, bool bOnlySingleInput)
    70     {
    71       struct InputBufferListenerTuple newListener = {listener, (void (InputBufferListener::*)())function, true, bOnlySingleInput, ' '};
    72       this->listeners_.insert(this->listeners_.end(), newListener);
    73     }
     83            void setConfigValues();
    7484
    75     template <class T>
    76     void registerListener(T* listener, void (T::*function)(), char char_, bool bOnlySingleInput)
    77     {
    78       struct InputBufferListenerTuple newListener = {listener, (void (InputBufferListener::*)())function, false, bOnlySingleInput, char_};
    79       this->listeners_.insert(this->listeners_.end(), newListener);
    80     }
    81     template <class T>
    82     void registerListener(T* listener, void (T::*function)() const, char char_, bool bOnlySingleInput)
    83     {
    84       struct InputBufferListenerTuple newListener = {listener, (void (InputBufferListener::*)())function, false, bOnlySingleInput, char_};
    85       this->listeners_.insert(this->listeners_.end(), newListener);
    86     }
     85            template <class T>
     86            void registerListener(T* listener, void (T::*function)(), bool bOnlySingleInput)
     87            {
     88                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, true, bOnlySingleInput, false, '\0', KeyCode::Unassigned);
     89                this->listeners_.insert(this->listeners_.end(), newTuple);
     90            }
     91            template <class T>
     92            void registerListener(T* listener, void (T::*function)() const, bool bOnlySingleInput)
     93            {
     94                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, true, bOnlySingleInput, false, '\0', KeyCode::Unassigned);
     95                this->listeners_.insert(this->listeners_.end(), newTuple);
     96            }
     97            template <class T>
     98            void registerListener(T* listener, void (T::*function)(), char _char, bool bOnlySingleInput)
     99            {
     100                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, bOnlySingleInput, false, _char, KeyCode::Unassigned);
     101                this->listeners_.insert(this->listeners_.end(), newTuple);
     102            }
     103            template <class T>
     104            void registerListener(T* listener, void (T::*function)() const, char _char, bool bOnlySingleInput)
     105            {
     106                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, bOnlySingleInput, false, _char, KeyCode::Unassigned);
     107                this->listeners_.insert(this->listeners_.end(), newTuple);
     108            }
    87109
    88     void set(const std::string& input);
    89     void append(const std::string& input);
    90     void append(const char& input);
    91     void removeLast();
    92     void clear();
     110            template <class T>
     111            void registerListener(T* listener, void (T::*function)(), KeyCode::Enum key)
     112            {
     113                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, true, true, '\0', key);
     114                this->listeners_.insert(this->listeners_.end(), newTuple);
     115            }
     116            template <class T>
     117            void registerListener(T* listener, void (T::*function)() const, KeyCode::Enum key)
     118            {
     119                InputBufferListenerTuple<T>* newTuple = new InputBufferListenerTuple<T>(listener, (void (T::*)())function, false, true, true, '\0', key);
     120                this->listeners_.insert(this->listeners_.end(), newTuple);
     121            }
    93122
    94     void updated();
    95     void updated(const char& update, bool bSingleInput);
     123            template <class T>
     124            void unregisterListener(T* listener)
     125            {
     126                for (std::list<BaseInputBufferListenerTuple*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
     127                {
     128                    InputBufferListenerTuple<T>* refListener = dynamic_cast<InputBufferListenerTuple<T>*>(*it);
     129                    if (refListener && refListener->listener_ == listener)
     130                        this->listeners_.erase(it++);
     131                    else
     132                        it++;
     133                }
     134            }
    96135
    97     inline std::string get() const
    98     { return this->buffer_; }
     136            void set(const std::string& input, bool update = true);
     137            void insert(const std::string& input, bool update = true);
     138            void insert(const char& input, bool update = true);
     139            void clear(bool update = true);
     140            void removeAtCursor(bool update = true);
     141            void removeBehindCursor(bool update = true);
    99142
    100   private:  // functions
    101     bool charIsAllowed(const char& input);
     143            void updated();
     144            void updated(const char& update, bool bSingleInput);
    102145
    103     void keyPressed (const KeyEvent& evt);
    104     void keyReleased(const KeyEvent& evt) { }
    105     void keyHeld    (const KeyEvent& evt);
    106     void processKey (const KeyEvent &e);
     146            inline std::string get() const
     147                { return this->buffer_; }
     148            inline unsigned int getSize() const
     149                { return this->buffer_.size(); }
    107150
    108     void tick(float dt);
     151            inline unsigned int getCursorPosition() const
     152                { return this->cursor_; }
     153            inline void setCursorPosition(unsigned int cursor)
     154                { if (cursor <= this->buffer_.size()) { this->cursor_ = cursor; } }
     155            inline void setCursorToEnd()
     156                { this->cursor_ = this->buffer_.size(); }
     157            inline void setCursorToBegin()
     158                { this->cursor_ = 0; }
     159            inline void increaseCursor()
     160                { if (this->cursor_ < this->buffer_.size()) { ++this->cursor_; } }
     161            inline void decreaseCursor()
     162                { if (this->cursor_ > 0) { --this->cursor_; } }
    109163
    110   private: // variables
    111     std::string buffer_;
    112     std::list<InputBufferListenerTuple> listeners_;
    113     std::string allowedChars_;
     164        private:
     165            bool charIsAllowed(const char& input);
    114166
    115     KeyCode::Enum lastKey_;
    116     float timeSinceKeyPressed_;
    117     float timeSinceKeyRepeated_;
    118     int keysToRepeat_;
     167            void keyPressed (const KeyEvent& evt);
     168            void keyReleased(const KeyEvent& evt) { }
     169            void keyHeld    (const KeyEvent& evt);
     170            void processKey (const KeyEvent &e);
    119171
    120     // configured values
    121     float keyRepeatDeleay_;
    122     float keyRepeatTime_;
    123   };
     172            void tickInput(float dt, const HandlerState& state);
     173
     174            std::string buffer_;
     175            std::list<BaseInputBufferListenerTuple*> listeners_;
     176            std::string allowedChars_;
     177            unsigned int cursor_;
     178
     179            KeyCode::Enum lastKey_;
     180            float timeSinceKeyPressed_;
     181            float timeSinceKeyRepeated_;
     182            int keysToRepeat_;
     183
     184            float keyRepeatDeleay_;
     185            float keyRepeatTime_;
     186    };
    124187}
    125188
  • code/trunk/src/core/InputInterfaces.h

    r1349 r1502  
    254254                std::vector<Vector3> mVectors;
    255255  };*/
     256 
     257  /**
     258  * Helper struct to determine which handlers of an object (can implement
     259  * multiple handlers) are active.
     260  */
     261  struct HandlerState
     262  {
     263    HandlerState() : key(false), mouse(false), joyStick(false) { }
     264    bool key;
     265    bool mouse;
     266    bool joyStick;
     267  };
    256268
    257269  class _CoreExport InputTickable
     
    259271  public:
    260272    virtual ~InputTickable() { }
    261     virtual void tick(float dt) = 0;
     273    virtual void tickInput(float dt, const HandlerState& state) = 0;
    262274  };
    263275
     
    272284    virtual void keyReleased(const KeyEvent& evt) = 0;
    273285    virtual void keyHeld    (const KeyEvent& evt) = 0;
     286    //virtual void tickKey    (float dt) { }
    274287  };
    275288
     
    286299    virtual void mouseMoved         (IntVector2 abs, IntVector2 rel, IntVector2 clippingSize) = 0;
    287300    virtual void mouseScrolled      (int abs, int rel)     = 0;
     301    //virtual void tickMouse          (float dt) { }
    288302  };
    289303
     
    299313    virtual void joyStickButtonReleased(int joyStickID, int button) = 0;
    300314    virtual void joyStickButtonHeld    (int joyStickID, int button) = 0;
    301     virtual void joyStickAxisMoved     (int joyStickID, int axis, int value) = 0;
     315    virtual void joyStickAxisMoved     (int joyStickID, int axis, float value) = 0;
    302316    //virtual bool joyStickVector3Moved  (int joyStickID, int index /*, fill list*/) {return true;}
     317    //virtual void tickJoyStick          (float dt) { }
    303318  };
    304319
  • code/trunk/src/core/InputManager.cc

    r1349 r1502  
    3434
    3535#include "InputManager.h"
     36#include "util/Convert.h"
    3637#include "CoreIncludes.h"
     38#include "ConfigValueIncludes.h"
    3739#include "Debug.h"
    3840#include "InputBuffer.h"
    39 #include "InputHandler.h"
     41#include "KeyBinder.h"
     42#include "CommandExecutor.h"
     43#include "ConsoleCommand.h"
     44#include "Shell.h"
    4045
    4146namespace orxonox
    4247{
     48  SetConsoleCommandShortcut(InputManager, keyBind);
     49  SetConsoleCommandShortcut(InputManager, storeKeyStroke);
     50  SetConsoleCommandShortcut(InputManager, calibrate);
     51
    4352  // ###############################
    4453  // ###    Internal Methods     ###
     
    5362      inputSystem_(0), keyboard_(0), mouse_(0),
    5463      joySticksSize_(0),
    55       state_(IS_UNINIT), stateRequest_(IS_UNINIT),
     64      keyBinder_(0), keyDetector_(0), buffer_(0), calibratorCallback_(0),
     65      state_(IS_UNINIT), stateRequest_(IS_UNINIT), savedState_(IS_UNINIT),
    5666      keyboardModifiers_(0)
    5767  {
     
    129139      if (mouse_)
    130140      {
    131         //// hack the mouse position
    132         //((OIS::MouseState&)mouse_->getMouseState()).X.abs = windowWidth/2;
    133         //((OIS::MouseState&)mouse_->getMouseState()).Y.abs = windowHeight/2;
    134141        setWindowExtents(windowWidth, windowHeight);
    135142      }
     
    137144      state_ = IS_NONE;
    138145      CCOUT(ORX_DEBUG) << "Initialising OIS components done." << std::endl;
     146
     147      // InputManager holds the input buffer --> create one and add it.
     148      buffer_ = new InputBuffer();
     149      addKeyHandler(buffer_, "buffer");
     150      Shell::getInstance().setInputBuffer(buffer_);
     151
     152      keyBinder_ = new KeyBinder();
     153      keyBinder_->loadBindings();
     154      addKeyHandler(keyBinder_, "keybinder");
     155      addMouseHandler(keyBinder_, "keybinder");
     156      addJoyStickHandler(keyBinder_, "keybinder");
     157
     158      keyDetector_ = new KeyDetector();
     159      keyDetector_->loadBindings();
     160      addKeyHandler(keyDetector_, "keydetector");
     161      addMouseHandler(keyDetector_, "keydetector");
     162      addJoyStickHandler(keyDetector_, "keydetector");
     163
     164      calibratorCallback_ = new CalibratorCallback();
     165      addKeyHandler(calibratorCallback_, "calibratorcallback");
     166
     167      setConfigValues();
     168
     169      CCOUT(ORX_DEBUG) << "Initialising complete." << std::endl;
    139170    }
    140171    else
     
    142173      CCOUT(ORX_WARNING) << "Warning: OIS compoments already initialised, skipping" << std::endl;
    143174    }
    144 
    145     // InputManager holds the input buffer --> create one and add it.
    146     addKeyHandler(new InputBuffer(), "buffer");
    147 
    148     KeyBinder* binder = new KeyBinder();
    149     binder->loadBindings();
    150     addKeyHandler(binder, "keybinder");
    151     addMouseHandler(binder, "keybinder");
    152     addJoyStickHandler(binder, "keybinder");
    153 
    154     // Read all the key bindings and assign them
    155     //if (!_loadBindings())
    156     //  return false;
    157 
    158     CCOUT(ORX_DEBUG) << "Initialising complete." << std::endl;
    159175    return true;
    160176  }
     
    216232        // register our listener in OIS.
    217233        mouse_->setEventCallback(this);
    218         CCOUT(ORX_DEBUG) << "Created OIS keyboard" << std::endl;
     234        CCOUT(ORX_DEBUG) << "Created OIS mouse" << std::endl;
    219235        return true;
    220236      }
     
    276292    povStates_.resize(joySticksSize_);
    277293    sliderStates_.resize(joySticksSize_);
     294    joySticksCalibration_.resize(joySticksSize_);
     295    for (unsigned int iJoyStick = 0; iJoyStick < joySticksSize_; iJoyStick++)
     296    {
     297      // reset the calibration with default values
     298      for (unsigned int i = 0; i < 24; i++)
     299      {
     300        joySticksCalibration_[iJoyStick].negativeCoeff[i] = 1.0f/32767.0f;
     301        joySticksCalibration_[iJoyStick].positiveCoeff[i] = 1.0f/32768.0f;
     302        joySticksCalibration_[iJoyStick].zeroStates[i] = 0;
     303      }
     304    }
    278305    return success;
    279306  }
    280307
    281308  /**
     309    @brief Sets the configurable values. Use keybindings.ini as file..
     310  */
     311  void InputManager::setConfigValues()
     312  {
     313    if (joySticksSize_)
     314    {
     315      std::vector<MultiTypeMath> coeffPos;
     316      std::vector<MultiTypeMath> coeffNeg;
     317      std::vector<MultiTypeMath> zero;
     318      coeffPos.resize(24);
     319      coeffNeg.resize(24);
     320      zero.resize(24);
     321      for (unsigned int i = 0; i < 24; i++)
     322      {
     323        coeffPos[i] =  1.0f/32767.0f;
     324        coeffNeg[i] =  1.0f/32768.0f;
     325        zero[i]     =  0;
     326      }
     327
     328      ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos");
     329      if (!cont)
     330      {
     331          cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "CoeffPos", coeffPos);
     332          getIdentifier()->addConfigValueContainer("CoeffPos", cont);
     333      }
     334      cont->getValue(&coeffPos);
     335
     336      cont = getIdentifier()->getConfigValueContainer("CoeffNeg");
     337      if (!cont)
     338      {
     339          cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "CoeffNeg", coeffNeg);
     340          getIdentifier()->addConfigValueContainer("CoeffNeg", cont);
     341      }
     342      cont->getValue(&coeffNeg);
     343
     344      cont = getIdentifier()->getConfigValueContainer("Zero");
     345      if (!cont)
     346      {
     347          cont = new ConfigValueContainer(CFT_Keybindings, getIdentifier(), "Zero", zero);
     348          getIdentifier()->addConfigValueContainer("Zero", cont);
     349      }
     350      cont->getValue(&zero);
     351
     352      // copy values to our own variables
     353      for (unsigned int i = 0; i < 24; i++)
     354      {
     355        joySticksCalibration_[0].positiveCoeff[i] = coeffPos[i];
     356        joySticksCalibration_[0].negativeCoeff[i] = coeffNeg[i];
     357        joySticksCalibration_[0].zeroStates[i]    = zero[i];
     358      }
     359    }
     360  }
     361
     362  /**
    282363    @brief Destroys all the created input devices and sets the InputManager to construction state.
    283364  */
     
    288369      CCOUT(ORX_DEBUG) << "Destroying ..." << std::endl;
    289370
    290       if (keyHandlers_.find("buffer") != keyHandlers_.end())
    291         delete keyHandlers_["buffer"];
    292 
    293       if (keyHandlers_.find("keybinder") != keyHandlers_.end())
    294         delete keyHandlers_["keybinder"];
     371      if (buffer_)
     372        delete buffer_;
     373
     374      if (keyBinder_)
     375        delete keyBinder_;
     376
     377      if (keyDetector_)
     378        delete keyDetector_;
     379
     380      if (calibratorCallback_)
     381        delete calibratorCallback_;
    295382
    296383      keyHandlers_.clear();
     
    301388      _destroyMouse();
    302389      _destroyJoySticks();
     390
     391      activeHandlers_.clear();
    303392
    304393      // inputSystem_ can never be 0, or else the code is mistaken
     
    355444      activeJoyStickHandlers_.clear();
    356445      joyStickButtonsDown_.clear();
     446      povStates_.clear();
     447      sliderStates_.clear();
     448      joySticksCalibration_.clear();
    357449    }
    358450    CCOUT(ORX_DEBUG) << "Joy sticks destroyed." << std::endl;
    359451  }
    360452
     453  void InputManager::_saveState()
     454  {
     455    savedHandlers_.activeHandlers_ = activeHandlers_;
     456    savedHandlers_.activeJoyStickHandlers_ = activeJoyStickHandlers_;
     457    savedHandlers_.activeKeyHandlers_ = activeKeyHandlers_;
     458    savedHandlers_.activeMouseHandlers_ = activeMouseHandlers_;
     459  }
     460
     461  void InputManager::_restoreState()
     462  {
     463    activeHandlers_ = savedHandlers_.activeHandlers_;
     464    activeJoyStickHandlers_ = savedHandlers_.activeJoyStickHandlers_;
     465    activeKeyHandlers_ = savedHandlers_.activeKeyHandlers_;
     466    activeMouseHandlers_ = savedHandlers_.activeMouseHandlers_;
     467  }
     468
    361469  void InputManager::_updateTickables()
    362470  {
    363     // we can use a set to have a list of unique pointers (an object can implement all 3 handlers)
    364     std::set<InputTickable*> tempSet;
     471    // we can use a map to have a list of unique pointers (an object can implement all 3 handlers)
     472    std::map<InputTickable*, HandlerState> tempSet;
    365473    for (unsigned int iHandler = 0; iHandler < activeKeyHandlers_.size(); iHandler++)
    366       tempSet.insert(activeKeyHandlers_[iHandler]);
     474      tempSet[activeKeyHandlers_[iHandler]].joyStick = true;
    367475    for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++)
    368       tempSet.insert(activeMouseHandlers_[iHandler]);
     476      tempSet[activeMouseHandlers_[iHandler]].mouse = true;
    369477    for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
    370478      for (unsigned int iHandler = 0; iHandler  < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    371         tempSet.insert(activeJoyStickHandlers_[iJoyStick][iHandler]);
    372 
    373     // copy the content of the set back to the actual vector
     479        tempSet[activeJoyStickHandlers_[iJoyStick][iHandler]].joyStick = true;
     480
     481    // copy the content of the map back to the actual vector
    374482    activeHandlers_.clear();
    375     for (std::set<InputTickable*>::const_iterator itHandler = tempSet.begin(); itHandler != tempSet.end(); itHandler++)
    376       activeHandlers_.push_back(*itHandler);
     483    for (std::map<InputTickable*, HandlerState>::const_iterator itHandler = tempSet.begin();
     484        itHandler != tempSet.end(); itHandler++)
     485      activeHandlers_.push_back(std::pair<InputTickable*, HandlerState>((*itHandler).first, (*itHandler).second));
    377486  }
    378487
     
    392501      return;
    393502
    394     // reset the game if it has changed
    395503    if (state_ != stateRequest_)
    396504    {
    397       if (stateRequest_ != IS_CUSTOM)
    398       {
     505      InputState sr = stateRequest_;
     506      switch (sr)
     507      {
     508      case IS_NORMAL:
    399509        activeKeyHandlers_.clear();
    400510        activeMouseHandlers_.clear();
     
    402512          activeJoyStickHandlers_[i].clear();
    403513
    404         switch (stateRequest_)
     514        // normal play mode
     515        // note: we assume that the handlers exist since otherwise, something's wrong anyway.
     516        enableKeyHandler("keybinder");
     517        enableMouseHandler("keybinder");
     518        enableJoyStickHandler("keybinder", 0);
     519        stateRequest_ = IS_NORMAL;
     520        state_ = IS_NORMAL;
     521        break;
     522
     523      case IS_GUI:
     524        state_ = IS_GUI;
     525        break;
     526
     527      case IS_CONSOLE:
     528        activeKeyHandlers_.clear();
     529        activeMouseHandlers_.clear();
     530        for (unsigned int i = 0; i < joySticksSize_; i++)
     531          activeJoyStickHandlers_[i].clear();
     532
     533        enableMouseHandler("keybinder");
     534        enableJoyStickHandler("keybinder", 0);
     535        enableKeyHandler("buffer");
     536        stateRequest_ = IS_CONSOLE;
     537        state_ = IS_CONSOLE;
     538        break;
     539
     540      case IS_DETECT:
     541        savedState_ = state_;
     542        _saveState();
     543
     544        activeKeyHandlers_.clear();
     545        activeMouseHandlers_.clear();
     546        for (unsigned int i = 0; i < joySticksSize_; i++)
     547          activeJoyStickHandlers_[i].clear();
     548
     549        enableKeyHandler("keydetector");
     550        enableMouseHandler("keydetector");
     551        enableJoyStickHandler("keydetector", 0);
     552
     553        stateRequest_ = IS_DETECT;
     554        state_ = IS_DETECT;
     555        break;
     556
     557      case IS_NODETECT:
     558        _restoreState();
     559        keysDown_.clear();
     560        mouseButtonsDown_.clear();
     561        joyStickButtonsDown_[0].clear();
     562        state_ = IS_NODETECT;
     563        stateRequest_ = savedState_;
     564        break;
     565
     566      case IS_CALIBRATE:
     567        if (joySticksSize_)
    405568        {
    406         case IS_NORMAL:
    407           // normal play mode
    408           // note: we assume that the handlers exist since otherwise, something's wrong anyway.
    409           enableKeyHandler("keybinder");
    410           enableMouseHandler("keybinder");
    411           enableMouseHandler("SpaceShip");
    412           enableJoyStickHandler("keybinder", 0);
    413           break;
    414 
    415         case IS_GUI:
    416           // TODO: do stuff
    417           break;
    418 
    419         case IS_CONSOLE:
    420           enableMouseHandler("keybinder");
    421           enableMouseHandler("SpaceShip");
    422           enableJoyStickHandler("keybinder", 0);
    423           enableKeyHandler("buffer");
    424           break;
    425 
    426         default:
    427           break;
     569          savedState_ = _getSingleton().state_;
     570          for (unsigned int i = 0; i < 24; i++)
     571          {
     572            marginalsMax_[i] = INT_MIN;
     573            marginalsMin_[i] = INT_MAX;
     574          }
     575          COUT(0) << "Move all joy stick axes in all directions a few times. "
     576            << "Then put all axes in zero state and hit enter." << std::endl;
     577
     578          savedState_ = state_;
     579          _saveState();
     580
     581          activeKeyHandlers_.clear();
     582          activeMouseHandlers_.clear();
     583          for (unsigned int i = 0; i < joySticksSize_; i++)
     584            activeJoyStickHandlers_[i].clear();
     585
     586          enableKeyHandler("calibratorcallback");
     587          stateRequest_ = IS_CALIBRATE;
     588          state_ = IS_CALIBRATE;
    428589        }
    429         state_ = stateRequest_;
     590        else
     591        {
     592          COUT(3) << "Connot calibrate, no joy stick found!" << std::endl;
     593          stateRequest_ = state_;
     594        }
     595        break;
     596
     597      case IS_NOCALIBRATE:
     598        _completeCalibration();
     599        _restoreState();
     600        keyBinder_->resetJoyStickAxes();
     601        state_ = IS_NOCALIBRATE;
     602        stateRequest_ = savedState_;
     603        break;
     604
     605      case IS_NONE:
     606        activeKeyHandlers_.clear();
     607        activeMouseHandlers_.clear();
     608        for (unsigned int i = 0; i < joySticksSize_; i++)
     609          activeJoyStickHandlers_[i].clear();
     610        state_ = IS_NONE;
     611
     612      default:
     613        break;
    430614      }
    431615    }
     
    439623      joySticks_[i]->capture();
    440624
    441 
    442     // call all the handlers for the held key events
    443     for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
    444       for (unsigned int iHandler = 0; iHandler < activeKeyHandlers_.size(); iHandler++)
    445         activeKeyHandlers_[iHandler]->keyHeld(KeyEvent(keysDown_[iKey], keyboardModifiers_));
    446 
    447     // call all the handlers for the held mouse button events
    448     for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
    449       for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++)
    450         activeMouseHandlers_[iHandler]->mouseButtonHeld(mouseButtonsDown_[iButton]);
    451 
    452     // call all the handlers for the held joy stick button events
    453     for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
    454       for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
    455         for (unsigned int iHandler = 0; iHandler  < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    456           activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
    457 
    458 
    459     // call the ticks
     625    if (state_ != IS_CALIBRATE)
     626    {
     627      // call all the handlers for the held key events
     628      for (unsigned int iKey = 0; iKey < keysDown_.size(); iKey++)
     629        for (unsigned int iHandler = 0; iHandler < activeKeyHandlers_.size(); iHandler++)
     630          activeKeyHandlers_[iHandler]->keyHeld(KeyEvent(keysDown_[iKey], keyboardModifiers_));
     631
     632      // call all the handlers for the held mouse button events
     633      for (unsigned int iButton = 0; iButton < mouseButtonsDown_.size(); iButton++)
     634        for (unsigned int iHandler = 0; iHandler < activeMouseHandlers_.size(); iHandler++)
     635          activeMouseHandlers_[iHandler]->mouseButtonHeld(mouseButtonsDown_[iButton]);
     636
     637      // call all the handlers for the held joy stick button events
     638      for (unsigned int iJoyStick  = 0; iJoyStick < joySticksSize_; iJoyStick++)
     639        for (unsigned int iButton   = 0; iButton   < joyStickButtonsDown_[iJoyStick].size(); iButton++)
     640          for (unsigned int iHandler = 0; iHandler  < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
     641            activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickButtonHeld(iJoyStick, joyStickButtonsDown_[iJoyStick][iButton]);
     642    }
     643
     644    // call the ticks for the handlers (need to be treated specially)
    460645    for (unsigned int iHandler = 0; iHandler < activeHandlers_.size(); iHandler++)
    461       activeHandlers_[iHandler]->tick(dt);
     646      activeHandlers_[iHandler].first->tickInput(dt, activeHandlers_[iHandler].second);
     647  }
     648
     649  void InputManager::_completeCalibration()
     650  {
     651    for (unsigned int i = 0; i < 24; i++)
     652    {
     653      // positive coefficient
     654      if (marginalsMax_[i] == INT_MIN)
     655        marginalsMax_[i] =  32767;
     656      // coefficients
     657      if (marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i])
     658        joySticksCalibration_[0].positiveCoeff[i] =  1.0f/(marginalsMax_[i] - joySticksCalibration_[0].zeroStates[i]);
     659      else
     660        joySticksCalibration_[0].positiveCoeff[i] =  1.0f;
     661
     662      // config value
     663      ConfigValueContainer* cont = getIdentifier()->getConfigValueContainer("CoeffPos");
     664      assert(cont);
     665      cont->set(i, joySticksCalibration_[0].positiveCoeff[i]);
     666
     667      // negative coefficient
     668      if (marginalsMin_[i] == INT_MAX)
     669        marginalsMin_[i] = -32768;
     670      // coefficients
     671      if (marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i])
     672        joySticksCalibration_[0].negativeCoeff[i] = -1.0f/(marginalsMin_[i] - joySticksCalibration_[0].zeroStates[i]);
     673      else
     674        joySticksCalibration_[0].negativeCoeff[i] =  1.0f;
     675      // config value
     676      cont = getIdentifier()->getConfigValueContainer("CoeffNeg");
     677      assert(cont);
     678      cont->set(i, joySticksCalibration_[0].negativeCoeff[i]);
     679
     680      // zero states
     681      if (i < 8)
     682      {
     683        if (!(i & 1))
     684          joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abX;
     685        else
     686          joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mSliders[i/2].abY;
     687      }
     688      else
     689      {
     690        if (i - 8 < joySticks_[0]->getJoyStickState().mAxes.size())
     691          joySticksCalibration_[0].zeroStates[i] = joySticks_[0]->getJoyStickState().mAxes[i - 8].abs;
     692        else
     693          joySticksCalibration_[0].zeroStates[i] = 0;
     694      }
     695      // config value
     696      cont = getIdentifier()->getConfigValueContainer("Zero");
     697      assert(cont);
     698      cont->set(i, joySticksCalibration_[0].zeroStates[i]);
     699    }
    462700  }
    463701
     
    594832  // ###### Joy Stick Events ######
    595833
    596   bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button)
     834  inline unsigned int InputManager::_getJoystick(const OIS::JoyStickEvent& arg)
    597835  {
    598836    // use the device to identify which one called the method
     
    600838    unsigned int iJoyStick = 0;
    601839    while (joySticks_[iJoyStick] != joyStick)
     840    {
    602841      iJoyStick++;
     842      if (iJoyStick == joySticksSize_)
     843      {
     844        CCOUT(3) << "Unknown joystick fired an event. This means there is a bug somewhere! Aborting." << std::endl;
     845        abort();
     846      }
     847    }
     848    return iJoyStick;
     849  }
     850
     851  bool InputManager::buttonPressed(const OIS::JoyStickEvent &arg, int button)
     852  {
     853    unsigned int iJoyStick = _getJoystick(arg);
    603854
    604855    // check whether the button already is in the list (can happen when focus was lost)
    605     std::vector<int> buttonsDown = joyStickButtonsDown_[iJoyStick];
     856    std::vector<int>& buttonsDown = joyStickButtonsDown_[iJoyStick];
    606857    unsigned int iButton = 0;
    607858    while (iButton < buttonsDown.size() && buttonsDown[iButton] != button)
     
    618869  bool InputManager::buttonReleased(const OIS::JoyStickEvent &arg, int button)
    619870  {
    620     // use the device to identify which one called the method
    621     OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
    622     unsigned int iJoyStick = 0;
    623     while (joySticks_[iJoyStick] != joyStick)
    624       iJoyStick++;
     871    unsigned int iJoyStick = _getJoystick(arg);
    625872
    626873    // remove the button from the joyStickButtonsDown_ list
    627     std::vector<int> buttonsDown = joyStickButtonsDown_[iJoyStick];
     874    std::vector<int>& buttonsDown = joyStickButtonsDown_[iJoyStick];
    628875    for (unsigned int iButton = 0; iButton < buttonsDown.size(); iButton++)
    629876    {
     
    641888  }
    642889
     890  void InputManager::_fireAxis(unsigned int iJoyStick, int axis, int value)
     891  {
     892    if (state_ == IS_CALIBRATE)
     893    {
     894      if (value > marginalsMax_[axis])
     895        marginalsMax_[axis] = value;
     896      if (value < marginalsMin_[axis])
     897        marginalsMin_[axis] = value;
     898    }
     899    else
     900    {
     901      float fValue = value - joySticksCalibration_[iJoyStick].zeroStates[axis];
     902      if (fValue > 0.0f)
     903        fValue *= joySticksCalibration_[iJoyStick].positiveCoeff[axis];
     904      else
     905        fValue *= joySticksCalibration_[iJoyStick].negativeCoeff[axis];
     906
     907      for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
     908        activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, axis, fValue);
     909    }
     910  }
     911
    643912  bool InputManager::axisMoved(const OIS::JoyStickEvent &arg, int axis)
    644913  {
    645     //CCOUT(3) << arg.state.mAxes[axis].abs << std::endl;
    646     // use the device to identify which one called the method
    647     OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
    648     unsigned int iJoyStick = 0;
    649     while (joySticks_[iJoyStick] != joyStick)
    650       iJoyStick++;
     914    //if (arg.state.mAxes[axis].abs > 10000 || arg.state.mAxes[axis].abs < -10000)
     915    //{ CCOUT(3) << "axis " << axis << " moved" << arg.state.mAxes[axis].abs << std::endl;}
     916
     917    unsigned int iJoyStick = _getJoystick(arg);
    651918
    652919    // keep in mind that the first 8 axes are reserved for the sliders
    653     for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    654       activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, axis + 8, arg.state.mAxes[axis].abs);
     920    _fireAxis(iJoyStick, axis + 8, arg.state.mAxes[axis].abs);
    655921
    656922    return true;
     
    659925  bool InputManager::sliderMoved(const OIS::JoyStickEvent &arg, int id)
    660926  {
     927    //if (arg.state.mSliders[id].abX > 10000 || arg.state.mSliders[id].abX < -10000)
     928    //{CCOUT(3) << "slider " << id << " moved" << arg.state.mSliders[id].abX << std::endl;}
    661929    //CCOUT(3) << arg.state.mSliders[id].abX << "\t |" << arg.state.mSliders[id].abY << std::endl;
    662     // use the device to identify which one called the method
    663     OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
    664     unsigned int iJoyStick = 0;
    665     while (joySticks_[iJoyStick] != joyStick)
    666       iJoyStick++;
     930
     931    unsigned int iJoyStick = _getJoystick(arg);
    667932
    668933    if (sliderStates_[iJoyStick].sliderStates[id].x != arg.state.mSliders[id].abX)
    669     {
    670       // slider X axis changed
    671       sliderStates_[iJoyStick].sliderStates[id].x = arg.state.mSliders[id].abX;
    672       for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    673         activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, id * 2, arg.state.mSliders[id].abX);
    674     }
     934      _fireAxis(iJoyStick, id * 2, arg.state.mSliders[id].abX);
    675935    else if (sliderStates_[iJoyStick].sliderStates[id].y != arg.state.mSliders[id].abY)
    676     {
    677       // slider Y axis changed
    678       sliderStates_[iJoyStick].sliderStates[id].y = arg.state.mSliders[id].abY;
    679       for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
    680         activeJoyStickHandlers_[iJoyStick][iHandler]->joyStickAxisMoved(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
    681     }
     936      _fireAxis(iJoyStick, id * 2 + 1, arg.state.mSliders[id].abY);
    682937
    683938    return true;
     
    686941  bool InputManager::povMoved(const OIS::JoyStickEvent &arg, int id)
    687942  {
    688     // use the device to identify which one called the method
    689     OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
    690     unsigned int iJoyStick = 0;
    691     while (joySticks_[iJoyStick] != joyStick)
    692       iJoyStick++;
     943    unsigned int iJoyStick = _getJoystick(arg);
    693944
    694945    // translate the POV into 8 simple buttons
     
    702953    if (lastState & OIS::Pov::West)
    703954      buttonReleased(arg, 32 + id * 4 + 3);
    704    
     955
    705956    povStates_[iJoyStick].povStates[id] = arg.state.mPOV[id].direction;
     957
    706958    int currentState = povStates_[iJoyStick][id];
    707959    if (currentState & OIS::Pov::North)
     
    719971  /*bool InputManager::vector3Moved(const OIS::JoyStickEvent &arg, int id)
    720972  {
    721     // use the device to identify which one called the method
    722     OIS::JoyStick* joyStick = (OIS::JoyStick*)arg.device;
    723     unsigned int iJoyStick = 0;
    724     while (joySticks_[iJoyStick] != joyStick)
    725       iJoyStick++;
     973    unsigned int iJoyStick = _getJoystick(arg);
    726974
    727975    for (unsigned int iHandler = 0; iHandler < activeJoyStickHandlers_[iJoyStick].size(); iHandler++)
     
    737985  // ################################
    738986
     987  std::string InputManager::bindingCommmandString_s = "";
     988
    739989  bool InputManager::initialise(const size_t windowHnd, int windowWidth, int windowHeight,
    740990    bool createKeyboard, bool createMouse, bool createJoySticks)
     
    7801030  }
    7811031
    782   bool InputManager::isKeyDown(KeyCode::Enum key)
     1032  /*bool InputManager::isKeyDown(KeyCode::Enum key)
    7831033  {
    7841034    if (_getSingleton().keyboard_)
     
    7861036    else
    7871037      return false;
    788   }
    789 
    790   bool InputManager::isModifierDown(KeyboardModifier::Enum modifier)
     1038  }*/
     1039
     1040  /*bool InputManager::isModifierDown(KeyboardModifier::Enum modifier)
    7911041  {
    7921042    if (_getSingleton().keyboard_)
     
    7941044    else
    7951045      return false;
    796   }
     1046  }*/
    7971047
    7981048  /*const MouseState InputManager::getMouseState()
     
    8111061      return JoyStickState();
    8121062  }*/
    813 
    8141063
    8151064  void InputManager::destroy()
     
    8701119  }
    8711120
     1121  void InputManager::storeKeyStroke(const std::string& name)
     1122  {
     1123    setInputState(IS_NODETECT);
     1124    COUT(0) << "Binding string \"" << bindingCommmandString_s << "\" on key '" << name << "'" << std::endl;
     1125    CommandExecutor::execute("config KeyBinder " + name + " " + bindingCommmandString_s, false);
     1126  }
     1127
     1128  void InputManager::keyBind(const std::string& command)
     1129  {
     1130    bindingCommmandString_s = command;
     1131    setInputState(IS_DETECT);
     1132    COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
     1133  }
     1134
     1135  void InputManager::calibrate()
     1136  {
     1137    _getSingleton().setInputState(IS_CALIBRATE);
     1138  }
    8721139
    8731140  // ###### KeyHandler ######
  • code/trunk/src/core/InputManager.h

    r1349 r1502  
    6565  public:
    6666    IntVector2 sliderStates[4];
     67  };
     68
     69  /**
     70  * Struct for storing a custom input state
     71  */
     72  struct StoredState
     73  {
     74    std::vector<KeyHandler*>                    activeKeyHandlers_;
     75    std::vector<MouseHandler*>                  activeMouseHandlers_;
     76    std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_;
     77    std::vector<std::pair<InputTickable*, HandlerState> > activeHandlers_;
     78  };
     79
     80  struct JoyStickCalibration
     81  {
     82    int zeroStates[24];
     83    float positiveCoeff[24];
     84    float negativeCoeff[24];
    6785  };
    6886
     
    8098    enum InputState
    8199    {
    82       IS_UNINIT,  //!< InputManager has not yet been initialised.
    83       IS_NONE,    //!< Input is discarded.
    84       IS_NORMAL,  //!< Normal play state. Key and button bindings are active.
    85       IS_GUI,     //!< All OIS input events are passed to CEGUI.
    86       IS_CONSOLE, //!< Keyboard input is redirected to the InputBuffer.
    87       IS_CUSTOM   //!< Any possible configuration.
     100      IS_UNINIT,    //!< InputManager has not yet been initialised.
     101      IS_NONE,      //!< Input is discarded.
     102      IS_NORMAL,    //!< Normal play state. Key and button bindings are active.
     103      IS_GUI,       //!< All OIS input events are passed to CEGUI.
     104      IS_CONSOLE,   //!< Keyboard input is redirected to the InputBuffer.
     105      IS_DETECT,    //!< All the input additionally goes to the KeyDetector
     106      IS_NODETECT,  //!< remove KeyDetector
     107      IS_NOCALIBRATE,
     108      IS_CALIBRATE,
     109      IS_CUSTOM     //!< Any possible configuration.
    88110    };
     111
     112  public: // member functions
     113    void setConfigValues();
    89114
    90115  public: // static functions
     
    103128    static void destroyJoySticks();
    104129
    105     static bool isModifierDown(KeyboardModifier::Enum modifier);
    106     static bool isKeyDown(KeyCode::Enum key);
     130    //static bool isModifierDown(KeyboardModifier::Enum modifier);
     131    //static bool isKeyDown(KeyCode::Enum key);
    107132    //static const MouseState getMouseState();
    108133    //static const JoyStickState getJoyStickState(unsigned int ID);
     
    112137    static void setInputState(const InputState state);
    113138    static InputState getInputState();
     139
     140    static void storeKeyStroke(const std::string& name);
     141    static void keyBind(const std::string& command);
     142
     143    static void calibrate();
    114144
    115145    static bool addKeyHandler                 (KeyHandler* handler, const std::string& name);
     
    152182
    153183    void _updateTickables();
     184
     185    void _saveState();
     186    void _restoreState();
     187
     188    void _completeCalibration();
     189
     190    void _fireAxis(unsigned int iJoyStick, int axis, int value);
     191    unsigned int _getJoystick(const OIS::JoyStickEvent& arg);
    154192
    155193    void tick(float dt);
     
    172210
    173211  private: // variables
    174     OIS::InputManager*                          inputSystem_; //!< OIS input manager
    175     OIS::Keyboard*                              keyboard_;    //!< OIS mouse
    176     OIS::Mouse*                                 mouse_;       //!< OIS keyboard
    177     std::vector<OIS::JoyStick*>                 joySticks_;   //!< OIS joy sticks
     212    OIS::InputManager*                          inputSystem_;     //!< OIS input manager
     213    OIS::Keyboard*                              keyboard_;        //!< OIS mouse
     214    OIS::Mouse*                                 mouse_;           //!< OIS keyboard
     215    std::vector<OIS::JoyStick*>                 joySticks_;       //!< OIS joy sticks
    178216    unsigned int                                joySticksSize_;
     217
     218    KeyBinder*                                  keyBinder_;       //!< KeyBinder instance
     219    KeyDetector*                                keyDetector_;     //!< KeyDetector instance
     220    InputBuffer*                                buffer_;          //!< InputBuffer instance
     221    CalibratorCallback*                         calibratorCallback_;
    179222
    180223    InputState state_;
    181224    InputState stateRequest_;
     225    InputState savedState_;
    182226    unsigned int keyboardModifiers_;
     227    StoredState savedHandlers_;
     228
     229    // joystick calibration
     230    //std::vector<int> marginalsMaxConfig_;
     231    //std::vector<int> marginalsMinConfig_;
     232    int marginalsMax_[24];
     233    int marginalsMin_[24];
     234    bool bCalibrated_;
    183235
    184236    //! Keeps track of the joy stick POV states
     
    186238    //! Keeps track of the possibly two slider axes
    187239    std::vector<SliderStates>                   sliderStates_;
     240    std::vector<JoyStickCalibration>            joySticksCalibration_;
    188241
    189242    std::map<std::string, KeyHandler*>          keyHandlers_;
     
    194247    std::vector<MouseHandler*>                  activeMouseHandlers_;
    195248    std::vector<std::vector<JoyStickHandler*> > activeJoyStickHandlers_;
    196     std::vector<InputTickable*>                activeHandlers_;
     249    std::vector<std::pair<InputTickable*, HandlerState> > activeHandlers_;
    197250
    198251    std::vector<Key>                            keysDown_;
     
    200253    std::vector<std::vector<int> >              joyStickButtonsDown_;
    201254
     255    static std::string                          bindingCommmandString_s;
    202256  };
    203257
  • code/trunk/src/core/Iterator.h

    r1063 r1502  
    5050
    5151#include "ObjectList.h"
    52 #include "Debug.h"
    5352
    5453namespace orxonox
  • code/trunk/src/core/Language.cc

    r1062 r1502  
    3737
    3838#include "CoreSettings.h"
     39
     40#include "Debug.h"
    3941
    4042namespace orxonox
  • code/trunk/src/core/Language.h

    r1064 r1502  
    5050#include <map>
    5151#include <string>
    52 
    5352
    5453#define AddLanguageEntry(label, fallbackstring) \
  • code/trunk/src/core/OrxonoxClass.cc

    r1293 r1502  
    3333
    3434#include "OrxonoxClass.h"
     35#include "MetaObjectList.h"
     36#include "Identifier.h"
    3537
    3638namespace orxonox
     
    4143      parents_(0)
    4244    {
     45        this->metaList_ = new MetaObjectList();
     46
    4347        this->setConfigValues();
    4448    }
     
    4751    OrxonoxClass::~OrxonoxClass()
    4852    {
     53        delete this->metaList_;
     54
    4955        // parents_ exists only if isCreatingHierarchy() of the associated Identifier returned true while creating the class
    5056        if (this->parents_)
    5157            delete this->parents_;
    5258    }
     59
     60    /** @brief Returns true if the objects class is of the given type or a derivative. */
     61    bool OrxonoxClass::isA(const Identifier* identifier)
     62        { return this->getIdentifier()->isA(identifier); }
     63    /** @brief Returns true if the objects class is exactly of the given type. */
     64    bool OrxonoxClass::isExactlyA(const Identifier* identifier)
     65        { return this->getIdentifier()->isExactlyA(identifier); }
     66    /** @brief Returns true if the objects class is a child of the given type. */
     67    bool OrxonoxClass::isChildOf(const Identifier* identifier)
     68        { return this->getIdentifier()->isChildOf(identifier); }
     69    /** @brief Returns true if the objects class is a direct child of the given type. */
     70    bool OrxonoxClass::isDirectChildOf(const Identifier* identifier)
     71        { return this->getIdentifier()->isDirectChildOf(identifier); }
     72    /** @brief Returns true if the objects class is a parent of the given type. */
     73    bool OrxonoxClass::isParentOf(const Identifier* identifier)
     74        { return this->getIdentifier()->isParentOf(identifier); }
     75    /** @brief Returns true if the objects class is a direct parent of the given type. */
     76    bool OrxonoxClass::isDirectParentOf(const Identifier* identifier)
     77        { return this->getIdentifier()->isDirectParentOf(identifier); }
     78
     79
     80    /** @brief Returns true if the objects class is of the given type or a derivative. */
     81    bool OrxonoxClass::isA(const SubclassIdentifier<class B>* identifier)
     82        { return this->getIdentifier()->isA(identifier->getIdentifier()); }
     83    /** @brief Returns true if the objects class is exactly of the given type. */
     84    bool OrxonoxClass::isExactlyA(const SubclassIdentifier<class B>* identifier)
     85        { return this->getIdentifier()->isExactlyA(identifier->getIdentifier()); }
     86    /** @brief Returns true if the objects class is a child of the given type. */
     87    bool OrxonoxClass::isChildOf(const SubclassIdentifier<class B>* identifier)
     88        { return this->getIdentifier()->isChildOf(identifier->getIdentifier()); }
     89    /** @brief Returns true if the objects class is a direct child of the given type. */
     90    bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<class B>* identifier)
     91        { return this->getIdentifier()->isDirectChildOf(identifier->getIdentifier()); }
     92    /** @brief Returns true if the objects class is a parent of the given type. */
     93    bool OrxonoxClass::isParentOf(const SubclassIdentifier<class B>* identifier)
     94        { return this->getIdentifier()->isParentOf(identifier->getIdentifier()); }
     95    /** @brief Returns true if the objects class is a direct parent of the given type. */
     96    bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<class B>* identifier)
     97        { return this->getIdentifier()->isDirectParentOf(identifier->getIdentifier()); }
     98
     99
     100    /** @brief Returns true if the objects class is of the given type or a derivative. */
     101    bool OrxonoxClass::isA(const SubclassIdentifier<class B> identifier)
     102        { return this->getIdentifier()->isA(identifier.getIdentifier()); }
     103    /** @brief Returns true if the objects class is exactly of the given type. */
     104    bool OrxonoxClass::isExactlyA(const SubclassIdentifier<class B> identifier)
     105        { return this->getIdentifier()->isExactlyA(identifier.getIdentifier()); }
     106    /** @brief Returns true if the objects class is a child of the given type. */
     107    bool OrxonoxClass::isChildOf(const SubclassIdentifier<class B> identifier)
     108        { return this->getIdentifier()->isChildOf(identifier.getIdentifier()); }
     109    /** @brief Returns true if the objects class is a direct child of the given type. */
     110    bool OrxonoxClass::isDirectChildOf(const SubclassIdentifier<class B> identifier)
     111        { return this->getIdentifier()->isDirectChildOf(identifier.getIdentifier()); }
     112    /** @brief Returns true if the objects class is a parent of the given type. */
     113    bool OrxonoxClass::isParentOf(const SubclassIdentifier<class B> identifier)
     114        { return this->getIdentifier()->isParentOf(identifier.getIdentifier()); }
     115    /** @brief Returns true if the objects class is a direct parent of the given type. */
     116    bool OrxonoxClass::isDirectParentOf(const SubclassIdentifier<class B> identifier)
     117        { return this->getIdentifier()->isDirectParentOf(identifier.getIdentifier()); }
     118
     119
     120    /** @brief Returns true if the objects class is of the given type or a derivative. */
     121    bool OrxonoxClass::isA(const OrxonoxClass* object)
     122        { return this->getIdentifier()->isA(object->getIdentifier()); }
     123    /** @brief Returns true if the objects class is exactly of the given type. */
     124    bool OrxonoxClass::isExactlyA(const OrxonoxClass* object)
     125        { return this->getIdentifier()->isExactlyA(object->getIdentifier()); }
     126    /** @brief Returns true if the objects class is a child of the given type. */
     127    bool OrxonoxClass::isChildOf(const OrxonoxClass* object)
     128        { return this->getIdentifier()->isChildOf(object->getIdentifier()); }
     129    /** @brief Returns true if the objects class is a direct child of the given type. */
     130    bool OrxonoxClass::isDirectChildOf(const OrxonoxClass* object)
     131        { return this->getIdentifier()->isDirectChildOf(object->getIdentifier()); }
     132    /** @brief Returns true if the objects class is a parent of the given type. */
     133    bool OrxonoxClass::isParentOf(const OrxonoxClass* object)
     134        { return this->getIdentifier()->isParentOf(object->getIdentifier()); }
     135    /** @brief Returns true if the objects class is a direct child of the given type. */
     136    bool OrxonoxClass::isDirectParentOf(const OrxonoxClass* object)
     137        { return this->getIdentifier()->isDirectParentOf(object->getIdentifier()); }
    53138}
  • code/trunk/src/core/OrxonoxClass.h

    r1062 r1502  
    4343#include <string>
    4444
    45 #include "MetaObjectList.h"
    46 #include "Iterator.h"
    47 
    4845namespace orxonox
    4946{
     
    7572
    7673            /** @brief Returns the MetaObjectList of the object, containing a link to all ObjectLists and ObjectListElements the object is registered in. @return The list */
    77             inline MetaObjectList& getMetaList() { return this->metaList_; }
     74            inline MetaObjectList& getMetaList() { return (*this->metaList_); }
    7875
    7976
    80             /** @brief Returns true if the objects class is of the given type or a derivative. */
    81             inline bool isA(const Identifier* identifier)
    82                 { return this->getIdentifier()->isA(identifier); }
    83             /** @brief Returns true if the objects class is exactly of the given type. */
    84             inline bool isExactlyA(const Identifier* identifier)
    85                 { return this->getIdentifier()->isExactlyA(identifier); }
    86             /** @brief Returns true if the objects class is a child of the given type. */
    87             inline bool isChildOf(const Identifier* identifier)
    88                 { return this->getIdentifier()->isChildOf(identifier); }
    89             /** @brief Returns true if the objects class is a direct child of the given type. */
    90             inline bool isDirectChildOf(const Identifier* identifier)
    91                 { return this->getIdentifier()->isDirectChildOf(identifier); }
    92             /** @brief Returns true if the objects class is a parent of the given type. */
    93             inline bool isParentOf(const Identifier* identifier)
    94                 { return this->getIdentifier()->isParentOf(identifier); }
    95             /** @brief Returns true if the objects class is a direct parent of the given type. */
    96             inline bool isDirectParentOf(const Identifier* identifier)
    97                 { return this->getIdentifier()->isDirectParentOf(identifier); }
     77            bool isA(const Identifier* identifier);
     78            bool isExactlyA(const Identifier* identifier);
     79            bool isChildOf(const Identifier* identifier);
     80            bool isDirectChildOf(const Identifier* identifier);
     81            bool isParentOf(const Identifier* identifier);
     82            bool isDirectParentOf(const Identifier* identifier);
    9883
     84            bool isA(const SubclassIdentifier<class B>* identifier);
     85            bool isExactlyA(const SubclassIdentifier<class B>* identifier);
     86            bool isChildOf(const SubclassIdentifier<class B>* identifier);
     87            bool isDirectChildOf(const SubclassIdentifier<class B>* identifier);
     88            bool isParentOf(const SubclassIdentifier<class B>* identifier);
     89            bool isDirectParentOf(const SubclassIdentifier<class B>* identifier);
    9990
    100             /** @brief Returns true if the objects class is of the given type or a derivative. */
    101             inline bool isA(const SubclassIdentifier<class B>* identifier)
    102                 { return this->getIdentifier()->isA(identifier->getIdentifier()); }
    103             /** @brief Returns true if the objects class is exactly of the given type. */
    104             inline bool isExactlyA(const SubclassIdentifier<class B>* identifier)
    105                 { return this->getIdentifier()->isExactlyA(identifier->getIdentifier()); }
    106             /** @brief Returns true if the objects class is a child of the given type. */
    107             inline bool isChildOf(const SubclassIdentifier<class B>* identifier)
    108                 { return this->getIdentifier()->isChildOf(identifier->getIdentifier()); }
    109             /** @brief Returns true if the objects class is a direct child of the given type. */
    110             inline bool isDirectChildOf(const SubclassIdentifier<class B>* identifier)
    111                 { return this->getIdentifier()->isDirectChildOf(identifier->getIdentifier()); }
    112             /** @brief Returns true if the objects class is a parent of the given type. */
    113             inline bool isParentOf(const SubclassIdentifier<class B>* identifier)
    114                 { return this->getIdentifier()->isParentOf(identifier->getIdentifier()); }
    115             /** @brief Returns true if the objects class is a direct parent of the given type. */
    116             inline bool isDirectParentOf(const SubclassIdentifier<class B>* identifier)
    117                 { return this->getIdentifier()->isDirectParentOf(identifier->getIdentifier()); }
     91            bool isA(const SubclassIdentifier<class B> identifier);
     92            bool isExactlyA(const SubclassIdentifier<class B> identifier);
     93            bool isChildOf(const SubclassIdentifier<class B> identifier);
     94            bool isDirectChildOf(const SubclassIdentifier<class B> identifier);
     95            bool isParentOf(const SubclassIdentifier<class B> identifier);
     96            bool isDirectParentOf(const SubclassIdentifier<class B> identifier);
    11897
    119 
    120             /** @brief Returns true if the objects class is of the given type or a derivative. */
    121             inline bool isA(const SubclassIdentifier<class B> identifier)
    122                 { return this->getIdentifier()->isA(identifier.getIdentifier()); }
    123             /** @brief Returns true if the objects class is exactly of the given type. */
    124             inline bool isExactlyA(const SubclassIdentifier<class B> identifier)
    125                 { return this->getIdentifier()->isExactlyA(identifier.getIdentifier()); }
    126             /** @brief Returns true if the objects class is a child of the given type. */
    127             inline bool isChildOf(const SubclassIdentifier<class B> identifier)
    128                 { return this->getIdentifier()->isChildOf(identifier.getIdentifier()); }
    129             /** @brief Returns true if the objects class is a direct child of the given type. */
    130             inline bool isDirectChildOf(const SubclassIdentifier<class B> identifier)
    131                 { return this->getIdentifier()->isDirectChildOf(identifier.getIdentifier()); }
    132             /** @brief Returns true if the objects class is a parent of the given type. */
    133             inline bool isParentOf(const SubclassIdentifier<class B> identifier)
    134                 { return this->getIdentifier()->isParentOf(identifier.getIdentifier()); }
    135             /** @brief Returns true if the objects class is a direct parent of the given type. */
    136             inline bool isDirectParentOf(const SubclassIdentifier<class B> identifier)
    137                 { return this->getIdentifier()->isDirectParentOf(identifier.getIdentifier()); }
    138 
    139 
    140             /** @brief Returns true if the objects class is of the given type or a derivative. */
    141             inline bool isA(const OrxonoxClass* object)
    142                 { return this->getIdentifier()->isA(object->getIdentifier()); }
    143             /** @brief Returns true if the objects class is exactly of the given type. */
    144             inline bool isExactlyA(const OrxonoxClass* object)
    145                 { return this->getIdentifier()->isExactlyA(object->getIdentifier()); }
    146             /** @brief Returns true if the objects class is a child of the given type. */
    147             inline bool isChildOf(const OrxonoxClass* object)
    148                 { return this->getIdentifier()->isChildOf(object->getIdentifier()); }
    149             /** @brief Returns true if the objects class is a direct child of the given type. */
    150             inline bool isDirectChildOf(const OrxonoxClass* object)
    151                 { return this->getIdentifier()->isDirectChildOf(object->getIdentifier()); }
    152             /** @brief Returns true if the objects class is a parent of the given type. */
    153             inline bool isParentOf(const OrxonoxClass* object)
    154                 { return this->getIdentifier()->isParentOf(object->getIdentifier()); }
    155             /** @brief Returns true if the objects class is a direct child of the given type. */
    156             inline bool isDirectParentOf(const OrxonoxClass* object)
    157                 { return this->getIdentifier()->isDirectParentOf(object->getIdentifier()); }
     98            bool isA(const OrxonoxClass* object);
     99            bool isExactlyA(const OrxonoxClass* object);
     100            bool isChildOf(const OrxonoxClass* object);
     101            bool isDirectChildOf(const OrxonoxClass* object);
     102            bool isParentOf(const OrxonoxClass* object);
     103            bool isDirectParentOf(const OrxonoxClass* object);
    158104
    159105        private:
    160             Identifier* identifier_;                    //!< The Identifier of the object
     106            Identifier* identifier_;                   //!< The Identifier of the object
    161107            std::set<const Identifier*>* parents_;     //!< List of all parents of the object
    162             MetaObjectList metaList_;                   //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
     108            MetaObjectList* metaList_;                 //!< MetaObjectList, containing all ObjectLists and ObjectListElements the object is registered in
    163109    };
    164110}
  • code/trunk/src/core/OutputHandler.cc

    r1062 r1502  
    3535#include "CoreSettings.h"
    3636#include "ConsoleCommand.h"
     37#include "Shell.h"
    3738
    3839namespace orxonox
    3940{
    40     ConsoleCommandShortcutGeneric(log, createExecutor(createFunctor(&OutputHandler::log), "log", AccessLevel::None));
     41    SetConsoleCommandShortcutGeneric(log,     createConsoleCommand(createFunctor(&OutputHandler::log),     "log"    ));
     42    SetConsoleCommandShortcutGeneric(error,   createConsoleCommand(createFunctor(&OutputHandler::error),   "error"  ));
     43    SetConsoleCommandShortcutGeneric(warning, createConsoleCommand(createFunctor(&OutputHandler::warning), "warning"));
     44    SetConsoleCommandShortcutGeneric(info,    createConsoleCommand(createFunctor(&OutputHandler::info),    "info"   ));
     45    SetConsoleCommandShortcutGeneric(debug,   createConsoleCommand(createFunctor(&OutputHandler::debug),   "debug"  ));
    4146
    4247    /**
     
    8287
    8388    /**
     89        @brief Returns the Shell's OutputBuffer. This is mere placed here to avoid
     90               recompiling the entire project when Shell.h changes.
     91        @return The OutputBuffer of the Shell
     92    */
     93    OutputBuffer& OutputHandler::getShellOutputBuffer()
     94    {
     95        return Shell::getInstance().getOutputBuffer();
     96    }
     97
     98    /**
    8499        @brief Overloaded << operator, redirects the output to the console and the logfile.
    85100        @param sb The streambuffer that should be shown in the console
     
    96111            this->logfile_.flush();
    97112        }
     113
     114        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
     115            Shell::getInstance().getOutputBuffer() << sb;
    98116
    99117        return *this;
     
    116134        }
    117135
     136        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
     137            Shell::getInstance().getOutputBuffer() << manipulator;
     138
    118139        return *this;
    119140    }
     
    134155            this->logfile_.flush();
    135156        }
     157
     158        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
     159            Shell::getInstance().getOutputBuffer() << manipulator;
    136160
    137161        return *this;
     
    154178        }
    155179
     180        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
     181            Shell::getInstance().getOutputBuffer() << manipulator;
     182
    156183        return *this;
    157184    }
  • code/trunk/src/core/OutputHandler.h

    r1064 r1502  
    4444#include <string>
    4545
     46#include "OutputBuffer.h"
     47
    4648namespace orxonox
    4749{
     
    6466                { OutputHandler::getOutStream().setOutputLevel(0); OutputHandler::getOutStream().output(text + "\n"); return text; }
    6567
     68            /** @brief Puts an error on the outstream. @param text The text */
     69            static inline std::string error(const std::string& text)
     70                { OutputHandler::getOutStream().setOutputLevel(1); OutputHandler::getOutStream().output(text + "\n"); return text; }
     71
     72            /** @brief Puts a warning on the outstream. @param text The text */
     73            static inline std::string warning(const std::string& text)
     74                { OutputHandler::getOutStream().setOutputLevel(2); OutputHandler::getOutStream().output(text + "\n"); return text; }
     75
     76            /** @brief Puts an info on the outstream. @param text The text */
     77            static inline std::string info(const std::string& text)
     78                { OutputHandler::getOutStream().setOutputLevel(3); OutputHandler::getOutStream().output(text + "\n"); return text; }
     79
     80            /** @brief Puts some debug output on the outstream. @param text The text */
     81            static inline std::string debug(const std::string& text)
     82                { OutputHandler::getOutStream().setOutputLevel(4); OutputHandler::getOutStream().output(text + "\n"); return text; }
     83
    6684            /** @brief Returns a reference to the logfile. @return The logfile */
    6785            inline std::ofstream& getLogfile()
     
    7795
    7896            static int getSoftDebugLevel(OutputHandler::OutputDevice device);
     97
     98            OutputBuffer& getShellOutputBuffer();
    7999
    80100            template <class T>
     
    138158        }
    139159
     160        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= this->outputLevel_)
     161            OutputHandler::getOutStream().getShellOutputBuffer() << output;
     162
    140163        return *this;
    141164    }
     
    159182        }
    160183
     184        if (OutputHandler::getSoftDebugLevel(OutputHandler::LD_Shell) >= out.getOutputLevel())
     185            OutputHandler::getOutStream().getShellOutputBuffer() << output;
     186
    161187        return out;
    162188    }
  • code/trunk/src/core/Script.cc

    r1153 r1502  
    6767  {
    6868    output_ += str;
    69     COUT(4) << "Lua_output!:" << std::endl << str << std::endl << "***" << std::endl;
     69//    COUT(4) << "Lua_output!:" << std::endl << str << std::endl << "***" << std::endl;
     70    COUT(5) << str;
    7071  }
    7172
     
    99100
    100101    if (luaTags) luaSource_ = replaceLuaTags(levelString);
    101     COUT(4) << "ParsedSourceCode: " << luaSource_ << std::endl;
     102    COUT(5) << "ParsedSourceCode: " << luaSource_ << std::endl;
    102103  }
    103104
     
    127128    if (error == 0)
    128129      error = lua_pcall(luaState_, 0, 0, 0);
    129     if (error != 0) COUT(2) << "Error in Lua-script: " << lua_tostring(luaState_, -1) << std::endl;
     130    if (error != 0)
     131    {
     132      COUT(2) << "Error in Lua-script: " << lua_tostring(luaState_, -1) << std::endl;
     133    }
    130134  }
    131135
  • code/trunk/src/core/TclBind.cc

    r1214 r1502  
    3333#include "CommandExecutor.h"
    3434#include "Debug.h"
     35#include "TclThreadManager.h"
    3536#include "TclBind.h"
     37#include "util/String.h"
    3638
    3739namespace orxonox
    3840{
    39     ConsoleCommandShortcutGeneric(tcl, createExecutor(createFunctor(&TclBind::tcl), "tcl", AccessLevel::None));
     41    SetConsoleCommandShortcutGeneric(tcl, createConsoleCommand(createFunctor(&TclBind::tcl), "tcl"));
     42    SetConsoleCommandShortcutGeneric(bgerror, createConsoleCommand(createFunctor(&TclBind::bgerror), "bgerror"));
    4043
    4144    TclBind::TclBind()
     
    5962    void TclBind::setDataPath(const std::string& datapath)
    6063    {
    61         this->tclLibPath_ = datapath + "/tcl";
     64        this->tclLibPath_ = datapath + "/tcl" + TCL_VERSION + "/";
    6265        this->bSetTclLibPath_ = true;
    6366
     
    7073        {
    7174            this->interpreter_ = new Tcl::interpreter(this->tclLibPath_);
    72             this->interpreter_->def("puts", TclBind::puts, Tcl::variadic());
    73             this->interpreter_->def("orxonox", TclBind::orxonox, Tcl::variadic());
    74             this->interpreter_->def("execute", TclBind::execute, Tcl::variadic());
    75             this->interpreter_->eval("proc unknown {args} { return [orxonox $args] }");
    76             this->interpreter_->eval("rename exit tclexit; proc exit {} { orxonox exit }");
     75            this->interpreter_->def("orxonox::query", TclBind::tcl_query, Tcl::variadic());
     76            this->interpreter_->def("orxonox::crossquery", TclThreadManager::tcl_crossquery, Tcl::variadic());
     77            this->interpreter_->def("execute", TclBind::tcl_execute, Tcl::variadic());
     78
     79            try
     80            {
     81                this->interpreter_->eval("proc query args { orxonox::query $args }");
     82                this->interpreter_->eval("proc crossquery {id args} { orxonox::crossquery 0 $id $args }");
     83                this->interpreter_->eval("set id 0");
     84                this->interpreter_->eval("rename exit tcl::exit; proc exit {} { execute exit }");
     85                this->interpreter_->eval("redef_puts");
     86            }
     87            catch (Tcl::tcl_error const &e)
     88            {   COUT(1) << "Tcl error while creating Tcl-interpreter: " << e.what() << std::endl;   }
     89            catch (std::exception const &e)
     90            {   COUT(1) << "Error while creating Tcl-interpreter: " << e.what() << std::endl;   }
    7791        }
    7892    }
     
    89103    }
    90104
    91     void TclBind::puts(Tcl::object const &args)
     105    std::string TclBind::tcl_query(Tcl::object const &args)
    92106    {
    93         COUT(0) << args.get() << std::endl;
    94     }
     107        COUT(4) << "Tcl_query: " << args.get() << std::endl;
    95108
    96     std::string TclBind::orxonox(Tcl::object const &args)
    97     {
    98 std::cout << "Tcl_execute: args: " << args.get() << std::endl;
    99         std::string command = args.get();
    100 
    101         if (command.size() >= 2 && command[0] == '{' && command[command.size() - 1] == '}')
    102             command = command.substr(1, command.size() - 2);
     109        std::string command = stripEnclosingBraces(args.get());
    103110
    104111        if (!CommandExecutor::execute(command, false))
     112        {
    105113            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
     114        }
    106115
    107116        if (CommandExecutor::getLastEvaluation().hasReturnvalue())
     
    111120    }
    112121
    113     void TclBind::execute(Tcl::object const &args)
     122    void TclBind::tcl_execute(Tcl::object const &args)
    114123    {
     124        COUT(4) << "Tcl_execute: " << args.get() << std::endl;
     125        std::string command = stripEnclosingBraces(args.get());
     126
     127        if (!CommandExecutor::execute(command, false))
     128        {
     129            COUT(1) << "Error: Can't execute command \"" << command << "\"!" << std::endl;
     130        }
    115131    }
    116132
    117133    std::string TclBind::tcl(const std::string& tclcode)
    118134    {
    119         try
     135        if (TclBind::getInstance().interpreter_)
    120136        {
    121             std::string output = TclBind::getInstance().interpreter_->eval(tclcode);
    122             if (output != "")
    123                 COUT(0) << "tcl> " << output << std::endl;
    124             return output;
    125         }
    126         catch (Tcl::tcl_error const &e)
    127         {
    128             COUT(1) << "tcl> Error: " << e.what() << std::endl;
    129         }
    130         catch (std::exception const &e)
    131         {
    132             COUT(1) << "Error while executing tcl: " << e.what() << std::endl;
     137            try
     138            {
     139                std::string output = TclBind::getInstance().interpreter_->eval(tclcode);
     140                if (output != "")
     141                {
     142                    COUT(0) << "tcl> " << output << std::endl;
     143                }
     144                return output;
     145            }
     146            catch (Tcl::tcl_error const &e)
     147            {   COUT(1) << "tcl> Error: " << e.what() << std::endl;   }
     148            catch (std::exception const &e)
     149            {   COUT(1) << "Error while executing Tcl: " << e.what() << std::endl;   }
    133150        }
    134151
    135152        return "";
     153    }
     154
     155    void TclBind::bgerror(std::string error)
     156    {
     157        COUT(1) << "Tcl background error: " << stripEnclosingBraces(error) << std::endl;
    136158    }
    137159
     
    144166        }
    145167        catch (Tcl::tcl_error const &e)
    146         {
    147             COUT(1) << "Error: " << e.what() << std::endl;
    148         }
     168        {   COUT(1) << "Tcl error: " << e.what() << std::endl;   }
    149169        catch (std::exception const &e)
    150         {
    151             COUT(1) << "Error while executing tcl: " << e.what() << std::endl;
    152         }
     170        {   COUT(1) << "Error while executing Tcl: " << e.what() << std::endl;   }
    153171
    154172        return false;
  • code/trunk/src/core/TclBind.h

    r1223 r1502  
    4141            static TclBind& getInstance();
    4242
     43            static std::string tcl(const std::string& tclcode);
     44            static void bgerror(std::string error);
     45
    4346            void setDataPath(const std::string& datapath);
     47            std::string getTclLibPath() const { return this->tclLibPath_; }
    4448            void createTclInterpreter();
    4549            void createNewTclInterpreter();
     50            Tcl::interpreter* getTclInterpreter() const { return this->interpreter_; }
    4651
    47             static void puts(Tcl::object const &args);
    48             static void execute(Tcl::object const &args);
    49             static std::string orxonox(Tcl::object const &args);
    50             static std::string tcl(const std::string& tclcode);
     52            static std::string tcl_query(Tcl::object const &args);
     53            static void tcl_execute(Tcl::object const &args);
     54
    5155            static bool eval(const std::string& tclcode);
    5256
  • code/trunk/src/core/XMLPort.h

    r1209 r1502  
    7878namespace orxonox
    7979{
    80 
    81 #ifndef _XMLPort_Mode__
    82 #define _XMLPort_Mode__
    83     namespace XMLPort
    84     {
    85         enum Mode
    86         {
    87             LoadObject,
    88             SaveObject
    89         };
    90     }
    91 #endif
    92 
    9380    // ###############################
    9481    // ###  XMLPortParamContainer  ###
     
    166153                        }
    167154                    }
    168                     catch(ticpp::Exception& ex)
     155                    catch (ticpp::Exception& ex)
    169156                    {
    170157                        COUT(1) << std::endl;
     
    344331                        }
    345332                    }
    346                     catch(ticpp::Exception& ex)
     333                    catch (ticpp::Exception& ex)
    347334                    {
    348335                        COUT(1) << std::endl;
Note: See TracChangeset for help on using the changeset viewer.