Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Dec 25, 2009, 1:18:03 PM (15 years ago)
Author:
dafrick
Message:

Merged presentation2 branch into pickup2 branch.

Location:
code/branches/pickup2
Files:
2 deleted
92 edited
4 copied

Legend:

Unmodified
Added
Removed
  • code/branches/pickup2

  • code/branches/pickup2/src/libraries/core/ArgumentCompletionFunctions.cc

    r5929 r6412  
    7272                else
    7373                {
    74                     std::string dir = startdirectory.string();
     74                    const std::string& dir = startdirectory.string();
    7575                    if (dir.size() > 0 && dir[dir.size() - 1] == ':')
    7676                        startdirectory = dir + '/';
     
    8484                {
    8585                    if (boost::filesystem::is_directory(*file))
    86                         dirlist.push_back(ArgumentCompletionListElement((*file).string() + '/', getLowercase((*file).string()) + '/', (*file).BOOST_LEAF_FUNCTION() + '/'));
     86                        dirlist.push_back(ArgumentCompletionListElement(file->string() + '/', getLowercase(file->string()) + '/', file->BOOST_LEAF_FUNCTION() + '/'));
    8787                    else
    88                         filelist.push_back(ArgumentCompletionListElement((*file).string(), getLowercase((*file).string()), (*file).BOOST_LEAF_FUNCTION()));
     88                        filelist.push_back(ArgumentCompletionListElement(file->string(), getLowercase(file->string()), file->BOOST_LEAF_FUNCTION()));
    8989                    ++file;
    9090                }
     
    101101
    102102            for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getStringIdentifierMapBegin(); it != Identifier::getStringIdentifierMapEnd(); ++it)
    103                 if ((*it).second->hasConfigValues())
    104                     classlist.push_back(ArgumentCompletionListElement((*it).second->getName(), getLowercase((*it).first)));
     103                if (it->second->hasConfigValues())
     104                    classlist.push_back(ArgumentCompletionListElement(it->first, getLowercase(it->first)));
    105105
    106106            return classlist;
     
    110110        {
    111111            ArgumentCompletionList configvalues;
    112             std::map<std::string, Identifier*>::const_iterator identifier = Identifier::getStringIdentifierMap().find(classname);
     112            std::map<std::string, Identifier*>::const_iterator identifier = Identifier::getLowercaseStringIdentifierMap().find(getLowercase(classname));
    113113
    114             if (identifier != Identifier::getStringIdentifierMapEnd() && (*identifier).second->hasConfigValues())
     114            if (identifier != Identifier::getLowercaseStringIdentifierMapEnd() && identifier->second->hasConfigValues())
    115115            {
    116                 for (std::map<std::string, ConfigValueContainer*>::const_iterator it = (*identifier).second->getConfigValueMapBegin(); it != (*identifier).second->getConfigValueMapEnd(); ++it)
    117                     configvalues.push_back(ArgumentCompletionListElement((*it).second->getName(), getLowercase((*it).first)));
     116                for (std::map<std::string, ConfigValueContainer*>::const_iterator it = identifier->second->getConfigValueMapBegin(); it != identifier->second->getConfigValueMapEnd(); ++it)
     117                    configvalues.push_back(ArgumentCompletionListElement(it->first, getLowercase(it->first)));
    118118            }
    119119
     
    127127            if (identifier != Identifier::getLowercaseStringIdentifierMapEnd())
    128128            {
    129                 std::map<std::string, ConfigValueContainer*>::const_iterator variable = (*identifier).second->getLowercaseConfigValueMap().find(getLowercase(varname));
    130                 if (variable != (*identifier).second->getLowercaseConfigValueMapEnd())
     129                std::map<std::string, ConfigValueContainer*>::const_iterator variable = identifier->second->getLowercaseConfigValueMap().find(getLowercase(varname));
     130                if (variable != identifier->second->getLowercaseConfigValueMapEnd())
    131131                {
    132                     std::string valuestring = (*variable).second->toString();
     132                    const std::string& valuestring = variable->second->toString();
    133133                    oldvalue.push_back(ArgumentCompletionListElement(valuestring, getLowercase(valuestring), "Old value: " + valuestring));
    134134                }
  • code/branches/pickup2/src/libraries/core/BaseObject.cc

    r5929 r6412  
    3636#include <tinyxml/tinyxml.h>
    3737
    38 #include "util/StringUtils.h"
    3938#include "CoreIncludes.h"
    4039#include "Event.h"
     
    119118        XMLPortObjectTemplate(BaseObject, Template, "templates", addTemplate, getTemplate, xmlelement, mode, Template*);
    120119        XMLPortObject(BaseObject, BaseObject, "eventlisteners", addEventListener, getEventListener, xmlelement, mode);
    121        
     120
    122121        Element* events = 0;
    123122        if (mode == XMLPort::LoadObject || mode == XMLPort::ExpandObject)
     
    139138        XMLPortEventState(BaseObject, BaseObject, "visibility", setVisible, xmlelement, mode);
    140139        XMLPortEventState(BaseObject, BaseObject, "mainstate", setMainState, xmlelement, mode);
    141        
     140
    142141        this->bRegisteredEventStates_ = true;
    143142    }
     
    236235            if (it->second != state)
    237236                continue;
    238            
     237
    239238            if (i == index)
    240239                return it->first;
     
    252251        listener->addEventSource(this, "mainstate");
    253252    }
    254    
     253
    255254    /**
    256255        @brief Returns an event listener with a given index.
     
    278277        if (it != this->eventStates_.end())
    279278        {
    280             COUT(2) << "Warning: Overwriting EventState in class " << this->getIdentifier()->getName() << "." << std::endl;
     279            COUT(2) << "Warning: Overwriting EventState in class " << this->getIdentifier()->getName() << '.' << std::endl;
    281280            delete (it->second);
    282281        }
     
    292291        std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(name);
    293292        if (it != this->eventStates_.end())
    294             return ((*it).second);
     293            return (it->second);
    295294        else
    296295            return 0;
     
    344343    {
    345344        this->registerEventStates();
    346        
     345
    347346        std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(event.statename_);
    348347        if (it != this->eventStates_.end())
    349348            it->second->process(event, this);
    350         else if (event.statename_ != "")
     349        else if (!event.statename_.empty())
    351350            COUT(2) << "Warning: \"" << event.statename_ << "\" is not a valid state in object \"" << this->getName() << "\" of class " << this->getIdentifier()->getName() << "." << std::endl;
    352351        else
     
    356355    /**
    357356        @brief Sets the main state of the object to a given boolean value.
    358        
     357
    359358        Note: The main state of an object can be set with the @ref setMainStateName function.
    360359        It's part of the eventsystem and used for event forwarding (when the target object can't specify a specific state,
     
    386385        this->mainStateFunctor_ = 0;
    387386
    388         if (this->mainStateName_ != "")
     387        if (!this->mainStateName_.empty())
    389388        {
    390389            this->registerEventStates();
    391            
     390
    392391            std::map<std::string, EventState*>::const_iterator it = this->eventStates_.find(this->mainStateName_);
    393392            if (it != this->eventStates_.end() && it->second->getFunctor())
     
    402401        }
    403402    }
    404    
     403
    405404    /**
    406405        @brief Calls XMLEventPort with an empty XML-element to register the event states if necessary.
     
    414413        }
    415414    }
    416    
     415
    417416    /**
    418417        @brief Manually loads all event states, even if the class doesn't officially support them. This is needed by some classes like @ref EventDispatcher or @ref EventTarget.
     
    437436            for (std::list<std::string>::iterator it = eventnames.begin(); it != eventnames.end(); ++it)
    438437            {
    439                 std::string statename = (*it);
     438                const std::string& statename = (*it);
    440439
    441440                // if the event state is already known, continue with the next state
     
    447446                if (!container)
    448447                {
    449                     ExecutorMember<BaseObject>* setfunctor = createExecutor(createFunctor(&BaseObject::addEventSource), std::string( "BaseObject" ) + "::" + "addEventSource" + "(" + statename + ")");
    450                     ExecutorMember<BaseObject>* getfunctor = createExecutor(createFunctor(&BaseObject::getEventSource), std::string( "BaseObject" ) + "::" + "getEventSource" + "(" + statename + ")");
     448                    ExecutorMember<BaseObject>* setfunctor = createExecutor(createFunctor(&BaseObject::addEventSource), std::string( "BaseObject" ) + "::" + "addEventSource" + '(' + statename + ')');
     449                    ExecutorMember<BaseObject>* getfunctor = createExecutor(createFunctor(&BaseObject::getEventSource), std::string( "BaseObject" ) + "::" + "getEventSource" + '(' + statename + ')');
    451450                    setfunctor->setDefaultValue(1, statename);
    452451                    getfunctor->setDefaultValue(1, statename);
  • code/branches/pickup2/src/libraries/core/BaseObject.h

    r5929 r6412  
    157157            void removeEventSource(BaseObject* source);
    158158            BaseObject* getEventSource(unsigned int index, const std::string& state) const;
    159            
     159
    160160            void addEventListener(BaseObject* listener);
    161161            BaseObject* getEventListener(unsigned int index) const;
     
    172172            /** @brief Returns the indentation of the debug output in the Loader. @return The indentation */
    173173            inline const std::string& getLoaderIndentation() const { return this->loaderIndentation_; }
    174            
     174
    175175            static void loadAllEventStates(Element& xmlelement, XMLPort::Mode mode, BaseObject* object, Identifier* identifier);
    176176
     
    210210            Gametype*              oldGametype_;
    211211            std::set<Template*>    templates_;
    212            
     212
    213213            std::map<BaseObject*, std::string>  eventSources_;           //!< List of objects which send events to this object, mapped to the state which they affect
    214214            std::set<BaseObject*>               eventListeners_;         //!< List of objects which listen to the events of this object
  • code/branches/pickup2/src/libraries/core/CMakeLists.txt

    r5929 r6412  
    2929  GraphicsManager.cc
    3030  GUIManager.cc
     31  IOConsole.cc
    3132  Language.cc
    3233  LuaState.cc
     
    4041  CommandEvaluation.cc
    4142  CommandExecutor.cc
    42   CommandLine.cc
     43  CommandLineParser.cc
    4344  ConsoleCommand.cc
    4445  ConsoleCommandCompilation.cc
     
    8586  TOLUA_FILES
    8687    CommandExecutor.h
     88    ConfigFileManager.h
     89    Game.h
     90    GameMode.h
     91    GUIManager.h
    8792    Loader.h
    8893    LuaState.h
     94    PathConfig.h
     95    input/InputManager.h
     96    input/KeyBinder.h
     97    input/KeyBinderManager.h
    8998  DEFINE_SYMBOL
    9099    "CORE_SHARED_BUILD"
  • code/branches/pickup2/src/libraries/core/ClassTreeMask.cc

    r5929 r6412  
    291291    void ClassTreeMask::add(const Identifier* subclass, bool bInclude, bool overwrite, bool clean)
    292292    {
     293        if (!subclass)
     294            return;
    293295        // Check if the given subclass is a child of our root-class
    294296        if (subclass->isA(this->root_->getClass()))
     
    320322    void ClassTreeMask::add(ClassTreeMaskNode* node, const Identifier* subclass, bool bInclude, bool overwrite)
    321323    {
     324        if (!subclass)
     325            return;
    322326        // Check if the current node contains exactly the subclass we want to add
    323327        if (subclass == node->getClass())
     
    395399    void ClassTreeMask::addSingle(const Identifier* subclass, bool bInclude, bool clean)
    396400    {
     401        if (!subclass)
     402            return;
    397403        for (std::set<const Identifier*>::const_iterator it = subclass->getDirectChildrenBegin(); it != subclass->getDirectChildrenEnd(); ++it)
    398404            this->add(*it, this->isIncluded(*it), false, false);
     
    428434    bool ClassTreeMask::isIncluded(ClassTreeMaskNode* node, const Identifier* subclass) const
    429435    {
     436        if (!subclass)
     437            return false;
    430438        // Check if the searched subclass is of the same type as the class in the current node or a derivative
    431439        if (subclass->isA(node->getClass()))
     
    816824            // Calculate the prefix: + means included, - means excluded
    817825            if (it->isIncluded())
    818                 out << "+";
     826                out << '+';
    819827            else
    820                 out << "-";
     828                out << '-';
    821829
    822830            // Put the name of the corresponding class on the stream
    823             out << it->getClass()->getName() << " ";
     831            out << it->getClass()->getName() << ' ';
    824832        }
    825833
     
    850858        // If there is a first subclass, move the object-iterator to the first object of this class. Else go to the end
    851859        if (this->subclassIterator_ != this->subclasses_.end())
    852             this->objectIterator_ = (*this->subclassIterator_).first->getObjects()->begin();
     860            this->objectIterator_ = this->subclassIterator_->first->getObjects()->begin();
    853861        else
    854862            this->objectIterator_ = ObjectList<BaseObject>::end();
    855863
    856864        // Check if the iterator points on a valid object. If not, go to the next object by calling ++
    857         if (!this->objectIterator_ || ((*this->subclassIterator_).second && !this->objectIterator_->isExactlyA((*this->subclassIterator_).first)))
     865        if (!this->objectIterator_ || (this->subclassIterator_->second && !this->objectIterator_->isExactlyA(this->subclassIterator_->first)))
    858866            this->operator++();
    859867
     
    882890                    // Check if there really is a next class. If yes, move the object-iterator to the first object
    883891                    if (this->subclassIterator_ != this->subclasses_.end())
    884                         this->objectIterator_ = (*this->subclassIterator_).first->getObjects()->begin();
     892                        this->objectIterator_ = this->subclassIterator_->first->getObjects()->begin();
    885893                    else
    886894                        return (*this);
     
    888896
    889897            // Repeat this until we reach a valid object or the end
    890             } while ((*this->subclassIterator_).second && !this->objectIterator_->isExactlyA((*this->subclassIterator_).first));
     898            } while (this->subclassIterator_->second && !this->objectIterator_->isExactlyA(this->subclassIterator_->first));
    891899        }
    892900        return (*this);
  • code/branches/pickup2/src/libraries/core/CommandEvaluation.cc

    r5781 r6412  
    5050        this->commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
    5151
    52         this->additionalParameter_ = "";
     52        this->additionalParameter_.clear();
    5353
    5454        this->bEvaluatedParams_ = false;
     
    6060        this->functionclass_ = 0;
    6161        this->function_ = 0;
    62         this->possibleArgument_ = "";
    63         this->argument_ = "";
    64 
    65         this->errorMessage_ = "";
     62        this->possibleArgument_.clear();
     63        this->argument_.clear();
     64
     65        this->errorMessage_.clear();
    6666        this->state_ = CommandState::Empty;
    6767    }
     
    7979        if (this->bEvaluatedParams_ && this->function_)
    8080        {
    81             COUT(6) << "CE_execute (evaluation): " << this->function_->getName() << " " << this->param_[0] << " " << this->param_[1] << " " << this->param_[2] << " " << this->param_[3] << " " << this->param_[4] << std::endl;
     81            COUT(6) << "CE_execute (evaluation): " << this->function_->getName() << ' ' << this->param_[0] << ' ' << this->param_[1] << ' ' << this->param_[2] << ' ' << this->param_[3] << ' ' << this->param_[4] << std::endl;
    8282            (*this->function_)(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]);
    8383            return true;
     
    9898    }
    9999
    100     std::string CommandEvaluation::complete()
     100    const std::string& CommandEvaluation::complete()
    101101    {
    102102        if (!this->bNewCommand_)
     
    114114                            return (this->command_ = this->function_->getName());
    115115                        else
    116                             return (this->command_ = this->function_->getName() + " ");
     116                            return (this->command_ = this->function_->getName() + ' ');
    117117                    }
    118118                    else if (this->functionclass_)
    119                         return (this->command_ = this->functionclass_->getName() + " ");
     119                        return (this->command_ = this->functionclass_->getName() + ' ');
    120120                    break;
    121121                case CommandState::Function:
     
    123123                    {
    124124                        if (this->function_->getParamCount() == 0)
    125                             return (this->command_ = this->functionclass_->getName() + " " + this->function_->getName());
     125                            return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName());
    126126                        else
    127                             return (this->command_ = this->functionclass_->getName() + " " + this->function_->getName() + " ");
     127                            return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName() + ' ');
    128128                    }
    129129                    break;
     
    131131                case CommandState::Params:
    132132                {
    133                     if (this->argument_ == "" && this->possibleArgument_ == "")
     133                    if (this->argument_.empty() && this->possibleArgument_.empty())
    134134                        break;
    135135
     
    137137                    if (this->command_[this->command_.size() - 1] != ' ')
    138138                        maxIndex -= 1;
    139                     std::string whitespace = "";
    140 
    141                     if (this->possibleArgument_ != "")
     139                    std::string whitespace;
     140
     141                    if (!this->possibleArgument_.empty())
    142142                    {
    143143                        this->argument_ = this->possibleArgument_;
     
    146146                    }
    147147
    148                     return (this->command_ = this->commandTokens_.subSet(0, maxIndex).join() + " " + this->argument_ + whitespace);
     148                    return (this->command_ = this->commandTokens_.subSet(0, maxIndex).join() + ' ' + this->argument_ + whitespace);
    149149                    break;
    150150                }
     
    262262    std::string CommandEvaluation::dump(const std::list<std::pair<const std::string*, const std::string*> >& list)
    263263    {
    264         std::string output = "";
     264        std::string output;
    265265        for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
    266266        {
    267267            if (it != list.begin())
    268                 output += " ";
    269 
    270             output += *(*it).second;
     268                output += ' ';
     269
     270            output += *(it->second);
    271271        }
    272272        return output;
     
    275275    std::string CommandEvaluation::dump(const ArgumentCompletionList& list)
    276276    {
    277         std::string output = "";
     277        std::string output;
    278278        for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
    279279        {
    280280            if (it != list.begin())
    281                 output += " ";
    282 
    283             output += (*it).getDisplay();
     281                output += ' ';
     282
     283            output += it->getDisplay();
    284284        }
    285285        return output;
     
    295295        {
    296296            if (i != 0)
    297                 output += " ";
     297                output += ' ';
    298298
    299299            if (command->defaultValueSet(i))
    300                 output += "[";
     300                output += '[';
    301301            else
    302                 output += "{";
     302                output += '{';
    303303
    304304            output += command->getTypenameParam(i);
    305305
    306306            if (command->defaultValueSet(i))
    307                 output += "=" + command->getDefaultValue(i).getString() + "]";
     307                output += '=' + command->getDefaultValue(i).getString() + ']';
    308308            else
    309                 output += "}";
     309                output += '}';
    310310        }
    311311        return output;
  • code/branches/pickup2/src/libraries/core/CommandEvaluation.h

    r5781 r6412  
    6666
    6767            bool execute() const;
    68             std::string complete();
     68            const std::string& complete();
    6969            std::string hint() const;
    7070            void evaluateParams();
     
    8282                { this->additionalParameter_ = param; this->bEvaluatedParams_ = false; }
    8383            inline std::string getAdditionalParameter() const
    84                 { return (this->additionalParameter_ != "") ? (" " + this->additionalParameter_) : ""; }
     84                { return (!this->additionalParameter_.empty()) ? (' ' + this->additionalParameter_) : ""; }
    8585
    8686            void setEvaluatedParameter(unsigned int index, MultiType param);
  • code/branches/pickup2/src/libraries/core/CommandExecutor.cc

    r5929 r6412  
    5959        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
    6060        {
    61             COUT(2) << "Warning: Overwriting console-command shortcut with name " << command->getName() << "." << std::endl;
     61            COUT(2) << "Warning: Overwriting console-command shortcut with name " << command->getName() << '.' << std::endl;
    6262        }
    6363
     
    8282        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_.find(name);
    8383        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_.end())
    84             return (*it).second;
     84            return it->second;
    8585        else
    8686            return 0;
     
    9696        std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getInstance().consoleCommandShortcuts_LC_.find(name);
    9797        if (it != CommandExecutor::getInstance().consoleCommandShortcuts_LC_.end())
    98             return (*it).second;
     98            return it->second;
    9999        else
    100100            return 0;
     
    215215                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
    216216                        AddLanguageEntry("commandexecutorunknownfirstargument", "is not a shortcut nor a classname");
    217                         CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + " " + GetLocalisation("commandexecutorunknownfirstargument") + ".";
     217                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getArgument(0) + ' ' + GetLocalisation("commandexecutorunknownfirstargument") + '.';
    218218                        return;
    219219                    }
     
    231231                    {
    232232                        // It's a shortcut
    233                         std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
     233                        const std::string& functionname = *CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()->first;
    234234                        CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname);
    235235                        if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(0)))
     
    243243                        if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
    244244                        {
    245                             CommandExecutor::getEvaluation().command_ += " ";
     245                            CommandExecutor::getEvaluation().command_ += ' ';
    246246                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
    247247                        }
     
    251251                    {
    252252                        // It's a classname
    253                         std::string classname = *(*CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()).first;
     253                        const std::string& classname = *CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.begin()->first;
    254254                        CommandExecutor::getEvaluation().functionclass_ = CommandExecutor::getPossibleIdentifier(classname);
    255255                        if (getLowercase(classname) != getLowercase(CommandExecutor::getArgument(0)))
     
    260260                        CommandExecutor::getEvaluation().state_ = CommandState::Function;
    261261                        CommandExecutor::getEvaluation().function_ = 0;
    262                         CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " ";
     262                        CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' ';
    263263                        // Move on to next case
    264264                    }
     
    268268                        CommandExecutor::getEvaluation().state_ = CommandState::Error;
    269269                        AddLanguageEntry("commandexecutorunknownfirstargumentstart", "There is no command or classname starting with");
    270                         CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + " " + CommandExecutor::getArgument(0) + ".";
     270                        CommandExecutor::getEvaluation().errorMessage_ = "Error: " + GetLocalisation("commandexecutorunknownfirstargumentstart") + ' ' + CommandExecutor::getArgument(0) + '.';
    271271                        return;
    272272                    }
     
    319319                        {
    320320                            // It's a function
    321                             std::string functionname = *(*CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()).first;
     321                            const std::string& functionname = *CommandExecutor::getEvaluation().listOfPossibleFunctions_.begin()->first;
    322322                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(functionname, CommandExecutor::getEvaluation().functionclass_);
    323323                            if (getLowercase(functionname) != getLowercase(CommandExecutor::getArgument(1)))
     
    327327                            }
    328328                            CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
    329                             CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getEvaluation().function_->getName();
     329                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + CommandExecutor::getEvaluation().function_->getName();
    330330                            if (CommandExecutor::getEvaluation().function_->getParamCount() > 0)
    331331                            {
    332                                 CommandExecutor::getEvaluation().command_ += " ";
     332                                CommandExecutor::getEvaluation().command_ += ' ';
    333333                                CommandExecutor::getEvaluation().bCommandChanged_ = true;
    334334                            }
     
    340340                            CommandExecutor::getEvaluation().state_ = CommandState::Error;
    341341                            AddLanguageEntry("commandexecutorunknownsecondargumentstart", "has no function starting with");
    342                             CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + " " + GetLocalisation("commandexecutorunknownsecondargumentstart") + " " + CommandExecutor::getArgument(1) + ".";
     342                            CommandExecutor::getEvaluation().errorMessage_ = "Error: " + CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + GetLocalisation("commandexecutorunknownsecondargumentstart") + ' ' + CommandExecutor::getArgument(1) + '.';
    343343                            return;
    344344                        }
     
    346346                        {
    347347                            // There are several possibilities
    348                             CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + " " + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_);
     348                            CommandExecutor::getEvaluation().command_ = CommandExecutor::getEvaluation().functionclass_->getName() + ' ' + CommandExecutor::getCommonBegin(CommandExecutor::getEvaluation().listOfPossibleFunctions_);
    349349                            CommandExecutor::getEvaluation().function_ = CommandExecutor::getPossibleCommand(CommandExecutor::getArgument(1), CommandExecutor::getEvaluation().functionclass_);
    350350                            CommandExecutor::getEvaluation().bCommandChanged_ = true;
     
    386386                {
    387387                    // There is exactly one possible argument
    388                     CommandExecutor::getEvaluation().argument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
    389                     CommandExecutor::getEvaluation().possibleArgument_ = (*CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()).getString();
     388                    CommandExecutor::getEvaluation().argument_ = CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()->getString();
     389                    CommandExecutor::getEvaluation().possibleArgument_ = CommandExecutor::getEvaluation().listOfPossibleArguments_.begin()->getString();
    390390                    CommandExecutor::getEvaluation().state_ = CommandState::ParamPreparation;
    391391                    return;
     
    451451    }
    452452
    453     std::string CommandExecutor::getArgument(unsigned int index)
     453    const std::string& CommandExecutor::getArgument(unsigned int index)
    454454    {
    455455        if (index < (CommandExecutor::getEvaluation().commandTokens_.size()))
    456456            return CommandExecutor::getEvaluation().commandTokens_[index];
    457457        else
    458             return "";
    459     }
    460 
    461     std::string CommandExecutor::getLastArgument()
     458            return BLANKSTRING;
     459    }
     460
     461    const std::string& CommandExecutor::getLastArgument()
    462462    {
    463463        return CommandExecutor::getArgument(CommandExecutor::argumentsGiven() - 1);
     
    467467    {
    468468        CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.clear();
    469         std::string lowercase = getLowercase(fragment);
     469        const std::string& lowercase = getLowercase(fragment);
    470470        for (std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMapBegin(); it != Identifier::getLowercaseStringIdentifierMapEnd(); ++it)
    471             if ((*it).second->hasConsoleCommands())
    472                 if ((*it).first.find(lowercase) == 0 || fragment == "")
    473                     CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     471            if (it->second->hasConsoleCommands())
     472                if (it->first.find(lowercase) == 0 || fragment.empty())
     473                    CommandExecutor::getEvaluation().listOfPossibleIdentifiers_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName()));
    474474    }
    475475
     
    477477    {
    478478        CommandExecutor::getEvaluation().listOfPossibleFunctions_.clear();
    479         std::string lowercase = getLowercase(fragment);
     479        const std::string& lowercase = getLowercase(fragment);
    480480        if (!identifier)
    481481        {
    482482            for (std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMapBegin(); it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd(); ++it)
    483                 if ((*it).first.find(lowercase) == 0 || fragment == "")
    484                     CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     483                if (it->first.find(lowercase) == 0 || fragment.empty())
     484                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName()));
    485485        }
    486486        else
    487487        {
    488488            for (std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMapBegin(); it != identifier->getLowercaseConsoleCommandMapEnd(); ++it)
    489                 if ((*it).first.find(lowercase) == 0 || fragment == "")
    490                     CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&(*it).first, &(*it).second->getName()));
     489                if (it->first.find(lowercase) == 0 || fragment.empty())
     490                    CommandExecutor::getEvaluation().listOfPossibleFunctions_.push_back(std::pair<const std::string*, const std::string*>(&it->first, &it->second->getName()));
    491491        }
    492492    }
     
    497497
    498498        CommandExecutor::getEvaluation().listOfPossibleArguments_.clear();
    499         std::string lowercase = getLowercase(fragment);
     499        const std::string& lowercase = getLowercase(fragment);
    500500        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
    501501        {
    502             if ((*it).lowercaseComparison())
    503             {
    504                 if ((*it).getComparable().find(lowercase) == 0 || fragment == "")
     502            if (it->lowercaseComparison())
     503            {
     504                if (it->getComparable().find(lowercase) == 0 || fragment.empty())
    505505                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
    506506            }
    507507            else
    508508            {
    509                 if ((*it).getComparable().find(fragment) == 0 || fragment == "")
     509                if (it->getComparable().find(fragment) == 0 || fragment.empty())
    510510                    CommandExecutor::getEvaluation().listOfPossibleArguments_.push_back(*it);
    511511            }
     
    515515    Identifier* CommandExecutor::getPossibleIdentifier(const std::string& name)
    516516    {
    517         std::string lowercase = getLowercase(name);
     517        const std::string& lowercase = getLowercase(name);
    518518        std::map<std::string, Identifier*>::const_iterator it = Identifier::getLowercaseStringIdentifierMap().find(lowercase);
    519         if ((it != Identifier::getLowercaseStringIdentifierMapEnd()) && (*it).second->hasConsoleCommands())
    520             return (*it).second;
     519        if ((it != Identifier::getLowercaseStringIdentifierMapEnd()) && it->second->hasConsoleCommands())
     520            return it->second;
    521521
    522522        return 0;
     
    525525    ConsoleCommand* CommandExecutor::getPossibleCommand(const std::string& name, Identifier* identifier)
    526526    {
    527         std::string lowercase = getLowercase(name);
     527        const std::string& lowercase = getLowercase(name);
    528528        if (!identifier)
    529529        {
    530530            std::map<std::string, ConsoleCommand*>::const_iterator it = CommandExecutor::getLowercaseConsoleCommandShortcutMap().find(lowercase);
    531531            if (it != CommandExecutor::getLowercaseConsoleCommandShortcutMapEnd())
    532                 return (*it).second;
     532                return it->second;
    533533        }
    534534        else
     
    536536            std::map<std::string, ConsoleCommand*>::const_iterator it = identifier->getLowercaseConsoleCommandMap().find(lowercase);
    537537            if (it != identifier->getLowercaseConsoleCommandMapEnd())
    538                 return (*it).second;
     538                return it->second;
    539539        }
    540540        return 0;
    541541    }
    542542
    543     std::string CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
     543    const std::string& CommandExecutor::getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param)
    544544    {
    545545        CommandExecutor::createArgumentCompletionList(command, param);
    546546
    547         std::string lowercase = getLowercase(name);
     547        const std::string& lowercase = getLowercase(name);
    548548        for (ArgumentCompletionList::const_iterator it = command->getArgumentCompletionListBegin(); it != command->getArgumentCompletionListEnd(); ++it)
    549549        {
    550             if ((*it).lowercaseComparison())
    551             {
    552                 if ((*it).getComparable() == lowercase)
    553                     return (*it).getString();
     550            if (it->lowercaseComparison())
     551            {
     552                if (it->getComparable() == lowercase)
     553                    return it->getString();
    554554            }
    555555            else
    556556            {
    557                 if ((*it).getComparable() == name)
    558                     return (*it).getString();
    559             }
    560         }
    561 
    562         return "";
     557                if (it->getComparable() == name)
     558                    return it->getString();
     559            }
     560        }
     561
     562        return BLANKSTRING;
    563563    }
    564564
     
    589589        else if (list.size() == 1)
    590590        {
    591             return ((*(*list.begin()).first) + " ");
    592         }
    593         else
    594         {
    595             std::string output = "";
     591            return ((*list.begin()->first) + ' ');
     592        }
     593        else
     594        {
     595            std::string output;
    596596            for (unsigned int i = 0; true; i++)
    597597            {
     
    599599                for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
    600600                {
    601                     if ((*(*it).first).size() > i)
     601                    if (it->first->size() > i)
    602602                    {
    603603                        if (it == list.begin())
    604604                        {
    605                             temp = (*(*it).first)[i];
     605                            temp = (*it->first)[i];
    606606                        }
    607607                        else
    608608                        {
    609                             if (temp != (*(*it).first)[i])
     609                            if (temp != (*it->first)[i])
    610610                                return output;
    611611                        }
     
    630630        else if (list.size() == 1)
    631631        {
    632             return ((*list.begin()).getComparable() + " ");
    633         }
    634         else
    635         {
    636             std::string output = "";
     632            return (list.begin()->getComparable() + ' ');
     633        }
     634        else
     635        {
     636            std::string output;
    637637            for (unsigned int i = 0; true; i++)
    638638            {
     639                char tempComparable = 0;
    639640                char temp = 0;
    640641                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
    641642                {
    642                     std::string argument = (*it).getComparable();
     643                    const std::string& argumentComparable = it->getComparable();
     644                    const std::string& argument = it->getString();
    643645                    if (argument.size() > i)
    644646                    {
    645647                        if (it == list.begin())
    646648                        {
     649                            tempComparable = argumentComparable[i];
    647650                            temp = argument[i];
    648651                        }
    649652                        else
    650653                        {
    651                             if (temp != argument[i])
     654                            if (tempComparable != argumentComparable[i])
    652655                                return output;
     656                            else if (temp != argument[i])
     657                                temp = tempComparable;
    653658                        }
    654659                    }
  • code/branches/pickup2/src/libraries/core/CommandExecutor.h

    r5781 r6412  
    9090            static unsigned int argumentsGiven();
    9191            static bool enoughArgumentsGiven(ConsoleCommand* command);
    92             static std::string getArgument(unsigned int index);
    93             static std::string getLastArgument();
     92            static const std::string& getArgument(unsigned int index);
     93            static const std::string& getLastArgument();
    9494
    9595            static void createListOfPossibleIdentifiers(const std::string& fragment);
     
    9999            static Identifier* getPossibleIdentifier(const std::string& name);
    100100            static ConsoleCommand* getPossibleCommand(const std::string& name, Identifier* identifier = 0);
    101             static std::string getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param);
     101            static const std::string& getPossibleArgument(const std::string& name, ConsoleCommand* command, unsigned int param);
    102102
    103103            static void createArgumentCompletionList(ConsoleCommand* command, unsigned int param);
  • code/branches/pickup2/src/libraries/core/CommandLineParser.cc

    r6105 r6412  
    6363                this->value_ = temp;
    6464            }
    65             else if (value == "")
     65            else if (value.empty())
    6666            {
    6767                this->bHasDefaultValue_ = false;
     
    140140                    OrxAssert(cmdLineArgsShortcut_.find(it->second->getShortcut()) == cmdLineArgsShortcut_.end(),
    141141                        "Cannot have two command line shortcut with the same name.");
    142                     if (it->second->getShortcut() != "")
     142                    if (!it->second->getShortcut().empty())
    143143                        cmdLineArgsShortcut_[it->second->getShortcut()] = it->second;
    144144                }
     
    165165                        {
    166166                            // negative number as a value
    167                             value += arguments[i] + " ";
     167                            value += arguments[i] + ' ';
    168168                        }
    169169                        else
     
    173173                            // save old data first
    174174                            value = removeTrailingWhitespaces(value);
    175                             if (name != "")
     175                            if (!name.empty())
    176176                            {
    177177                                checkFullArgument(name, value, bParsingFile);
    178                                 name = "";
    179                                 assert(shortcut == "");
     178                                name.clear();
     179                                assert(shortcut.empty());
    180180                            }
    181                             else if (shortcut != "")
     181                            else if (!shortcut.empty())
    182182                            {
    183183                                checkShortcut(shortcut, value, bParsingFile);
    184                                 shortcut = "";
    185                                 assert(name == "");
     184                                shortcut.clear();
     185                                assert(name.empty());
    186186                            }
    187187
     
    198198
    199199                            // reset value string
    200                             value = "";
     200                            value.clear();
    201201                        }
    202202                    }
     
    205205                        // value string
    206206
    207                         if (name == "" && shortcut == "")
     207                        if (name.empty() && shortcut.empty())
    208208                        {
    209209                            ThrowException(Argument, "Expected \"-\" or \"-\" in command line arguments.\n");
     
    218218            // parse last argument
    219219            value = removeTrailingWhitespaces(value);
    220             if (name != "")
     220            if (!name.empty())
    221221            {
    222222                checkFullArgument(name, value, bParsingFile);
    223                 assert(shortcut == "");
    224             }
    225             else if (shortcut != "")
     223                assert(shortcut.empty());
     224            }
     225            else if (!shortcut.empty())
    226226            {
    227227                checkShortcut(shortcut, value, bParsingFile);
    228                 assert(name == "");
     228                assert(name.empty());
    229229            }
    230230        }
     
    291291            it != inst.cmdLineArgs_.end(); ++it)
    292292        {
    293             if (it->second->getShortcut() != "")
     293            if (!it->second->getShortcut().empty())
    294294                infoStr << " [-" << it->second->getShortcut() << "] ";
    295295            else
    296296                infoStr << "      ";
    297             infoStr << "--" << it->second->getName() << " ";
     297            infoStr << "--" << it->second->getName() << ' ';
    298298            if (it->second->getValue().getType() != MT_Type::Bool)
    299299                infoStr << "ARG ";
     
    347347    void CommandLineParser::_parseFile()
    348348    {
    349         std::string filename = CommandLineParser::getValue("optionsFile").getString();
     349        const std::string& filename = CommandLineParser::getValue("optionsFile").getString();
    350350
    351351        // look for additional arguments in given file or start.ini as default
  • code/branches/pickup2/src/libraries/core/ConfigFileManager.cc

    r5929 r6412  
    5151        if (identifier != Identifier::getLowercaseStringIdentifierMapEnd())
    5252        {
    53             std::map<std::string, ConfigValueContainer*>::const_iterator variable = (*identifier).second->getLowercaseConfigValueMap().find(getLowercase(varname));
    54             if (variable != (*identifier).second->getLowercaseConfigValueMapEnd())
    55                 return (*variable).second->set(value);
     53            std::map<std::string, ConfigValueContainer*>::const_iterator variable = identifier->second->getLowercaseConfigValueMap().find(getLowercase(varname));
     54            if (variable != identifier->second->getLowercaseConfigValueMapEnd())
     55                return variable->second->set(value);
    5656        }
    5757        return false;
     58    }
     59
     60    std::string getConfig(const std::string& classname, const std::string& varname)
     61    {
     62        return ConfigFileManager::getInstance().getValue(ConfigFileType::Settings, classname, varname, "", true);
    5863    }
    5964
     
    6368        if (identifier != Identifier::getLowercaseStringIdentifierMapEnd())
    6469        {
    65             std::map<std::string, ConfigValueContainer*>::const_iterator variable = (*identifier).second->getLowercaseConfigValueMap().find(getLowercase(varname));
    66             if (variable != (*identifier).second->getLowercaseConfigValueMapEnd())
    67                 return (*variable).second->tset(value);
     70            std::map<std::string, ConfigValueContainer*>::const_iterator variable = identifier->second->getLowercaseConfigValueMap().find(getLowercase(varname));
     71            if (variable != identifier->second->getLowercaseConfigValueMapEnd())
     72                return variable->second->tset(value);
    6873        }
    6974        return false;
     
    9499            this->value_ = value;
    95100        else
    96             this->value_ = "\"" + addSlashes(stripEnclosingQuotes(value)) + "\"";
     101            this->value_ = '"' + addSlashes(stripEnclosingQuotes(value)) + '"';
    97102    }
    98103
     
    107112    std::string ConfigFileEntryValue::getFileEntry() const
    108113    {
    109         if (this->additionalComment_ == "" || this->additionalComment_.size() == 0)
    110             return (this->name_ + "=" + this->value_);
    111         else
    112             return (this->name_ + "=" + this->value_ + " " + this->additionalComment_);
     114        if (this->additionalComment_.empty())
     115            return (this->name_ + '=' + this->value_);
     116        else
     117            return (this->name_ + '=' + this->value_ + " " + this->additionalComment_);
    113118    }
    114119
     
    119124    std::string ConfigFileEntryVectorValue::getFileEntry() const
    120125    {
    121         if (this->additionalComment_ == "" || this->additionalComment_.size() == 0)
    122             return (this->name_ + "[" + multi_cast<std::string>(this->index_) + "]" + "=" + this->value_);
    123         else
    124             return (this->name_ + "[" + multi_cast<std::string>(this->index_) + "]=" + this->value_ + " " + this->additionalComment_);
     126        if (this->additionalComment_.empty())
     127            return (this->name_ + '[' + multi_cast<std::string>(this->index_) + ']' + '=' + this->value_);
     128        else
     129            return (this->name_ + '[' + multi_cast<std::string>(this->index_) + "]=" + this->value_ + ' ' + this->additionalComment_);
    125130    }
    126131
     
    166171    std::string ConfigFileSection::getFileEntry() const
    167172    {
    168         if (this->additionalComment_ == "" || this->additionalComment_.size() == 0)
    169             return ("[" + this->name_ + "]");
    170         else
    171             return ("[" + this->name_ + "] " + this->additionalComment_);
     173        if (this->additionalComment_.empty())
     174            return ('[' + this->name_ + ']');
     175        else
     176            return ('[' + this->name_ + "] " + this->additionalComment_);
    172177    }
    173178
     
    246251                std::getline(file, line);
    247252
    248                 std::string temp = getStripped(line);
     253                const std::string& temp = getStripped(line);
    249254                if (!isEmpty(temp) && !isComment(temp))
    250255                {
     
    256261                    {
    257262                        // New section
    258                         std::string comment = line.substr(pos2 + 1);
     263                        const std::string& comment = line.substr(pos2 + 1);
    259264                        if (isComment(comment))
    260265                            newsection = new ConfigFileSection(line.substr(pos1 + 1, pos2 - pos1 - 1), comment);
     
    288293                                commentposition = getNextCommentPosition(line, commentposition + 1);
    289294                            }
    290                             std::string value = "", comment = "";
     295                            std::string value, comment;
    291296                            if (commentposition == std::string::npos)
    292297                            {
     
    377382        {
    378383            std::map<std::string, Identifier*>::const_iterator it2 = Identifier::getStringIdentifierMap().find((*it1)->getName());
    379             if (it2 != Identifier::getStringIdentifierMapEnd() && (*it2).second->hasConfigValues())
     384            if (it2 != Identifier::getStringIdentifierMapEnd() && it2->second->hasConfigValues())
    380385            {
    381386                // The section exists, delete comment
     
    384389                for (std::list<ConfigFileEntry*>::iterator it3 = (*it1)->entries_.begin(); it3 != (*it1)->entries_.end(); )
    385390                {
    386                     std::map<std::string, ConfigValueContainer*>::const_iterator it4 = (*it2).second->getConfigValueMap().find((*it3)->getName());
    387                     if (it4 != (*it2).second->getConfigValueMapEnd())
     391                    std::map<std::string, ConfigValueContainer*>::const_iterator it4 = it2->second->getConfigValueMap().find((*it3)->getName());
     392                    if (it4 != it2->second->getConfigValueMapEnd())
    388393                    {
    389394                        // The config-value exists, delete comment
     
    459464                if (it->second->hasConfigValues())
    460465                {
    461                     for (std::map<std::string, ConfigValueContainer*>::const_iterator it2 = (*it).second->getConfigValueMapBegin(); it2 != (*it).second->getConfigValueMapEnd(); ++it2)
     466                    for (std::map<std::string, ConfigValueContainer*>::const_iterator it2 = it->second->getConfigValueMapBegin(); it2 != it->second->getConfigValueMapEnd(); ++it2)
    462467                        it2->second->update();
    463468
  • code/branches/pickup2/src/libraries/core/ConfigFileManager.h

    r5738 r6412  
    4040#include "util/Singleton.h"
    4141
     42// tolua_begin
    4243namespace orxonox
    4344{
     45    // tolua_end
    4446    // Use int as config file type to have an arbitrary number of files
    4547    struct ConfigFileType : OrxEnum<ConfigFileType>
     
    5052        static const int Settings            = 1;
    5153        static const int JoyStickCalibration = 2;
     54        static const int CommandHistory      = 3;
    5255
    5356        static const int numberOfReservedTypes = 1024;
    5457    };
    5558
    56     bool config(const std::string& classname, const std::string& varname, const std::string& value);
    57     bool tconfig(const std::string& classname, const std::string& varname, const std::string& value);
    58     void reloadConfig();
    59     void saveConfig();
    60     void cleanConfig();
    61     void loadSettings(const std::string& filename);
     59    _CoreExport bool config(const std::string& classname, const std::string& varname, const std::string& value); // tolua_export
     60    _CoreExport std::string getConfig(const std::string& classname, const std::string& varname); // tolua_export
     61    _CoreExport bool tconfig(const std::string& classname, const std::string& varname, const std::string& value);
     62    _CoreExport void reloadConfig();
     63    _CoreExport void saveConfig();
     64    _CoreExport void cleanConfig();
     65    _CoreExport void loadSettings(const std::string& filename);
    6266
    6367
     
    8589    {
    8690        public:
    87             inline ConfigFileEntryValue(const std::string& name, const std::string& value = "", bool bString = false, const std::string& additionalComment = "") : name_(name), value_(value), bString_(bString), additionalComment_(additionalComment) {}
     91            inline ConfigFileEntryValue(const std::string& name, const std::string& value = "", bool bString = false, const std::string& additionalComment = "")
     92                : name_(name)
     93                , value_(value)
     94                , bString_(bString)
     95                , additionalComment_(additionalComment)
     96                {}
    8897            inline virtual ~ConfigFileEntryValue() {}
    8998
     
    169178
    170179        public:
    171             inline ConfigFileSection(const std::string& name, const std::string& additionalComment = "") : name_(name), additionalComment_(additionalComment), bUpdated_(false) {}
     180            inline ConfigFileSection(const std::string& name, const std::string& additionalComment = "")
     181                : name_(name)
     182                , additionalComment_(additionalComment)
     183                , bUpdated_(false)
     184                {}
    172185            ~ConfigFileSection();
    173186
     
    240253                { this->getSection(section)->setValue(name, value, bString); this->save(); }
    241254            inline std::string getValue(const std::string& section, const std::string& name, const std::string& fallback, bool bString)
    242                 { std::string output = this->getSection(section)->getValue(name, fallback, bString); this->saveIfUpdated(); return output; }
     255                { const std::string& output = this->getSection(section)->getValue(name, fallback, bString); this->saveIfUpdated(); return output; }
    243256
    244257            inline void setValue(const std::string& section, const std::string& name, unsigned int index, const std::string& value, bool bString)
    245258                { this->getSection(section)->setValue(name, index, value, bString); this->save(); }
    246259            inline std::string getValue(const std::string& section, const std::string& name, unsigned int index, const std::string& fallback, bool bString)
    247                 { std::string output = this->getSection(section)->getValue(name, index, fallback, bString); this->saveIfUpdated(); return output; }
     260                { const std::string& output = this->getSection(section)->getValue(name, index, fallback, bString); this->saveIfUpdated(); return output; }
    248261
    249262            inline void deleteVectorEntries(const std::string& section, const std::string& name, unsigned int startindex = 0)
     
    319332            static ConfigFileManager* singletonPtr_s;
    320333    };
    321 }
     334} // tolua_export
    322335
    323336#endif /* _ConfigFileManager_H__ */
  • code/branches/pickup2/src/libraries/core/ConfigValueContainer.h

    r5738 r6412  
    121121                @param defvalue The default-value
    122122            */
    123             template <class V>
    124             ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const std::vector<V>& defvalue)
     123            template <class D, class V>
     124            ConfigValueContainer(ConfigFileType type, Identifier* identifier, const std::string& sectionname, const std::string& varname, const std::vector<D>& defvalue, const std::vector<V>& value)
    125125            {
    126126                this->init(type, identifier, sectionname, varname);
     
    146146                if ((this->callback_ && object) || this->bContainerIsNew_)
    147147                {
    148                     if (this->bContainerIsNew_)
    149                         this->bContainerIsNew_ = false;
    150 
    151148                    T temp = *value;
    152149                    this->value_.getValue(value);
    153                     if ((*value) != temp)
    154                     {
     150                    if (this->bContainerIsNew_ || (*value) != temp)
     151                    {
     152                        this->bContainerIsNew_ = false;
    155153                        if (this->callback_ && object)
    156154                            this->callback_->call(object);
  • code/branches/pickup2/src/libraries/core/ConfigValueIncludes.h

    r5738 r6412  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder (functions)
    2626 *
    2727 */
    2828
    2929/**
    30     @file
    31     @brief Definition of macros for config-values.
     30@file
     31@brief
     32    Definition of macros and functions for config-values.
    3233*/
    3334
     
    4142#include "ConfigFileManager.h"
    4243
     44namespace orxonox
     45{
     46    /** Sets a runtime configurable value.
     47        If the container for the value doesn't yet exist, a new one is created.
     48        Also, the @a variable argument will be modified and set to the new value (default or from ini file).
     49    @param object
     50        Class instance that the config value should belong to (usually just 'this')
     51    @param variable
     52        Pointer to the variable where the value should be written to
     53    @param type
     54        Type of the config file, usually ConfigFileType::Settings
     55    @param sectionName
     56        Name of the section in the ini file (e.g. [MySection])
     57    @param entryName
     58        Name of the entry in the ini file (e.g. [MySection] myValue)
     59    @param defaultValue
     60        Value to be used if it cannot be read from the ini file
     61    */
     62    template <class T, class D, class V>
     63    inline ConfigValueContainer& setConfigValueGeneric(T* object, V* variable, ConfigFileType type, const std::string& sectionName, const std::string& entryName, const D& defaultValue)
     64    {
     65        ConfigValueContainer* container = object->getIdentifier()->getConfigValueContainer(entryName);
     66        if (!container)
     67        {
     68            container = new ConfigValueContainer(type, object->getIdentifier(), sectionName, entryName, defaultValue, *variable);
     69            object->getIdentifier()->addConfigValueContainer(entryName, container);
     70        }
     71        return container->getValue(variable, object);
     72    }
     73}
    4374
    44 /**
    45     @brief Assigns the value, defined in the config-file, to the variable (or the default-value, if there is no entry in the file).
    46     @param varname The name of the variable
    47     @param defvalue The default-value of the variable
     75/** Sets a runtime configurable value (simplified macro version of setConfigValueGeneric)
     76    If the container for the value doesn't yet exist, a new one is created.
     77    Also, the @a varname argument will be modified and set to the new value (default or from ini file).
     78@param varname
     79    Variable name as C++ identifier. It will be used as entry name and as variable pointer
     80@param defaultValue
     81    Value to be used if it cannot be read from the ini file
    4882*/
    49 #define SetConfigValueGeneric(type, varname, defvalue) \
    50     static orxonox::Identifier* identifier##varname = this->getIdentifier(); \
    51     orxonox::ConfigValueContainer* container##varname = identifier##varname->getConfigValueContainer(#varname); \
    52     if (!container##varname) \
    53     { \
    54         container##varname = new orxonox::ConfigValueContainer(type, identifier##varname, identifier##varname->getName(), #varname, defvalue, varname); \
    55         identifier##varname->addConfigValueContainer(#varname, container##varname); \
    56     } \
    57     container##varname->getValue(&varname, this)
     83#define SetConfigValue(varname, defaultValue) \
     84    orxonox::setConfigValueGeneric(this, &varname, ConfigFileType::Settings, this->getIdentifier()->getName(), #varname, defaultValue)
    5885
    59 #define SetConfigValue(varname, defvalue) SetConfigValueGeneric(ConfigFileType::Settings, varname, defvalue)
     86/** Sets a runtime configurable value (simplified macro version of setConfigValueGeneric)
     87    If the container for the value doesn't yet exist, a new one is created.
     88    Also, the @a varname argument will be modified and set to the new value (default or from ini file).
     89@param variable
     90    Variable name as C++ identifier.
     91@param entryName
     92    Name of the entry in the ini file (e.g. [MySection] myValue)
     93@param defaultValue
     94    Value to be used if it cannot be read from the ini file
     95*/
     96#define SetConfigValueAlias(variable, entryName, defaultValue) \
     97    orxonox::setConfigValueGeneric(this, &variable, ConfigFileType::Settings, this->getIdentifier()->getName(), entryName, defaultValue)
    6098
    6199
    62 /**
    63     @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).
    64     @param varname The name of the std::vector
    65     @param defvalue The default-value
     100namespace orxonox
     101{
     102    /** Resets a runtime configurable value to its default.
     103        If the container for the value doesn't yet exist, a warning is displayed.
     104        Also, the @a variable argument will be modified and set to the default value.
     105    @param object
     106        Class instance that the config value should belong to (usually just 'this')
     107    @param variable
     108        Pointer to the variable where the value should be written to
     109    @param entryName
     110        Name of the entry in the ini file (e.g. [MySection] myValue)
     111    */
     112    template <class T, class V>
     113    inline void resetConfigValueGeneric(T* object, V* variable, const std::string& entryName)
     114    {
     115        ConfigValueContainer* container = object->getIdentifier()->getConfigValueContainer(entryName);
     116        if (container)
     117        {
     118            container->reset();
     119            container->getValue(variable, object);
     120        }
     121        else
     122        {
     123            COUT(2) << "Warning: Couldn't reset config-value '" << entryName << "' in class '"
     124                    << object->getIdentifier()->getName() << "', corresponding container doesn't exist." << std::endl;
     125        }
     126    }
     127}
     128
     129/** Resets a runtime configurable value to its default (simplified macro version of modifyConfigValueGeneric)
     130    If the container for the value doesn't yet exist, a warning is displayed.
     131    Also, the @a varname argument will be modified and set to the default value.
     132@param varname
     133    Variable name as C++ identifier. It will be used as entry name and as variable pointer
    66134*/
    67 #define SetConfigValueVectorGeneric(type, varname, defvalue) \
    68     static orxonox::Identifier* identifier##varname = this->getIdentifier(); \
    69     orxonox::ConfigValueContainer* container##varname = identifier##varname->getConfigValueContainer(#varname); \
    70     if (!container##varname) \
    71     { \
    72         container##varname = new orxonox::ConfigValueContainer(type, identifier##varname, identifier##varname->getName(), #varname, defvalue); \
    73         identifier##varname->addConfigValueContainer(#varname, container##varname); \
    74     } \
    75     container##varname->getValue(&varname, this)
    76 
    77 #define SetConfigValueVector(varname, defvalue) SetConfigValueVectorGeneric(ConfigFileType::Settings, varname, defvalue)
     135#define ResetConfigValue(varname) \
     136    orxonox::resetConfigValueGeneric(this, &varname, #varname)
    78137
    79138
    80 /**
    81     @brief Sets the variable and the config-file entry back to the previously defined default-value.
    82     @param varname The name of the variable
     139/** Modifies a runtime configurable value by using a modifier and some arguments.
     140    If the container for the value doesn't yet exist, a warning is displayed.
     141    Also, the @a variable argument will be modified and set to the current value.
     142@param object
     143    Class instance that the config value should belong to (usually just 'this')
     144@param variable
     145    Pointer to the variable where the value should be written to
     146@param entryName
     147    Name of the entry in the ini file (e.g. [MySection] myValue)
     148@param modifier
     149    On of these functions: set, tset, add, remove, reset, update
     150@param ...
     151    Arguments for the modifier function
    83152*/
    84 #define ResetConfigValue(varname) \
    85     orxonox::ConfigValueContainer* container##varname##reset = this->getIdentifier()->getConfigValueContainer(#varname); \
    86     if (container##varname##reset) \
     153#define ModifyConfigValueGeneric(object, variable, entryName, modifier, ...) \
     154    if (orxonox::ConfigValueContainer* container = object->getIdentifier()->getConfigValueContainer(entryName)) \
    87155    { \
    88         container##varname##reset->reset(); \
    89         container##varname##reset->getValue(&varname, this); \
     156        container->modifier(__VA_ARGS__); \
     157        container->getValue(variable, object); \
    90158    } \
    91159    else \
    92160    { \
    93         COUT(2) << "Warning: Couldn't reset config-value '" << #varname << "', corresponding container doesn't exist." << std::endl; \
     161        COUT(2) << "Warning: Couln't modify config-value '" << entryName << "' in class '" \
     162                << object->getIdentifier()->getName() << "', corresponding container doesn't exist." << std::endl; \
    94163    }
    95164
    96 
    97 /**
    98     @brief Modifies a config-value by using a modifier and some arguments.
    99     @param varname The name of the config-value
    100     @param modifier The name of the modifier: set, tset, add, remove, reset, update
     165/** Modifies a runtime configurable value by using a modifier and some arguments.
     166    If the container for the value doesn't yet exist, a warning is displayed.
     167    Also, the @a varname argument will be modified and set to the current value.
     168@param varname
     169    Variable name as C++ identifier. It will be used as entry name and as variable pointer
     170@param modifier
     171    On of these functions: set, tset, add, remove, reset, update
     172@param ...
     173    Arguments for the modifier function
    101174*/
    102175#define ModifyConfigValue(varname, modifier, ...) \
    103     orxonox::ConfigValueContainer* container##varname##modify##modifier = this->getIdentifier()->getConfigValueContainer(#varname); \
    104     if (container##varname##modify##modifier) \
    105     { \
    106         container##varname##modify##modifier->modifier(__VA_ARGS__); \
    107         container##varname##modify##modifier->getValue(&varname, this); \
    108     } \
    109     else \
    110     { \
    111         COUT(2) << "Warning: Couln't modify config-value '" << #varname << "', corresponding container doesn't exist." << std::endl; \
    112     }
     176    ModifyConfigValueGeneric(this, &varname, #varname, modifier, __VA_ARGS__)
    113177
    114178#endif /* _ConfigValueIncludes_H__ */
  • code/branches/pickup2/src/libraries/core/ConsoleCommandCompilation.cc

    r5781 r6412  
    3535#include "util/Debug.h"
    3636#include "util/ExprParser.h"
     37#include "util/StringUtils.h"
    3738#include "ConsoleCommand.h"
    3839
     
    8687    std::string echo(const std::string& text)
    8788    {
    88         std::cout << text << std::endl;
    8989        return text;
    9090    }
     
    143143        }
    144144
    145         std::string output = "";
     145        std::string output;
    146146        while (file.good() && !file.eof())
    147147        {
     
    159159    float calculate(const std::string& calculation)
    160160    {
    161         ExprParser expr(calculation);
     161        ExprParser expr;
     162        expr.parse(calculation);
    162163        if (expr.getSuccess())
    163164        {
     
    166167                COUT(3) << "Greetings from the restaurant at the end of the universe." << std::endl;
    167168            }
    168             if (expr.getRemains() != "")
     169            if (!expr.getRemains().empty())
    169170            {
    170                 COUT(2) << "Warning: Expression could not be parsed to the end! Remains: '" << expr.getRemains() << "'" << std::endl;
     171                COUT(2) << "Warning: Expression could not be parsed to the end! Remains: '" << expr.getRemains() << '\'' << std::endl;
    171172            }
    172173            return static_cast<float>(expr.getResult());
  • code/branches/pickup2/src/libraries/core/Core.cc

    r5929 r6412  
    5151#include "util/Debug.h"
    5252#include "util/Exception.h"
     53#include "util/Scope.h"
    5354#include "util/SignalHandler.h"
    5455#include "PathConfig.h"
    5556#include "CommandExecutor.h"
    56 #include "CommandLine.h"
     57#include "CommandLineParser.h"
    5758#include "ConfigFileManager.h"
    5859#include "ConfigValueIncludes.h"
     
    6465#include "Identifier.h"
    6566#include "Language.h"
     67#include "IOConsole.h"
    6668#include "LuaState.h"
    6769#include "ScopedSingletonManager.h"
    68 #include "Shell.h"
    6970#include "TclBind.h"
    7071#include "TclThreadManager.h"
     
    7879    SetCommandLineArgument(settingsFile, "orxonox.ini").information("THE configuration file");
    7980#ifdef ORXONOX_PLATFORM_WINDOWS
    80     SetCommandLineArgument(limitToCPU, 0).information("Limits the program to one cpu/core (1, 2, 3, etc.). 0 turns it off (default)");
    81 #endif
    82 
    83     /**
    84     @brief
    85         Helper class for the Core singleton: we cannot derive
    86         Core from OrxonoxClass because we need to handle the Identifier
    87         destruction in the Core destructor.
    88     */
    89     class CoreConfiguration : public OrxonoxClass
    90     {
    91     public:
    92         CoreConfiguration()
    93         {
    94         }
    95 
    96         void initialise()
    97         {
    98             RegisterRootObject(CoreConfiguration);
    99             this->setConfigValues();
    100         }
    101 
    102         /**
    103             @brief Function to collect the SetConfigValue-macro calls.
    104         */
    105         void setConfigValues()
    106         {
    107 #ifdef NDEBUG
    108             const unsigned int defaultLevelConsole = 1;
    109             const unsigned int defaultLevelLogfile = 3;
    110             const unsigned int defaultLevelShell   = 1;
    111 #else
    112             const unsigned int defaultLevelConsole = 3;
    113             const unsigned int defaultLevelLogfile = 4;
    114             const unsigned int defaultLevelShell   = 3;
    115 #endif
    116             SetConfigValue(softDebugLevelConsole_, defaultLevelConsole)
    117                 .description("The maximal level of debug output shown in the console")
    118                 .callback(this, &CoreConfiguration::debugLevelChanged);
    119             SetConfigValue(softDebugLevelLogfile_, defaultLevelLogfile)
    120                 .description("The maximal level of debug output shown in the logfile")
    121                 .callback(this, &CoreConfiguration::debugLevelChanged);
    122             SetConfigValue(softDebugLevelShell_, defaultLevelShell)
    123                 .description("The maximal level of debug output shown in the ingame shell")
    124                 .callback(this, &CoreConfiguration::debugLevelChanged);
    125 
    126             SetConfigValue(language_, Language::getInstance().defaultLanguage_)
    127                 .description("The language of the ingame text")
    128                 .callback(this, &CoreConfiguration::languageChanged);
    129             SetConfigValue(bInitializeRandomNumberGenerator_, true)
    130                 .description("If true, all random actions are different each time you start the game")
    131                 .callback(this, &CoreConfiguration::initializeRandomNumberGenerator);
    132         }
    133 
    134         /**
    135             @brief Callback function if the debug level has changed.
    136         */
    137         void debugLevelChanged()
    138         {
    139             // softDebugLevel_ is the maximum of the 3 variables
    140             this->softDebugLevel_ = this->softDebugLevelConsole_;
    141             if (this->softDebugLevelLogfile_ > this->softDebugLevel_)
    142                 this->softDebugLevel_ = this->softDebugLevelLogfile_;
    143             if (this->softDebugLevelShell_ > this->softDebugLevel_)
    144                 this->softDebugLevel_ = this->softDebugLevelShell_;
    145 
    146             OutputHandler::setSoftDebugLevel(OutputHandler::LD_All,     this->softDebugLevel_);
    147             OutputHandler::setSoftDebugLevel(OutputHandler::LD_Console, this->softDebugLevelConsole_);
    148             OutputHandler::setSoftDebugLevel(OutputHandler::LD_Logfile, this->softDebugLevelLogfile_);
    149             OutputHandler::setSoftDebugLevel(OutputHandler::LD_Shell,   this->softDebugLevelShell_);
    150         }
    151 
    152         /**
    153             @brief Callback function if the language has changed.
    154         */
    155         void languageChanged()
    156         {
    157             // Read the translation file after the language was configured
    158             Language::getInstance().readTranslatedLanguageFile();
    159         }
    160 
    161         /**
    162             @brief Sets the language in the config-file back to the default.
    163         */
    164         void resetLanguage()
    165         {
    166             ResetConfigValue(language_);
    167         }
    168 
    169         void initializeRandomNumberGenerator()
    170         {
    171             static bool bInitialized = false;
    172             if (!bInitialized && this->bInitializeRandomNumberGenerator_)
    173             {
    174                 srand(static_cast<unsigned int>(time(0)));
    175                 rand();
    176                 bInitialized = true;
    177             }
    178         }
    179 
    180         int softDebugLevel_;                            //!< The debug level
    181         int softDebugLevelConsole_;                     //!< The debug level for the console
    182         int softDebugLevelLogfile_;                     //!< The debug level for the logfile
    183         int softDebugLevelShell_;                       //!< The debug level for the ingame shell
    184         std::string language_;                          //!< The language
    185         bool bInitializeRandomNumberGenerator_;         //!< If true, srand(time(0)) is called
    186     };
    187 
     81    SetCommandLineArgument(limitToCPU, 1).information("Limits the program to one CPU/core (1, 2, 3, etc.). Default is the first core (faster than off)");
     82#endif
    18883
    18984    Core::Core(const std::string& cmdLine)
     
    19287        // Cleanup guard for external console commands that don't belong to an Identifier
    19388        , consoleCommandDestroyer_(CommandExecutor::destroyExternalCommands)
    194         , configuration_(new CoreConfiguration()) // Don't yet create config values!
    19589        , bGraphicsLoaded_(false)
    19690    {
     
    216110
    217111        // Parse command line arguments AFTER the modules have been loaded (static code!)
    218         CommandLine::parseCommandLine(cmdLine);
     112        CommandLineParser::parseCommandLine(cmdLine);
    219113
    220114        // Set configurable paths like log, config and media
    221115        this->pathConfig_->setConfigurablePaths();
    222116
    223         // create a signal handler (only active for linux)
     117        // create a signal handler (only active for Linux)
    224118        // This call is placed as soon as possible, but after the directories are set
    225119        this->signalHandler_.reset(new SignalHandler());
    226120        this->signalHandler_->doCatch(PathConfig::getExecutablePathString(), PathConfig::getLogPathString() + "orxonox_crash.log");
    227121
    228         // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% was used
    229         OutputHandler::getOutStream().setLogPath(PathConfig::getLogPathString());
     122        // Set the correct log path. Before this call, /tmp (Unix) or %TEMP% (Windows) was used
     123        OutputHandler::getInstance().setLogPath(PathConfig::getLogPathString());
    230124
    231125        // Parse additional options file now that we know its path
    232         CommandLine::parseFile();
     126        CommandLineParser::parseFile();
    233127
    234128#ifdef ORXONOX_PLATFORM_WINDOWS
     
    236130        // do this after ogre has initialised. Somehow Ogre changes the settings again (not through
    237131        // the timer though).
    238         int limitToCPU = CommandLine::getValue("limitToCPU");
     132        int limitToCPU = CommandLineParser::getValue("limitToCPU");
    239133        if (limitToCPU > 0)
    240134            setThreadAffinity(static_cast<unsigned int>(limitToCPU));
     
    244138        this->configFileManager_.reset(new ConfigFileManager());
    245139        this->configFileManager_->setFilename(ConfigFileType::Settings,
    246             CommandLine::getValue("settingsFile").getString());
     140            CommandLineParser::getValue("settingsFile").getString());
    247141
    248142        // Required as well for the config values
    249143        this->languageInstance_.reset(new Language());
    250144
     145        // Do this soon after the ConfigFileManager has been created to open up the
     146        // possibility to configure everything below here
     147        ClassIdentifier<Core>::getIdentifier("Core")->initialiseObject(this, "Core", true);
     148        this->setConfigValues();
     149
     150        // create persistent io console
     151        this->ioConsole_.reset(new IOConsole());
     152
    251153        // creates the class hierarchy for all classes with factories
    252154        Identifier::createClassHierarchy();
    253 
    254         // Do this soon after the ConfigFileManager has been created to open up the
    255         // possibility to configure everything below here
    256         this->configuration_->initialise();
    257155
    258156        // Load OGRE excluding the renderer and the render window
     
    262160        this->tclBind_.reset(new TclBind(PathConfig::getDataPathString()));
    263161        this->tclThreadManager_.reset(new TclThreadManager(tclBind_->getTclInterpreter()));
    264 
    265         // create a shell
    266         this->shell_.reset(new Shell());
    267162
    268163        // Create singletons that always exist (in other libraries)
     
    276171    Core::~Core()
    277172    {
     173        // Remove us from the object lists again to avoid problems when destroying them
     174        this->unregisterObject();
     175    }
     176
     177    //! Function to collect the SetConfigValue-macro calls.
     178    void Core::setConfigValues()
     179    {
     180#ifdef ORXONOX_RELEASE
     181        const unsigned int defaultLevelLogFile = 3;
     182#else
     183        const unsigned int defaultLevelLogFile = 4;
     184#endif
     185        setConfigValueGeneric(this, &this->softDebugLevelLogFile_, ConfigFileType::Settings, "OutputHandler", "softDebugLevelLogFile", defaultLevelLogFile)
     186            .description("The maximum level of debug output shown in the log file");
     187        OutputHandler::getInstance().setSoftDebugLevel(OutputHandler::logFileOutputListenerName_s, this->softDebugLevelLogFile_);
     188
     189        SetConfigValue(language_, Language::getInstance().defaultLanguage_)
     190            .description("The language of the in game text")
     191            .callback(this, &Core::languageChanged);
     192        SetConfigValue(bInitRandomNumberGenerator_, true)
     193            .description("If true, all random actions are different each time you start the game")
     194            .callback(this, &Core::initRandomNumberGenerator);
     195    }
     196
     197    //! Callback function if the language has changed.
     198    void Core::languageChanged()
     199    {
     200        // Read the translation file after the language was configured
     201        Language::getInstance().readTranslatedLanguageFile();
     202    }
     203
     204    void Core::initRandomNumberGenerator()
     205    {
     206        static bool bInitialized = false;
     207        if (!bInitialized && this->bInitRandomNumberGenerator_)
     208        {
     209            srand(static_cast<unsigned int>(time(0)));
     210            rand();
     211            bInitialized = true;
     212        }
    278213    }
    279214
     
    327262    }
    328263
    329     /**
    330         @brief Returns the softDebugLevel for the given device (returns a default-value if the class is right about to be created).
    331         @param device The device
    332         @return The softDebugLevel
    333     */
    334     /*static*/ int Core::getSoftDebugLevel(OutputHandler::OutputDevice device)
    335     {
    336         switch (device)
    337         {
    338         case OutputHandler::LD_All:
    339             return Core::getInstance().configuration_->softDebugLevel_;
    340         case OutputHandler::LD_Console:
    341             return Core::getInstance().configuration_->softDebugLevelConsole_;
    342         case OutputHandler::LD_Logfile:
    343             return Core::getInstance().configuration_->softDebugLevelLogfile_;
    344         case OutputHandler::LD_Shell:
    345             return Core::getInstance().configuration_->softDebugLevelShell_;
    346         default:
    347             assert(0);
    348             return 2;
    349         }
    350     }
    351 
    352      /**
    353         @brief Sets the softDebugLevel for the given device. Please use this only temporary and restore the value afterwards, as it overrides the configured value.
    354         @param device The device
    355         @param level The level
    356     */
    357     /*static*/ void Core::setSoftDebugLevel(OutputHandler::OutputDevice device, int level)
    358     {
    359         if (device == OutputHandler::LD_All)
    360             Core::getInstance().configuration_->softDebugLevel_ = level;
    361         else if (device == OutputHandler::LD_Console)
    362             Core::getInstance().configuration_->softDebugLevelConsole_ = level;
    363         else if (device == OutputHandler::LD_Logfile)
    364             Core::getInstance().configuration_->softDebugLevelLogfile_ = level;
    365         else if (device == OutputHandler::LD_Shell)
    366             Core::getInstance().configuration_->softDebugLevelShell_ = level;
    367 
    368         OutputHandler::setSoftDebugLevel(device, level);
    369     }
    370 
    371     /**
    372         @brief Returns the configured language.
    373     */
    374     /*static*/ const std::string& Core::getLanguage()
    375     {
    376         return Core::getInstance().configuration_->language_;
    377     }
    378 
    379     /**
    380         @brief Sets the language in the config-file back to the default.
    381     */
    382     /*static*/ void Core::resetLanguage()
    383     {
    384         Core::getInstance().configuration_->resetLanguage();
     264    //! Sets the language in the config-file back to the default.
     265    void Core::resetLanguage()
     266    {
     267        ResetConfigValue(language_);
    385268    }
    386269
     
    433316    void Core::preUpdate(const Clock& time)
    434317    {
    435         // singletons from other libraries
    436         ScopedSingletonManager::update<ScopeID::Root>(time);
     318        // Update singletons before general ticking
     319        ScopedSingletonManager::preUpdate<ScopeID::Root>(time);
    437320        if (this->bGraphicsLoaded_)
    438321        {
    439             // process input events
    440             this->inputManager_->update(time);
    441             // process gui events
    442             this->guiManager_->update(time);
    443             // graphics singletons from other libraries
    444             ScopedSingletonManager::update<ScopeID::Graphics>(time);
    445         }
    446         // process thread commands
    447         this->tclThreadManager_->update(time);
     322            // Process input events
     323            this->inputManager_->preUpdate(time);
     324            // Update GUI
     325            this->guiManager_->preUpdate(time);
     326            // Update singletons before general ticking
     327            ScopedSingletonManager::preUpdate<ScopeID::Graphics>(time);
     328        }
     329        // Process console events and status line
     330        this->ioConsole_->preUpdate(time);
     331        // Process thread commands
     332        this->tclThreadManager_->preUpdate(time);
    448333    }
    449334
    450335    void Core::postUpdate(const Clock& time)
    451336    {
     337        // Update singletons just before rendering
     338        ScopedSingletonManager::postUpdate<ScopeID::Root>(time);
    452339        if (this->bGraphicsLoaded_)
    453340        {
     341            // Update singletons just before rendering
     342            ScopedSingletonManager::postUpdate<ScopeID::Graphics>(time);
    454343            // Render (doesn't throw)
    455             this->graphicsManager_->update(time);
     344            this->graphicsManager_->postUpdate(time);
    456345        }
    457346    }
  • code/branches/pickup2/src/libraries/core/Core.h

    r5929 r6412  
    3535#include <cassert>
    3636#include <boost/scoped_ptr.hpp>
    37 #include "util/OutputHandler.h"
    38 #include "util/Scope.h"
    3937#include "util/ScopeGuard.h"
    4038#include "util/Singleton.h"
     39#include "core/OrxonoxClass.h"
    4140
    4241namespace orxonox
    4342{
    44     class CoreConfiguration;
    45 
    4643    /**
    4744    @brief
     
    5047        You should only create this singleton once because it destroys the identifiers!
    5148    */
    52     class _CoreExport Core : public Singleton<Core>
     49    class _CoreExport Core : public Singleton<Core>, public OrxonoxClass
    5350    {
    5451        typedef Loki::ScopeGuardImpl0<void (*)()> SimpleScopeGuard;
     
    6966            void setConfigValues();
    7067
    71             static int   getSoftDebugLevel(OutputHandler::OutputDevice device = OutputHandler::LD_All);
    72             static void  setSoftDebugLevel(OutputHandler::OutputDevice device, int level);
    73             static const std::string& getLanguage();
    74             static void resetLanguage();
     68            //! Returns the configured language.
     69            const std::string& getLanguage()
     70                { return this->language_; }
     71            void resetLanguage();
    7572
    7673        private:
    7774            Core(const Core&); //!< Don't use (undefined symbol)
     75
     76            void languageChanged();
     77            void initRandomNumberGenerator();
    7878
    7979            void preUpdate(const Clock& time);
     
    8484
    8585            void setThreadAffinity(int limitToCPU);
    86 
     86            // MANAGED SINGLETONS/OBJECTS
    8787            // Mind the order for the destruction!
    8888            scoped_ptr<PathConfig>        pathConfig_;
     
    9393            scoped_ptr<ConfigFileManager> configFileManager_;
    9494            scoped_ptr<Language>          languageInstance_;
    95             scoped_ptr<CoreConfiguration> configuration_;
     95            scoped_ptr<IOConsole>         ioConsole_;
    9696            scoped_ptr<TclBind>           tclBind_;
    9797            scoped_ptr<TclThreadManager>  tclThreadManager_;
    98             scoped_ptr<Shell>             shell_;
     98            scoped_ptr<Scope<ScopeID::Root> >     rootScope_;
    9999            // graphical
    100100            scoped_ptr<GraphicsManager>   graphicsManager_;     //!< Interface to OGRE
    101101            scoped_ptr<InputManager>      inputManager_;        //!< Interface to OIS
    102102            scoped_ptr<GUIManager>        guiManager_;          //!< Interface to GUI
    103             scoped_ptr<Scope<ScopeID::Root> >     rootScope_;
    104103            scoped_ptr<Scope<ScopeID::Graphics> > graphicsScope_;
    105104
    106105            bool                          bGraphicsLoaded_;
    107             static Core* singletonPtr_s;
     106            int                           softDebugLevelLogFile_;      //!< The debug level for the log file (belongs to OutputHandler)
     107            std::string                   language_;                   //!< The language
     108            bool                          bInitRandomNumberGenerator_; //!< If true, srand(time(0)) is called
     109
     110            static Core*                  singletonPtr_s;
    108111    };
    109112}
  • code/branches/pickup2/src/libraries/core/CorePrereqs.h

    r5929 r6412  
    116116    class ClassTreeMaskObjectIterator;
    117117    class CommandEvaluation;
    118     class CommandLine;
     118    class CommandLineParser;
    119119    class CommandLineArgument;
    120120    class ConfigFile;
     
    148148    class GUIManager;
    149149    class Identifier;
     150    class IOConsole;
    150151    class IRC;
    151152    template <class T>
  • code/branches/pickup2/src/libraries/core/DynLib.cc

    r5750 r6412  
    7070        COUT(2) << "Loading module " << mName << std::endl;
    7171
    72                 std::string name = mName;
     72        const std::string& name = mName;
    7373#ifdef ORXONOX_PLATFORM_LINUX
    7474        // dlopen() does not add .so to the filename, like windows does for .dll
     
    9393
    9494        if( DYNLIB_UNLOAD( m_hInst ) )
    95                 {
     95        {
    9696            ThrowException(
    9797                General,
    9898                "Could not unload dynamic library " + mName +
    9999                ".  System Error: " + dynlibError());
    100                 }
     100        }
    101101
    102102    }
     
    132132        return std::string(mac_errorBundle());
    133133#else
    134         return std::string("");
     134        return "";
    135135#endif
    136136    }
  • code/branches/pickup2/src/libraries/core/DynLib.h

    r5738 r6412  
    7272            Resource
    7373    */
    74         class _CoreExport DynLib
     74    class _CoreExport DynLib
    7575    {
    76         protected:
    77                 std::string mName;
     76    protected:
     77        std::string mName;
    7878        /// Gets the last loading error
    7979        std::string dynlibError(void);
     
    9595        */
    9696        void unload();
    97                 /// Get the name of the library
    98                 const std::string& getName(void) const { return mName; }
     97        /// Get the name of the library
     98        const std::string& getName(void) const { return mName; }
    9999
    100100        /**
  • code/branches/pickup2/src/libraries/core/DynLibManager.cc

    r5738 r6412  
    4141
    4242    //-----------------------------------------------------------------------
    43         DynLibManager::DynLibManager()
    44         {
    45         }
    46         //-----------------------------------------------------------------------
     43    DynLibManager::DynLibManager()
     44    {
     45    }
     46    //-----------------------------------------------------------------------
    4747    DynLib* DynLibManager::load( const std::string& filename)
    4848    {
    49                 DynLibList::iterator i = mLibList.find(filename);
    50                 if (i != mLibList.end())
    51                 {
    52                         return i->second;
    53                 }
    54                 else
    55                 {
    56                 DynLib* pLib = new DynLib(filename);
    57                         pLib->load();
    58                 mLibList[filename] = pLib;
    59                 return pLib;
    60                 }
     49        DynLibList::iterator i = mLibList.find(filename);
     50        if (i != mLibList.end())
     51        {
     52            return i->second;
     53        }
     54        else
     55        {
     56            DynLib* pLib = new DynLib(filename);
     57            pLib->load();
     58            mLibList[filename] = pLib;
     59            return pLib;
     60        }
    6161    }
    62         //-----------------------------------------------------------------------
    63         void DynLibManager::unload(DynLib* lib)
    64         {
    65                 DynLibList::iterator i = mLibList.find(lib->getName());
    66                 if (i != mLibList.end())
    67                 {
    68                         mLibList.erase(i);
    69                 }
    70                 lib->unload();
    71                 delete lib;
    72         }
    73         //-----------------------------------------------------------------------
     62    //-----------------------------------------------------------------------
     63    void DynLibManager::unload(DynLib* lib)
     64    {
     65        DynLibList::iterator i = mLibList.find(lib->getName());
     66        if (i != mLibList.end())
     67        {
     68            mLibList.erase(i);
     69        }
     70        lib->unload();
     71        delete lib;
     72    }
     73    //-----------------------------------------------------------------------
    7474    DynLibManager::~DynLibManager()
    7575    {
  • code/branches/pickup2/src/libraries/core/Event.cc

    r5929 r6412  
    4545    /**
    4646        @brief Processes an event (calls the set-function if the necessary conditions are met).
    47        
     47
    4848        @param event     The fired event
    4949        @param object    The object whose state is affected by the event (only needed for debug output)
     
    5353        if (this->bProcessingEvent_)
    5454        {
    55             COUT(2) << "Warning: Detected Event loop in section \"" << event.statename_ << "\" of object \"" << object->getName() << "\" and fired by \"" << event.originator_->getName() << "\"" << std::endl;
     55            COUT(2) << "Warning: Detected Event loop in section \"" << event.statename_ << "\" of object \"" << object->getName() << "\" and fired by \"" << event.originator_->getName() << '"' << std::endl;
    5656            return;
    5757        }
  • code/branches/pickup2/src/libraries/core/Event.h

    r5929 r6412  
    5050    /**
    5151        @brief The EventState contains information about an event state.
    52        
     52
    5353        An event state is a state of an object, which can be changed by events.
    5454        Event states are changed through functions. Possible functions headers for set event states are:
     
    5656         - boolean state:    function(bool state)
    5757         - individual state: function(bool state, SomeClass originator)
    58          
     58
    5959        Note that SomeClass may be any class deriving from BaseObject. You will not receive events from originators of other classes.
    6060        The actual class for SomeClass must be specified as the second argument of the XMLPortEventState macro.
    61        
     61
    6262        The this pointer of the affected object is hidden in the functors, because the events are processed in the BaseObject, but some
    6363        statefunctions may be from child-classes.
     
    7070
    7171            void process(const Event& event, BaseObject* object);
    72            
     72
    7373            Functor* getFunctor() const
    7474                { return this->statefunction_; }
  • code/branches/pickup2/src/libraries/core/EventIncludes.h

    r5929 r6412  
    3636/**
    3737    @brief Defines a new event state (a state of the object which can be changed by events).
    38    
     38
    3939    @param classname    The name of this class
    4040    @param subclassname Usually BaseObject - if different, only instances of this class can send events to this object
     
    6666
    6767#define XMLPortEventStateIntern(name, classname, statename, xmlelement, mode) \
    68     static orxonox::ExecutorMember<classname>* xmlsetfunctor##name = (orxonox::ExecutorMember<classname>*)&orxonox::createExecutor(orxonox::createFunctor(&classname::addEventSource), std::string( #classname ) + "::" + "addEventSource" + "(" + statename + ")")->setDefaultValue(1, statename); \
    69     static orxonox::ExecutorMember<classname>* xmlgetfunctor##name = (orxonox::ExecutorMember<classname>*)&orxonox::createExecutor(orxonox::createFunctor(&classname::getEventSource), std::string( #classname ) + "::" + "getEventSource" + "(" + statename + ")")->setDefaultValue(1, statename); \
     68    static orxonox::ExecutorMember<classname>* xmlsetfunctor##name = (orxonox::ExecutorMember<classname>*)&orxonox::createExecutor(orxonox::createFunctor(&classname::addEventSource), std::string( #classname ) + "::" + "addEventSource" + '(' + statename + ')')->setDefaultValue(1, statename); \
     69    static orxonox::ExecutorMember<classname>* xmlgetfunctor##name = (orxonox::ExecutorMember<classname>*)&orxonox::createExecutor(orxonox::createFunctor(&classname::getEventSource), std::string( #classname ) + "::" + "getEventSource" + '(' + statename + ')')->setDefaultValue(1, statename); \
    7070    XMLPortObjectGeneric(xmlport##name, classname, orxonox::BaseObject, statename, xmlsetfunctor##name, xmlgetfunctor##name, xmlelement, mode, false, true)
    71    
     71
    7272
    7373/**
    7474    @brief Defines a new event name for a class. Named events can only have names which were defined with this macro.
    75    
     75
    7676    @param classname The name of the class
    7777    @param name      The name of the event
     
    8282/**
    8383    @brief This macro is needed to fire an event with this name. The event name must previously be declared with @ref CreateEventName.
    84 */   
     84*/
    8585#define FireEventName(classname, name) \
    8686    eventname##classname##name
    87  
     87
    8888#endif /* _EventIncludes_H__ */
  • code/branches/pickup2/src/libraries/core/Executor.cc

    r5738 r6412  
    7373        {
    7474            // only one param: check if there are params given, otherwise try to use default values
    75             std::string temp = getStripped(params);
    76             if ((temp != "") && (temp.size() != 0))
     75            if (!getStripped(params).empty())
    7776            {
    7877                param[0] = params;
  • code/branches/pickup2/src/libraries/core/Executor.h

    r5738 r6412  
    6363    else if (paramCount == 1) \
    6464    { \
    65         std::string temp = getStripped(params); \
    66         if ((temp != "") && (temp.size() != 0)) \
     65        const std::string& temp = getStripped(params); \
     66        if (!temp.empty()) \
    6767        { \
    6868            COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using whole string: " << params << std::endl; \
     
    187187                { return this->functor_->getTypenameReturnvalue(); }
    188188
    189             inline void setName(const std::string name)
     189            inline void setName(const std::string& name)
    190190                { this->name_ = name; }
    191191            inline const std::string& getName() const
  • code/branches/pickup2/src/libraries/core/Functor.h

    r5929 r6412  
    3535#include "util/Debug.h"
    3636#include "util/MultiType.h"
    37 #include "util/StringUtils.h"
    3837
    3938namespace orxonox
  • code/branches/pickup2/src/libraries/core/GUIManager.cc

    r5929 r6412  
    4040#include <CEGUIResourceProvider.h>
    4141#include <CEGUISystem.h>
     42#include <CEGUIWindow.h>
    4243#include <ogreceguirenderer/OgreCEGUIRenderer.h>
    4344
     
    5051
    5152#include "util/Clock.h"
     53#include "util/Convert.h"
    5254#include "util/Debug.h"
    5355#include "util/Exception.h"
    5456#include "util/OrxAssert.h"
     57#include "ConsoleCommand.h"
    5558#include "Core.h"
    5659#include "LuaState.h"
     
    6063namespace orxonox
    6164{
     65    static void key_esc()
     66        { GUIManager::getInstance().keyESC(); }
     67    SetConsoleCommandShortcutExternAlias(key_esc, "keyESC");
     68
    6269    class CEGUILogger : public CEGUI::DefaultLogger
    6370    {
     
    7582                default: OrxAssert(false, "CEGUI log level out of range, inpect immediately!");
    7683            }
    77             OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
     84            OutputHandler::getOutStream(orxonoxLevel)
    7885                << "CEGUI: " << message << std::endl;
    7986
     
    8592
    8693    GUIManager* GUIManager::singletonPtr_s = 0;
     94
     95    SetConsoleCommandShortcut(GUIManager, showGUI).accessLevel(AccessLevel::User).defaultValue(1, false).defaultValue(2, true);
     96    SetConsoleCommandShortcut(GUIManager, hideGUI).accessLevel(AccessLevel::User);
    8797
    8898    /**
     
    102112        , resourceProvider_(0)
    103113        , camera_(NULL)
     114        , bShowIngameGUI_(false)
    104115    {
    105116        using namespace CEGUI;
     
    114125        // setup scripting
    115126        luaState_.reset(new LuaState());
     127        rootFileInfo_ = Resource::getInfo("InitialiseGUI.lua");
     128        // This is necessary to ensure that input events also use the right resource info when triggering lua functions
     129        luaState_->setDefaultResourceInfo(this->rootFileInfo_);
    116130        scriptModule_.reset(new LuaScriptModule(luaState_->getInternalLuaState()));
    117131
     
    121135        // set the log level according to ours (translate by subtracting 1)
    122136        ceguiLogger->setLoggingLevel(
    123             static_cast<LoggingLevel>(Core::getSoftDebugLevel(OutputHandler::LD_Logfile) - 1));
     137            static_cast<LoggingLevel>(OutputHandler::getInstance().getSoftDebugLevel("logFile") - 1));
    124138        this->ceguiLogger_ = ceguiLogger.release();
    125139
     
    127141        guiSystem_.reset(new System(guiRenderer_.get(), resourceProvider_, 0, scriptModule_.get()));
    128142
    129         // Initialise the basic lua code
    130         rootFileInfo_ = Resource::getInfo("InitialiseGUI.lua", "GUI");
    131         this->luaState_->doFile("InitialiseGUI.lua", "GUI", false);
     143        // Initialise the basic Lua code
     144        this->luaState_->doFile("InitialiseGUI.lua");
    132145
    133146        // Align CEGUI mouse with OIS mouse
    134147        guiSystem_->injectMousePosition(mousePosition.first, mousePosition.second);
    135148
    136         // Hide the mouse cursor unless playing in fullscreen mode
     149        // Hide the mouse cursor unless playing in full screen mode
    137150        if (!bFullScreen)
    138151            CEGUI::MouseCursor::getSingleton().hide();
     
    157170        This time value is then used to provide a fluent animation of the GUI.
    158171    */
    159     void GUIManager::update(const Clock& time)
     172    void GUIManager::preUpdate(const Clock& time)
    160173    {
    161174        assert(guiSystem_);
     
    204217        For more details check out loadGUI_2.lua where the function presides.
    205218    */
    206     void GUIManager::showGUI(const std::string& name)
    207     {
    208         this->luaState_->doString("showGUI(\"" + name + "\")", rootFileInfo_);
     219    /*static*/ void GUIManager::showGUI(const std::string& name, bool hidePrevious, bool showCursor)
     220    {
     221        GUIManager::getInstance().executeCode("showGUI(\"" + name + "\", " + multi_cast<std::string>(hidePrevious) + ", " + multi_cast<std::string>(showCursor) + ")");
     222    }
     223
     224    /**
     225    @brief
     226        Hack-ish. Needed for GUIOverlay.
     227    */
     228    void GUIManager::showGUIExtra(const std::string& name, const std::string& ptr, bool hidePrevious, bool showCursor)
     229    {
     230        this->executeCode("showGUI(\"" + name + "\", " + multi_cast<std::string>(hidePrevious) + ", " + multi_cast<std::string>(showCursor) + ", " + ptr + ")");
     231    }
     232
     233    /**
     234    @brief
     235        Hides specified GUI.
     236    @param name
     237        The name of the GUI.
     238    */
     239    /*static*/ void GUIManager::hideGUI(const std::string& name)
     240    {
     241        GUIManager::getInstance().executeCode("hideGUI(\"" + name + "\")");
     242    }
     243
     244    void GUIManager::keyESC()
     245    {
     246        this->executeCode("keyESC()");
     247    }
     248
     249    void GUIManager::setBackground(const std::string& name)
     250    {
     251        this->executeCode("setBackground(\"" + name + "\")");
    209252    }
    210253
     
    280323        code of the mouse button as it is used by CEGUI
    281324
    282         Simple convertion from mouse event code in Orxonox to the one used in CEGUI.
     325        Simple conversion from mouse event code in Orxonox to the one used in CEGUI.
    283326     */
    284327    static inline CEGUI::MouseButton convertButton(MouseButtonCode::ByEnum button)
     
    305348        }
    306349    }
     350
     351    void GUIManager::subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function)
     352    {
     353        window->subscribeScriptedEvent(event, function);
     354    }
    307355}
  • code/branches/pickup2/src/libraries/core/GUIManager.h

    r5929 r6412  
    3434
    3535#include <map>
     36#include <set>
    3637#include <string>
    3738#include <CEGUIForwardRefs.h>
     
    4344#include "input/InputHandler.h"
    4445
    45 namespace orxonox
    46 {
     46namespace orxonox // tolua_export
     47{ // tolua_export
    4748    class PlayerInfo; // Forward declaration
    4849
     
    5859        Those input events are then injected into CEGUI in Lua.
    5960    */
    60     class _CoreExport GUIManager : public Singleton<GUIManager>, public InputHandler
    61     {
     61    class _CoreExport GUIManager // tolua_export
     62        : public Singleton<GUIManager>, public InputHandler
     63    { // tolua_export
    6264        friend class Singleton<GUIManager>;
    6365    public:
     
    6567        ~GUIManager();
    6668
    67         void update(const Clock& time);
     69        void preUpdate(const Clock& time);
    6870
    69         void showGUI(const std::string& name);
    70         void executeCode(const std::string& str);
     71        static void showGUI(const std::string& name, bool hidePrevious=false, bool showCursor=true);
     72        void showGUIExtra(const std::string& name, const std::string& ptr, bool hidePrevious=false, bool showCursor=true);
     73        static void hideGUI(const std::string& name);
     74        void keyESC();
     75        void setBackground(const std::string& name);
    7176
    7277        void setCamera(Ogre::Camera* camera);
     
    8085            { std::map<std::string, PlayerInfo*>::const_iterator it = this->players_.find(guiname); return (it != this->players_.end()) ? it->second : 0; }
    8186
     87        // TODO: Temporary hack because the tolua exported CEGUI method does not seem to work
     88        static void subscribeEventHelper(CEGUI::Window* window, const std::string& event, const std::string& function); //tolua_export
     89
    8290    private:
    8391        GUIManager(const GUIManager& instance); //!< private and undefined copy c'tor (this is a singleton class)
     92
     93        void executeCode(const std::string& str);
    8494
    8595        // keyHandler functions
     
    105115
    106116        static GUIManager*                   singletonPtr_s;    //!< Singleton reference to GUIManager
     117        bool                                 bShowIngameGUI_;
    107118
    108     };
    109 }
     119    }; // tolua_export
     120} // tolua_export
    110121
    111122#endif /* _GUIManager_H__ */
  • code/branches/pickup2/src/libraries/core/Game.cc

    r5929 r6412  
    4444#include "util/Sleep.h"
    4545#include "util/SubString.h"
    46 #include "CommandLine.h"
     46#include "CommandLineParser.h"
    4747#include "ConsoleCommand.h"
    4848#include "Core.h"
     
    5151#include "GameMode.h"
    5252#include "GameState.h"
     53#include "GUIManager.h"
    5354
    5455namespace orxonox
     
    6768    Game* Game::singletonPtr_s = 0;
    6869
    69 
    70     /**
    71     @brief
    72         Represents one node of the game state tree.
    73     */
     70    //! Represents one node of the game state tree.
    7471    struct GameStateTreeNode
    7572    {
     
    7976    };
    8077
    81 
    82     /**
    83     @brief
    84         Another helper class for the Game singleton: we cannot derive
    85         Game from OrxonoxClass because we need to handle the Identifier
    86         destruction in the Core destructor.
    87     */
    88     class GameConfiguration : public OrxonoxClass
    89     {
    90     public:
    91         GameConfiguration()
    92         {
    93             RegisterRootObject(GameConfiguration);
    94             this->setConfigValues();
    95         }
    96 
    97         void setConfigValues()
    98         {
    99             SetConfigValue(statisticsRefreshCycle_, 250000)
    100                 .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
    101             SetConfigValue(statisticsAvgLength_, 1000000)
    102                 .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
    103             SetConfigValue(fpsLimit_, 50)
    104                 .description("Sets the desired framerate (0 for no limit).");
    105         }
    106 
    107         unsigned int statisticsRefreshCycle_;
    108         unsigned int statisticsAvgLength_;
    109         unsigned int fpsLimit_;
    110     };
    111 
    112 
    113     /**
    114     @brief
    115         Non-initialising constructor.
    116     */
    11778    Game::Game(const std::string& cmdLine)
    11879        // Destroy factories before the Core!
     
    12889#endif
    12990
     91        // reset statistics
     92        this->statisticsStartTime_ = 0;
     93        this->statisticsTickTimes_.clear();
     94        this->periodTickTime_ = 0;
     95        this->periodTime_ = 0;
     96        this->avgFPS_ = 0.0f;
     97        this->avgTickTime_ = 0.0f;
     98        this->excessSleepTime_ = 0;
     99
    130100        // Create an empty root state
    131101        this->declareGameState<GameState>("GameState", "emptyRootGameState", true, false);
     
    136106        // Create the Core
    137107        this->core_.reset(new Core(cmdLine));
     108
     109        // Do this after the Core creation!
     110        ClassIdentifier<Game>::getIdentifier("Game")->initialiseObject(this, "Game", true);
     111        this->setConfigValues();
    138112
    139113        // After the core has been created, we can safely instantiate the GameStates that don't require graphics
     
    150124        this->loadedTopStateNode_ = this->rootStateNode_;
    151125        this->loadedStates_.push_back(this->getState(rootStateNode_->name_));
    152 
    153         // Do this after the Core creation!
    154         this->configuration_.reset(new GameConfiguration());
    155126    }
    156127
     
    161132    Game::~Game()
    162133    {
     134        // Remove us from the object lists again to avoid problems when destroying them
     135        this->unregisterObject();
     136    }
     137
     138    void Game::setConfigValues()
     139    {
     140        SetConfigValue(statisticsRefreshCycle_, 250000)
     141            .description("Sets the time in microseconds interval at which average fps, etc. get updated.");
     142        SetConfigValue(statisticsAvgLength_, 1000000)
     143            .description("Sets the time in microseconds interval at which average fps, etc. gets calculated.");
     144        SetConfigValue(fpsLimit_, 50)
     145            .description("Sets the desired frame rate (0 for no limit).");
    163146    }
    164147
     
    176159            COUT(0) << "Warning: Starting game without requesting GameState. This automatically terminates the program." << std::endl;
    177160
    178         // reset statistics
    179         this->statisticsStartTime_ = 0;
    180         this->statisticsTickTimes_.clear();
    181         this->periodTickTime_ = 0;
    182         this->periodTime_ = 0;
    183         this->avgFPS_ = 0.0f;
    184         this->avgTickTime_ = 0.0f;
    185         this->excessSleepTime_ = 0;
    186 
    187161        // START GAME
    188162        // first delta time should be about 0 seconds
     
    204178            this->updateGameStateStack();
    205179
    206             // Core preUpdate (doesn't throw)
     180            // Core preUpdate
    207181            try
    208182                { this->core_->preUpdate(*this->gameClock_); }
     
    218192            this->updateGameStates();
    219193
    220             // Core postUpdate (doesn't throw)
     194            // Core postUpdate
    221195            try
    222196                { this->core_->postUpdate(*this->gameClock_); }
     
    232206            this->updateStatistics();
    233207
    234             // Limit framerate
     208            // Limit frame rate
    235209            this->updateFPSLimiter();
    236210        }
     
    312286        this->statisticsTickTimes_.back().tickLength += currentRealTime - currentTime;
    313287        this->periodTickTime_ += currentRealTime - currentTime;
    314         if (this->periodTime_ > this->configuration_->statisticsRefreshCycle_)
     288        if (this->periodTime_ > this->statisticsRefreshCycle_)
    315289        {
    316290            std::list<StatisticsTickInfo>::iterator it = this->statisticsTickTimes_.begin();
    317291            assert(it != this->statisticsTickTimes_.end());
    318             int64_t lastTime = currentTime - this->configuration_->statisticsAvgLength_;
     292            int64_t lastTime = currentTime - this->statisticsAvgLength_;
    319293            if (static_cast<int64_t>(it->tickTime) < lastTime)
    320294            {
     
    330304
    331305            uint32_t framesPerPeriod = this->statisticsTickTimes_.size();
    332             this->avgFPS_ = static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
     306            // Why minus 1? No idea, but otherwise the fps rate is always (from 10 to 200!) one frame too low
     307            this->avgFPS_ = -1 + static_cast<float>(framesPerPeriod) / (currentTime - this->statisticsTickTimes_.front().tickTime) * 1000000.0f;
    333308            this->avgTickTime_ = static_cast<float>(this->periodTickTime_) / framesPerPeriod / 1000.0f;
    334309
    335             this->periodTime_ -= this->configuration_->statisticsRefreshCycle_;
     310            this->periodTime_ -= this->statisticsRefreshCycle_;
    336311        }
    337312    }
     
    339314    void Game::updateFPSLimiter()
    340315    {
    341         // Why configuration_->fpsLimit_ - 1? No idea, but otherwise the fps rate is always (from 10 to 200!) one frame too high
    342         uint32_t nextTime = gameClock_->getMicroseconds() - excessSleepTime_ + static_cast<uint32_t>(1000000.0f / (configuration_->fpsLimit_ - 1));
     316        uint64_t nextTime = gameClock_->getMicroseconds() - excessSleepTime_ + static_cast<uint32_t>(1000000.0f / fpsLimit_);
    343317        uint64_t currentRealTime = gameClock_->getRealMicroseconds();
    344318        while (currentRealTime < nextTime - minimumSleepTime_)
     
    584558
    585559        shared_ptr<GameState> state = this->getState(name);
    586         state->activate();
     560        state->activateInternal();
    587561        if (!this->loadedStates_.empty())
    588562            this->loadedStates_.back()->activity_.topState = false;
     
    603577            if (!this->loadedStates_.empty())
    604578                this->loadedStates_.back()->activity_.topState = true;
    605             state->deactivate();
     579            state->deactivateInternal();
    606580        }
    607581        catch (...)
  • code/branches/pickup2/src/libraries/core/Game.h

    r5929 r6412  
    5050#include "util/ScopeGuard.h"
    5151#include "util/Singleton.h"
     52#include "core/OrxonoxClass.h"
    5253
    5354/**
     
    5859#define DeclareGameState(className, stateName, bIgnoreTickTime, bGraphicsMode) \
    5960    static bool BOOST_PP_CAT(bGameStateDummy_##className, __LINE__) = orxonox::Game::declareGameState<className>(#className, stateName, bIgnoreTickTime, bGraphicsMode)
    60 
     61// tolua_begin
    6162namespace orxonox
    6263{
    63     class GameConfiguration;
     64// tolua_end
    6465
    6566    //! Helper object required before GameStates are being constructed
     
    7879        You should only create this singleton once because it owns the Core class! (see remark there)
    7980    */
    80     class _CoreExport Game : public Singleton<Game>
    81     {
     81// tolua_begin
     82    class _CoreExport Game
     83// tolua_end
     84        : public Singleton<Game>, public OrxonoxClass
     85    { // tolua_export
    8286        friend class Singleton<Game>;
    8387        typedef std::vector<shared_ptr<GameState> > GameStateVector;
     
    8993        ~Game();
    9094
     95        void setConfigValues();
     96
    9197        void setStateHierarchy(const std::string& str);
    9298        shared_ptr<GameState> getState(const std::string& name);
     
    95101        void stop();
    96102
    97         void requestState(const std::string& name);
    98         void requestStates(const std::string& names);
    99         void popState();
     103        static Game& getInstance(){ return Singleton<Game>::getInstance(); } // tolua_export
     104
     105        void requestState(const std::string& name); //tolua_export
     106        void requestStates(const std::string& names); //tolua_export
     107        void popState(); //tolua_export
    100108
    101109        const Clock& getGameClock() { return *this->gameClock_; }
     
    160168        scoped_ptr<Core>                   core_;
    161169        ObjScopeGuard                      gsFactoryDestroyer_;
    162         scoped_ptr<GameConfiguration>      configuration_;
    163170
    164171        GameStateMap                       constructedStates_;
     
    181188        unsigned int                       minimumSleepTime_;
    182189
     190        // config values
     191        unsigned int                       statisticsRefreshCycle_;
     192        unsigned int                       statisticsAvgLength_;
     193        unsigned int                       fpsLimit_;
     194
    183195        static std::map<std::string, GameStateInfo> gameStateDeclarations_s;
    184196        static Game* singletonPtr_s;        //!< Pointer to the Singleton
    185     };
     197    }; //tolua_export
    186198
    187199    template <class T>
     
    209221        return true;
    210222    }
    211 }
     223} //tolua_export
    212224
    213225#endif /* _Game_H__ */
  • code/branches/pickup2/src/libraries/core/GameMode.h

    r5929 r6412  
    3737#include "CorePrereqs.h"
    3838
     39// tolua_begin
    3940namespace orxonox
    4041{
    4142    class _CoreExport GameMode
    4243    {
     44// tolua_end
    4345        friend class Core;
    4446
    4547        public:
     48// tolua_begin
    4649            static bool showsGraphics() { return bShowsGraphics_s; }
    4750            static bool playsSound()    { return bPlaysSound_s; }
     
    5053            static bool isStandalone()  { return bIsStandalone_s; }
    5154            static bool isMaster()      { return bIsMaster_s; }
     55// tolua_end
    5256
    5357            static void setPlaysSound   (bool val) { bPlaysSound_s    = val; }
     
    7276            static bool bIsStandalone_s;
    7377            static bool bIsMaster_s;
    74     };
    75 }
     78    }; // tolua_export
     79} // tolua_export
    7680
    7781#endif /* _GameMode_H__ */
  • code/branches/pickup2/src/libraries/core/GameState.cc

    r5738 r6412  
    8383        this->activity_.active = false;
    8484        this->activity_.deactivating = true;
    85         this->activate();
     85        this->deactivate();
    8686        this->activity_.deactivating = false;
    8787        this->activity_.suspended = false;
  • code/branches/pickup2/src/libraries/core/GraphicsManager.cc

    r5929 r6412  
    9898        // Ogre setup procedure (creating Ogre::Root)
    9999        this->loadOgreRoot();
    100         // load all the required plugins for Ogre
    101         this->loadOgrePlugins();
    102100
    103101        // At first, add the root paths of the data directories as resource locations
    104         Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getDataPathString(), "FileSystem", "dataRoot", false);
     102        Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getDataPathString(), "FileSystem");
    105103        // Load resources
    106         resources_.reset(new XMLFile("resources.oxr", "dataRoot"));
     104        resources_.reset(new XMLFile("DefaultResources.oxr"));
    107105        resources_->setLuaSupport(false);
    108106        Loader::open(resources_.get());
     
    111109        if (PathConfig::isDevelopmentRun())
    112110        {
    113             Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getExternalDataPathString(), "FileSystem", "externalDataRoot", false);
    114             extResources_.reset(new XMLFile("resources.oxr", "externalDataRoot"));
     111            Ogre::ResourceGroupManager::getSingleton().addResourceLocation(PathConfig::getExternalDataPathString(), "FileSystem");
     112            extResources_.reset(new XMLFile("resources.oxr"));
    115113            extResources_->setLuaSupport(false);
    116114            Loader::open(extResources_.get());
     
    171169        if (renderWindow_ != NULL)
    172170            return;
     171
     172        // load all the required plugins for Ogre
     173        this->loadOgrePlugins();
    173174
    174175        this->loadRenderer();
     
    207208                shared_array<char> data(new char[output.str().size()]);
    208209                // Debug optimisations
    209                 const std::string outputStr = output.str();
     210                const std::string& outputStr = output.str();
    210211                char* rawData = data.get();
    211212                for (unsigned i = 0; i < outputStr.size(); ++i)
     
    237238        COUT(3) << "Setting up Ogre..." << std::endl;
    238239
    239         if (ogreConfigFile_ == "")
     240        if (ogreConfigFile_.empty())
    240241        {
    241242            COUT(2) << "Warning: Ogre config file set to \"\". Defaulting to config.cfg" << std::endl;
    242243            ModifyConfigValue(ogreConfigFile_, tset, "config.cfg");
    243244        }
    244         if (ogreLogFile_ == "")
     245        if (ogreLogFile_.empty())
    245246        {
    246247            COUT(2) << "Warning: Ogre log file set to \"\". Defaulting to ogre.log" << std::endl;
     
    284285    {
    285286        // just to make sure the next statement doesn't segfault
    286         if (ogrePluginsDirectory_ == "")
    287             ogrePluginsDirectory_ = ".";
     287        if (ogrePluginsDirectory_.empty())
     288            ogrePluginsDirectory_ = '.';
    288289
    289290        boost::filesystem::path folder(ogrePluginsDirectory_);
     
    340341        need the time. So we shouldn't run into problems.
    341342    */
    342     void GraphicsManager::update(const Clock& time)
     343    void GraphicsManager::postUpdate(const Clock& time)
    343344    {
    344345        Ogre::FrameEvent evt;
     
    394395    {
    395396        int orxonoxLevel;
    396         switch (lml)
    397         {
    398         case Ogre::LML_TRIVIAL:
    399             orxonoxLevel = this->ogreLogLevelTrivial_;
    400             break;
    401         case Ogre::LML_NORMAL:
    402             orxonoxLevel = this->ogreLogLevelNormal_;
    403             break;
    404         case Ogre::LML_CRITICAL:
    405             orxonoxLevel = this->ogreLogLevelCritical_;
    406             break;
    407         default:
    408             orxonoxLevel = 0;
    409         }
    410         OutputHandler::getOutStream().setOutputLevel(orxonoxLevel)
    411             << "Ogre: " << message << std::endl;
     397        std::string introduction;
     398        // Do not show caught OGRE exceptions in front
     399        if (message.find("EXCEPTION") != std::string::npos)
     400        {
     401            orxonoxLevel = OutputLevel::Debug;
     402            introduction = "Ogre, caught exception: ";
     403        }
     404        else
     405        {
     406            switch (lml)
     407            {
     408            case Ogre::LML_TRIVIAL:
     409                orxonoxLevel = this->ogreLogLevelTrivial_;
     410                break;
     411            case Ogre::LML_NORMAL:
     412                orxonoxLevel = this->ogreLogLevelNormal_;
     413                break;
     414            case Ogre::LML_CRITICAL:
     415                orxonoxLevel = this->ogreLogLevelCritical_;
     416                break;
     417            default:
     418                orxonoxLevel = 0;
     419            }
     420            introduction = "Ogre: ";
     421        }
     422        OutputHandler::getOutStream(orxonoxLevel)
     423            << introduction << message << std::endl;
    412424    }
    413425
     
    439451    {
    440452        assert(this->renderWindow_);
    441        
    442         this->renderWindow_->writeContentsToTimestampedFile(PathConfig::getLogPathString() + "screenShot_", ".jpg");
     453        this->renderWindow_->writeContentsToTimestampedFile(PathConfig::getLogPathString() + "screenShot_", ".png");
    443454    }
    444455}
  • code/branches/pickup2/src/libraries/core/GraphicsManager.h

    r5929 r6412  
    6363        void setConfigValues();
    6464
    65         void update(const Clock& time);
     65        void postUpdate(const Clock& time);
    6666
    6767        Ogre::Viewport* getViewport()         { return this->viewport_; }
     
    106106
    107107        // config values
    108         std::string         ogreConfigFile_;           //!< ogre config file name
     108        std::string         ogreConfigFile_;           //!< ogre config filename
    109109        std::string         ogrePluginsDirectory_;     //!< Directory where the Ogre plugins are located
    110110        std::string         ogrePlugins_;              //!< Comma separated list of all plugins to load
    111         std::string         ogreLogFile_;              //!< log file name for Ogre log messages
    112         int                 ogreLogLevelTrivial_;      //!< Corresponding Orxonx debug level for LL_TRIVIAL
    113         int                 ogreLogLevelNormal_;       //!< Corresponding Orxonx debug level for LL_NORMAL
    114         int                 ogreLogLevelCritical_;     //!< Corresponding Orxonx debug level for LL_CRITICAL
     111        std::string         ogreLogFile_;              //!< log filename for Ogre log messages
     112        int                 ogreLogLevelTrivial_;      //!< Corresponding Orxonox debug level for LL_TRIVIAL
     113        int                 ogreLogLevelNormal_;       //!< Corresponding Orxonox debug level for LL_NORMAL
     114        int                 ogreLogLevelCritical_;     //!< Corresponding Orxonox debug level for LL_CRITICAL
    115115
    116116        // console commands
  • code/branches/pickup2/src/libraries/core/IOConsole.cc

    r6105 r6412  
    3232#include <iomanip>
    3333#include <iostream>
     34
     35#include "util/Clock.h"
     36#include "util/Math.h"
    3437#include "core/Game.h"
    3538#include "core/input/InputBuffer.h"
     
    4245    IOConsole* IOConsole::singletonPtr_s = NULL;
    4346
    44     int IOConsole::extractLogLevel(std::string* text)
    45     {
    46         // Handle line colouring by inspecting the first letter
    47         char level = 0;
    48         if (!text->empty())
    49         {
    50             level = (*text)[0];
    51             if (level == -1 || level >= 1 && level <= 6)
    52             {
    53                 *text = text->substr(1);
    54                 if (level != -1)
    55                     return level;
    56             }
    57         }
    58         return 0;
    59     }
    60 
    61     inline bool IOConsole::willPrintStatusLines()
    62     {
    63         return !this->statusLineWidths_.empty()
    64              && this->terminalWidth_  >= this->statusLineMaxWidth_
    65              && this->terminalHeight_ >= (this->minOutputLines_ + this->statusLineWidths_.size());
    66     }
    67 
    6847    // ###############################
    6948    // ###  ShellListener methods  ###
     
    7857    }
    7958
    80     //! Called if the text in the input-line has changed
    81     void IOConsole::inputChanged()
    82     {
    83         this->printInputLine();
    84         this->cout_.flush();
    85     }
    86 
    87     //! Called if the position of the cursor in the input-line has changed
    88     void IOConsole::cursorChanged()
    89     {
    90         this->printInputLine();
    91         this->cout_.flush();
    92     }
    93 
    9459    //! Called if a command is about to be executed
    9560    void IOConsole::executed()
    9661    {
    97         this->shell_->addOutputLine(this->promptString_ + this->shell_->getInput());
     62        this->shell_->addOutput(this->promptString_ + this->shell_->getInput() + '\n', Shell::Command);
    9863    }
    9964
     
    12691
    12792    IOConsole::IOConsole()
    128         : shell_(new Shell("IOConsole", false, true))
     93        : shell_(new Shell("IOConsole", false))
    12994        , buffer_(shell_->getInputBuffer())
    13095        , cout_(std::cout.rdbuf())
     96        , promptString_("orxonox # ")
    13197        , bStatusPrinted_(false)
    132         , promptString_("orxonox # ")
    133         , originalTerminalSettings_(new termios())
     98        , originalTerminalSettings_(0)
    13499    {
    135100        this->setTerminalMode();
     
    151116
    152117        // Make sure we make way for the status lines
    153         this->update(Game::getInstance().getGameClock());
     118        this->preUpdate(Game::getInstance().getGameClock());
    154119    }
    155120
    156121    IOConsole::~IOConsole()
    157122    {
    158         // Empty all buffers
    159         this->update(Game::getInstance().getGameClock());
     123        // Process output written to std::cout in the meantime
     124        std::cout.flush();
     125        if (!this->origCout_.str().empty())
     126            this->shell_->addOutput(this->origCout_.str(), Shell::None);
    160127        // Erase input and status lines
    161128        this->cout_ << "\033[1G\033[J";
     
    166133
    167134        resetTerminalMode();
    168         delete this->originalTerminalSettings_;
    169135        this->shell_->destroy();
    170136
     
    175141    }
    176142
    177     void IOConsole::update(const Clock& time)
     143    void IOConsole::preUpdate(const Clock& time)
    178144    {
    179145        unsigned char c;
     
    284250        }
    285251
    286         // We always assume that the cursor is on the inputline.
     252        // We always assume that the cursor is on the input line.
    287253        // But we cannot always be sure about that, esp. if we scroll the console
    288254        this->cout_ << "\033[" << this->statusLineWidths_.size() << 'B';
     
    296262
    297263        // Process output written to std::cout
     264        std::cout.flush();
    298265        if (!this->origCout_.str().empty())
    299266        {
    300             this->shell_->addOutputLine(this->origCout_.str());
     267            this->shell_->addOutput(this->origCout_.str(), Shell::None);
    301268            this->origCout_.str("");
    302269        }
    303270    }
    304271
    305     void IOConsole::printLogText(const std::string& text)
    306     {
    307         std::string output = text;
    308         /*int level =*/ this->extractLogLevel(&output);
    309 
     272    void IOConsole::printOutputLine(const std::string& text, Shell::LineType type)
     273    {
    310274/*
    311275        // Colour line
    312         switch (level)
    313         {
    314         case -1: this->cout_ << "\033[37m"; break;
    315         case  1: this->cout_ << "\033[91m"; break;
    316         case  2: this->cout_ << "\033[31m"; break;
    317         case  3: this->cout_ << "\033[34m"; break;
    318         case  4: this->cout_ << "\033[36m"; break;
    319         case  5: this->cout_ << "\033[35m"; break;
    320         case  6: this->cout_ << "\033[37m"; break;
     276        switch (type)
     277        {
     278        case Shell::None:    this->cout_ << "\033[37m"; break;
     279        case Shell::Error:  this->cout_ << "\033[91m"; break;
     280        case Shell::Warning: this->cout_ << "\033[31m"; break;
     281        case Shell::Info:    this->cout_ << "\033[34m"; break;
     282        case Shell::Debug:  this->cout_ << "\033[36m"; break;
     283        case Shell::Verbose: this->cout_ << "\033[35m"; break;
     284        case Shell::Ultra:  this->cout_ << "\033[37m"; break;
    321285        default: break;
    322286        }
     
    324288
    325289        // Print output line
    326         this->cout_ << output;
     290        this->cout_ << text;
    327291
    328292        // Reset colour to white
     
    343307        this->cout_ << "\033[u";
    344308        if (this->buffer_->getCursorPosition() > 0)
    345             this->cout_ << "\033[" << this->buffer_->getCursorPosition() << "C";
     309            this->cout_ << "\033[" << this->buffer_->getCursorPosition() << 'C';
    346310    }
    347311
     
    367331    {
    368332        termios new_settings;
     333        this->originalTerminalSettings_ = new termios();
    369334
    370335        tcgetattr(0, this->originalTerminalSettings_);
     
    375340        new_settings.c_cc[VMIN]  = 0;
    376341        tcsetattr(0, TCSANOW, &new_settings);
    377     }
    378 
    379     void IOConsole::resetTerminalMode()
    380     {
    381         tcsetattr(0, TCSANOW, IOConsole::originalTerminalSettings_);
     342        atexit(&IOConsole::resetTerminalMode);
     343    }
     344
     345    /*static*/ void IOConsole::resetTerminalMode()
     346    {
     347        if(IOConsole::singletonPtr_s && IOConsole::singletonPtr_s->originalTerminalSettings_)
     348        {
     349            tcsetattr(0, TCSANOW, IOConsole::singletonPtr_s->originalTerminalSettings_);
     350            delete IOConsole::singletonPtr_s->originalTerminalSettings_;
     351            IOConsole::singletonPtr_s->originalTerminalSettings_ = 0;
     352        }
    382353    }
    383354
     
    411382    }
    412383
     384    inline bool IOConsole::willPrintStatusLines()
     385    {
     386        return !this->statusLineWidths_.empty()
     387             && this->terminalWidth_  >= this->statusLineMaxWidth_
     388             && this->terminalHeight_ >= this->minOutputLines_ + (int)this->statusLineWidths_.size();
     389    }
     390
    413391    // ###############################
    414392    // ###  ShellListener methods  ###
     
    423401        this->cout_ << "\033[K";
    424402        // Reprint the last output line
    425         this->printLogText(*(this->shell_->getNewestLineIterator()));
     403        this->printOutputLine(this->shell_->getNewestLineIterator()->first, this->shell_->getNewestLineIterator()->second);
    426404        // Restore cursor
    427405        this->cout_ << "\033[u";
     
    432410    void IOConsole::lineAdded()
    433411    {
    434         int newLines = this->shell_->getNewestLineIterator()->size() / this->terminalWidth_ + 1;
     412        int newLines = this->shell_->getNewestLineIterator()->first.size() / this->terminalWidth_ + 1;
    435413        // Create new lines by scrolling the screen
    436414        this->cout_ << "\033[" << newLines << 'S';
     
    441419        // Print the new output lines
    442420        for (int i = 0; i < newLines; ++i)
    443             this->printLogText(this->shell_->getNewestLineIterator()->substr(i*this->terminalWidth_, this->terminalWidth_));
     421        {
     422            Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
     423            this->printOutputLine(it->first.substr(i*this->terminalWidth_, this->terminalWidth_), it->second);
     424        }
    444425        // Move cursor down
    445426        this->cout_ << "\033[1B\033[1G";
     
    449430        this->cout_.flush();
    450431    }
     432
     433    //! Called if the text in the input-line has changed
     434    void IOConsole::inputChanged()
     435    {
     436        this->printInputLine();
     437        this->cout_.flush();
     438    }
     439
     440    //! Called if the position of the cursor in the input-line has changed
     441    void IOConsole::cursorChanged()
     442    {
     443        this->printInputLine();
     444        this->cout_.flush();
     445    }
    451446}
    452447
     
    456451// ##################################
    457452
     453#include <windows.h>
     454
    458455namespace orxonox
    459456{
     457    //! Redirects std::cout, creates the corresponding Shell and changes the terminal mode
    460458    IOConsole::IOConsole()
    461         : shell_(new Shell("IOConsole", false, true))
     459        : shell_(new Shell("IOConsole", false))
    462460        , buffer_(shell_->getInputBuffer())
    463461        , cout_(std::cout.rdbuf())
    464         , bStatusPrinted_(false)
    465462        , promptString_("orxonox # ")
    466     {
     463        , inputLineHeight_(1)
     464        , statusLines_(1)
     465        , lastOutputLineHeight_(0)
     466    {
     467        // Disable standard this->cout_ logging
     468        OutputHandler::getInstance().disableCout();
     469        // Redirect std::cout to an ostringstream
     470        // (Other part is in the initialiser list)
     471        std::cout.rdbuf(this->origCout_.rdbuf());
     472
     473        this->setTerminalMode();
     474        CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
     475        GetConsoleScreenBufferInfo(this->stdOutHandle_, &screenBufferInfo);
     476        this->terminalWidth_  = screenBufferInfo.dwSize.X;
     477        this->terminalHeight_ = screenBufferInfo.dwSize.Y;
     478        // Determines where we are in respect to output already written with std::cout
     479        this->inputLineRow_ = screenBufferInfo.dwCursorPosition.Y;
    467480/*
    468         this->setTerminalMode();
     481        this->lastTerminalWidth_  = this->terminalWidth_;
     482        this->lastTerminalHeight_ = this->terminalHeight_;
     483*/
     484
     485        // Cursor already at the end of the screen buffer?
     486        // (assuming the current input line height is 1)
     487        if (this->inputLineRow_ >= this->terminalHeight_ - this->statusLines_)
     488            SetConsoleCursorPosition(this->stdOutHandle_, makeCOORD(0, this->terminalHeight_ - this->statusLines_));
     489
     490        // Prevent input line from overflowing
     491        int maxInputLength = (this->terminalHeight_ - this->statusLines_) * this->terminalWidth_ - 1 - this->promptString_.size();
     492        // Consider that the echo of a command might include the command plus some other characters (assumed max 80)
     493        // Also put a minimum so the config file parser is not overwhelmed with the command history
     494        this->buffer_->setMaxLength(std::min(8192, (maxInputLength - 80) / 2));
     495
     496        // Print input and status line and position cursor
     497        this->inputChanged();
     498        this->cursorChanged();
     499        this->lastRefreshTime_ = Game::getInstance().getGameClock().getRealMicroseconds();
     500        this->preUpdate(Game::getInstance().getGameClock());
     501
    469502        this->shell_->registerListener(this);
    470 
    471         // Manually set the widths of the individual status lines
    472         this->statusLineWidths_.push_back(29);
    473         this->statusLineMaxWidth_ = 29;
    474 
    475         this->getTerminalSize();
     503    }
     504
     505    //! Resets std::cout redirection and restores the terminal mode
     506    IOConsole::~IOConsole()
     507    {
     508        // Process output written to std::cout in the meantime
     509        std::cout.flush();
     510        if (!this->origCout_.str().empty())
     511            this->shell_->addOutput(this->origCout_.str(), Shell::None);
     512
     513        this->shell_->unregisterListener(this);
     514
     515        // Erase input and status lines
     516        COORD pos = {0, this->inputLineRow_};
     517        this->writeText(std::string((this->inputLineHeight_ + this->statusLines_) * this->terminalWidth_, ' '), pos);
     518        // Move cursor to the beginning of the line
     519        SetConsoleCursorPosition(stdOutHandle_, pos);
     520
     521        // Restore this->cout_ redirection
     522        std::cout.rdbuf(this->cout_.rdbuf());
     523        // Enable standard this->cout_ logging again
     524        OutputHandler::getInstance().enableCout();
     525
     526        resetTerminalMode();
     527        this->shell_->destroy();
     528    }
     529
     530    //! Processes the pending input key strokes, refreshes the status lines and handles std::cout (redirected)
     531    void IOConsole::preUpdate(const Clock& time)
     532    {
     533        // Process input
     534        while (true)
     535        {
     536            DWORD count;
     537            INPUT_RECORD inrec;
     538            PeekConsoleInput(this->stdInHandle_, &inrec, 1, &count);
     539            if (count == 0)
     540                break;
     541            ReadConsoleInput(this->stdInHandle_, &inrec, 1, &count);
     542            if (inrec.EventType == KEY_EVENT && inrec.Event.KeyEvent.bKeyDown)
     543            {
     544                // Process keyboard modifiers (Ctrl, Alt and Shift)
     545                DWORD modifiersIn = inrec.Event.KeyEvent.dwControlKeyState;
     546                int modifiersOut = 0;
     547                if ((modifiersIn & (LEFT_ALT_PRESSED  | RIGHT_ALT_PRESSED))  != 0)
     548                    modifiersOut |= KeyboardModifier::Alt;
     549                if ((modifiersIn & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED)) != 0)
     550                    modifiersOut |= KeyboardModifier::Ctrl;
     551                if ((modifiersIn & SHIFT_PRESSED) != 0)
     552                    modifiersOut |= KeyboardModifier::Shift;
     553
     554                // ASCII character (0 for special keys)
     555                char asciiChar = inrec.Event.KeyEvent.uChar.AsciiChar;
     556
     557                // Process special keys and if not found, use Key::A as dummy (InputBuffer uses the ASCII text anyway)
     558                switch (inrec.Event.KeyEvent.wVirtualKeyCode)
     559                {
     560                case VK_BACK:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Back,     asciiChar, modifiersOut)); break;
     561                case VK_TAB:    this->buffer_->buttonPressed(KeyEvent(KeyCode::Tab,      asciiChar, modifiersOut)); break;
     562                case VK_RETURN: this->buffer_->buttonPressed(KeyEvent(KeyCode::Return,   asciiChar, modifiersOut)); break;
     563                case VK_PAUSE:  this->buffer_->buttonPressed(KeyEvent(KeyCode::Pause,    asciiChar, modifiersOut)); break;
     564                case VK_ESCAPE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Escape,   asciiChar, modifiersOut)); break;
     565                case VK_SPACE:  this->buffer_->buttonPressed(KeyEvent(KeyCode::Space,    asciiChar, modifiersOut)); break;
     566                case VK_PRIOR:  this->buffer_->buttonPressed(KeyEvent(KeyCode::PageUp,   asciiChar, modifiersOut)); break;
     567                case VK_NEXT:   this->buffer_->buttonPressed(KeyEvent(KeyCode::PageDown, asciiChar, modifiersOut)); break;
     568                case VK_END:    this->buffer_->buttonPressed(KeyEvent(KeyCode::End,      asciiChar, modifiersOut)); break;
     569                case VK_HOME:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Home,     asciiChar, modifiersOut)); break;
     570                case VK_LEFT:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Left,     asciiChar, modifiersOut)); break;
     571                case VK_UP:     this->buffer_->buttonPressed(KeyEvent(KeyCode::Up,       asciiChar, modifiersOut)); break;
     572                case VK_RIGHT:  this->buffer_->buttonPressed(KeyEvent(KeyCode::Right,    asciiChar, modifiersOut)); break;
     573                case VK_DOWN:   this->buffer_->buttonPressed(KeyEvent(KeyCode::Down,     asciiChar, modifiersOut)); break;
     574                case VK_INSERT: this->buffer_->buttonPressed(KeyEvent(KeyCode::Insert,   asciiChar, modifiersOut)); break;
     575                case VK_DELETE: this->buffer_->buttonPressed(KeyEvent(KeyCode::Delete,   asciiChar, modifiersOut)); break;
     576                default:        this->buffer_->buttonPressed(KeyEvent(KeyCode::A,        asciiChar, modifiersOut));
     577                }
     578            }
     579        }
     580
     581        // TODO: Respect screen buffer size changes
     582/*
     583        // The user can manually adjust the screen buffer size on Windows
     584        // And we don't want to screw the console because of that
    476585        this->lastTerminalWidth_ = this->terminalWidth_;
    477586        this->lastTerminalHeight_ = this->terminalHeight_;
    478 
    479         // Disable standard this->cout_ logging
    480         OutputHandler::getInstance().disableCout();
     587        this->getTerminalSize(); // Also sets this->inputLineRow_ according to the cursor position
     588        // Is there still enough space below the cursor for the status line(s)?
     589        if (this->inputLineRow_ >= this->terminalHeight_ - this->statusLines_)
     590            this->moveCursor(0, -this->inputLineRow_ + this->terminalHeight_ - this->statusLines_ - 1);
    481591*/
    482     }
    483 
    484     IOConsole::~IOConsole()
    485     {
    486 /*
    487         resetTerminalMode();
    488         this->shell_->destroy();
    489 
    490         // Enable standard this->cout_ logging again
    491         OutputHandler::getInstance().enableCout();
    492 */
    493     }
    494 
    495     void IOConsole::update(const Clock& time)
    496     {
    497 /*
    498         unsigned char c = 0;
    499         while (std::cin.good())
    500         {
    501             c = std::cin.get();
    502             if (std::cin.bad())
    503                 break;
    504         }
    505         // Reset error flags in std::cin
    506         std::cin.clear();
    507 
    508         // Determine terminal width and height
    509         this->lastTerminalWidth_ = this->terminalWidth_;
    510         this->lastTerminalHeight_ = this->terminalHeight_;
    511         this->getTerminalSize();
    512 */
    513     }
    514 
    515     void IOConsole::printLogText(const std::string& text)
    516     {
    517     }
    518 
    519     void IOConsole::printInputLine()
    520     {
    521     }
    522 
     592
     593        // Refresh status line 5 times per second
     594        if (time.getMicroseconds() > this->lastRefreshTime_ + 1000000)
     595        {
     596            this->printStatusLines();
     597            this->lastRefreshTime_ = time.getMicroseconds();
     598        }
     599
     600        // Process output written to std::cout
     601        std::cout.flush();
     602        if (!this->origCout_.str().empty())
     603        {
     604            this->shell_->addOutput(this->origCout_.str(), Shell::None);
     605            this->origCout_.str("");
     606        }
     607    }
     608
     609    //! Prints output text. Similar to writeText, but sets the colour according to the output level
     610    void IOConsole::printOutputLine(const std::string& text, Shell::LineType type, const COORD& pos)
     611    {
     612        // Colour line
     613        WORD colour = 0;
     614        switch (type)
     615        {
     616        case Shell::Error:   colour = FOREGROUND_INTENSITY                    | FOREGROUND_RED; break;
     617        case Shell::Warning: colour = FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED; break;
     618        case Shell::Info:
     619        case Shell::Debug:
     620        case Shell::Verbose:
     621        case Shell::Ultra:   colour = FOREGROUND_INTENSITY                                     ; break;
     622        case Shell::Command: colour =                        FOREGROUND_GREEN                  | FOREGROUND_BLUE; break;
     623        case Shell::Hint:    colour =                        FOREGROUND_GREEN | FOREGROUND_RED                  ; break;
     624        default:             colour =                        FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE; break;
     625        }
     626
     627        // Print output line
     628        this->writeText(text, pos, colour);
     629    }
     630
     631    //! Prints all status lines with current content
    523632    void IOConsole::printStatusLines()
    524633    {
    525 /*
    526         if (this->willPrintStatusLines())
    527         {
    528             this->bStatusPrinted_ = true;
    529         }
    530         else
    531             this->bStatusPrinted_ = false;
    532 */
    533     }
    534 
     634        // Prepare text to be written
     635        std::ostringstream oss;
     636        oss << std::fixed << std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgFPS() << " fps, ";
     637        oss <<               std::setprecision(2) << std::setw(5) << Game::getInstance().getAvgTickTime() << " ms tick time";
     638        // Clear rest of the line by inserting spaces
     639        oss << std::string(this->terminalWidth_ - oss.str().size(), ' ');
     640        this->writeText(oss.str(), makeCOORD(0, this->inputLineRow_ + this->inputLineHeight_), FOREGROUND_GREEN);
     641    }
     642
     643    //! Changes the console parameters for unbuffered input
    535644    void IOConsole::setTerminalMode()
    536645    {
    537     }
    538 
     646        // Set the console mode to no-echo, raw input, and no window or mouse events
     647        this->stdOutHandle_ = GetStdHandle(STD_OUTPUT_HANDLE);
     648        this->stdInHandle_  = GetStdHandle(STD_INPUT_HANDLE);
     649        if (this->stdInHandle_ == INVALID_HANDLE_VALUE
     650            || !GetConsoleMode(this->stdInHandle_, &this->originalTerminalSettings_)
     651            || !SetConsoleMode(this->stdInHandle_, 0))
     652        {
     653            COUT(1) << "Error: Could not set Windows console settings" << std::endl;
     654            return;
     655        }
     656        FlushConsoleInputBuffer(this->stdInHandle_);
     657    }
     658
     659    //! Restores the console parameters
    539660    void IOConsole::resetTerminalMode()
    540661    {
    541     }
    542 
     662        SetConsoleMode(this->stdInHandle_, this->originalTerminalSettings_);
     663    }
     664
     665    //! Sets this->terminalWidth_ and this->terminalHeight_
    543666    void IOConsole::getTerminalSize()
    544667    {
     668        CONSOLE_SCREEN_BUFFER_INFO screenBufferInfo;
     669        GetConsoleScreenBufferInfo(this->stdOutHandle_, &screenBufferInfo);
     670        this->terminalWidth_  = screenBufferInfo.dwSize.X;
     671        this->terminalHeight_ = screenBufferInfo.dwSize.Y;
     672    }
     673
     674    //! Writes arbitrary text to the console with a certain colour and screen buffer position
     675    void IOConsole::writeText(const std::string& text, const COORD& coord, WORD attributes)
     676    {
     677        DWORD count;
     678        WriteConsoleOutputCharacter(stdOutHandle_, text.c_str(), text.size(), coord, &count);
     679        FillConsoleOutputAttribute(stdOutHandle_, attributes, text.size(), coord, &count);
     680    }
     681
     682    /** Scrolls the console screen buffer to create empty lines above the input line.
     683    @details
     684        If the input and status lines are already at the bottom of the screen buffer
     685        the whole output gets scrolled up. In the other case the input and status
     686        lines get scrolled down.
     687        In any case the status and input lines get scrolled down as far as possible.
     688    @param lines
     689        Number of lines to be inserted. Behavior for negative values is undefined.
     690    */
     691    void IOConsole::createNewOutputLines(int lines)
     692    {
     693        CHAR_INFO fillChar = {{' '}, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED};
     694        // Lines to scroll input/status down (if possible)
     695        int linesDown = clamp(terminalHeight_ - inputLineRow_ - inputLineHeight_ - statusLines_, 0, lines);
     696        if (linesDown > 0)
     697        {
     698            // Scroll input and status lines down
     699            SMALL_RECT oldRect = {0, this->inputLineRow_,
     700                this->terminalWidth_ - 1, this->inputLineRow_ + this->inputLineHeight_ + this->statusLines_ - 1};
     701            this->inputLineRow_ += linesDown;
     702            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, makeCOORD(0, this->inputLineRow_), &fillChar);
     703            // Move cursor down to the new bottom so the user can see the status lines
     704            COORD pos = {0, this->inputLineRow_ + this->inputLineHeight_ - 1 + this->statusLines_};
     705            SetConsoleCursorPosition(stdOutHandle_, pos);
     706            // Get cursor back to the right position
     707            this->cursorChanged();
     708        }
     709        // Check how many lines we still have to scroll up the output
     710        if (lines - linesDown > 0)
     711        {
     712            // Scroll output up
     713            SMALL_RECT oldRect = {0, lines - linesDown, this->terminalWidth_ - 1, this->inputLineRow_ - 1};
     714            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, makeCOORD(0, 0), &fillChar);
     715        }
    545716    }
    546717
     
    549720    // ###############################
    550721
     722    //! Called if the text in the input line has changed
     723    void IOConsole::inputChanged()
     724    {
     725        int newInputLineLength = this->promptString_.size() + this->shell_->getInput().size();
     726        int newInputLineHeight = 1 + newInputLineLength / this->terminalWidth_;
     727        int newLines = newInputLineHeight - this->inputLineHeight_;
     728        if (newLines > 0)
     729        {
     730            // Abuse this function to scroll the console
     731            this->createNewOutputLines(newLines);
     732            // Either Compensate for side effects (input/status lines scrolled down)
     733            // or we have to do this anyway (output scrolled up)
     734            this->inputLineRow_ -= newLines;
     735        }
     736        else if (newLines < 0)
     737        {
     738            // Scroll status lines up
     739            int statusLineRow = this->inputLineRow_ + this->inputLineHeight_;
     740            SMALL_RECT oldRect = {0, statusLineRow, this->terminalWidth_ - 1, statusLineRow + this->statusLines_};
     741            CHAR_INFO fillChar = {{' '}, FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED};
     742            ScrollConsoleScreenBuffer(stdOutHandle_, &oldRect, NULL, makeCOORD(0, statusLineRow + newLines), &fillChar);
     743            // Clear potential leftovers
     744            if (-newLines - this->statusLines_ > 0)
     745            {
     746                COORD pos = {0, this->inputLineRow_ + newInputLineHeight + this->statusLines_};
     747                this->writeText(std::string((-newLines - this->statusLines_) * this->terminalWidth_, ' '), pos);
     748            }
     749        }
     750        this->inputLineHeight_ = newInputLineHeight;
     751
     752        // Print the whole line, including spaces that erase leftovers
     753        std::string inputLine = this->promptString_ + this->shell_->getInput();
     754        inputLine += std::string(this->terminalWidth_ - newInputLineLength % this->terminalWidth_, ' ');
     755        this->writeText(inputLine, makeCOORD(0, this->inputLineRow_), FOREGROUND_GREEN | FOREGROUND_INTENSITY);
     756        // If necessary, move cursor
     757        if (newLines != 0)
     758            this->cursorChanged();
     759    }
     760
     761    //! Called if the position of the cursor in the input-line has changed
     762    void IOConsole::cursorChanged()
     763    {
     764        int rawCursorPos = this->promptString_.size() + this->buffer_->getCursorPosition();
     765        // Compensate for cursor further to the right than the terminal width
     766        COORD pos;
     767        pos.X = rawCursorPos % this->terminalWidth_;
     768        pos.Y = this->inputLineRow_ + rawCursorPos / this->terminalWidth_;
     769        SetConsoleCursorPosition(stdOutHandle_, pos);
     770    }
     771
    551772    //! Called if only the last output-line has changed
    552773    void IOConsole::onlyLastLineChanged()
    553774    {
    554     }
    555 
    556     //! Called if a new output-line was added
     775        int newLineHeight = 1 + this->shell_->getNewestLineIterator()->first.size() / this->terminalWidth_;
     776        // Compute the number of new lines needed
     777        int newLines = newLineHeight - this->lastOutputLineHeight_;
     778        this->lastOutputLineHeight_ = newLineHeight;
     779        // Scroll console if necessary
     780        if (newLines > 0) // newLines < 0 is assumed impossible
     781            this->createNewOutputLines(newLines);
     782        Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
     783        this->printOutputLine(it->first, it->second, makeCOORD(0, this->inputLineRow_ - newLineHeight));
     784    }
     785
     786    //! Called if a new output line was added
    557787    void IOConsole::lineAdded()
    558788    {
     789        Shell::LineList::const_iterator it = this->shell_->getNewestLineIterator();
     790        // Scroll console
     791        this->lastOutputLineHeight_ = 1 + it->first.size() / this->terminalWidth_;
     792        this->createNewOutputLines(this->lastOutputLineHeight_);
     793        // Write the text
     794        COORD pos = {0, this->inputLineRow_ - this->lastOutputLineHeight_};
     795        this->printOutputLine(it->first, it->second, pos);
    559796    }
    560797}
  • code/branches/pickup2/src/libraries/core/IOConsole.h

    r6105 r6412  
    4141#ifdef ORXONOX_PLATFORM_UNIX
    4242struct termios;
     43#elif defined(ORXONOX_PLATFORM_WINDOWS)
     44#define WIN32_LEAN_AND_MEAN
     45#ifndef NOMINMAX
     46#define NOMINMAX
     47#endif
     48#include <windows.h>
    4349#endif
    4450
     
    5359        ~IOConsole();
    5460
    55         void update(const Clock& time);
     61        void preUpdate(const Clock& time);
    5662
    5763    private:
    5864        void setTerminalMode();
    59         void resetTerminalMode();
    6065        void getTerminalSize();
    61         bool willPrintStatusLines();
    62         int extractLogLevel(std::string* text);
    63 
    64         void printLogText(const std::string& line);
    65         void printInputLine();
    6666        void printStatusLines();
     67        static int extractLogLevel(std::string* text);
    6768
    6869        // Methods from ShellListener
     
    7475        void executed();
    7576        void exit();
     77
    7678        Shell*                  shell_;
    7779        InputBuffer*            buffer_;
    7880        std::ostream            cout_;
    7981        std::ostringstream      origCout_;
    80         unsigned int            terminalWidth_;
    81         unsigned int            terminalHeight_;
    82         unsigned int            lastTerminalWidth_;
    83         unsigned int            lastTerminalHeight_;
     82        int                     terminalWidth_;
     83        int                     terminalHeight_;
     84        int                     lastTerminalWidth_;
     85        int                     lastTerminalHeight_;
     86        const std::string       promptString_;
     87
     88#ifdef ORXONOX_PLATFORM_UNIX
     89        bool willPrintStatusLines();
     90        void printInputLine();
     91        void printOutputLine(const std::string& line, Shell::LineType type);
     92        static void resetTerminalMode();
     93
    8494        bool                    bPrintStatusLine_;
    8595        bool                    bStatusPrinted_;
    86         std::vector<unsigned>   statusLineWidths_;
    87         unsigned int            statusLineMaxWidth_;
    88         const std::string       promptString_;
    89         static const unsigned   minOutputLines_ = 3;
     96        std::vector<int>        statusLineWidths_;
     97        int                     statusLineMaxWidth_;
     98        static const int        minOutputLines_ = 3;
     99        termios*                originalTerminalSettings_;
    90100
    91 #ifdef ORXONOX_PLATFORM_UNIX
    92         termios*                originalTerminalSettings_;
     101#elif defined(ORXONOX_PLATFORM_WINDOWS)
     102        void resetTerminalMode();
     103        void moveCursor(int dx, int dy);
     104        void writeText(const std::string& text, const COORD& pos, WORD attributes = FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED);
     105        void createNewOutputLines(int lines);
     106        void printOutputLine(const std::string& line, Shell::LineType type, const COORD& pos);
     107
     108        static inline COORD makeCOORD(int x, int y)
     109        {
     110            COORD val = {x, y};
     111            return val;
     112        }
     113
     114        DWORD                   originalTerminalSettings_;
     115        HANDLE                  stdInHandle_;
     116        HANDLE                  stdOutHandle_;
     117        int                     inputLineRow_;
     118        int                     inputLineHeight_;
     119        const int               statusLines_;
     120        int                     lastOutputLineHeight_;
     121        uint64_t                lastRefreshTime_;
    93122#endif
    94123
  • code/branches/pickup2/src/libraries/core/IRC.cc

    r5781 r6412  
    3333#include "util/Convert.h"
    3434#include "util/Exception.h"
     35#include "util/StringUtils.h"
    3536#include "ConsoleCommand.h"
    3637#include "CoreIncludes.h"
     
    103104    void IRC::say(const std::string& message)
    104105    {
    105         if (IRC::eval("irk::say $conn #orxonox {" + message + "}"))
     106        if (IRC::eval("irk::say $conn #orxonox {" + message + '}'))
    106107            IRC::tcl_say(Tcl::object(), Tcl::object(IRC::getInstance().nickname_), Tcl::object(message));
    107108    }
     
    109110    void IRC::msg(const std::string& channel, const std::string& message)
    110111    {
    111         if (IRC::eval("irk::say $conn " + channel + " {" + message + "}"))
     112        if (IRC::eval("irk::say $conn " + channel + " {" + message + '}'))
    112113            IRC::tcl_privmsg(Tcl::object(channel), Tcl::object(IRC::getInstance().nickname_), Tcl::object(message));
    113114    }
     
    131132    void IRC::tcl_action(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
    132133    {
    133         COUT(0) << "IRC> * " << nick.get() << " " << stripEnclosingBraces(args.get()) << std::endl;
     134        COUT(0) << "IRC> * " << nick.get() << ' ' << stripEnclosingBraces(args.get()) << std::endl;
    134135    }
    135136
  • code/branches/pickup2/src/libraries/core/Identifier.cc

    r5929 r6412  
    410410        if (it != this->configValues_.end())
    411411        {
    412             COUT(2) << "Warning: Overwriting config-value with name " << varname << " in class " << this->getName() << "." << std::endl;
     412            COUT(2) << "Warning: Overwriting config-value with name " << varname << " in class " << this->getName() << '.' << std::endl;
    413413            delete (it->second);
    414414        }
     
    458458        if (it != this->consoleCommands_.end())
    459459        {
    460             COUT(2) << "Warning: Overwriting console-command with name " << command->getName() << " in class " << this->getName() << "." << std::endl;
     460            COUT(2) << "Warning: Overwriting console-command with name " << command->getName() << " in class " << this->getName() << '.' << std::endl;
    461461            delete (it->second);
    462462        }
     
    524524        if (it != this->xmlportParamContainers_.end())
    525525        {
    526             COUT(2) << "Warning: Overwriting XMLPortParamContainer in class " << this->getName() << "." << std::endl;
     526            COUT(2) << "Warning: Overwriting XMLPortParamContainer in class " << this->getName() << '.' << std::endl;
    527527            delete (it->second);
    528528        }
     
    555555        if (it != this->xmlportObjectContainers_.end())
    556556        {
    557             COUT(2) << "Warning: Overwriting XMLPortObjectContainer in class " << this->getName() << "." << std::endl;
     557            COUT(2) << "Warning: Overwriting XMLPortObjectContainer in class " << this->getName() << '.' << std::endl;
    558558            delete (it->second);
    559559        }
     
    573573        {
    574574            if (it != list.begin())
    575                 out << " ";
     575                out << ' ';
    576576            out << (*it)->getName();
    577577        }
  • code/branches/pickup2/src/libraries/core/Identifier.h

    r5929 r6412  
    411411    {
    412412        // Get the name of the class
    413         std::string name = typeid(T).name();
     413        const std::string& name = typeid(T).name();
    414414
    415415        // create a new identifier anyway. Will be deleted in Identifier::getIdentifier if not used.
  • code/branches/pickup2/src/libraries/core/Language.cc

    r5929 r6412  
    6262    {
    6363        // Check if the translation is more than just an empty string
    64         if ((localisation != "") && (localisation.size() > 0))
     64        if (!localisation.empty())
    6565        {
    6666            this->localisedEntry_ = localisation;
     
    130130        }
    131131
    132         COUT(2) << "Warning: Language entry " << label << " is duplicate in " << getFilename(this->defaultLanguage_) << "!" << std::endl;
     132        COUT(2) << "Warning: Language entry " << label << " is duplicate in " << getFilename(this->defaultLanguage_) << '!' << std::endl;
    133133        return it->second;
    134134    }
     
    199199        COUT(4) << "Read default language file." << std::endl;
    200200
    201         std::string filepath = PathConfig::getConfigPathString() + getFilename(this->defaultLanguage_);
     201        const std::string& filepath = PathConfig::getConfigPathString() + getFilename(this->defaultLanguage_);
    202202
    203203        // This creates the file if it's not existing
     
    224224
    225225            // Check if the line is empty
    226             if ((lineString != "") && (lineString.size() > 0))
     226            if (!lineString.empty())
    227227            {
    228228                size_t pos = lineString.find('=');
     
    246246    void Language::readTranslatedLanguageFile()
    247247    {
    248         COUT(4) << "Read translated language file (" << Core::getLanguage() << ")." << std::endl;
    249 
    250         std::string filepath = PathConfig::getConfigPathString() + getFilename(Core::getLanguage());
     248        COUT(4) << "Read translated language file (" << Core::getInstance().getLanguage() << ")." << std::endl;
     249
     250        const std::string& filepath = PathConfig::getConfigPathString() + getFilename(Core::getInstance().getLanguage());
    251251
    252252        // Open the file
     
    257257        {
    258258            COUT(1) << "An error occurred in Language.cc:" << std::endl;
    259             COUT(1) << "Error: Couldn't open file " << getFilename(Core::getLanguage()) << " to read the translated language entries!" << std::endl;
    260             Core::resetLanguage();
    261             COUT(3) << "Info: Reset language to " << this->defaultLanguage_ << "." << std::endl;
     259            COUT(1) << "Error: Couldn't open file " << getFilename(Core::getInstance().getLanguage()) << " to read the translated language entries!" << std::endl;
     260            Core::getInstance().resetLanguage();
     261            COUT(3) << "Info: Reset language to " << this->defaultLanguage_ << '.' << std::endl;
    262262            return;
    263263        }
     
    270270
    271271            // Check if the line is empty
    272             if ((lineString != "") && (lineString.size() > 0))
     272            if (!lineString.empty())
    273273            {
    274274                size_t pos = lineString.find('=');
     
    287287                else
    288288                {
    289                     COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFilename(Core::getLanguage()) << std::endl;
     289                    COUT(2) << "Warning: Invalid language entry \"" << lineString << "\" in " << getFilename(Core::getInstance().getLanguage()) << std::endl;
    290290                }
    291291            }
     
    302302        COUT(4) << "Language: Write default language file." << std::endl;
    303303
    304         std::string filepath = PathConfig::getConfigPathString() + getFilename(this->defaultLanguage_);
     304        const std::string& filepath = PathConfig::getConfigPathString() + getFilename(this->defaultLanguage_);
    305305
    306306        // Open the file
     
    318318        for (std::map<std::string, LanguageEntry*>::const_iterator it = this->languageEntries_.begin(); it != this->languageEntries_.end(); ++it)
    319319        {
    320             file << (*it).second->getLabel() << "=" << (*it).second->getDefault() << std::endl;
     320            file << it->second->getLabel() << '=' << it->second->getDefault() << std::endl;
    321321        }
    322322
  • code/branches/pickup2/src/libraries/core/Language.h

    r5738 r6412  
    116116    {
    117117        friend class Singleton<Language>;
    118         friend class CoreConfiguration;
     118        friend class Core;
    119119
    120120        public:
  • code/branches/pickup2/src/libraries/core/Loader.cc

    r5929 r6412  
    8080        for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it)
    8181        {
    82             if ((*it).first == file)
     82            if (it->first == file)
    8383            {
    8484                Loader::files_s.erase(it);
     
    9292        bool success = true;
    9393        for (std::vector<std::pair<const XMLFile*, ClassTreeMask> >::iterator it = Loader::files_s.begin(); it != Loader::files_s.end(); ++it)
    94             if (!Loader::load((*it).first, (*it).second * mask))
     94            if (!Loader::load(it->first, it->second * mask))
    9595                success = false;
    9696
     
    128128            scoped_ptr<LuaState> luaState(new LuaState());
    129129            luaState->setIncludeParser(&Loader::replaceLuaTags);
    130             luaState->includeFile(file->getFilename(), file->getResourceGroup(), false);
     130            luaState->includeFile(file->getFilename());
    131131            xmlInput = luaState->getOutput().str();
    132132        }
    133133        else
    134134        {
    135             shared_ptr<ResourceInfo> info = Resource::getInfo(file->getFilename(), file->getResourceGroup());
     135            shared_ptr<ResourceInfo> info = Resource::getInfo(file->getFilename());
    136136            if (info == NULL)
    137137            {
     
    139139                return false;
    140140            }
    141             xmlInput = Resource::open(file->getFilename(), file->getResourceGroup())->getAsString();
     141            xmlInput = Resource::open(file->getFilename())->getAsString();
    142142        }
    143143
     
    165165            rootNamespace->XMLPort(rootElement, XMLPort::LoadObject);
    166166
    167             COUT(0) << "Finished loading " << file->getFilename() << "." << std::endl;
     167            COUT(0) << "Finished loading " << file->getFilename() << '.' << std::endl;
    168168
    169169            COUT(4) << "Namespace-tree:" << std::endl << rootNamespace->toString("  ") << std::endl;
     
    174174        {
    175175            COUT(1) << std::endl;
    176             COUT(1) << "An XML-error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl;
     176            COUT(1) << "An XML-error occurred in Loader.cc while loading " << file->getFilename() << ':' << std::endl;
    177177            COUT(1) << ex.what() << std::endl;
    178178            COUT(1) << "Loading aborted." << std::endl;
     
    182182        {
    183183            COUT(1) << std::endl;
    184             COUT(1) << "A loading-error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl;
     184            COUT(1) << "A loading-error occurred in Loader.cc while loading " << file->getFilename() << ':' << std::endl;
    185185            COUT(1) << ex.what() << std::endl;
    186186            COUT(1) << "Loading aborted." << std::endl;
     
    190190        {
    191191            COUT(1) << std::endl;
    192             COUT(1) << "An error occurred in Loader.cc while loading " << file->getFilename() << ":" << std::endl;
     192            COUT(1) << "An error occurred in Loader.cc while loading " << file->getFilename() << ':' << std::endl;
    193193            COUT(1) << Exception::handleMessage() << std::endl;
    194194            COUT(1) << "Loading aborted." << std::endl;
     
    218218    std::string Loader::replaceLuaTags(const std::string& text)
    219219    {
    220         // chreate map with all Lua tags
     220        // create map with all Lua tags
    221221        std::map<size_t, bool> luaTags;
    222222        {
     
    291291            {
    292292                if (it != luaTags.end())
    293                     end = (*(it++)).first;
     293                    end = (it++)->first;
    294294                else
    295295                    end = std::string::npos;
     
    300300                {
    301301                    // count ['='[ and ]'='] and replace tags with print([[ and ]])
    302                     std::string temp = text.substr(start, end - start);
     302                    const std::string& temp = text.substr(start, end - start);
    303303                    {
    304304                    size_t pos = 0;
     
    345345                        }
    346346                    }
    347                     std::string equalSigns = "";
     347                    std::string equalSigns;
    348348                    for(unsigned int i = 0; i < equalSignCounter; i++)
    349349                    {
    350                         equalSigns += "=";
     350                        equalSigns += '=';
    351351                    }
    352                     output << "print([" + equalSigns + "[" + temp + "]" + equalSigns +"])";
     352                    output << "print([" + equalSigns + '[' + temp + ']' + equalSigns +"])";
    353353                    start = end + 5;
    354354                }
  • code/branches/pickup2/src/libraries/core/LuaState.cc

    r5929 r6412  
    8686    }
    8787
    88     shared_ptr<ResourceInfo> LuaState::getFileInfo(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
    89     {
    90         shared_ptr<ResourceInfo> sourceInfo;
    91         if (resourceGroup != "NoResourceGroupProvided")
    92             sourceInfo = Resource::getInfo(filename, resourceGroup);
    93 
    94         // Continue search if not explicitely forbidden
    95         if (bSearchOtherPaths && sourceInfo == NULL)
    96         {
    97             // Call might be relative to the file currently being processed
    98             sourceInfo = Resource::getInfo(sourceFileInfo_->path + filename, sourceFileInfo_->group);
    99             if (sourceInfo == NULL)
    100             {
    101                 // Maybe find something in the same group but in the root path
    102                 sourceInfo = Resource::getInfo(filename, sourceFileInfo_->group);
    103             }
    104         }
     88    shared_ptr<ResourceInfo> LuaState::getFileInfo(const std::string& filename)
     89    {
     90        // Look in the current directory first
     91        shared_ptr<ResourceInfo> sourceInfo = Resource::getInfo(sourceFileInfo_->path + filename);
     92        // Continue search in root directories
     93        if (sourceInfo == NULL && !sourceFileInfo_->path.empty())
     94            sourceInfo = Resource::getInfo(filename);
    10595        return sourceInfo;
    10696    }
    10797
    108     void LuaState::includeFile(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
    109     {
    110         shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
     98    void LuaState::includeFile(const std::string& filename)
     99    {
     100        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
    111101        if (sourceInfo != NULL)
    112             this->includeString(Resource::open(sourceInfo->filename, sourceInfo->group)->getAsString(), sourceInfo);
    113         else
    114             COUT(2) << "LuaState: Cannot include file '" << filename << "' in resource group '"
    115                     << (resourceGroup == "NoResourceGroupProvided" ? sourceFileInfo_->group : resourceGroup) << "': group not found." << std::endl;
    116     }
    117 
    118     void LuaState::includeString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo)
     102            this->includeString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
     103        else
     104            COUT(2) << "LuaState: Cannot include file '" << filename << "'." << std::endl;
     105    }
     106
     107    void LuaState::includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
    119108    {
    120109        // Parse string with provided include parser (otherwise don't preparse at all)
     
    128117    }
    129118
    130     void LuaState::doFile(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
    131     {
    132         shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
     119    void LuaState::doFile(const std::string& filename)
     120    {
     121        shared_ptr<ResourceInfo> sourceInfo = this->getFileInfo(filename);
    133122        if (sourceInfo != NULL)
    134             this->doString(Resource::open(sourceInfo->filename, sourceInfo->group)->getAsString(), sourceInfo);
    135         else
    136             COUT(2) << "LuaState: Cannot do file '" << filename << "' in resource group '"
    137                 << (resourceGroup == "NoResourceGroupProvided" ? sourceFileInfo_->group : resourceGroup) << "': group not found." << std::endl;
    138     }
    139 
    140     void LuaState::doString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo)
    141     {
    142         // Save the oold source file info
     123            this->doString(Resource::open(sourceInfo)->getAsString(), sourceInfo);
     124        else
     125            COUT(2) << "LuaState: Cannot do file '" << filename << "'." << std::endl;
     126    }
     127
     128    void LuaState::doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo)
     129    {
     130        // Save the old source file info
    143131        shared_ptr<ResourceInfo> oldSourceFileInfo = sourceFileInfo_;
    144132        // Only override if sourceFileInfo provides useful information
     
    164152            if (sourceFileInfo != NULL)
    165153                origin = " originating from " + sourceFileInfo_->filename;
    166             COUT(2) << "Error in Lua-script" << origin << ": " << lua_tostring(luaState_, -1) << std::endl;
     154            COUT(1) << "Error in Lua-script" << origin << ": " << lua_tostring(luaState_, -1) << std::endl;
    167155            // return value is nil
    168156            lua_pushnil(luaState_);
     
    182170    void LuaState::luaLog(unsigned int level, const std::string& message)
    183171    {
    184         OutputHandler::getOutStream().setOutputLevel(level) << message << std::endl;
    185     }
    186 
    187     bool LuaState::fileExists(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths)
    188     {
    189         shared_ptr<ResourceInfo> info =  this->getFileInfo(filename, resourceGroup, bSearchOtherPaths);
     172        OutputHandler::getOutStream(level) << message << std::endl;
     173    }
     174
     175    bool LuaState::fileExists(const std::string& filename)
     176    {
     177        shared_ptr<ResourceInfo> info = this->getFileInfo(filename);
    190178        if (info == NULL)
    191179            return false;
     
    263251        }
    264252    }
     253
     254
     255    LuaFunctor::LuaFunctor(const std::string& code, LuaState* luaState)
     256    {
     257        this->code_ = code;
     258        this->lua_ = luaState;
     259    }
     260
     261    void LuaFunctor::operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
     262    {
     263        lua_->doString(this->code_);
     264    }
    265265}
  • code/branches/pickup2/src/libraries/core/LuaState.h

    r5781 r6412  
    4040
    4141#include "util/ScopeGuard.h"
     42#include "core/Functor.h"
    4243#include "ToluaInterface.h"
    4344
    44 // tolua_begin
    45 namespace orxonox
    46 {
     45namespace orxonox // tolua_export
     46{ // tolua_export
     47    class Functor; // tolua_export
     48
     49    //! Functor subclass that simply executes code with 0 arguments.
     50    class _CoreExport LuaFunctor : public Functor
     51    {
     52        public:
     53            LuaFunctor(const std::string& code, LuaState* luaState);
     54            void operator()(const MultiType& param1 = MT_Type::Null, const MultiType& param2 = MT_Type::Null, const MultiType& param3 = MT_Type::Null, const MultiType& param4 = MT_Type::Null, const MultiType& param5 = MT_Type::Null);
     55            void evaluateParam(unsigned int index, MultiType& param) const {}
     56
     57        private:
     58            std::string code_;
     59            LuaState*   lua_;
     60    };
     61
     62
    4763    /**
    4864    @brief
    4965        Representation of an interface to lua
    5066    */
    51     class _CoreExport LuaState
    52     {
    53 // tolua_end
     67    class _CoreExport LuaState // tolua_export
     68    { // tolua_export
    5469    public:
    5570        LuaState();
    5671        ~LuaState();
    5772
    58         void doFile(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
    59         void doString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo = shared_ptr<ResourceInfo>());
     73        void doFile(const std::string& filename); // tolua_export
     74        void doString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
    6075
    61         void includeFile(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
    62         void includeString(const std::string& code, shared_ptr<ResourceInfo> sourceFileInfo = shared_ptr<ResourceInfo>());
     76        void includeFile(const std::string& filename); // tolua_export
     77        void includeString(const std::string& code, const shared_ptr<ResourceInfo>& sourceFileInfo = shared_ptr<ResourceInfo>());
    6378
    6479        void luaPrint(const std::string& str); // tolua_export
    6580        void luaLog(unsigned int level, const std::string& message); // tolua_export
    66         bool fileExists(const std::string& filename, const std::string& resourceGroup = "General", bool bSearchOtherPaths = true); // tolua_export
     81        bool fileExists(const std::string& filename); // tolua_export
    6782
    6883        const std::stringstream& getOutput() const { return output_; }
     
    7287        lua_State* getInternalLuaState() { return luaState_; }
    7388
     89        void setDefaultResourceInfo(const shared_ptr<ResourceInfo>& sourceFileInfo) { this->sourceFileInfo_ = sourceFileInfo; }
     90        const shared_ptr<ResourceInfo>& getDefaultResourceInfo() { return this->sourceFileInfo_; }
     91
     92        Functor* createLuaFunctor(const std::string& code) { return new LuaFunctor(code, this); } // tolua_export
     93
    7494        static bool addToluaInterface(int (*function)(lua_State*), const std::string& name);
    7595        static bool removeToluaInterface(const std::string& name);
     
    7898
    7999    private:
    80         shared_ptr<ResourceInfo> getFileInfo(const std::string& filename, const std::string& resourceGroup, bool bSearchOtherPaths);
     100        shared_ptr<ResourceInfo> getFileInfo(const std::string& filename);
    81101
    82102#if LUA_VERSION_NUM != 501
  • code/branches/pickup2/src/libraries/core/MemoryArchive.cc

    r5940 r6412  
    6464    }
    6565
    66     void MemoryArchive::findFiles(const String& pattern, bool bRecursive, 
     66    void MemoryArchive::findFiles(const String& pattern, bool bRecursive,
    6767        bool bDirs, StringVector* simpleList, FileInfoList* detailList)
    6868    {
     
    118118    }
    119119
    120     FileInfoListPtr MemoryArchive::findFileInfo(const String& pattern, 
     120    FileInfoListPtr MemoryArchive::findFileInfo(const String& pattern,
    121121        bool recursive, bool dirs)
    122122    {
  • code/branches/pickup2/src/libraries/core/MemoryArchive.h

    r5781 r6412  
    7979
    8080    private:
    81         void findFiles(const Ogre::String& pattern, bool bRecursive, 
     81        void findFiles(const Ogre::String& pattern, bool bRecursive,
    8282            bool bDirs, Ogre::StringVector* simpleList, Ogre::FileInfoList* detailList);
    8383
  • code/branches/pickup2/src/libraries/core/Namespace.cc

    r5781 r6412  
    173173        {
    174174            if (i > 0)
    175                 output += "\n";
     175                output += '\n';
    176176
    177177            output += (*it)->toString(indentation);
  • code/branches/pickup2/src/libraries/core/NamespaceNode.cc

    r5781 r6412  
    4343    {
    4444        for (std::map<std::string, NamespaceNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); )
    45             delete ((*(it++)).second);
     45            delete (it++)->second;
    4646    }
    4747
     
    5050        std::set<NamespaceNode*> nodes;
    5151
    52         if ((name.size() == 0) || (name == ""))
     52        if (name.empty())
    5353        {
    5454            nodes.insert(this);
     
    8989                    it = this->subnodes_.insert(this->subnodes_.begin(), std::pair<std::string, NamespaceNode*>(firstPart, new NamespaceNode(firstPart, this)));
    9090
    91                 if ((*it).second->isHidden())
     91                if (it->second->isHidden())
    9292                {
    9393                    COUT(2) << "Warning: Subnamespace '" << firstPart << "' in namespace '" << this->name_ << "' is hidden and can't be accessed." << std::endl;
     
    9696                else
    9797                {
    98                     nodes = (*it).second->getNodeRelative(secondPart);
     98                    nodes = it->second->getNodeRelative(secondPart);
    9999                }
    100100            }
     
    105105                for (std::map<std::string, NamespaceNode*>::iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
    106106                {
    107                     if ((*it).first.find(firstPart) == ((*it).first.size() - firstPart.size()))
     107                    if (it->first.find(firstPart) == (it->first.size() - firstPart.size()))
    108108                    {
    109                         std::set<NamespaceNode*> temp2 = (*it).second->getNodeRelative(secondPart);
     109                        std::set<NamespaceNode*> temp2 = it->second->getNodeRelative(secondPart);
    110110                        nodes.insert(temp2.begin(), temp2.end());
    111111                        bFoundMatchingNamespace = true;
     
    133133        {
    134134            for (std::map<std::string, NamespaceNode*>::const_iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
    135                 if ((*it).second->includes(ns))
     135                if (it->second->includes(ns))
    136136                    return true;
    137137        }
     
    154154                    output += ", ";
    155155
    156                 output += (*it).second->toString();
     156                output += it->second->toString();
    157157            }
    158158
    159             output += ")";
     159            output += ')';
    160160        }
    161161
     
    165165    std::string NamespaceNode::toString(const std::string& indentation) const
    166166    {
    167         std::string output = (indentation + this->name_ + "\n");
     167        std::string output = (indentation + this->name_ + '\n');
    168168
    169169        for (std::map<std::string, NamespaceNode*>::const_iterator it = this->subnodes_.begin(); it != this->subnodes_.end(); ++it)
    170             output += (*it).second->toString(indentation + "  ");
     170            output += it->second->toString(indentation + "  ");
    171171
    172172        return output;
  • code/branches/pickup2/src/libraries/core/OrxonoxClass.cc

    r5929 r6412  
    3434#include "OrxonoxClass.h"
    3535
     36#include <cassert>
    3637#include "MetaObjectList.h"
    3738#include "Identifier.h"
     
    4849        this->referenceCount_ = 0;
    4950        this->requestedDestruction_ = false;
     51        // Optimisation
     52        this->objectPointers_.reserve(6);
    5053    }
    5154
     
    5457    {
    5558//        if (!this->requestedDestruction_)
    56 //            COUT(2) << "Warning: Destroyed object without destroy() (" << this->getIdentifier()->getName() << ")" << std::endl;
     59//            COUT(2) << "Warning: Destroyed object without destroy() (" << this->getIdentifier()->getName() << ')' << std::endl;
    5760
    5861        assert(this->referenceCount_ <= 0);
    5962
    60         delete this->metaList_;
     63        this->unregisterObject();
    6164
    6265        // parents_ exists only if isCreatingHierarchy() of the associated Identifier returned true while creating the class
    6366        if (this->parents_)
    6467            delete this->parents_;
    65            
     68
    6669        // reset all weak pointers pointing to this object
    6770        for (std::set<WeakPtr<OrxonoxClass>*>::iterator it = this->weakPointers_.begin(); it != this->weakPointers_.end(); )
     
    7275    void OrxonoxClass::destroy()
    7376    {
     77        assert(this); // Just in case someone tries to delete a NULL pointer
    7478        this->requestedDestruction_ = true;
    7579        if (this->referenceCount_ == 0)
    76             delete this;
     80        {
     81            this->preDestroy();
     82            if (this->referenceCount_ == 0)
     83                delete this;
     84        }
     85    }
     86
     87    void OrxonoxClass::unregisterObject()
     88    {
     89        if (this->metaList_)
     90            delete this->metaList_;
     91        this->metaList_ = 0;
    7792    }
    7893
  • code/branches/pickup2/src/libraries/core/OrxonoxClass.h

    r5929 r6412  
    4343#include <vector>
    4444
     45/**
     46@def CCOUT
     47    Acts almost exactly like COUT(x), but prepends "ClassName: "
     48*/
     49#define CCOUT(level) \
     50    COUT(level) << this->getIdentifier()->getName() << ": "
     51
    4552namespace orxonox
    4653{
     
    6673
    6774            void destroy();
     75            void unregisterObject();
    6876
    6977            /** @brief Function to collect the SetConfigValue-macro calls. */
     
    127135            {   return const_cast<OrxonoxClass*>(this)->getDerivedPointer<T>(classID);   }
    128136
     137        protected:
     138            virtual void preDestroy() {}
     139
    129140        private:
    130141            /** @brief Increments the reference counter (for smart pointers). */
     
    133144            /** @brief Decrements the reference counter (for smart pointers). */
    134145            inline void decrementReferenceCount()
    135                 { --this->referenceCount_; if (this->referenceCount_ == 0 && this->requestedDestruction_) { delete this; } }
    136                
     146            {
     147                --this->referenceCount_;
     148                if (this->referenceCount_ == 0 && this->requestedDestruction_)
     149                    this->destroy();
     150            }
     151
    137152            /** @brief Register a weak pointer which points to this object. */
    138153            template <class T>
  • code/branches/pickup2/src/libraries/core/PathConfig.cc

    r5929 r6412  
    5454#include "util/Debug.h"
    5555#include "util/Exception.h"
    56 #include "CommandLine.h"
     56#include "CommandLineParser.h"
    5757
    5858// Boost 1.36 has some issues with deprecated functions that have been omitted
     
    186186
    187187            // Check for data path override by the command line
    188             if (!CommandLine::getArgument("externalDataPath")->hasDefaultValue())
    189                 externalDataPath_ = CommandLine::getValue("externalDataPath").getString();
     188            if (!CommandLineParser::getArgument("externalDataPath")->hasDefaultValue())
     189                externalDataPath_ = CommandLineParser::getValue("externalDataPath").getString();
    190190            else
    191191                externalDataPath_ = specialConfig::externalDataDevDirectory;
     
    224224
    225225        // Option to put all the config and log files in a separate folder
    226         if (!CommandLine::getArgument("writingPathSuffix")->hasDefaultValue())
    227         {
    228             std::string directory(CommandLine::getValue("writingPathSuffix").getString());
     226        if (!CommandLineParser::getArgument("writingPathSuffix")->hasDefaultValue())
     227        {
     228            const std::string& directory(CommandLineParser::getValue("writingPathSuffix").getString());
    229229            configPath_ = configPath_ / directory;
    230230            logPath_    = logPath_    / directory;
     
    256256
    257257        // We search for helper files with the following extension
    258         std::string moduleextension = specialConfig::moduleExtension;
     258        const std::string& moduleextension = specialConfig::moduleExtension;
    259259        size_t moduleextensionlength = moduleextension.size();
    260260
    261261        // Add that path to the PATH variable in case a module depends on another one
    262         std::string pathVariable = getenv("PATH");
    263         putenv(const_cast<char*>(("PATH=" + pathVariable + ";" + modulePath_.string()).c_str()));
     262        std::string pathVariable(getenv("PATH"));
     263        putenv(const_cast<char*>(("PATH=" + pathVariable + ';' + modulePath_.string()).c_str()));
     264
     265        // Make sure the path exists, otherwise don't load modules
     266        if (!boost::filesystem::exists(modulePath_))
     267            return modulePaths;
    264268
    265269        boost::filesystem::directory_iterator file(modulePath_);
     
    269273        while (file != end)
    270274        {
    271             std::string filename = file->BOOST_LEAF_FUNCTION();
     275            const std::string& filename = file->BOOST_LEAF_FUNCTION();
    272276
    273277            // Check if the file ends with the exension in question
     
    277281                {
    278282                    // We've found a helper file
    279                     std::string library = filename.substr(0, filename.size() - moduleextensionlength);
     283                    const std::string& library = filename.substr(0, filename.size() - moduleextensionlength);
    280284                    modulePaths.push_back((modulePath_ / library).file_string());
    281285                }
  • code/branches/pickup2/src/libraries/core/PathConfig.h

    r5929 r6412  
    3636#include "util/Singleton.h"
    3737
     38//tolua_begin
    3839namespace orxonox
    3940{
     41//tolua_end
    4042    /**
    4143    @brief
     
    5052        - externalData only for development builds in the build tree
    5153    */
    52     class _CoreExport PathConfig : public Singleton<PathConfig>
    53     {
     54    class _CoreExport PathConfig //tolua_export
     55        : public Singleton<PathConfig>
     56    { //tolua_export
    5457        friend class Singleton<PathConfig>;
    5558        friend class Core;
     
    99102            static std::string getExternalDataPathString();
    100103            //! Returns the path to the config files as std::string
    101             static std::string getConfigPathString();
     104            static std::string getConfigPathString(); //tolua_export
    102105            //! Returns the path to the log files as std::string
    103106            static std::string getLogPathString();
     
    132135            bool                     bDevRun_;               //!< True for runs in the build directory (not installed)
    133136            static PathConfig* singletonPtr_s;
    134     };
    135 }
     137    }; //tolua_export
     138} //tolua_export
    136139
    137140#endif /* _PathConfig_H__ */
  • code/branches/pickup2/src/libraries/core/Resource.cc

    r5781 r6412  
    3434    std::string Resource::DEFAULT_GROUP(Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
    3535
    36     DataStreamPtr Resource::open(const std::string& name, const std::string& group, bool bSearchGroupsIfNotFound)
     36    DataStreamPtr Resource::open(const std::string& name)
    3737    {
    38         return Ogre::ResourceGroupManager::getSingleton().openResource(name, group, bSearchGroupsIfNotFound);
     38        return Ogre::ResourceGroupManager::getSingleton().openResource(name,
     39            Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, true);
    3940    }
    4041
    41     DataStreamListPtr Resource::openMulti(const std::string& pattern, const std::string& group)
     42    DataStreamListPtr Resource::openMulti(const std::string& pattern)
    4243    {
    43         return Ogre::ResourceGroupManager::getSingleton().openResources(pattern, group);
     44        DataStreamListPtr resources(new Ogre::DataStreamList());
     45        const Ogre::StringVector& groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
     46        for (Ogre::StringVector::const_iterator it = groups.begin(); it != groups.end(); ++it)
     47        {
     48            DataStreamListPtr temp = Ogre::ResourceGroupManager::getSingleton().openResources(pattern, *it);
     49            resources->insert(resources->end(), temp->begin(), temp->end());
     50        }
     51        return resources;
    4452    }
    4553
    46     bool Resource::exists(const std::string& name, const std::string& group)
     54    bool Resource::exists(const std::string& name)
    4755    {
    48         return Ogre::ResourceGroupManager::getSingleton().resourceExists(group, name);
     56        try
     57        {
     58            Ogre::ResourceGroupManager::getSingleton().findGroupContainingResource(name);
     59            return true;
     60        }
     61        catch (const Ogre::Exception&)
     62        {
     63            return false;
     64        }
    4965    }
    5066
    51     shared_ptr<ResourceInfo> Resource::getInfo(const std::string& name, const std::string& group)
     67    shared_ptr<ResourceInfo> Resource::getInfo(const std::string& name)
    5268    {
     69        std::string group;
     70        try
     71        {
     72            group = Ogre::ResourceGroupManager::getSingleton().findGroupContainingResource(name);
     73        }
     74        catch (const Ogre::Exception&)
     75        {
     76            return shared_ptr<ResourceInfo>();
     77        }
    5378        Ogre::FileInfoListPtr infos = Ogre::ResourceGroupManager::getSingleton().findResourceFileInfo(group, name);
    5479        for (std::vector<Ogre::FileInfo>::const_iterator it = infos->begin(); it != infos->end(); ++it)
     
    6792        return shared_ptr<ResourceInfo>();
    6893    }
     94
     95    StringVectorPtr Resource::findResourceNames(const std::string& pattern)
     96    {
     97        StringVectorPtr resourceNames(new Ogre::StringVector());
     98        const Ogre::StringVector& groups = Ogre::ResourceGroupManager::getSingleton().getResourceGroups();
     99        for (Ogre::StringVector::const_iterator it = groups.begin(); it != groups.end(); ++it)
     100        {
     101            StringVectorPtr temp = Ogre::ResourceGroupManager::getSingleton().findResourceNames(*it, pattern);
     102            resourceNames->insert(resourceNames->end(), temp->begin(), temp->end());
     103        }
     104        return resourceNames;
     105    }
    69106}
  • code/branches/pickup2/src/libraries/core/Resource.h

    r5929 r6412  
    3434#include <boost/shared_ptr.hpp>
    3535#include <OgreDataStream.h>
     36#include <OgreStringVector.h>
    3637
    3738namespace orxonox
     
    4041    using Ogre::DataStreamList;
    4142    using Ogre::DataStreamListPtr;
     43    using Ogre::StringVector;
     44    using Ogre::StringVectorPtr;
    4245
    4346    //! Stores basic information about a Resource from Ogre
     
    5659    };
    5760
    58     /**
    59     @brief
    60         Provides simple functions to easily access the Ogre::ResourceGroupManager
     61    /** Provides simple functions to easily access the Ogre::ResourceGroupManager.
     62        The wrapper functions also avoid having to deal with resource groups.
    6163    */
    6264    class _CoreExport Resource
     
    7274            Even if resource locations are added recursively, you
    7375            must provide a fully qualified name to this method.
    74         @param groupName
    75             The name of the resource group; this determines which
    76             locations are searched.
    77         @param searchGroupsIfNotFound
    78             If true, if the resource is not found in
    79             the group specified, other groups will be searched.
    8076        @return
    8177            Shared pointer to data stream containing the data. Will be
    8278            destroyed automatically when no longer referenced.
    8379        */
    84         static DataStreamPtr open(const std::string& name,
    85             const std::string& group = Resource::DEFAULT_GROUP,
    86             bool bSearchGroupsIfNotFound = false);
     80        static DataStreamPtr open(const std::string& name);
     81
     82        //! Similar to open(string, string, bool), but with a fileInfo struct
     83        static DataStreamPtr open(shared_ptr<ResourceInfo> fileInfo)
     84        {
     85            return open(fileInfo->filename);
     86        }
    8787
    8888        /**
    8989        @brief
    9090            Open all resources matching a given pattern (which can contain
    91             the character '*' as a wildcard), and return a collection of 
     91            the character '*' as a wildcard), and return a collection of
    9292            DataStream objects on them.
    9393        @param pattern
     
    9595            added recursively, subdirectories will be searched too so this
    9696            does not need to be fully qualified.
    97         @param groupName
    98             The resource group; this determines which locations
    99             are searched.
    10097        @return
    10198            Shared pointer to a data stream list , will be
    10299            destroyed automatically when no longer referenced
    103100        */
    104         static DataStreamListPtr openMulti(const std::string& pattern, const std::string& group = Resource::DEFAULT_GROUP);
     101        static DataStreamListPtr openMulti(const std::string& pattern);
    105102
    106103        /**
    107             Find out if the named file exists in a group.
     104            Find out if the named file exists.
    108105        @param filename
    109106            Fully qualified name of the file to test for
    110         @param group
    111             The name of the resource group
    112107        */
    113         static bool exists(const std::string& name, const std::string& group = Resource::DEFAULT_GROUP);
     108        static bool exists(const std::string& name);
    114109
    115110        /**
    116             Get struct with information about group, path and size.
     111            Get struct with information about path and size.
    117112        @param filename
    118113            Fully qualified name of the file to test for
    119         @param group
    120             The name of the resource group
    121114        */
    122         static shared_ptr<ResourceInfo> getInfo(const std::string& name, const std::string& group = Resource::DEFAULT_GROUP);
     115        static shared_ptr<ResourceInfo> getInfo(const std::string& name);
     116
     117        /**
     118            Retrieves a list with all resources matching a certain pattern.
     119        @param pattern
     120            The pattern to look for. If resource locations have been
     121            added recursively, subdirectories will be searched too so this
     122            does not need to be fully qualified.
     123        */
     124        static StringVectorPtr findResourceNames(const std::string& pattern);
    123125
    124126        //! Name of the default resource group (usually "General")
  • code/branches/pickup2/src/libraries/core/ScopedSingletonManager.cc

    r5929 r6412  
    4747        getManagersByScope().insert(std::make_pair(manager->scope_, manager));
    4848    }
    49 
    50     /*static*/ void ScopedSingletonManager::removeManager(ScopedSingletonManager* manager)
    51     {
    52         getManagers().erase(getManagers().find(manager->className_));
    53         for (ManagerMultiMap::iterator it = getManagersByScope().lower_bound(manager->scope_); it != getManagersByScope().upper_bound(manager->scope_);)
    54             if (it->second == manager)
    55                 getManagersByScope().erase(it++);
    56             else
    57                 ++it;
    58     }
    5949}
  • code/branches/pickup2/src/libraries/core/ScopedSingletonManager.h

    r5929 r6412  
    3939
    4040#define ManageScopedSingleton(className, scope, allowedToFail) \
     41    className* className::singletonPtr_s = NULL; \
    4142    static ClassScopedSingletonManager<className, scope, allowedToFail> className##ScopedSingletonManager(#className)
    4243
     
    5253            virtual ~ScopedSingletonManager() { }
    5354            static void addManager(ScopedSingletonManager* manager);
    54             static void removeManager(ScopedSingletonManager* manager);
    5555
    5656            template<ScopeID::Value scope>
    57             static void update(const Clock& time)
     57            static void preUpdate(const Clock& time)
    5858            {
    5959                assert(Scope<scope>::isActive());
    6060                for (ManagerMultiMap::iterator it = getManagersByScope().lower_bound(scope); it != getManagersByScope().upper_bound(scope); ++it)
    61                     it->second->update(time);
     61                    it->second->preUpdate(time);
    6262            }
    63             virtual void update(const Clock& time) = 0;
     63            virtual void preUpdate(const Clock& time) = 0;
     64            template<ScopeID::Value scope>
     65            static void postUpdate(const Clock& time)
     66            {
     67                assert(Scope<scope>::isActive());
     68                for (ManagerMultiMap::iterator it = getManagersByScope().lower_bound(scope); it != getManagersByScope().upper_bound(scope); ++it)
     69                    it->second->postUpdate(time);
     70            }
     71            virtual void postUpdate(const Clock& time) = 0;
    6472
    6573            static std::map<std::string, ScopedSingletonManager*>& getManagers();
     
    8694        ~ClassScopedSingletonManager()
    8795        {
    88             //assert(singletonPtr_ == NULL); // Might get triggered in the SignalHandler
    89             ScopedSingletonManager::removeManager(this);
    9096        }
    9197
     
    115121
    116122        //! Called every frame by the ScopedSingletonManager
    117         void update(const Clock& time)
    118         {
    119             assert(Scope<scope>::isActive());
    120             // assuming T inherits Singleton<T>
    121             singletonPtr_->updateSingleton(time);
     123        void preUpdate(const Clock& time)
     124        {
     125            assert(Scope<scope>::isActive());
     126            // assuming T inherits Singleton<T>
     127            singletonPtr_->preUpdateSingleton(time);
     128        }
     129
     130        //! Called every frame by the ScopedSingletonManager
     131        void postUpdate(const Clock& time)
     132        {
     133            assert(Scope<scope>::isActive());
     134            // assuming T inherits Singleton<T>
     135            singletonPtr_->postUpdateSingleton(time);
    122136        }
    123137
     
    140154        ~ClassScopedSingletonManager()
    141155        {
    142             assert(singletonPtr_ == NULL);
    143             ScopedSingletonManager::removeManager(this);
    144156        }
    145157
     
    150162            try
    151163                { singletonPtr_ = new T(); }
     164            catch (const InitialisationAbortedException& ex)
     165                { COUT(3) << ex.getDescription() << std::endl; }
    152166            catch (...)
    153167                { COUT(1) << "Singleton creation failed: " << Exception::handleMessage() << std::endl; }
     
    174188
    175189        //! Called every frame by the ScopedSingletonManager
    176         void update(const Clock& time)
     190        void preUpdate(const Clock& time)
    177191        {
    178192            assert(Scope<scope>::isActive());
    179193            // assuming T inherits Singleton<T>
    180194            if (singletonPtr_ != NULL)
    181                 singletonPtr_->updateSingleton(time);
     195                singletonPtr_->preUpdateSingleton(time);
     196        }
     197
     198        //! Called every frame by the ScopedSingletonManager
     199        void postUpdate(const Clock& time)
     200        {
     201            assert(Scope<scope>::isActive());
     202            // assuming T inherits Singleton<T>
     203            if (singletonPtr_ != NULL)
     204                singletonPtr_->postUpdateSingleton(time);
    182205        }
    183206
  • code/branches/pickup2/src/libraries/core/Shell.cc

    r5929 r6412  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder
    2626 *
    2727 */
     
    3030
    3131#include "util/OutputHandler.h"
     32#include "util/StringUtils.h"
     33#include "util/SubString.h"
    3234#include "CommandExecutor.h"
    3335#include "CoreIncludes.h"
    3436#include "ConfigValueIncludes.h"
    35 #include "Core.h"
    3637#include "ConsoleCommand.h"
    37 
    38 #define SHELL_UPDATE_LISTENERS(function) \
    39     for (std::list<ShellListener*>::iterator it = this->listeners_.begin(); it != this->listeners_.end(); ) \
    40         (*(it++))->function()
    4138
    4239namespace orxonox
    4340{
    44     SetConsoleCommand(Shell, clearShell, true);
    45     SetConsoleCommand(Shell, history, true);
    46 
    4741    SetConsoleCommandShortcut(OutputHandler, log);
    4842    SetConsoleCommandShortcut(OutputHandler, error);
     
    5145    SetConsoleCommandShortcut(OutputHandler, debug);
    5246
    53     Shell* Shell::singletonPtr_s = 0;
    54 
    55     Shell::Shell()
    56     {
    57         int level = Core::getSoftDebugLevel(OutputHandler::LD_Shell);
    58         Core::setSoftDebugLevel(OutputHandler::LD_Shell, -1);
    59 
     47    Shell::Shell(const std::string& consoleName, bool bScrollable)
     48        : OutputListener(consoleName)
     49        , inputBuffer_(new InputBuffer())
     50        , consoleName_(consoleName)
     51        , bScrollable_(bScrollable)
     52    {
    6053        RegisterRootObject(Shell);
    6154
     
    6457        this->historyPosition_ = 0;
    6558        this->historyOffset_ = 0;
    66         this->finishedLastLine_ = true;
    67         this->bAddOutputLevel_ = false;
    68 
    69         this->clearLines();
    70 
    71         this->inputBuffer_ = new InputBuffer();
     59        this->bFinishedLastLine_ = true;
     60
     61        this->clearOutput();
    7262        this->configureInputBuffer();
    7363
    74         this->outputBuffer_.registerListener(this);
    75         OutputHandler::getOutStream().setOutputBuffer(&this->outputBuffer_);
    76 
    77         // Get a config file for the command history
    78         this->commandHistoryConfigFileType_ = ConfigFileManager::getInstance().getNewConfigFileType();
    79         ConfigFileManager::getInstance().setFilename(this->commandHistoryConfigFileType_, "commandHistory.ini");
     64        // Specify file for the command history
     65        ConfigFileManager::getInstance().setFilename(ConfigFileType::CommandHistory, "commandHistory.ini");
     66
     67        // Use a stringstream object to buffer the output
     68        this->outputStream_ = &this->outputBuffer_;
    8069
    8170        this->setConfigValues();
    8271
    83         Core::setSoftDebugLevel(OutputHandler::LD_Shell, level);
     72        // Get the previous output and add it to the Shell
     73        for (OutputHandler::OutputVectorIterator it = OutputHandler::getInstance().getOutputVectorBegin();
     74            it != OutputHandler::getInstance().getOutputVectorEnd(); ++it)
     75        {
     76            if (it->first <= this->getSoftDebugLevel())
     77            {
     78                this->outputBuffer_ << it->second;
     79                this->outputChanged(it->first);
     80            }
     81        }
     82
     83        // Register the shell as output listener
     84        OutputHandler::getInstance().registerOutputListener(this);
    8485    }
    8586
    8687    Shell::~Shell()
    8788    {
    88         OutputHandler::getOutStream().setOutputBuffer(0);
    89         if (this->inputBuffer_)
    90             this->inputBuffer_->destroy();
     89        OutputHandler::getInstance().unregisterOutputListener(this);
     90        this->inputBuffer_->destroy();
    9191    }
    9292
    9393    void Shell::setConfigValues()
    9494    {
    95         SetConfigValueGeneric(commandHistoryConfigFileType_, maxHistoryLength_, 100)
     95        SetConfigValue(maxHistoryLength_, 100)
    9696            .callback(this, &Shell::commandHistoryLengthChanged);
    97         SetConfigValueGeneric(commandHistoryConfigFileType_, historyOffset_, 0)
     97        SetConfigValue(historyOffset_, 0)
    9898            .callback(this, &Shell::commandHistoryOffsetChanged);
    99         SetConfigValueVectorGeneric(commandHistoryConfigFileType_, commandHistory_, std::vector<std::string>());
     99        setConfigValueGeneric(this, &commandHistory_, ConfigFileType::CommandHistory, "Shell", "commandHistory_", std::vector<std::string>());
     100
     101#ifdef ORXONOX_RELEASE
     102        const unsigned int defaultLevel = 1;
     103#else
     104        const unsigned int defaultLevel = 3;
     105#endif
     106        setConfigValueGeneric(this, &softDebugLevel_, ConfigFileType::Settings, "OutputHandler", "softDebugLevel" + this->consoleName_, defaultLevel)
     107            .description("The maximal level of debug output shown in the Shell");
     108        this->setSoftDebugLevel(this->softDebugLevel_);
    100109    }
    101110
     
    121130    {
    122131        this->inputBuffer_->registerListener(this, &Shell::inputChanged, true);
    123         this->inputBuffer_->registerListener(this, &Shell::execute, '\r', false);
    124         this->inputBuffer_->registerListener(this, &Shell::hintandcomplete, '\t', true);
    125         this->inputBuffer_->registerListener(this, &Shell::backspace, '\b', true);
    126         this->inputBuffer_->registerListener(this, &Shell::deletechar, KeyCode::Delete);
    127         this->inputBuffer_->registerListener(this, &Shell::exit, static_cast<char>(27), true);
    128         this->inputBuffer_->registerListener(this, &Shell::cursor_right, KeyCode::Right);
    129         this->inputBuffer_->registerListener(this, &Shell::cursor_left, KeyCode::Left);
    130         this->inputBuffer_->registerListener(this, &Shell::cursor_end, KeyCode::End);
    131         this->inputBuffer_->registerListener(this, &Shell::cursor_home, KeyCode::Home);
    132         this->inputBuffer_->registerListener(this, &Shell::history_up, KeyCode::Up);
    133         this->inputBuffer_->registerListener(this, &Shell::history_down, KeyCode::Down);
    134         this->inputBuffer_->registerListener(this, &Shell::scroll_up, KeyCode::PageUp);
    135         this->inputBuffer_->registerListener(this, &Shell::scroll_down, KeyCode::PageDown);
    136     }
    137 
    138     void Shell::clearShell()
    139     {
    140         Shell::getInstance().clearLines();
    141     }
    142 
     132        this->inputBuffer_->registerListener(this, &Shell::execute,         '\r',   false);
     133        this->inputBuffer_->registerListener(this, &Shell::execute,         '\n',   false);
     134        this->inputBuffer_->registerListener(this, &Shell::hintAndComplete, '\t',   true);
     135        this->inputBuffer_->registerListener(this, &Shell::backspace,       '\b',   true);
     136        this->inputBuffer_->registerListener(this, &Shell::backspace,       '\177', true);
     137        this->inputBuffer_->registerListener(this, &Shell::exit,            '\033', true); // escape
     138        this->inputBuffer_->registerListener(this, &Shell::deleteChar,      KeyCode::Delete);
     139        this->inputBuffer_->registerListener(this, &Shell::cursorRight,     KeyCode::Right);
     140        this->inputBuffer_->registerListener(this, &Shell::cursorLeft,      KeyCode::Left);
     141        this->inputBuffer_->registerListener(this, &Shell::cursorEnd,       KeyCode::End);
     142        this->inputBuffer_->registerListener(this, &Shell::cursorHome,      KeyCode::Home);
     143        this->inputBuffer_->registerListener(this, &Shell::historyUp,       KeyCode::Up);
     144        this->inputBuffer_->registerListener(this, &Shell::historyDown,     KeyCode::Down);
     145        if (this->bScrollable_)
     146        {
     147            this->inputBuffer_->registerListener(this, &Shell::scrollUp,    KeyCode::PageUp);
     148            this->inputBuffer_->registerListener(this, &Shell::scrollDown,  KeyCode::PageDown);
     149        }
     150        else
     151        {
     152            this->inputBuffer_->registerListener(this, &Shell::historySearchUp,   KeyCode::PageUp);
     153            this->inputBuffer_->registerListener(this, &Shell::historySearchDown, KeyCode::PageDown);
     154        }
     155    }
     156
     157    /*
    143158    void Shell::history()
    144159    {
     
    146161
    147162        for (unsigned int i = instance.historyOffset_; i < instance.commandHistory_.size(); ++i)
    148             instance.addLine(instance.commandHistory_[i], -1);
     163            instance.addOutput(instance.commandHistory_[i] + '\n', -1);
    149164        for (unsigned int i =  0; i < instance.historyOffset_; ++i)
    150             instance.addLine(instance.commandHistory_[i], -1);
    151     }
     165            instance.addOutput(instance.commandHistory_[i] + '\n', -1);
     166    }
     167    */
    152168
    153169    void Shell::registerListener(ShellListener* listener)
    154170    {
    155         this->listeners_.insert(this->listeners_.end(), listener);
     171        this->listeners_.push_back(listener);
    156172    }
    157173
     
    161177        {
    162178            if ((*it) == listener)
    163                 this->listeners_.erase(it++);
     179                it = this->listeners_.erase(it);
    164180            else
    165181                ++it;
     
    170186    {
    171187        this->inputBuffer_->setCursorPosition(cursor);
    172         SHELL_UPDATE_LISTENERS(cursorChanged);
    173     }
    174 
    175     void Shell::setInput(const std::string& input)
    176     {
    177         this->inputBuffer_->set(input);
    178         this->inputChanged();
    179     }
    180 
    181     void Shell::addLine(const std::string& line, int level)
    182     {
    183         int original_level = OutputHandler::getOutStream().getOutputLevel();
    184         OutputHandler::getOutStream().setOutputLevel(level);
    185 
    186         if (!this->finishedLastLine_)
    187             this->outputBuffer_ << std::endl;
    188 
    189         this->outputBuffer_ << line << std::endl;
    190         OutputHandler::getOutStream().setOutputLevel(original_level);
    191     }
    192 
    193     void Shell::clearLines()
    194     {
    195         this->lines_.clear();
    196         this->scrollIterator_ = this->lines_.begin();
     188        this->updateListeners<&ShellListener::cursorChanged>();
     189    }
     190
     191    void Shell::addOutput(const std::string& text, LineType type)
     192    {
     193        this->outputBuffer_ << text;
     194        this->outputChanged(type);
     195    }
     196
     197    void Shell::clearOutput()
     198    {
     199        this->outputLines_.clear();
     200        this->scrollIterator_ = this->outputLines_.begin();
    197201
    198202        this->scrollPosition_ = 0;
    199         this->finishedLastLine_ = true;
    200 
    201         SHELL_UPDATE_LISTENERS(linesChanged);
    202     }
    203 
    204     std::list<std::string>::const_iterator Shell::getNewestLineIterator() const
     203        this->bFinishedLastLine_ = true;
     204
     205        this->updateListeners<&ShellListener::linesChanged>();
     206    }
     207
     208    Shell::LineList::const_iterator Shell::getNewestLineIterator() const
    205209    {
    206210        if (this->scrollPosition_)
    207211            return this->scrollIterator_;
    208212        else
    209             return this->lines_.begin();
    210     }
    211 
    212     std::list<std::string>::const_iterator Shell::getEndIterator() const
    213     {
    214         return this->lines_.end();
     213            return this->outputLines_.begin();
     214    }
     215
     216    Shell::LineList::const_iterator Shell::getEndIterator() const
     217    {
     218        return this->outputLines_.end();
    215219    }
    216220
     
    222226    }
    223227
    224     std::string Shell::getFromHistory() const
     228    const std::string& Shell::getFromHistory() const
    225229    {
    226230        unsigned int index = mod(static_cast<int>(this->historyOffset_) - static_cast<int>(this->historyPosition_), this->maxHistoryLength_);
     
    228232            return this->commandHistory_[index];
    229233        else
    230             return "";
    231     }
    232 
    233     void Shell::outputChanged()
    234     {
    235         std::string output;
    236         bool newline;
     234            return BLANKSTRING;
     235    }
     236
     237    void Shell::outputChanged(int lineType)
     238    {
     239        bool newline = false;
    237240        do
    238241        {
    239             newline = this->outputBuffer_.getLine(&output);
    240 
    241             if (!newline && output == "")
     242            std::string output;
     243            std::getline(this->outputBuffer_, output);
     244
     245            bool eof = this->outputBuffer_.eof();
     246            bool fail = this->outputBuffer_.fail();
     247            if (eof)
     248                this->outputBuffer_.flush();
     249            if (eof || fail)
     250                this->outputBuffer_.clear();
     251            newline = (!eof && !fail);
     252
     253            if (!newline && output.empty())
    242254                break;
    243255
    244             if (this->finishedLastLine_)
     256            if (this->bFinishedLastLine_)
    245257            {
    246                 if (this->bAddOutputLevel_)
    247                     output.insert(0, 1, static_cast<char>(OutputHandler::getOutStream().getOutputLevel()));
    248 
    249                 this->lines_.insert(this->lines_.begin(), output);
     258                this->outputLines_.push_front(std::make_pair(output, static_cast<LineType>(lineType)));
    250259
    251260                if (this->scrollPosition_)
    252261                    this->scrollPosition_++;
    253262                else
    254                     this->scrollIterator_ = this->lines_.begin();
    255 
    256                 this->finishedLastLine_ = newline;
     263                    this->scrollIterator_ = this->outputLines_.begin();
     264
     265                this->bFinishedLastLine_ = newline;
    257266
    258267                if (!this->scrollPosition_)
    259                 {
    260                     SHELL_UPDATE_LISTENERS(lineAdded);
    261                 }
     268                    this->updateListeners<&ShellListener::lineAdded>();
    262269            }
    263270            else
    264271            {
    265                 (*this->lines_.begin()) += output;
    266                 this->finishedLastLine_ = newline;
    267                 SHELL_UPDATE_LISTENERS(onlyLastLineChanged);
     272                this->outputLines_.front().first += output;
     273                this->bFinishedLastLine_ = newline;
     274                this->updateListeners<&ShellListener::onlyLastLineChanged>();
    268275            }
     276            this->bFinishedLastLine_ = newline;
    269277
    270278        } while (newline);
    271279    }
    272280
    273     void Shell::inputChanged()
    274     {
    275         SHELL_UPDATE_LISTENERS(inputChanged);
    276         SHELL_UPDATE_LISTENERS(cursorChanged);
    277     }
    278 
    279     void Shell::execute()
    280     {
    281         this->addToHistory(this->inputBuffer_->get());
    282         this->addLine(this->inputBuffer_->get(), 0);
    283 
    284         if (!CommandExecutor::execute(this->inputBuffer_->get()))
    285             this->addLine("Error: Can't execute \"" + this->inputBuffer_->get() + "\".", 1);
    286 
    287         this->clear();
    288     }
    289 
    290     void Shell::hintandcomplete()
    291     {
    292         this->inputBuffer_->set(CommandExecutor::complete(this->inputBuffer_->get()));
    293         this->addLine(CommandExecutor::hint(this->inputBuffer_->get()), -1);
    294 
    295         this->inputChanged();
    296     }
    297 
    298     void Shell::backspace()
    299     {
    300         this->inputBuffer_->removeBehindCursor();
    301         SHELL_UPDATE_LISTENERS(inputChanged);
    302         SHELL_UPDATE_LISTENERS(cursorChanged);
    303     }
    304 
    305     void Shell::deletechar()
    306     {
    307         this->inputBuffer_->removeAtCursor();
    308         SHELL_UPDATE_LISTENERS(inputChanged);
    309     }
    310 
    311     void Shell::clear()
     281    void Shell::clearInput()
    312282    {
    313283        this->inputBuffer_->clear();
    314284        this->historyPosition_ = 0;
    315         SHELL_UPDATE_LISTENERS(inputChanged);
    316         SHELL_UPDATE_LISTENERS(cursorChanged);
    317     }
    318 
    319     void Shell::cursor_right()
     285        this->updateListeners<&ShellListener::inputChanged>();
     286        this->updateListeners<&ShellListener::cursorChanged>();
     287    }
     288
     289    void Shell::setPromptPrefix(const std::string& str)
     290    {
     291    }
     292
     293
     294    // ##########################################
     295    // ###   InputBuffer callback functions   ###
     296    // ##########################################
     297
     298    void Shell::inputChanged()
     299    {
     300        this->updateListeners<&ShellListener::inputChanged>();
     301        this->updateListeners<&ShellListener::cursorChanged>();
     302    }
     303
     304    void Shell::execute()
     305    {
     306        this->addToHistory(this->inputBuffer_->get());
     307        this->updateListeners<&ShellListener::executed>();
     308
     309        if (!CommandExecutor::execute(this->inputBuffer_->get()))
     310        {
     311            this->outputBuffer_ << "Error: Can't execute \"" << this->inputBuffer_->get() << "\"." << std::endl;
     312            this->outputChanged(Error);
     313        }
     314
     315        this->clearInput();
     316    }
     317
     318    void Shell::hintAndComplete()
     319    {
     320        this->inputBuffer_->set(CommandExecutor::complete(this->inputBuffer_->get()));
     321        this->outputBuffer_ << CommandExecutor::hint(this->inputBuffer_->get()) << std::endl;
     322        this->outputChanged(Hint);
     323
     324        this->inputChanged();
     325    }
     326
     327    void Shell::backspace()
     328    {
     329        this->inputBuffer_->removeBehindCursor();
     330        this->updateListeners<&ShellListener::inputChanged>();
     331        this->updateListeners<&ShellListener::cursorChanged>();
     332    }
     333
     334    void Shell::exit()
     335    {
     336        if (this->inputBuffer_->getSize() > 0)
     337        {
     338            this->clearInput();
     339            return;
     340        }
     341
     342        this->clearInput();
     343        this->scrollPosition_ = 0;
     344        this->scrollIterator_ = this->outputLines_.begin();
     345
     346        this->updateListeners<&ShellListener::exit>();
     347    }
     348
     349    void Shell::deleteChar()
     350    {
     351        this->inputBuffer_->removeAtCursor();
     352        this->updateListeners<&ShellListener::inputChanged>();
     353    }
     354
     355    void Shell::cursorRight()
    320356    {
    321357        this->inputBuffer_->increaseCursor();
    322         SHELL_UPDATE_LISTENERS(cursorChanged);
    323     }
    324 
    325     void Shell::cursor_left()
     358        this->updateListeners<&ShellListener::cursorChanged>();
     359    }
     360
     361    void Shell::cursorLeft()
    326362    {
    327363        this->inputBuffer_->decreaseCursor();
    328         SHELL_UPDATE_LISTENERS(cursorChanged);
    329     }
    330 
    331     void Shell::cursor_end()
     364        this->updateListeners<&ShellListener::cursorChanged>();
     365    }
     366
     367    void Shell::cursorEnd()
    332368    {
    333369        this->inputBuffer_->setCursorToEnd();
    334         SHELL_UPDATE_LISTENERS(cursorChanged);
    335     }
    336 
    337     void Shell::cursor_home()
     370        this->updateListeners<&ShellListener::cursorChanged>();
     371    }
     372
     373    void Shell::cursorHome()
    338374    {
    339375        this->inputBuffer_->setCursorToBegin();
    340         SHELL_UPDATE_LISTENERS(cursorChanged);
    341     }
    342 
    343     void Shell::history_up()
     376        this->updateListeners<&ShellListener::cursorChanged>();
     377    }
     378
     379    void Shell::historyUp()
    344380    {
    345381        if (this->historyPosition_ < this->commandHistory_.size())
     
    350386    }
    351387
    352     void Shell::history_down()
     388    void Shell::historyDown()
    353389    {
    354390        if (this->historyPosition_ > 0)
     
    359395    }
    360396
    361     void Shell::scroll_up()
    362     {
    363         if (this->scrollIterator_ != this->lines_.end())
     397    void Shell::historySearchUp()
     398    {
     399        if (this->historyPosition_ == this->historyOffset_)
     400            return;
     401        unsigned int cursorPosition = this->getCursorPosition();
     402        const std::string& input_str(this->getInput().substr(0, cursorPosition)); // only search for the expression from the beginning of the inputline until the cursor position
     403        for (unsigned int newPos = this->historyPosition_ + 1; newPos <= this->historyOffset_; newPos++)
     404        {
     405            if (getLowercase(this->commandHistory_[this->historyOffset_ - newPos]).find(getLowercase(input_str)) == 0) // search case insensitive
     406            {
     407                this->historyPosition_ = newPos;
     408                this->inputBuffer_->set(this->getFromHistory());
     409                this->setCursorPosition(cursorPosition);
     410                return;
     411            }
     412        }
     413    }
     414
     415    void Shell::historySearchDown()
     416    {
     417        if (this->historyPosition_ == 0)
     418            return;
     419        unsigned int cursorPosition = this->getCursorPosition();
     420        const std::string& input_str(this->getInput().substr(0, cursorPosition)); // only search for the expression from the beginning
     421        for (unsigned int newPos = this->historyPosition_ - 1; newPos > 0; newPos--)
     422        {
     423            if (getLowercase(this->commandHistory_[this->historyOffset_ - newPos]).find(getLowercase(input_str)) == 0) // sear$
     424            {
     425                this->historyPosition_ = newPos;
     426                this->inputBuffer_->set(this->getFromHistory());
     427                this->setCursorPosition(cursorPosition);
     428                return;
     429            }
     430        }
     431    }
     432
     433    void Shell::scrollUp()
     434    {
     435        if (this->scrollIterator_ != this->outputLines_.end())
    364436        {
    365437            ++this->scrollIterator_;
    366438            ++this->scrollPosition_;
    367439
    368             SHELL_UPDATE_LISTENERS(linesChanged);
    369         }
    370     }
    371 
    372     void Shell::scroll_down()
    373     {
    374         if (this->scrollIterator_ != this->lines_.begin())
     440            this->updateListeners<&ShellListener::linesChanged>();
     441        }
     442    }
     443
     444    void Shell::scrollDown()
     445    {
     446        if (this->scrollIterator_ != this->outputLines_.begin())
    375447        {
    376448            --this->scrollIterator_;
    377449            --this->scrollPosition_;
    378450
    379             SHELL_UPDATE_LISTENERS(linesChanged);
    380         }
    381     }
    382 
    383     void Shell::exit()
    384     {
    385         if (this->inputBuffer_->getSize() > 0)
    386         {
    387             this->clear();
    388             return;
    389         }
    390 
    391         this->clear();
    392         this->scrollPosition_ = 0;
    393         this->scrollIterator_ = this->lines_.begin();
    394 
    395         SHELL_UPDATE_LISTENERS(exit);
     451            this->updateListeners<&ShellListener::linesChanged>();
     452        }
    396453    }
    397454}
  • code/branches/pickup2/src/libraries/core/Shell.h

    r5781 r6412  
    2323 *      Fabian 'x3n' Landau
    2424 *   Co-authors:
    25  *      ...
     25 *      Reto Grieder
    2626 *
    2727 */
     
    3232#include "CorePrereqs.h"
    3333
    34 #include <cassert>
    3534#include <list>
     35#include <sstream>
    3636#include <string>
    3737#include <vector>
    3838
    39 #include "util/OutputBuffer.h"
    40 #include "input/InputBuffer.h"
     39#include "util/OutputHandler.h"
    4140#include "OrxonoxClass.h"
    4241#include "ConfigFileManager.h"
     42#include "input/InputBuffer.h"
    4343
    4444namespace orxonox
     
    5757            virtual void inputChanged() {}
    5858            virtual void cursorChanged() {}
     59            virtual void executed() {}
    5960            virtual void exit() {}
    6061    };
    6162
    62     class _CoreExport Shell : public Singleton<Shell>, virtual public OrxonoxClass, public OutputBufferListener
     63
     64    class _CoreExport Shell : virtual public OrxonoxClass, public OutputListener
    6365    {
    64         friend class Singleton<Shell>;
    6566        public:
    66             Shell();
    67             virtual ~Shell();
     67            enum LineType
     68            {
     69                None    = OutputLevel::None,
     70                Warning = OutputLevel::Warning,
     71                Error   = OutputLevel::Error,
     72                Info    = OutputLevel::Info,
     73                Debug   = OutputLevel::Debug,
     74                Verbose = OutputLevel::Verbose,
     75                Ultra   = OutputLevel::Ultra,
     76                Input,
     77                Command,
     78                Hint
     79            };
    6880
    69             static void clearShell();
    70             static void history();
     81            Shell(const std::string& consoleName, bool bScrollable);
     82            ~Shell();
    7183
    72             virtual void setConfigValues();
     84            void setConfigValues();
    7385            void commandHistoryOffsetChanged();
    7486            void commandHistoryLengthChanged();
     
    7991            inline InputBuffer* getInputBuffer()
    8092                { return this->inputBuffer_; }
    81             inline OutputBuffer& getOutputBuffer()
    82                 { return this->outputBuffer_; }
    8393
    8494            void setCursorPosition(unsigned int cursor);
     
    8696                { return this->inputBuffer_->getCursorPosition(); }
    8797
    88             void setInput(const std::string& input);
    89 
    90             inline void clearInput()
    91                 { this->setInput(""); }
    92             inline std::string getInput() const
     98            inline const std::string& getInput() const
    9399                { return this->inputBuffer_->get(); }
    94100
    95             std::list<std::string>::const_iterator getNewestLineIterator() const;
    96             std::list<std::string>::const_iterator getEndIterator() const;
     101            typedef std::list<std::pair<std::string, LineType> > LineList;
     102            LineList::const_iterator getNewestLineIterator() const;
     103            LineList::const_iterator getEndIterator() const;
    97104
    98             void addLine(const std::string& line, int level = 0);
    99             void clearLines();
     105            void addOutput(const std::string& text, LineType type = None);
     106            void clearOutput();
    100107
    101108            inline unsigned int getNumLines() const
    102                 { return this->lines_.size(); }
     109                { return this->outputLines_.size(); }
    103110            inline unsigned int getScrollPosition() const
    104111                { return this->scrollPosition_; }
    105112
    106             inline void addOutputLevel(bool bAddOutputLevel)
    107                 { this->bAddOutputLevel_ = bAddOutputLevel; }
     113            inline const std::string& getPromptPrefix() const { return this->promptPrefix_; }
     114            void setPromptPrefix(const std::string& str);
    108115
    109116        private:
    110117            Shell(const Shell& other);
    111118
     119            void addToHistory(const std::string& command);
     120            const std::string& getFromHistory() const;
     121            void clearInput();
     122            // OutputListener
     123            void outputChanged(int level);
     124
    112125            void configureInputBuffer();
    113126
    114             void addToHistory(const std::string& command);
    115             std::string getFromHistory() const;
    116 
    117             virtual void outputChanged();
     127            // InputBuffer callbacks
    118128            void inputChanged();
    119129            void execute();
    120             void hintandcomplete();
     130            void hintAndComplete();
    121131            void backspace();
    122             void deletechar();
    123             void clear();
    124             void cursor_right();
    125             void cursor_left();
    126             void cursor_end();
    127             void cursor_home();
    128             void history_up();
    129             void history_down();
    130             void scroll_up();
    131             void scroll_down();
     132            void deleteChar();
     133            void cursorRight();
     134            void cursorLeft();
     135            void cursorEnd();
     136            void cursorHome();
     137            void historyUp();
     138            void historyDown();
     139            void historySearchUp();
     140            void historySearchDown();
     141            void scrollUp();
     142            void scrollDown();
    132143            void exit();
    133144
     145            template <void (ShellListener::*F)()>
     146            void updateListeners()
     147            {
     148                for (std::list<ShellListener*>::const_iterator it = this->listeners_.begin(); it != this->listeners_.end(); )
     149                    ((*(it++))->*F)();
     150            }
     151
    134152            std::list<ShellListener*> listeners_;
    135             InputBuffer* inputBuffer_;
    136             OutputBuffer outputBuffer_;
    137             bool finishedLastLine_;
    138             std::list<std::string> lines_;
    139             std::list<std::string>::const_iterator scrollIterator_;
    140             unsigned int scrollPosition_;
    141             std::vector<std::string> commandHistory_;
    142             unsigned int maxHistoryLength_;
    143             unsigned int historyPosition_;
    144             unsigned int historyOffset_;
    145             bool bAddOutputLevel_;
     153            InputBuffer*              inputBuffer_;
     154            std::stringstream         outputBuffer_;
     155            bool                      bFinishedLastLine_;
     156            LineList                  outputLines_;
     157            LineList::const_iterator  scrollIterator_;
     158            unsigned int              scrollPosition_;
     159            unsigned int              historyPosition_;
    146160
    147             ConfigFileType commandHistoryConfigFileType_;
     161            std::string               promptPrefix_;
     162            const std::string         consoleName_;
     163            const bool                bScrollable_;
    148164
    149             static Shell* singletonPtr_s;
     165            // Config values
     166            unsigned int              maxHistoryLength_;
     167            unsigned int              historyOffset_;
     168            std::vector<std::string>  commandHistory_;
     169            int                       softDebugLevel_;
    150170    };
    151171}
  • code/branches/pickup2/src/libraries/core/SmartPtr.h

    r5929 r6412  
    8484                    this->base_->decrementReferenceCount();
    8585            }
    86            
     86
    8787            inline const SmartPtr& operator=(int)
    8888            {
  • code/branches/pickup2/src/libraries/core/SubclassIdentifier.h

    r5929 r6412  
    9898                    if (identifier)
    9999                    {
    100                         COUT(1) << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << "!" << std::endl;
     100                        COUT(1) << "Error: Class " << identifier->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << '!' << std::endl;
    101101                        COUT(1) << "Error: SubclassIdentifier<" << ClassIdentifier<T>::getIdentifier()->getName() << "> = Class(" << identifier->getName() << ") is forbidden." << std::endl;
    102102                    }
     
    166166                    {
    167167                        COUT(1) << "An error occurred in SubclassIdentifier (Identifier.h):" << std::endl;
    168                         COUT(1) << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << "!" << std::endl;
     168                        COUT(1) << "Error: Class " << this->identifier_->getName() << " is not a " << ClassIdentifier<T>::getIdentifier()->getName() << '!' << std::endl;
    169169                        COUT(1) << "Error: Couldn't fabricate a new Object." << std::endl;
    170170                    }
  • code/branches/pickup2/src/libraries/core/TclBind.cc

    r5929 r6412  
    101101    {
    102102        Tcl::interpreter* interpreter = new Tcl::interpreter();
    103         std::string libpath = TclBind::getTclLibraryPath();
     103        const std::string& libpath = TclBind::getTclLibraryPath();
    104104
    105105        try
    106106        {
    107             if (libpath != "")
    108                 interpreter->eval("set tcl_library \"" + libpath + "\"");
     107            if (!libpath.empty())
     108                interpreter->eval("set tcl_library \"" + libpath + '"');
    109109
    110110            Tcl_Init(interpreter->get());
     
    136136        COUT(4) << "Tcl_query: " << args.get() << std::endl;
    137137
    138         std::string command = stripEnclosingBraces(args.get());
     138        const std::string& command = stripEnclosingBraces(args.get());
    139139
    140140        if (!CommandExecutor::execute(command, false))
     
    152152    {
    153153        COUT(4) << "Tcl_execute: " << args.get() << std::endl;
    154         std::string command = stripEnclosingBraces(args.get());
     154        const std::string& command = stripEnclosingBraces(args.get());
    155155
    156156        if (!CommandExecutor::execute(command, false))
     
    166166            try
    167167            {
    168                 std::string output = TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
    169                 if (output != "")
     168                const std::string& output = TclBind::getInstance().interpreter_->eval("uplevel #0 " + tclcode);
     169                if (!output.empty())
    170170                {
    171171                    COUT(0) << "tcl> " << output << std::endl;
     
    182182    }
    183183
    184     void TclBind::bgerror(std::string error)
     184    void TclBind::bgerror(const std::string& error)
    185185    {
    186186        COUT(1) << "Tcl background error: " << stripEnclosingBraces(error) << std::endl;
  • code/branches/pickup2/src/libraries/core/TclBind.h

    r5781 r6412  
    4646
    4747            static std::string tcl(const std::string& tclcode);
    48             static void bgerror(std::string error);
     48            static void bgerror(const std::string& error);
    4949
    5050            void setDataPath(const std::string& datapath);
  • code/branches/pickup2/src/libraries/core/TclThreadManager.cc

    r5929 r6412  
    3939#include "util/Convert.h"
    4040#include "util/Exception.h"
     41#include "util/StringUtils.h"
    4142#include "CommandExecutor.h"
    4243#include "ConsoleCommand.h"
     
    122123        @brief The "main loop" of the TclThreadManager. Creates new threads if needed and handles queries and queued commands for the main interpreter.
    123124    */
    124     void TclThreadManager::update(const Clock& time)
     125    void TclThreadManager::preUpdate(const Clock& time)
    125126    {
    126127        // Get the bundle of the main interpreter (0)
     
    252253    void TclThreadManager::initialize(TclInterpreterBundle* bundle)
    253254    {
    254         std::string id_string = getConvertedValue<unsigned int, std::string>(bundle->id_);
     255        const std::string& id_string = getConvertedValue<unsigned int, std::string>(bundle->id_);
    255256
    256257        // Initialize the new interpreter
     
    403404            {
    404405                // This query would lead to a deadlock - return with an error
    405                 TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + " " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
     406                TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + ' ' + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
    406407                            + " -> " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
    407408                            + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
    408                             + " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) + ".");
     409                            + " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) + '.');
    409410            }
    410411            else
     
    524525    std::string TclThreadManager::dumpList(const std::list<unsigned int>& list)
    525526    {
    526         std::string output = "";
     527        std::string output;
    527528        for (std::list<unsigned int>::const_iterator it = list.begin(); it != list.end(); ++it)
    528529        {
    529530            if (it != list.begin())
    530                 output += " ";
     531                output += ' ';
    531532
    532533            output += getConvertedValue<unsigned int, std::string>(*it);
     
    600601        @param command the Command to execute
    601602    */
    602     void tclThread(TclInterpreterBundle* bundle, std::string command)
     603    void tclThread(TclInterpreterBundle* bundle, const std::string& command)
    603604    {
    604605        TclThreadManager::debug("TclThread_execute: " + command);
     
    613614        @param file The name of the file that should be executed by the non-interactive interpreter.
    614615    */
    615     void sourceThread(std::string file)
     616    void sourceThread(const std::string& file)
    616617    {
    617618        TclThreadManager::debug("TclThread_source: " + file);
     
    651652
    652653        // Initialize the non-interactive interpreter (like in @ref TclBind::createTclInterpreter but exception safe)
    653         std::string libpath = TclBind::getTclLibraryPath();
    654         if (libpath != "")
    655             TclThreadManager::eval(bundle, "set tcl_library \"" + libpath + "\"", "source");
     654        const std::string& libpath = TclBind::getTclLibraryPath();
     655        if (!libpath.empty())
     656            TclThreadManager::eval(bundle, "set tcl_library \"" + libpath + '"', "source");
    656657        int cc = Tcl_Init(interp);
    657658        TclThreadManager::eval(bundle, "source \"" + TclBind::getInstance().getTclDataPath() + "/init.tcl\"", "source");
  • code/branches/pickup2/src/libraries/core/TclThreadManager.h

    r5781 r6412  
    4848        friend class Singleton<TclThreadManager>;
    4949        friend class TclBind;
    50         friend _CoreExport void tclThread(TclInterpreterBundle* bundle, std::string command);
    51         friend _CoreExport void sourceThread(std::string file);
     50        friend _CoreExport void tclThread(TclInterpreterBundle* bundle, const std::string& command);
     51        friend _CoreExport void sourceThread(const std::string& file);
    5252        friend _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
    5353
     
    6666            static void debug(const std::string& error);
    6767
    68             void update(const Clock& time);
     68            void preUpdate(const Clock& time);
    6969
    7070            std::list<unsigned int> getThreadList() const;
     
    9595    };
    9696
    97     _CoreExport void tclThread(TclInterpreterBundle* bundle, std::string command);
    98     _CoreExport void sourceThread(std::string file);
     97    _CoreExport void tclThread(TclInterpreterBundle* bundle, const std::string& command);
     98    _CoreExport void sourceThread(const std::string& file);
    9999    _CoreExport int Tcl_OrxonoxAppInit(Tcl_Interp* interp);
    100100}
  • code/branches/pickup2/src/libraries/core/Template.cc

    r5781 r6412  
    7979        SUPER(Template, changedName);
    8080
    81         if (this->getName() != "")
     81        if (!this->getName().empty())
    8282        {
    8383            std::map<std::string, Template*>::iterator it;
  • code/branches/pickup2/src/libraries/core/Template.h

    r5781 r6412  
    4848
    4949            inline void setLink(const std::string& link)
    50                 { this->link_ = link; this->bIsLink_ = (link != ""); }
     50                { this->link_ = link; this->bIsLink_ = !link.empty(); }
    5151            inline const std::string& getLink() const
    5252                { return this->link_; }
  • code/branches/pickup2/src/libraries/core/Thread.cc

    r5738 r6412  
    4141{
    4242    boost::posix_time::millisec THREAD_WAIT_BEFORE_DETACH(1000);
    43    
    44    
     43
     44
    4545    Thread::Thread():
    4646        executor_(0),
     
    5353        this->workerThread_ = new boost::thread( boost::bind(&Thread::threadLoop, this) );
    5454    }
    55    
     55
    5656    Thread::~Thread()
    5757    {
     
    6666        delete this->isWorkingMutex_;
    6767    }
    68    
     68
    6969    bool Thread::isWorking()
    7070    {
     
    7474      return isWorking;
    7575    }
    76    
     76
    7777    bool Thread::evaluateExecutor( Executor* executor )
    7878    {
     
    8585        return true;
    8686    }
    87    
     87
    8888    void Thread::threadLoop()
    8989    {
     
    114114        }
    115115    }
    116    
     116
    117117    void Thread::waitUntilFinished()
    118118    {
  • code/branches/pickup2/src/libraries/core/Thread.h

    r5738 r6412  
    5050    private:
    5151        void            threadLoop();
    52        
     52
    5353        Executor*       executor_;
    5454        bool            isWorking_;
  • code/branches/pickup2/src/libraries/core/ThreadPool.cc

    r5738 r6412  
    3737    {
    3838    }
    39    
     39
    4040    ThreadPool::~ThreadPool()
    4141    {
     
    4343        assert(a == 0);
    4444    }
    45    
     45
    4646    void ThreadPool::addThreads( unsigned int nr )
    4747    {
     
    8080        }
    8181    }
    82    
     82
    8383    bool ThreadPool::passFunction( Executor* executor, bool addThread )
    8484    {
     
    103103            return false;
    104104    }
    105    
     105
    106106    void ThreadPool::synchronise()
    107107    {
  • code/branches/pickup2/src/libraries/core/ThreadPool.h

    r5738 r6412  
    4141        ThreadPool();
    4242        virtual ~ThreadPool();
    43        
     43
    4444        void addThreads( unsigned int nr );
    4545        unsigned int removeThreads( unsigned int nr );
    4646        unsigned int setNrOfThreads( unsigned int nr );
    47        
     47
    4848        bool passFunction( Executor* executor, bool addThread=false );
    4949        void synchronise();
    50        
     50
    5151    private:
    5252        std::vector<Thread*> threadPool_;
    53        
     53
    5454    };
    5555}
  • code/branches/pickup2/src/libraries/core/WeakPtr.h

    r5929 r6412  
    4444    {
    4545        friend class OrxonoxClass;
    46        
     46
    4747        public:
    4848            inline WeakPtr() : pointer_(0), base_(0), callback_(0)
     
    7979                if (this->callback_)
    8080                    delete this->callback_;
    81                    
    82             }
    83            
     81
     82            }
     83
    8484            inline const WeakPtr& operator=(int)
    8585            {
     
    145145                if (other.base_)
    146146                    other.base_->unregisterWeakPtr(&other);
    147                
     147
    148148                {
    149149                    T* temp = this->pointer_;
     
    167167                WeakPtr().swap(*this);
    168168            }
    169            
     169
    170170            inline void setCallback(Functor* callback)
    171171            {
    172172                this->callback_ = callback;
    173173            }
    174            
     174
    175175            inline Functor* getFunctor() const
    176176            {
     
    186186                    (*this->callback_)();
    187187            }
    188        
     188
    189189            T* pointer_;
    190190            OrxonoxClass* base_;
  • code/branches/pickup2/src/libraries/core/XMLFile.h

    r5781 r6412  
    4040    {
    4141        public:
    42             XMLFile(const std::string& filename, const std::string& resourceGroup = "General")
     42            XMLFile(const std::string& filename)
    4343                : filename_(filename)
    44                 , group_(resourceGroup)
    4544                , bLuaSupport_(true)
    4645            { }
    47             XMLFile(const ClassTreeMask& mask, const std::string& filename, const std::string& resourceGroup = "General")
     46            XMLFile(const ClassTreeMask& mask, const std::string& filename)
    4847                : filename_(filename)
    49                 , group_(resourceGroup)
    5048                , mask_(mask)
    5149                , bLuaSupport_(true)
     
    5553
    5654            const std::string& getFilename() const { return this->filename_; }
    57             const std::string& getResourceGroup() const { return this->group_; }
    5855            const ClassTreeMask& getMask() const { return this->mask_; }
    5956            bool getLuaSupport() const { return this->bLuaSupport_; }
     
    6158        private:
    6259            std::string filename_;
    63             std::string group_;
    6460            ClassTreeMask mask_;
    6561            bool bLuaSupport_; // Default is true
  • code/branches/pickup2/src/libraries/core/XMLPort.h

    r5929 r6412  
    5151#include "util/MultiType.h"
    5252#include "util/OrxAssert.h"
     53#include "util/StringUtils.h"
    5354#include "Identifier.h"
    5455#include "Executor.h"
     
    184185        ClassIdentifier<classname>::getIdentifier()->addXMLPortParamContainer(paramname, containername); \
    185186    } \
    186     containername->port(static_cast<BaseObject*>(this), object, xmlelement, mode)
     187    containername->port(dynamic_cast<BaseObject*>(this), object, xmlelement, mode)
    187188
    188189// --------------------
     
    316317                { return this->paramname_; }
    317318
    318             virtual XMLPortParamContainer& description(const std::string description) = 0;
     319            virtual XMLPortParamContainer& description(const std::string& description) = 0;
    319320            virtual const std::string& getDescription() = 0;
    320321
     
    344345
    345346        public:
    346             XMLPortClassParamContainer(const std::string paramname, Identifier* identifier, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor)
     347            XMLPortClassParamContainer(const std::string& paramname, Identifier* identifier, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor)
    347348            {
    348349                this->paramname_ = paramname;
     
    385386                        }
    386387                        std::map<std::string, std::string>::const_iterator it = this->owner_->xmlAttributes_.find(getLowercase(this->paramname_));
    387                         std::string attributeValue("");
     388                        std::string attributeValue;
    388389                        if (it != this->owner_->xmlAttributes_.end())
    389390                            attributeValue = it->second;
     
    407408                    {
    408409                        COUT(1) << std::endl;
    409                         COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << this->owner_->getName() << ") in " << this->owner_->getFilename() << ":" << std::endl;
     410                        COUT(1) << "An error occurred in XMLPort.h while loading attribute '" << this->paramname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << this->owner_->getName() << ") in " << this->owner_->getFilename() << ':' << std::endl;
    410411                        COUT(1) << ex.what() << std::endl;
    411412                    }
     
    435436            }
    436437
    437             virtual XMLPortParamContainer& description(const std::string description)
     438            virtual XMLPortParamContainer& description(const std::string& description)
    438439                { this->loadexecutor_->setDescription(description); return (*this); }
    439440            virtual const std::string& getDescription()
     
    497498                { return this->sectionname_; }
    498499
    499             virtual XMLPortObjectContainer& description(const std::string description) = 0;
     500            virtual XMLPortObjectContainer& description(const std::string& description) = 0;
    500501            virtual const std::string& getDescription() = 0;
    501502
     
    513514    {
    514515        public:
    515             XMLPortClassObjectContainer(const std::string sectionname, Identifier* identifier, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor, bool bApplyLoaderMask, bool bLoadBefore)
     516            XMLPortClassObjectContainer(const std::string& sectionname, Identifier* identifier, ExecutorMember<T>* loadexecutor, ExecutorMember<T>* saveexecutor, bool bApplyLoaderMask, bool bLoadBefore)
    516517            {
    517518                this->sectionname_ = sectionname;
     
    538539                    {
    539540                        Element* xmlsubelement;
    540                         if ((this->sectionname_ != "") && (this->sectionname_.size() > 0))
     541                        if (!this->sectionname_.empty())
    541542                            xmlsubelement = xmlelement.FirstChildElement(this->sectionname_, false);
    542543                        else
     
    570571                                                    {
    571572                                                        newObject->XMLPort(*child, XMLPort::LoadObject);
    572                                                         COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ")" << std::endl;
     573                                                        COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (objectname " << newObject->getName() << ") to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ')' << std::endl;
    573574                                                    }
    574575                                                    else
    575576                                                    {
    576                                                         COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ")" << std::endl;
     577                                                        COUT(4) << object->getLoaderIndentation() << "assigning " << child->Value() << " (object not yet loaded) to " << this->identifier_->getName() << " (objectname " << static_cast<BaseObject*>(object)->getName() << ')' << std::endl;
    577578                                                    }
    578579
     
    609610                                else
    610611                                {
    611                                     if (this->sectionname_ != "")
     612                                    if (!this->sectionname_.empty())
    612613                                    {
    613614                                        COUT(2) << object->getLoaderIndentation() << "Warning: '" << child->Value() << "' is not a valid classname." << std::endl;
     
    624625                    {
    625626                        COUT(1) << std::endl;
    626                         COUT(1) << "An error occurred in XMLPort.h while loading a '" << ClassIdentifier<O>::getIdentifier()->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << object->getName() << ") in " << object->getFilename() << ":" << std::endl;
     627                        COUT(1) << "An error occurred in XMLPort.h while loading a '" << ClassIdentifier<O>::getIdentifier()->getName() << "' in '" << this->sectionname_ << "' of '" << this->identifier_->getName() << "' (objectname: " << object->getName() << ") in " << object->getFilename() << ':' << std::endl;
    627628                        COUT(1) << ex.what() << std::endl;
    628629                    }
     
    635636            }
    636637
    637             virtual XMLPortObjectContainer& description(const std::string description)
     638            virtual XMLPortObjectContainer& description(const std::string& description)
    638639                { this->loadexecutor_->setDescription(description); return (*this); }
    639640            virtual const std::string& getDescription()
  • code/branches/pickup2/src/libraries/core/input/Button.cc

    r5929 r6412  
    116116        for (unsigned int iCommand = 0; iCommand < commandStrings.size(); iCommand++)
    117117        {
    118             if (commandStrings[iCommand] != "")
     118            if (!commandStrings[iCommand].empty())
    119119            {
    120120                SubString tokens(commandStrings[iCommand], " ", SubString::WhiteSpaces, false,
     
    123123                KeybindMode::Value mode = KeybindMode::None;
    124124                float paramModifier = 1.0f;
    125                 std::string commandStr = "";
     125                std::string commandStr;
    126126
    127127                for (unsigned int iToken = 0; iToken < tokens.size(); ++iToken)
    128128                {
    129                     std::string token = getLowercase(tokens[iToken]);
     129                    const std::string& token = getLowercase(tokens[iToken]);
    130130
    131131                    if (token == "onpress")
     
    159159                        // we interpret everything from here as a command string
    160160                        while (iToken != tokens.size())
    161                             commandStr += tokens[iToken++] + " ";
    162                     }
    163                 }
    164 
    165                 if (commandStr == "")
     161                            commandStr += tokens[iToken++] + ' ';
     162                    }
     163                }
     164
     165                if (commandStr.empty())
    166166                {
    167167                    parseError("No command string given.", false);
     
    242242    }
    243243
    244     inline void Button::parseError(std::string message, bool serious)
     244    inline void Button::parseError(const std::string& message, bool serious)
    245245    {
    246246        if (serious)
  • code/branches/pickup2/src/libraries/core/input/Button.h

    r5781 r6412  
    7676
    7777    private:
    78         void parseError(std::string message, bool serious);
     78        void parseError(const std::string& message, bool serious);
    7979    };
    8080
  • code/branches/pickup2/src/libraries/core/input/InputBuffer.cc

    r5781 r6412  
    3939        RegisterRootObject(InputBuffer);
    4040
    41         this->buffer_ = "";
    4241        this->cursor_ = 0;
     42        this->maxLength_ = 1024;
    4343        this->allowedChars_ = "abcdefghijklmnopqrstuvwxyz \
    4444                               ABCDEFGHIJKLMNOPQRSTUVWXYZ \
     
    5959        RegisterRootObject(InputBuffer);
    6060
     61        this->maxLength_ = 1024;
    6162        this->allowedChars_ = allowedChars;
    62         this->buffer_ = "";
    6363        this->cursor_ = 0;
    6464
     
    8080    void InputBuffer::setConfigValues()
    8181    {
    82         SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat deleay of the input buffer");
     82        SetConfigValue(keyRepeatDeleay_, 0.4).description("Key repeat delay of the input buffer");
    8383        SetConfigValue(keyRepeatTime_, 0.022).description("Key repeat time of the input buffer");
    8484
     
    9191            ResetConfigValue(keyRepeatTime_);
    9292        }
     93    }
     94
     95    void InputBuffer::setMaxLength(unsigned int length)
     96    {
     97        this->maxLength_ = length;
     98        if (this->buffer_.size() > length)
     99            this->buffer_.resize(length);
    93100    }
    94101
     
    117124        if (this->charIsAllowed(input))
    118125        {
     126            if (this->buffer_.size() >= this->maxLength_)
     127                return;
    119128            this->buffer_.insert(this->cursor_, 1, input);
    120129            ++this->cursor_;
     
    127136    void InputBuffer::clear(bool update)
    128137    {
    129         this->buffer_ = "";
     138        this->buffer_.clear();
    130139        this->cursor_ = 0;
    131140
     
    177186    bool InputBuffer::charIsAllowed(const char& input)
    178187    {
    179         if (this->allowedChars_ == "")
     188        if (this->allowedChars_.empty())
    180189            return true;
    181190        else
     
    186195    void InputBuffer::processKey(const KeyEvent& evt)
    187196    {
     197        // Prevent disaster when switching applications
    188198        if (evt.isModifierDown(KeyboardModifier::Alt) && evt.getKeyCode() == KeyCode::Tab)
    189199            return;
     
    222232
    223233    /**
    224         @brief This update() function is called by the InputManager if the InputBuffer is active.
     234        @brief This update() function is called by the InputState if the InputBuffer is active.
    225235        @param dt Delta time
    226236    */
  • code/branches/pickup2/src/libraries/core/input/InputBuffer.h

    r5781 r6412  
    8383            void setConfigValues();
    8484
     85            unsigned int getMaxLength() const { return this->maxLength_; }
     86            void setMaxLength(unsigned int length);
     87
    8588            template <class T>
    8689            void registerListener(T* listener, void (T::*function)(), bool bOnlySingleInput)
     
    162165                { if (this->cursor_ > 0) { --this->cursor_; } }
    163166
     167            void buttonPressed(const KeyEvent& evt);
     168
    164169        private:
    165170            bool charIsAllowed(const char& input);
    166171
    167             void buttonPressed(const KeyEvent& evt);
    168172            void buttonHeld   (const KeyEvent& evt);
    169173            void processKey   (const KeyEvent& evt);
     
    174178            std::list<BaseInputBufferListenerTuple*> listeners_;
    175179            std::string allowedChars_;
     180            unsigned int maxLength_;
    176181            unsigned int cursor_;
    177182
  • code/branches/pickup2/src/libraries/core/input/InputCommands.h

    r5781 r6412  
    7171    @brief
    7272        Executes a simple command with no additional paramters.
    73     @return 
     73    @return
    7474        True if command execution was successful, false otherwise.
    7575    */
  • code/branches/pickup2/src/libraries/core/input/InputDevice.h

    r5929 r6412  
    203203        {
    204204            // remove the button from the pressedButtons_ list
     205            bool found = false;
    205206            for (unsigned int iButton = 0; iButton < pressedButtons_.size(); iButton++)
    206207            {
     
    208209                {
    209210                    pressedButtons_.erase(pressedButtons_.begin() + iButton);
     211                    found = true;
    210212                    break;
    211213                }
    212214            }
     215            if (!found)
     216                return; // We ignore release strokes when the press was not captured
    213217
    214218            // Call states
  • code/branches/pickup2/src/libraries/core/input/InputHandler.h

    r5781 r6412  
    7373            , modifiers_(0)
    7474        { }
     75        KeyEvent(KeyCode::ByEnum key, unsigned int text, int modifiers)
     76            : key_(key)
     77            , text_(text)
     78            , modifiers_(modifiers)
     79        { }
    7580        bool operator==(const KeyEvent& rhs) const
    7681            { return rhs.key_ == key_; }
     
    97102
    98103        Derive from this class if you wish to receive input events.
    99         But keep in mind that this is pointless wihtout first having an InputState.
     104        But keep in mind that this is pointless without first having an InputState.
    100105    @note
    101106        The definitions for the button events with the weird arguments are simply
    102         to avoid redunant code in the input devices.
     107        to avoid redundant code in the input devices.
    103108    */
    104109    class _CoreExport InputHandler
  • code/branches/pickup2/src/libraries/core/input/InputManager.cc

    r5929 r6412  
    4848#include "core/ConfigValueIncludes.h"
    4949#include "core/ConsoleCommand.h"
    50 #include "core/CommandLine.h"
     50#include "core/CommandLineParser.h"
    5151#include "core/Functor.h"
    5252#include "core/GraphicsManager.h"
     
    170170        if (mouseMode_ == MouseMode::Exclusive || GraphicsManager::getInstance().isFullScreen())
    171171        {
    172             if (CommandLine::getValue("keyboard_no_grab").getBool())
     172            if (CommandLineParser::getValue("keyboard_no_grab").getBool())
    173173                paramList.insert(std::make_pair("x11_keyboard_grab", "false"));
    174174            else
     
    190190            // Exception-safety
    191191            Loki::ScopeGuard guard = Loki::MakeGuard(OIS::InputManager::destroyInputSystem, oisInputManager_);
    192             CCOUT(ORX_DEBUG) << "Created OIS input manager." << std::endl;
     192            CCOUT(4) << "Created OIS input manager." << std::endl;
    193193
    194194            if (oisInputManager_->getNumberOfDevices(OIS::OISKeyboard) > 0)
     
    232232        }
    233233        else
    234             CCOUT(ORX_WARNING) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
     234            CCOUT(2) << "Warning: No mouse found! Proceeding without mouse support." << std::endl;
    235235    }
    236236
     
    275275        // destroy all user InputStates
    276276        while (statesByName_.size() > 0)
    277             this->destroyStateInternal((*statesByName_.rbegin()).second);
     277            this->destroyStateInternal(statesByName_.rbegin()->second);
    278278
    279279        if (!(internalState_ & Bad))
     
    297297            if (device == NULL)
    298298                continue;
    299             std::string className = device->getClassName();
     299            const std::string& className = device->getClassName();
    300300            try
    301301            {
     
    366366    // ############################################################
    367367
    368     void InputManager::update(const Clock& time)
     368    void InputManager::preUpdate(const Clock& time)
    369369    {
    370370        if (internalState_ & Bad)
     
    466466    @brief
    467467        Updates the currently active states (according to activeStates_) for each device.
    468         Also, a list of all active states (no duplicates!) is compiled for the general update().
     468        Also, a list of all active states (no duplicates!) is compiled for the general preUpdate().
    469469    */
    470470    void InputManager::updateActiveStates()
     
    508508        if (mouseStates.empty())
    509509            requestedMode = MouseMode::Nonexclusive;
    510         else 
     510        else
    511511            requestedMode = mouseStates.front()->getMouseMode();
    512512        if (requestedMode != MouseMode::Dontcare && mouseMode_ != requestedMode)
     
    554554    }
    555555
    556     //! Gets called by WindowEventListener upon focus change --> clear buffers 
     556    //! Gets called by WindowEventListener upon focus change --> clear buffers
    557557    void InputManager::windowFocusChanged()
    558558    {
     
    579579    InputState* InputManager::createInputState(const std::string& name, bool bAlwaysGetsInput, bool bTransparent, InputStatePriority priority)
    580580    {
    581         if (name == "")
     581        if (name.empty())
    582582            return 0;
    583583        if (statesByName_.find(name) == statesByName_.end())
     
    631631                {
    632632                    // not scheduled for destruction
    633                     // prevents a state being added multiple times
     633                    // prevents a state from being added multiple times
    634634                    stateEnterRequests_.insert(it->second);
    635635                    return true;
    636636                }
    637637            }
     638            else if (this->stateLeaveRequests_.find(it->second) != this->stateLeaveRequests_.end())
     639            {
     640                // State already scheduled for leaving --> cancel
     641                this->stateLeaveRequests_.erase(this->stateLeaveRequests_.find(it->second));
     642            }
    638643        }
    639644        return false;
     
    658663                return true;
    659664            }
     665            else if (this->stateEnterRequests_.find(it->second) != this->stateEnterRequests_.end())
     666            {
     667                // State already scheduled for entering --> cancel
     668                this->stateEnterRequests_.erase(this->stateEnterRequests_.find(it->second));
     669            }
    660670        }
    661671        return false;
  • code/branches/pickup2/src/libraries/core/input/InputManager.h

    r5929 r6412  
    4141#include "InputState.h"
    4242
     43// tolua_begin
    4344namespace orxonox
    4445{
     
    4748        Manages the input devices (mouse, keyboard, joy sticks) and the input states.
    4849
    49         Every input device has its own wrapper class which does the actualy input event
     50        Every input device has its own wrapper class which does the actually input event
    5051        distribution. The InputManager only creates reloads (on request) those devices.
    5152
     
    5859          in the InputDevices themselves.
    5960        - The devices_ vector always has at least two elements: Keyboard (first) and mouse.
    60           You best access them intenally with InputDeviceEnumerator::Keyboard/Mouse
     61          You best access them internally with InputDeviceEnumerator::Keyboard/Mouse
    6162          The first joy stick is accessed with InputDeviceEnumerator::FirstJoyStick.
    6263        - Keyboard construction is mandatory , mouse and joy sticks are not.
    6364          If the OIS::InputManager or the Keyboard fail, an exception is thrown.
    6465    */
    65     class _CoreExport InputManager : public Singleton<InputManager>, public WindowEventListener
    66     {
     66    class _CoreExport InputManager
     67// tolua_end
     68        : public Singleton<InputManager>, public WindowEventListener
     69    { // tolua_export
    6770        friend class Singleton<InputManager>;
    6871    public:
     
    8083        @brief
    8184            Loads the devices and initialises the KeyDetector and the Calibrator.
    82            
     85
    8386            If either the OIS input system and/or the keyboard could not be created,
    8487            the constructor fails with an std::exception.
     
    9497
    9598            Any InpuStates changes (destroy, enter, leave) and happens here. If a reload request
    96             was submitted while updating, the request wil be postponed until the next update call.
    97         */
    98         void update(const Clock& time);
     99            was submitted while updating, the request will be postponed until the next update call.
     100        */
     101        void preUpdate(const Clock& time);
    99102        //! Clears all input device buffers. This usually only includes the pressed button list.
    100103        void clearBuffers();
     
    105108            Reloads all the input devices. Use this method to initialise new joy sticks.
    106109        @note
    107             Only reloads immediately if the call stack doesn't include the update() method.
     110            Only reloads immediately if the call stack doesn't include the preUpdate() method.
    108111        */
    109112        void reload();
     
    135138        @brief
    136139            Activates a specific input state.
    137             It might not be actually activated if the priority is too low!
     140            It might not actually be activated if the priority is too low!
    138141        @return
    139142            False if name was not found, true otherwise.
    140143        */
    141         bool enterState(const std::string& name);
     144        bool enterState(const std::string& name); // tolua_export
    142145        /**
    143146        @brief
     
    146149            False if name was not found, true otherwise.
    147150        */
    148         bool leaveState(const std::string& name);
     151        bool leaveState(const std::string& name); // tolua_export
    149152        /**
    150153        @brief
     
    154157        @remarks
    155158            - You can't remove the internal states "empty", "calibrator" and "detector".
    156             - The removal process is being postponed if InputManager::update() is currently running.
     159            - The removal process is being postponed if InputManager::preUpdate() is currently running.
    157160        */
    158161        bool destroyState(const std::string& name);
     
    168171        std::pair<int, int> getMousePosition() const;
    169172
     173        static InputManager& getInstance() { return Singleton<InputManager>::getInstance(); } // tolua_export
     174
    170175    private: // functions
    171176        // don't mess with a Singleton
    172177        InputManager(const InputManager&);
    173178
    174         // Intenal methods
     179        // Internal methods
    175180        void loadDevices();
    176181        void loadMouse();
     
    207212
    208213        static InputManager*                singletonPtr_s;        //!< Pointer reference to the singleton
    209     };
    210 }
     214    }; // tolua_export
     215} // tolua_export
    211216
    212217#endif /* _InputManager_H__ */
  • code/branches/pickup2/src/libraries/core/input/InputPrereqs.h

    r5781 r6412  
    202202            MediaSelect   = OIS::KC_MEDIASELECT      // Media Select
    203203        };
    204        
     204
    205205        //! Key codes as strings
    206206        const char* const ByString[] =
  • code/branches/pickup2/src/libraries/core/input/InputState.cc

    r5929 r6412  
    102102        if (enterFunctor_)
    103103            (*enterFunctor_)();
    104            
     104
    105105    }
    106106
  • code/branches/pickup2/src/libraries/core/input/JoyStick.cc

    r5781 r6412  
    3333#include <boost/foreach.hpp>
    3434
     35#include "util/StringUtils.h"
    3536#include "core/ConfigFileManager.h"
    3637#include "core/ConfigValueIncludes.h"
     
    6162            std::string name = oisDevice_->vendor();
    6263            replaceCharacters(name, ' ', '_');
    63             deviceName_ = name + "_";
    64         }
    65         deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + "_";
    66         deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + "_";
    67         deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + "_";
     64            deviceName_ = name + '_';
     65        }
     66        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Button))  + '_';
     67        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Axis))    + '_';
     68        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Slider))  + '_';
    6869        deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_POV));
    6970        //deviceName_ += multi_cast<std::string>(oisDevice_->getNumberOfComponents(OIS::OIS_Vector3));
     
    7475            {
    7576                // Make the ID unique for this execution time.
    76                 deviceName_ += "_" + multi_cast<std::string>(this->getDeviceName());
     77                deviceName_ += '_' + multi_cast<std::string>(this->getDeviceName());
    7778                break;
    7879            }
  • code/branches/pickup2/src/libraries/core/input/JoyStickQuantityListener.h

    r5781 r6412  
    2929/**
    3030@file
    31 @brief 
     31@brief
    3232*/
    3333
  • code/branches/pickup2/src/libraries/core/input/KeyBinder.cc

    r5929 r6412  
    2929#include "KeyBinder.h"
    3030
     31#include <algorithm>
     32#include <sstream>
    3133#include "util/Convert.h"
    3234#include "util/Debug.h"
     
    5052        mouseRelative_[0] = 0;
    5153        mouseRelative_[1] = 0;
    52         mousePosition_[0] = 0;
    53         mousePosition_[1] = 0;
     54        mousePosition_[0] = 0.0;
     55        mousePosition_[1] = 0.0;
    5456
    5557        RegisterRootObject(KeyBinder);
     
    5961        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
    6062        {
    61             std::string keyname = KeyCode::ByString[i];
     63            const std::string& keyname = KeyCode::ByString[i];
    6264            if (!keyname.empty())
    6365                keys_[i].name_ = std::string("Key") + keyname;
    6466            else
    65                 keys_[i].name_ = "";
     67                keys_[i].name_.clear();
    6668            keys_[i].paramCommandBuffer_ = &paramCommandBuffer_;
    6769            keys_[i].groupName_ = "Keys";
     
    126128        SetConfigValue(bFilterAnalogNoise_, false)
    127129            .description("Specifies whether to filter small analog values like joy stick fluctuations.");
    128         SetConfigValue(mouseSensitivity_, 1.0f)
     130        SetConfigValue(mouseSensitivity_, 3.0f)
    129131            .description("Mouse sensitivity.");
     132        this->totalMouseSensitivity_ = this->mouseSensitivity_ / this->mouseClippingSize_;
    130133        SetConfigValue(bDeriveMouseInput_, false)
    131134            .description("Whether or not to derive moues movement for the absolute value.");
     
    185188        this->joyStickButtons_.resize(joySticks_.size());
    186189
    187         // reinitialise all joy stick binings (doesn't overwrite the old ones)
     190        // reinitialise all joy stick bindings (doesn't overwrite the old ones)
    188191        for (unsigned int iDev = 0; iDev < joySticks_.size(); iDev++)
    189192        {
    190             std::string deviceName = joySticks_[iDev]->getDeviceName();
     193            const std::string& deviceName = joySticks_[iDev]->getDeviceName();
    191194            // joy stick buttons
    192195            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
     
    218221        for (unsigned int i = 0; i < KeyCode::numberOfKeys; i++)
    219222            if (!keys_[i].name_.empty())
    220                 allButtons_[keys_[i].groupName_ + "." + keys_[i].name_] = keys_ + i;
     223                allButtons_[keys_[i].groupName_ + '.' + keys_[i].name_] = keys_ + i;
    221224        for (unsigned int i = 0; i < numberOfMouseButtons_; i++)
    222             allButtons_[mouseButtons_[i].groupName_ + "." + mouseButtons_[i].name_] = mouseButtons_ + i;
     225            allButtons_[mouseButtons_[i].groupName_ + '.' + mouseButtons_[i].name_] = mouseButtons_ + i;
    223226        for (unsigned int i = 0; i < MouseAxisCode::numberOfAxes * 2; i++)
    224227        {
    225             allButtons_[mouseAxes_[i].groupName_ + "." + mouseAxes_[i].name_] = mouseAxes_ + i;
     228            allButtons_[mouseAxes_[i].groupName_ + '.' + mouseAxes_[i].name_] = mouseAxes_ + i;
    226229            allHalfAxes_.push_back(mouseAxes_ + i);
    227230        }
     
    229232        {
    230233            for (unsigned int i = 0; i < JoyStickButtonCode::numberOfButtons; i++)
    231                 allButtons_[(*joyStickButtons_[iDev])[i].groupName_ + "." + (*joyStickButtons_[iDev])[i].name_] = &((*joyStickButtons_[iDev])[i]);
     234                allButtons_[(*joyStickButtons_[iDev])[i].groupName_ + '.' + (*joyStickButtons_[iDev])[i].name_] = &((*joyStickButtons_[iDev])[i]);
    232235            for (unsigned int i = 0; i < JoyStickAxisCode::numberOfAxes * 2; i++)
    233236            {
    234                 allButtons_[(*joyStickAxes_[iDev])[i].groupName_ + "." + (*joyStickAxes_[iDev])[i].name_] = &((*joyStickAxes_[iDev])[i]);
     237                allButtons_[(*joyStickAxes_[iDev])[i].groupName_ + '.' + (*joyStickAxes_[iDev])[i].name_] = &((*joyStickAxes_[iDev])[i]);
    235238                allHalfAxes_.push_back(&((*joyStickAxes_[iDev])[i]));
    236239            }
     
    253256        // Parse bindings and create the ConfigValueContainers if necessary
    254257        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
     258        {
    255259            it->second->readConfigValue(this->configFile_);
     260            addButtonToCommand(it->second->bindingString_, it->second);
     261        }
    256262
    257263        COUT(3) << "KeyBinder: Loading key bindings done." << std::endl;
     
    263269        if (it != allButtons_.end())
    264270        {
     271            addButtonToCommand(binding, it->second);
    265272            if (bTemporary)
    266273                it->second->configContainer_->tset(binding);
     
    275282            return false;
    276283        }
     284    }
     285
     286     void KeyBinder::addButtonToCommand(const std::string& command, Button* button)
     287     {
     288        std::ostringstream stream;
     289        stream << button->groupName_  << '.' << button->name_;
     290
     291        std::vector<std::string>& oldKeynames = this->allCommands_[button->bindingString_];
     292        std::vector<std::string>::iterator it = std::find(oldKeynames.begin(), oldKeynames.end(), stream.str());
     293        if(it != oldKeynames.end())
     294        {
     295            oldKeynames.erase(it);
     296        }
     297
     298        if (!command.empty())
     299        {
     300            std::vector<std::string>& keynames = this->allCommands_[command];
     301            if( std::find(keynames.begin(), keynames.end(), stream.str()) == keynames.end())
     302            {
     303                this->allCommands_[command].push_back(stream.str());
     304            }
     305        }
     306     }
     307
     308    /**
     309    @brief
     310        Return the first key name for a specific command
     311    */
     312    const std::string& KeyBinder::getBinding(const std::string& commandName)
     313    {
     314        if( this->allCommands_.find(commandName) != this->allCommands_.end())
     315        {
     316            std::vector<std::string>& keynames = this->allCommands_[commandName];
     317            return keynames.front();
     318        }
     319
     320        return BLANKSTRING;
     321    }
     322
     323    /**
     324    @brief
     325        Return the key name for a specific command at a given index.
     326    @param commandName
     327        The command name the key name is returned for.
     328    @param index
     329        The index at which the key name is returned for.
     330    */
     331    const std::string& KeyBinder::getBinding(const std::string& commandName, unsigned int index)
     332    {
     333        if( this->allCommands_.find(commandName) != this->allCommands_.end())
     334        {
     335            std::vector<std::string>& keynames = this->allCommands_[commandName];
     336            if(index < keynames.size())
     337            {
     338                return keynames[index];
     339            }
     340
     341            return BLANKSTRING;
     342        }
     343
     344        return BLANKSTRING;
     345    }
     346
     347    /**
     348    @brief
     349        Get the number of different key bindings of a specific command.
     350    @param commandName
     351        The command.
     352    */
     353    unsigned int KeyBinder::getNumberOfBindings(const std::string& commandName)
     354    {
     355        if( this->allCommands_.find(commandName) != this->allCommands_.end())
     356        {
     357            std::vector<std::string>& keynames = this->allCommands_[commandName];
     358            return keynames.size();
     359        }
     360
     361        return 0;
    277362    }
    278363
     
    395480
    396481        // these are the actually useful axis bindings for analog input
    397         if (!bFilterAnalogNoise_ || halfAxis.relVal_ > analogThreshold_ || halfAxis.absVal_ > analogThreshold_)
    398         {
    399             halfAxis.execute();
    400         }
     482        halfAxis.execute();
    401483    }
    402484
     
    426508                    mouseAxes_[2*i + 0].hasChanged_ = true;
    427509                    mouseAxes_[2*i + 1].hasChanged_ = true;
    428                     mousePosition_[i] += rel[i];
     510                    mousePosition_[i] += rel[i] * totalMouseSensitivity_;
    429511
    430512                    // clip absolute position
    431                     if (mousePosition_[i] > mouseClippingSize_)
    432                         mousePosition_[i] =  mouseClippingSize_;
    433                     if (mousePosition_[i] < -mouseClippingSize_)
    434                         mousePosition_[i] = -mouseClippingSize_;
    435 
    436                     if (mousePosition_[i] < 0)
     513                    if (mousePosition_[i] > 1.0)
     514                        mousePosition_[i] =  1.0;
     515                    if (mousePosition_[i] < -1.0)
     516                        mousePosition_[i] = -1.0;
     517
     518                    if (mousePosition_[i] < 0.0)
    437519                    {
    438                         mouseAxes_[2*i + 0].absVal_ = -mouseSensitivity_ * mousePosition_[i] / mouseClippingSize_;
     520                        mouseAxes_[2*i + 0].absVal_ = -mousePosition_[i];
    439521                        mouseAxes_[2*i + 1].absVal_ = 0.0f;
    440522                    }
     
    442524                    {
    443525                        mouseAxes_[2*i + 0].absVal_ = 0.0f;
    444                         mouseAxes_[2*i + 1].absVal_ =  mouseSensitivity_ * mousePosition_[i] / mouseClippingSize_;
     526                        mouseAxes_[2*i + 1].absVal_ =  mousePosition_[i];
    445527                    }
    446528                }
     
    452534        {
    453535            if (rel[i] < 0)
    454                 mouseAxes_[0 + 2*i].relVal_ = -mouseSensitivity_ * rel[i] / mouseClippingSize_;
     536                mouseAxes_[0 + 2*i].relVal_ = -rel[i] * totalMouseSensitivity_;
    455537            else
    456                 mouseAxes_[1 + 2*i].relVal_ =  mouseSensitivity_ * rel[i] / mouseClippingSize_;
     538                mouseAxes_[1 + 2*i].relVal_ =  rel[i] * totalMouseSensitivity_;
    457539        }
    458540    }
     
    474556    void KeyBinder::axisMoved(unsigned int device, unsigned int axisID, float value)
    475557    {
     558        // Filter analog noise
     559        if (this->bFilterAnalogNoise_ && std::abs(value) < this->analogThreshold_)
     560            value = 0.0;
    476561        int i = axisID * 2;
    477562        JoyStickAxisVector& axis = *joyStickAxes_[device];
  • code/branches/pickup2/src/libraries/core/input/KeyBinder.h

    r5929 r6412  
    3535#include <string>
    3636#include <vector>
     37#include <map>
    3738#include <boost/shared_ptr.hpp>
    3839
     
    4344#include "JoyStickQuantityListener.h"
    4445
     46// tolua_begin
    4547namespace orxonox
    4648{
     49    // tolua_end
    4750    /**
    4851    @brief
     
    5457        KeyBinders. If you need to load other bindings, just create a new one.
    5558    */
    56     class _CoreExport KeyBinder : public InputHandler, public JoyStickQuantityListener
    57     {
     59    class _CoreExport KeyBinder // tolua_export
     60        : public InputHandler, public JoyStickQuantityListener
     61    { // tolua_export
    5862    public:
    5963        KeyBinder (const std::string& filename);
     
    6266        void clearBindings();
    6367        bool setBinding(const std::string& binding, const std::string& name, bool bTemporary = false);
     68        const std::string& getBinding(const std::string& commandName); //tolua_export
     69        const std::string& getBinding(const std::string& commandName, unsigned int index); //tolua_export
     70        unsigned int getNumberOfBindings(const std::string& commandName); //tolua_export
     71
    6472        const std::string& getBindingsFilename()
    6573            { return this->filename_; }
     
    130138        //! Pointer list with all half axes
    131139        std::vector<HalfAxis*> allHalfAxes_;
     140        //! Maps input commands to all Button names, including half axes
     141        std::map< std::string, std::vector<std::string> > allCommands_;
    132142
    133143        /**
     
    138148        std::vector<BufferedParamCommand*> paramCommandBuffer_;
    139149
    140         //! Keeps track of the absolute mouse value (incl. scroll wheel)
    141         int mousePosition_[2];
     150        //! Keeps track of the absolute mouse value
     151        float mousePosition_[2];
    142152        //! Used to derive mouse input if requested
    143153        int mouseRelative_[2];
     
    150160
    151161    private:
     162        void addButtonToCommand(const std::string& command, Button* button);
     163
    152164        //##### ConfigValues #####
    153165        //! Whether to filter small value analog input
     
    165177        //! mouse sensitivity if mouse input is derived
    166178        float mouseSensitivityDerived_;
    167         //! Equals one step of the mousewheel
     179        //! Equals one step of the mouse wheel
    168180        int mouseWheelStepSize_;
     181
     182        //! Multiplication of mouse sensitivity and clipping size
     183        float totalMouseSensitivity_;
    169184
    170185        //##### Constant config variables #####
    171186        // Use some value at about 1000. This can be configured with mouseSensitivity_ anyway.
    172187        static const int mouseClippingSize_ = 1024;
    173     };
     188    };// tolua_export
    174189
    175190
     
    216231            mouseAxes_[i].relVal_ = 0.0f;
    217232    }
    218 }
     233}// tolua_export
    219234
    220235#endif /* _KeyBinder_H__ */
  • code/branches/pickup2/src/libraries/core/input/KeyBinderManager.cc

    r5929 r6412  
    4040namespace orxonox
    4141{
    42     KeyBinderManager* KeyBinderManager::singletonPtr_s = 0;
    4342    ManageScopedSingleton(KeyBinderManager, ScopeID::Graphics, false);
    4443
     
    4847        , bBinding_(false)
    4948    {
    50         this->callbackFunction_ = createFunctor(&KeyBinderManager::callback, this);
    51 
    5249        RegisterObject(KeyBinderManager);
    5350        this->setConfigValues();
     
    5754            .defaultValues("");
    5855        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::tkeybind, this), "tkeybind"))
     56            .defaultValues("");
     57        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::unbind, this), "unbind"))
     58            .defaultValues("");
     59        CommandExecutor::addConsoleCommandShortcut(createConsoleCommand(createFunctor(&KeyBinderManager::tunbind, this), "tunbind"))
    5960            .defaultValues("");
    6061
     
    6869        for (std::map<std::string, KeyBinder*>::const_iterator it = this->binders_.begin(); it != this->binders_.end(); ++it)
    6970            delete it->second;
    70         delete this->callbackFunction_;
    7171    }
    7272
     
    9191        else
    9292            this->bDefaultFileLoaded_ = false;
     93    }
     94
     95    inline void KeyBinderManager::unbind(const std::string& binding)
     96    {
     97        this->currentBinder_->setBinding("", binding, false);
     98    }
     99
     100    inline void KeyBinderManager::tunbind(const std::string& binding)
     101    {
     102        this->currentBinder_->setBinding("", binding, true);
    93103    }
    94104
     
    146156        {
    147157            COUT(0) << "Press any button/key or move a mouse/joystick axis" << std::endl;
    148             KeyDetector::getInstance().setCallback(callbackFunction_);
     158            KeyDetector::getInstance().setCallback(shared_ptr<Functor>(createFunctor(&KeyBinderManager::keybindKeyPressed, this)));
    149159            InputManager::getInstance().enterState("detector");
    150160            this->command_ = command;
     
    156166
    157167    // Gets called by the KeyDetector (registered with a Functor)
    158     void KeyBinderManager::callback(const std::string& keyName)
     168    void KeyBinderManager::keybindKeyPressed(const std::string& keyName)
    159169    {
    160170        if (this->bBinding_)
    161171        {
    162             COUT(0) << "Binding string \"" << command_ << "\" on key '" << keyName << "'" << std::endl;
    163             this->currentBinder_->setBinding(command_, keyName, bTemporary_);
     172            if (keyName == "Keys.KeyEscape")
     173            {
     174                COUT(0) << "Keybinding aborted." << std::endl;
     175            }
     176            else
     177            {
     178                COUT(0) << "Binding string \"" << command_ << "\" on key '" << keyName << "'" << std::endl;
     179                this->currentBinder_->setBinding(command_, keyName, bTemporary_);
     180            }
    164181            InputManager::getInstance().leaveState("detector");
     182            // inform whatever was calling the command
     183            if (this->callbackFunction_)
     184                (*this->callbackFunction_)();
    165185            this->bBinding_ = false;
    166186        }
  • code/branches/pickup2/src/libraries/core/input/KeyBinderManager.h

    r5929 r6412  
    3434#include <map>
    3535#include <string>
     36#include <boost/shared_ptr.hpp>
     37
    3638#include "util/Singleton.h"
    3739#include "core/OrxonoxClass.h"
    3840
    39 namespace orxonox
    40 {
     41namespace orxonox //tolua_export
     42{ //tolua_export
    4143    /**
    4244    @brief
     
    4648        maps to the currently active KeyBinder. You can set that with setCurrent().
    4749        There is also a default one, retrieved with getDefault(). The idea is that
    48         mostly the default KeyBinder is active except for special situtations (mini-game for inst).
     50        mostly the default KeyBinder is active except for special situations (mini-game for inst).
    4951    @remarks
    5052        You are not forced to use the KeyBinder imposed by getCurrent(). But be aware that "keybind"
    5153        will not work as expected!
    5254    */
    53     class _CoreExport KeyBinderManager : public Singleton<KeyBinderManager>, public OrxonoxClass
    54     {
     55    class _CoreExport KeyBinderManager //tolua_export
     56        : public Singleton<KeyBinderManager>, public OrxonoxClass
     57    { //tolua_export
    5558        friend class Singleton<KeyBinderManager>;
    5659    public:
     
    5962        void setConfigValues();
    6063
     64        static KeyBinderManager& getInstance() { return Singleton<KeyBinderManager>::getInstance(); } //tolua_export
    6165        //! Returns the currently selected KeyBinder
    62         KeyBinder*    getCurrent()
    63             { return this->currentBinder_; }
     66        KeyBinder* getCurrent() { return this->currentBinder_; } //tolua_export
    6467        //! Like getCurrent(), but returns it as InputHandler* (so you don't have to include KeyBinder.h)
    6568        InputHandler* getCurrentAsHandler();
     
    6871
    6972        //! Returns the default KeyBinder
    70         KeyBinder*    getDefault()
     73        KeyBinder* getDefault()
    7174            { return binders_[this->defaultFilename_]; }
    7275        //! Returns the default KeyBinder as InputHandler* (so you don't have to include KeyBinder.h)
     
    8083
    8184        //! Returns a pointer to a KeyBinder (creates it if not yet loaded)
    82         KeyBinder*    get(const std::string& name);
     85        KeyBinder* get(const std::string& name);
    8386        //! Like get() but return value is of type InputHandler* (so you don't have to include KeyBinder.h)
    8487        InputHandler* getAsHandler(const std::string& name);
    8588
    8689        //! Loads a KeyBinder by creating it (no different from get() except for the return value)
    87         void load  (const std::string& filename);
     90        void load(const std::string& filename);
    8891        //! Destroys a KeyBinder completely (does nothing if not yet loaded)
    8992        void unload(const std::string& filename);
    9093
    9194        //! Bind 'command' to any key pressed after this call (use with care!)
    92         inline void keybind(const std::string& command)
    93             { this->keybindInternal(command, false); }
     95        inline void keybind(const std::string& command) { this->keybindInternal(command, false); } //tolua_export
    9496        //! Bind 'command' to any key pressed after this call (use with care!), but temporarily (no file save)
    9597        inline void tkeybind(const std::string& command)
    9698            { this->keybindInternal(command, true); }
     99        void unbind(const std::string& binding); //tolua_export
     100        void tunbind(const std::string& binding);
     101        inline void registerKeybindCallback(Functor* function) { this->callbackFunction_.reset(function); } // tolua_export
    97102
    98103    private:
    99104        KeyBinderManager(const KeyBinderManager&);
    100105        void keybindInternal(const std::string& command, bool bTemporary);
    101         void callback(const std::string& keyName);
     106        void keybindKeyPressed(const std::string& keyName);
    102107        void defaultFilenameChanged();
    103108
     
    109114
    110115        // keybind command related
    111         Functor* callbackFunction_;                  //! Function to be called when key was pressed after "keybind" command
     116        shared_ptr<Functor> callbackFunction_;       //! Function to be called when key was pressed after "keybind" command
    112117        bool bBinding_;                              //! Tells whether a key binding process is active
    113118        bool bTemporary_;                            //! Stores tkeybind/keybind value
     
    115120
    116121        static KeyBinderManager* singletonPtr_s;
    117     };
    118 }
     122    }; //tolua_export
     123} //tolua_export
    119124
    120125#endif /* _KeyBinderManager_H__ */
  • code/branches/pickup2/src/libraries/core/input/KeyDetector.cc

    r5929 r6412  
    3939{
    4040    std::string KeyDetector::callbackCommand_s = "KeyDetectorKeyPressed";
    41     KeyDetector* KeyDetector::singletonPtr_s = 0;
    4241    ManageScopedSingleton(KeyDetector, ScopeID::Graphics, false);
    4342
     
    6867        for (std::map<std::string, Button*>::const_iterator it = allButtons_.begin(); it != allButtons_.end(); ++it)
    6968        {
    70             it->second->bindingString_ = callbackCommand_s + " " + it->second->groupName_ + "." + it->second->name_;
     69            it->second->bindingString_ = callbackCommand_s + ' ' + it->second->groupName_ + "." + it->second->name_;
    7170            it->second->parse();
    7271        }
  • code/branches/pickup2/src/libraries/core/input/KeyDetector.h

    r5929 r6412  
    3232#include "InputPrereqs.h"
    3333
     34#include <boost/shared_ptr.hpp>
    3435#include "util/Singleton.h"
    3536#include "KeyBinder.h"
     
    4546        ~KeyDetector();
    4647
    47         void setCallback(Functor* function) { this->callbackFunction_ = function; }
     48        void setCallback(const shared_ptr<Functor>& function) { this->callbackFunction_ = function; }
    4849
    4950    private:
     
    5455        void assignCommands();
    5556
    56         Functor* callbackFunction_;
     57        shared_ptr<Functor> callbackFunction_;
    5758        InputState* inputState_;
    5859        static std::string callbackCommand_s;
  • code/branches/pickup2/src/libraries/core/input/Keyboard.cc

    r5781 r6412  
    4343            modifiers_ |= KeyboardModifier::Shift; // shift key
    4444
     45        // Do not distribute the alt+tab event (messes with the operating system)
     46        if ((modifiers_ & KeyboardModifier::Alt) != 0 && arg.key == OIS::KC_TAB)
     47            return true;
     48
    4549        KeyEvent evt(arg);
    4650        super::buttonPressed(evt);
Note: See TracChangeset for help on using the changeset viewer.