Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Sep 11, 2010, 12:34:00 AM (14 years ago)
Author:
landauf
Message:

merged doc branch back to trunk

Location:
code/trunk
Files:
30 edited

Legend:

Unmodified
Added
Removed
  • code/trunk

  • code/trunk/src/libraries/core/command/ArgumentCompleter.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @defgroup ArgumentCompletion Argument completion
     31    @ingroup Command
     32*/
     33
     34/**
     35    @file
     36    @ingroup Command ArgumentCompletion
     37    @brief Definition of the orxonox::ArgumentCompleter class that is used to execute @ref ArgumentCompletionFunctions.h "argument completion functions".
     38
     39    An ArgumentCompleter can be assigned to an orxonox::ConsoleCommand using
     40    @ref orxonox::ConsoleCommand::argumentCompleter "argumentCompleter()".
     41    The ArgumentCompleter calls an argument completion function that is defined
     42    in ArgumentCompletionFunctions.h. This can be used to list possible arguments
     43    for console commands and to allow auto-completion.
     44
     45    Instances of ArgumentCompleter are usually not created manually but rather
     46    by the macros defined in ArgumentCompletionFunctions.h. There you'll also
     47    find some examples.
     48
     49    @see See the @ref ArgumentCompletionExample "examples".
     50*/
     51
    2952#ifndef _ArgumentCompleter_H__
    3053#define _ArgumentCompleter_H__
     
    3558namespace orxonox
    3659{
     60    /**
     61        @brief This class executes an argument completion function and returns a list of the possible arguments.
     62
     63        ArgumentCompleter is used to wrap argument completion functions as defined
     64        in ArgumentCompletionFunctions.h and can be assigned to a ConsoleCommand to
     65        create a list of possible arguments.
     66
     67        @see See ArgumentCompleter.h for more information.
     68        @see See @ref ArgumentCompletionExample "ArgumentCompletionFunctions.h" for an example.
     69    */
    3770    class _CoreExport ArgumentCompleter
    3871    {
    3972        public:
    40             ArgumentCompleter(ArgumentCompletionList (*function) (void), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(0), function_0_(function) {}
    41             ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(1), function_1_(function) {}
    42             ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(2), function_2_(function) {}
    43             ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(3), function_3_(function) {}
    44             ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(4), function_4_(function) {}
    45             ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(5), function_5_(function) {}
     73            ArgumentCompleter(ArgumentCompletionList (*function) (void), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(0), function_0_(function) {} ///< Constructor, assigns a function-pointer with no arguments.
     74            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(1), function_1_(function) {} ///< Constructor, assigns a function-pointer with one argument.
     75            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(2), function_2_(function) {} ///< Constructor, assigns a function-pointer with two arguments.
     76            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(3), function_3_(function) {} ///< Constructor, assigns a function-pointer with three arguments.
     77            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(4), function_4_(function) {} ///< Constructor, assigns a function-pointer with four arguments.
     78            ArgumentCompleter(ArgumentCompletionList (*function) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5), bool bUseMultipleWords) : bUseMultipleWords_(bUseMultipleWords), paramCount_(5), function_5_(function) {} ///< Constructor, assigns a function-pointer with five arguments.
    4679
     80            /**
     81                @brief Calls the argument completion function with a maximum of five parameters.
     82                @return Returns the list of possible arguments, created by the argument completion function
     83            */
    4784            ArgumentCompletionList operator()(const std::string& param1 = "", const std::string& param2 = "", const std::string& param3 = "", const std::string& param4 = "", const std::string& param5 = "")
    4885            {
     
    66103            }
    67104
     105            /// Returns true if the argument completion list supports multiple words.
    68106            inline bool useMultipleWords() const
    69107                { return this->bUseMultipleWords_; }
    70108
    71109        private:
    72             bool bUseMultipleWords_;
    73             unsigned char paramCount_;
    74             ArgumentCompletionList (*function_0_) (void);
    75             ArgumentCompletionList (*function_1_) (const std::string& param1);
    76             ArgumentCompletionList (*function_2_) (const std::string& param1, const std::string& param2);
    77             ArgumentCompletionList (*function_3_) (const std::string& param1, const std::string& param2, const std::string& param3);
    78             ArgumentCompletionList (*function_4_) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4);
    79             ArgumentCompletionList (*function_5_) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5);
     110            bool bUseMultipleWords_;    ///< If true, the argument completion list supports multiple words
     111            unsigned char paramCount_;  ///< The number of parameters of the argument completion function
     112            ArgumentCompletionList (*function_0_) (void);   ///< Function-pointer for an argument completion function with no arguments
     113            ArgumentCompletionList (*function_1_) (const std::string& param1);   ///< Function-pointer for an argument completion function with one argument
     114            ArgumentCompletionList (*function_2_) (const std::string& param1, const std::string& param2);   ///< Function-pointer for an argument completion function with two arguments
     115            ArgumentCompletionList (*function_3_) (const std::string& param1, const std::string& param2, const std::string& param3);   ///< Function-pointer for an argument completion function with three arguments
     116            ArgumentCompletionList (*function_4_) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4);   ///< Function-pointer for an argument completion function with four arguments
     117            ArgumentCompletionList (*function_5_) (const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5);   ///< Function-pointer for an argument completion function with five arguments
    80118    };
    81119}
  • code/trunk/src/libraries/core/command/ArgumentCompletionFunctions.cc

    r7284 r7401  
    2626 *
    2727 */
     28
     29/**
     30    @file
     31    @brief Implementation of all argument completion functions
     32*/
    2833
    2934#include "ArgumentCompletionFunctions.h"
     
    5358    namespace autocompletion
    5459    {
     60        /**
     61            @brief Fallback implementation, returns an empty list.
     62        */
    5563        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(fallback)()
    5664        {
     
    6068        namespace detail
    6169        {
     70            /**
     71                @brief Returns true if a group of console commands is visible (i.e. if at least one command in this group is visible).
     72            */
    6273            bool groupIsVisible(const std::map<std::string, ConsoleCommand*>& group, bool bOnlyShowHidden)
    6374            {
     
    6980            }
    7081
     82            /**
     83                @brief Returns a list of all console command groups AND all console command shortcuts.
     84                @param fragment The last argument
     85                @param bOnlyShowHidden If true, only hidden groups and commands are returned
     86            */
    7187            ArgumentCompletionList _groupsandcommands(const std::string& fragment, bool bOnlyShowHidden)
    7288            {
     89                // note: this function returns only arguments that begin with "fragment", which would't be necessary for the
     90                //       auto-completion, but it's necessary to place the line-break "\n" between groups and commands
     91                //       only if both groups AND commands are in the list.
     92
    7393                ArgumentCompletionList groupList;
    7494                std::string fragmentLC = getLowercase(fragment);
    7595
     96                // get all the groups that are visible (except the shortcut group "")
    7697                const std::map<std::string, std::map<std::string, ConsoleCommand*> >& commands = ConsoleCommand::getCommands();
    7798                for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = commands.begin(); it_group != commands.end(); ++it_group)
     
    79100                        groupList.push_back(ArgumentCompletionListElement(it_group->first, getLowercase(it_group->first)));
    80101
     102                // now add all shortcuts (in group "")
    81103                std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = commands.find("");
    82104                if (it_group != commands.end())
    83105                {
     106                    // add a line-break if the list isn't empty
    84107                    if (!groupList.empty())
    85108                        groupList.push_back(ArgumentCompletionListElement("", "", "\n"));
    86109
     110                    // add the shortcuts
    87111                    for (std::map<std::string, ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command)
    88112                        if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden && (fragmentLC == "" || getLowercase(it_command->first).find_first_of(fragmentLC) == 0))
     
    90114                }
    91115
     116                // if no shortcut was added, remove the line-break again
    92117                if (!groupList.empty() && groupList.back().getDisplay() == "\n")
    93118                    groupList.pop_back();
     
    96121            }
    97122
     123            /**
     124                @brief Returns a list of all console commands in a given group.
     125                @param fragment The last argument
     126                @param group The group's name
     127                @param bOnlyShowHidden If true, only hidden console commands are returned
     128            */
    98129            ArgumentCompletionList _subcommands(const std::string& fragment, const std::string& group, bool bOnlyShowHidden)
    99130            {
     
    102133                std::string groupLC = getLowercase(group);
    103134
     135                // find the iterator of the given group
    104136                std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommands().begin();
    105137                for ( ; it_group != ConsoleCommand::getCommands().end(); ++it_group)
     
    107139                        break;
    108140
     141                // add all commands in the group to the list
    109142                if (it_group != ConsoleCommand::getCommands().end())
    110143                {
     
    118151        }
    119152
     153        /**
     154            @brief Returns a list of all console command groups AND all console command shortcuts.
     155        */
    120156        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(groupsandcommands)(const std::string& fragment)
    121157        {
     
    123159        }
    124160
     161        /**
     162            @brief Returns a list of all console commands in a given group.
     163        */
    125164        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(subcommands)(const std::string& fragment, const std::string& group)
    126165        {
     
    128167        }
    129168
     169        /**
     170            @brief Returns a list of commands and groups and also supports auto-completion of the arguments of these commands.
     171
     172            This is a multi-word function, because commands are composed of 1-2 words and additional arguments.
     173        */
    130174        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(command)(const std::string& fragment)
    131175        {
     
    145189        }
    146190
     191        /**
     192            @brief Returns a list of hidden commands and groups and also supports auto-completion of the arguments of these commands.
     193
     194            This is a multi-word function, because commands are composed of 1-2 words and additional arguments.
     195
     196            This function makes commands visible that would usually be hidden.
     197        */
    147198        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(hiddencommand)(const std::string& fragment)
    148199        {
     
    170221        }
    171222
     223        /**
     224            @brief Returns possible files and directories and also supports files in arbitrary deeply nested subdirectories.
     225
     226            This function returns files and directories in the given path. This allows to
     227            navigate iteratively through the file system. The first argument @a fragment
     228            is used to get the current path.
     229        */
    172230        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(files)(const std::string& fragment)
    173231        {
     
    211269        }
    212270
     271        /**
     272            @brief Returns the sections of the config file.
     273        */
    213274        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingssections)()
    214275        {
     
    222283        }
    223284
     285        /**
     286            @brief Returns the entries in a given section of the config file.
     287        */
    224288        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsentries)(const std::string& fragment, const std::string& section)
    225289        {
     
    235299        }
    236300
     301        /**
     302            @brief Returns the current value of a given value in a given section of the config file.
     303        */
    237304        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsvalue)(const std::string& fragment, const std::string& entry, const std::string& section)
    238305        {
     
    255322        }
    256323
     324        /**
     325            @brief Returns a list of indexes of the available Tcl threads (see TclThreadManager).
     326        */
    257327        ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(tclthreads)()
    258328        {
  • code/trunk/src/libraries/core/command/ArgumentCompletionFunctions.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command ArgumentCompletion
     32    @brief Declaration of all argument completion functions and macros used to define them.
     33
     34    @anchor ArgumentCompletionExample
     35
     36    Argument completion functions are used to create a list of possible arguments
     37    for an orxonox::ConsoleCommand. These functions are usually wrapped by an instance
     38    of orxonox::ArgumentCompleter.
     39
     40    Argument completion functions can be declared and implemented by using the macros
     41    ARGUMENT_COMPLETION_FUNCTION_DECLARATION() and ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION()
     42    respectively. They are necessary because they don't simply define the function, but they also
     43    create a static helper function that returns an instance of orxonox::ArgumentCompleter which
     44    wraps the defined function. This allows easier referencing of argument completion functions
     45    by simply calling autocompletion::functionname().
     46
     47    Argument completion functions can take up to 5 arguments, all of type std::string.
     48    The first argument is always the current argument which is being entered by the user
     49    in the shell. The second argument is the argument before, so in fact arguments from
     50    the shell are sent in reversed order to the argument completion function. This is
     51    necessary because the number of arguments can be variable
     52
     53    Example: The user types the following into the shell:
     54    @code
     55    $ commandname argument1 argument2 argum
     56    @endcode
     57    Then he presses the @a tab key to print the possible arguments. Now the argument
     58    completion function for the @a third argument of @a commandname will be called in
     59    the following way:
     60    @code
     61    list = argcompfunction3("argum", "argument2", "argument1");
     62    @endcode
     63
     64    Usually each argument is one word (without whitespaces in it), but some argument completion
     65    functions need more than one word. This can be achieved by using ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI().
     66    In this case all supernumerous words are passed to the first (!) argument.
     67
     68    An example to show how to declare, implement, and use an argument completion function:
     69    @code
     70    // ArgumentCompletionFunctions.h:
     71    // ------------------------------
     72
     73    // Declaration of the function:
     74    ARGUMENT_COMPLETION_FUNCTION_DECLARATION(month)(const std::string& fragment);
     75
     76    // ArgumentCompletionFunctions.cc:
     77    // -------------------------------
     78
     79    // Implementation of the function
     80    ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(month)(const std::string& fragment)
     81    {
     82        ArgumentCompletionList list;
     83
     84        // check if the first part of the argument is a number - if yes, the user likely wants to enter the month as a number
     85        if (isNumber(fragment))
     86        {
     87            for (int month = 1; month <= 12; ++month)
     88                list.push_back(ArgumentCompletionListElement(multi_cast<std::string>(month)));
     89        }
     90        else
     91        {
     92            list.push_back(ArgumentCompletionListElement("January",   "january"));
     93            list.push_back(ArgumentCompletionListElement("February",  "february"));
     94            list.push_back(ArgumentCompletionListElement("March",     "march"));
     95            list.push_back(ArgumentCompletionListElement("April",     "april"));
     96            list.push_back(ArgumentCompletionListElement("May",       "may"));
     97            list.push_back(ArgumentCompletionListElement("June",      "june"));
     98            list.push_back(ArgumentCompletionListElement("July",      "july"));
     99            list.push_back(ArgumentCompletionListElement("August",    "august"));
     100            list.push_back(ArgumentCompletionListElement("September", "september"));
     101            list.push_back(ArgumentCompletionListElement("October",   "october"));
     102            list.push_back(ArgumentCompletionListElement("November",  "november"));
     103            list.push_back(ArgumentCompletionListElement("December",  "december"));
     104        }
     105
     106        return list;
     107    }
     108
     109    // SomeFile:
     110    // ---------
     111
     112    // A class to manage the date:
     113    class Date
     114    {
     115        public:
     116            static void setDate(int day, const std::string& month, int year);
     117    };
     118
     119    // Define a console command that needs a date. Add argument completion for the month:
     120    SetConsoleCommand("setDate", &Date::setDate).argumentCompleter(1, autocompletion::month());
     121    @endcode
     122
     123    This example defines an argument completion function that returns a list of possible
     124    months. If the first part of the argument is a number, it returns the numbers 1-12,
     125    otherwise the name of the months are returned. Note how the list is composed by
     126    instances of orxonox::ArgumentCompletionListElement. For the name of the months,
     127    two strings are provided, one in normal case and one in lower case. See the documentation
     128    of orxonox::ArgumentCompletionListElement for more information about this.
     129
     130    Also note that the argument completion list is assigned to the console command by using
     131    @ref orxonox::ConsoleCommand::argumentCompleter "argumentCompleter()". The first argument
     132    is the index of the argument:
     133     - 0 is the first argument (@a day)
     134     - 1 is the second argument (@a month)
     135     - 2 is the third argument (@a year)
     136
     137    @a day and @a year don't need an argument completion function as they are just integers.
     138
     139    The function @c autocompletion::month() is automatically created by the macros
     140    ARGUMENT_COMPLETION_FUNCTION_DECLARATION() and ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION()
     141    and returns an orxonox::ArgumentCompleter that wraps the defined argument completion function.
     142
     143    The implemented argument completion function uses only one argument, the fragment of the
     144    currently entered argument. More complex functions can also use the previous arguments
     145    to return different arguments depending on the other arguments (for example to list the
     146    members of a class, where the class-name is the first argument and the member the second).
     147*/
     148
    29149#ifndef _ArgumentCompletionFunctions_H__
    30150#define _ArgumentCompletionFunctions_H__
     
    33153#include "ArgumentCompleter.h"
    34154
    35 
     155/**
     156    @brief Used to declare an argument completion function with name @a functionname.
     157    @param functionname The name of the function, will also be used for the implementation of the function.
     158
     159    The macro also defines a static function that returns an orxonox::ArgumentCompleter
     160    which wraps the defined function. This can be accessed by calling autocompletion::functionname();
     161*/
    36162#define ARGUMENT_COMPLETION_FUNCTION_DECLARATION(functionname) \
    37163    _CoreExport ArgumentCompleter* functionname(); \
    38164    _CoreExport ArgumentCompletionList acf_##functionname
    39165
     166/**
     167    @brief Used to implement an argument completion function.
     168    @param functionname The name of the function
     169*/
    40170#define ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(functionname) \
    41171    _ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_INTERNAL(functionname, false)
     172
     173/**
     174    @brief Used to implement an argument completion function which allows multiple words.
     175    @param functionname The name of the function
     176*/
    42177#define ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(functionname) \
    43178    _ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_INTERNAL(functionname, true)
    44179
     180/// Internal macro
    45181#define _ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_INTERNAL(functionname, bUseMultipleWords) \
    46182    ArgumentCompleter* functionname() \
     
    52188    ArgumentCompletionList acf_##functionname
    53189
     190/// Calls an argument completion function. Used for functions that return the results of another argument completion function.
    54191#define ARGUMENT_COMPLETION_FUNCTION_CALL(functionname) acf_##functionname
    55192
  • code/trunk/src/libraries/core/command/ArgumentCompletionListElement.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command ArgumentCompletion
     32    @brief Definition of ArgumentCompletionList, which is  used in @ref ArgumentCompletionFunctions.h "argument completion functions", and its element.
     33*/
     34
    2935#ifndef _ArgumentCompletionListElement_H__
    3036#define _ArgumentCompletionListElement_H__
     
    3743namespace orxonox
    3844{
    39     const int ACL_MODE_NORMAL    = 1;
    40     const int ACL_MODE_COMPARABLE = 2;
    41     const int ACL_MODE_DISPLAY   = 4;
     45    const int ACL_MODE_NORMAL     = 1;  ///< A flag, used if there's a normal string
     46    const int ACL_MODE_COMPARABLE = 2;  ///< A flag, used if there's a different string used to compare
     47    const int ACL_MODE_DISPLAY    = 4;  ///< A flag, used if there's a different string used to be displayed
    4248
    4349    typedef std::list<ArgumentCompletionListElement> ArgumentCompletionList;
    4450
     51    /**
     52        @brief This class is used in argument completion lists and contains up to three different strings, used in different situations.
     53
     54        A list containing elements of type ArgumentCompletionListElement is returned by
     55        an @ref ArgumentCompletionFunctions.h "argument completion function". These elements
     56        are composed of up to three strings with different usage:
     57         - normal: What is used as the actual argument
     58         - comparable: What is used to compere the argument to the input of the user (usually lowercase, except for case-sensitive arguments)
     59         - display: This is displayed in the list of possible arguments - can differ from what is actually used for better readability
     60
     61        @remarks An element with an empty ("") 'comparable' string will be ignored by the argument
     62        completion algorithms, but it's 'display' string will still be printed in the list. This
     63        can be used to add additional information, whitespaces, linebreaks or whatever is needed
     64        to format the output.
     65    */
    4566    class _CoreExport ArgumentCompletionListElement
    4667    {
    4768        public:
     69            /// Constructor: Normal, comparable, and display string are all the same.
    4870            ArgumentCompletionListElement(const std::string& normalcase) : mode_(ACL_MODE_NORMAL), normal_(normalcase) {}
     71            /// Constructor: Normal and display string are the same, a different (usually lowercase) string is used for comparison.
    4972            ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase) : mode_(ACL_MODE_NORMAL | ACL_MODE_COMPARABLE), normal_(normalcase), comparable_(lowercase) {}
     73            /// Constructor: Normal, comparable, and display are all different strings.
    5074            ArgumentCompletionListElement(const std::string& normalcase, const std::string& lowercase, const std::string& display) : mode_(ACL_MODE_NORMAL | ACL_MODE_COMPARABLE | ACL_MODE_DISPLAY), normal_(normalcase), comparable_(lowercase), display_(display) {}
    5175
     76            /// Returns the normal string which is used as the actual argument.
    5277            const std::string& getString() const
    5378                { return this->normal_; }
     79            /// Returns the comparable string which is used to compare arguments and user input
    5480            const std::string& getComparable() const
    5581                { return (this->mode_ & ACL_MODE_COMPARABLE) ? this->comparable_ : this->normal_; }
     82            /// Returns the display string which is used in the displayed list of possible arguments
    5683            const std::string& getDisplay() const
    5784                { return (this->mode_ & ACL_MODE_DISPLAY) ? this->display_ : this->normal_; }
    5885
     86            /// Returns true if there's a different string for comparison.
    5987            bool hasComparable() const
    6088                { return (this->mode_ & ACL_MODE_COMPARABLE); }
     89            /// Returns true if there's a different string to display.
    6190            bool hasDisplay() const
    6291                { return (this->mode_ & ACL_MODE_DISPLAY); }
    6392
     93            /// Overloaded operator for usage in maps and sets.
    6494            bool operator<(const ArgumentCompletionListElement& other) const
    6595                { return (this->getComparable() < other.getComparable()); }
    6696
    6797        private:
    68             unsigned char mode_;
    69             std::string normal_;
    70             std::string comparable_;
    71             std::string display_;
     98            unsigned char mode_;        ///< The flags
     99            std::string normal_;        ///< The normal string
     100            std::string comparable_;    ///< The comparable (usually lowercase) string
     101            std::string display_;       ///< The string to display
    72102    };
    73103}
  • code/trunk/src/libraries/core/command/CommandEvaluation.cc

    r7286 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @brief Implementation of CommandEvaluation
     32*/
     33
    2934#include "CommandEvaluation.h"
    3035
     
    3540namespace orxonox
    3641{
     42    /**
     43        @brief Constructor: Initializes the command evaluation with an empty command.
     44    */
    3745    CommandEvaluation::CommandEvaluation()
    3846    {
     
    4048    }
    4149
     50    /**
     51        @brief Initializes all values.
     52    */
    4253    void CommandEvaluation::initialize(const std::string& command)
    4354    {
     
    4960        this->bPossibleArgumentsRetrieved_ = false;
    5061        this->possibleArguments_.clear();
    51         this->bEvaluatedParams_ = false;
    52         this->bTriedToEvaluatedParams_ = false;
    53         this->numberOfEvaluatedParams_ = 0;
    54 
     62        this->bEvaluatedArguments_ = false;
     63        this->bTriedToEvaluatedArguments_ = false;
     64        this->numberOfEvaluatedArguments_ = 0;
     65
     66        // split the command into tokens
    5567        this->tokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', true, '"', true, '{', '}', true, '\0');
    5668    }
    5769
     70    /**
     71        @brief Returns the number of tokens according to the definition of CommandExecutor (which counts also an empty argument at the end of the string).
     72    */
    5873    unsigned int CommandEvaluation::getNumberOfArguments() const
    5974    {
    6075        unsigned int count = this->tokens_.size();
    61         if (count > 0 && this->string_[this->string_.size() - 1] != ' ')
     76
     77        // If the last char in the string is a space character (or the string is empty), add +1 to the number of tokens, because this counts as an additional (but empty) argument
     78        if (count == 0 || this->string_[this->string_.size() - 1] == ' ')
     79            return count + 1;
     80        else
    6281            return count;
     82    }
     83
     84    /**
     85        @brief Returns the last argument (which is the one the user currently enters into the shell).
     86    */
     87    const std::string& CommandEvaluation::getLastArgument() const
     88    {
     89        // the string is empty or ends with a space character, the user is just about to enter a new argument (but its still empty). return a blank string in this case.
     90        if (this->tokens_.size() == 0 || this->string_[this->string_.size() - 1] == ' ')
     91            return BLANKSTRING;
    6392        else
    64             return count + 1;
    65     }
    66 
    67     const std::string& CommandEvaluation::getLastArgument() const
    68     {
    69         if (this->tokens_.size() > 0 && this->string_[this->string_.size() - 1] != ' ')
    7093            return this->tokens_.back();
    71         else
    72             return BLANKSTRING;
    73     }
    74 
     94    }
     95
     96    /**
     97        @brief Returns the token with the given index (or a blank string if it doesn't exist).
     98    */
    7599    const std::string& CommandEvaluation::getToken(unsigned int i) const
    76100    {
     
    81105    }
    82106
     107    /**
     108        @brief Executes the command which was evaluated by this object.
     109        @return Returns the error code (see @ref CommandExecutorErrorCodes "CommandExecutor error codes")
     110    */
    83111    int CommandEvaluation::execute()
    84112    {
     
    88116    }
    89117
     118    /**
     119        @brief Executes the command which was evaluated by this object and returns its return-value.
     120        @param error A pointer to an integer (or NULL) which will be used to write error codes to (see @ref CommandExecutorErrorCodes "CommandExecutor error codes")
     121        @return Returns the result of the command (or MT_Type::Null if there is no return value)
     122    */
    90123    MultiType CommandEvaluation::query(int* error)
    91124    {
     125        // check if an error value was passed by reference
    92126        if (error)
    93127        {
     128            // Determine the error-code and return if it is not Success
     129
    94130            *error = CommandExecutor::Success;
    95131
     
    105141        }
    106142
     143        // check if it's possible to execute the command
    107144        if (this->execCommand_ && this->execCommand_->isActive() && this->execCommand_->hasAccess())
    108145        {
    109             if (!this->bTriedToEvaluatedParams_)
    110                 this->evaluateParams(false);
    111 
    112             if (this->bEvaluatedParams_)
    113             {
    114                 COUT(6) << "CE_execute (evaluation): " << this->execCommand_->getName() << " with " << this->numberOfEvaluatedParams_ << " params: " << this->param_[0] << ' ' << this->param_[1] << ' ' << this->param_[2] << ' ' << this->param_[3] << ' ' << this->param_[4] << std::endl;
    115                 switch (this->numberOfEvaluatedParams_)
     146            // if the arguments weren't evaluated yet, do it now.
     147            if (!this->bTriedToEvaluatedArguments_)
     148                this->evaluateArguments(false);
     149
     150            // check if the argument evaluation succeded
     151            if (this->bEvaluatedArguments_)
     152            {
     153                COUT(6) << "CE_execute (evaluation): " << this->execCommand_->getName() << " with " << this->numberOfEvaluatedArguments_ << " arguments: " << this->arguments_[0] << ' ' << this->arguments_[1] << ' ' << this->arguments_[2] << ' ' << this->arguments_[3] << ' ' << this->arguments_[4] << std::endl;
     154
     155                // pass as many arguments to the executor as were evaluated (thus the executor can still use additional default values)
     156                switch (this->numberOfEvaluatedArguments_)
    116157                {
    117158                    case 0:  return (*this->execCommand_->getExecutor())();
    118                     case 1:  return (*this->execCommand_->getExecutor())(this->param_[0]);
    119                     case 2:  return (*this->execCommand_->getExecutor())(this->param_[0], this->param_[1]);
    120                     case 3:  return (*this->execCommand_->getExecutor())(this->param_[0], this->param_[1], this->param_[2]);
    121                     case 4:  return (*this->execCommand_->getExecutor())(this->param_[0], this->param_[1], this->param_[2], this->param_[3]);
     159                    case 1:  return (*this->execCommand_->getExecutor())(this->arguments_[0]);
     160                    case 2:  return (*this->execCommand_->getExecutor())(this->arguments_[0], this->arguments_[1]);
     161                    case 3:  return (*this->execCommand_->getExecutor())(this->arguments_[0], this->arguments_[1], this->arguments_[2]);
     162                    case 4:  return (*this->execCommand_->getExecutor())(this->arguments_[0], this->arguments_[1], this->arguments_[2], this->arguments_[3]);
    122163                    case 5:
    123                     default: return (*this->execCommand_->getExecutor())(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]);
     164                    default: return (*this->execCommand_->getExecutor())(this->arguments_[0], this->arguments_[1], this->arguments_[2], this->arguments_[3], this->arguments_[4]);
    124165                }
    125166            }
     
    128169        }
    129170
     171        // return a null value in case of an error
    130172        return MT_Type::Null;
    131173    }
    132174
    133     int CommandEvaluation::evaluateParams(bool bPrintError)
    134     {
    135         this->bTriedToEvaluatedParams_ = true;
    136 
     175    /**
     176        @brief Evaluates the arguments of the command.
     177        @param bPrintError If true, the function prints an error message if it doesn't succeed
     178        @return Returns the error code (see @ref CommandExecutorErrorCodes "CommandExecutor error codes")
     179    */
     180    int CommandEvaluation::evaluateArguments(bool bPrintError)
     181    {
     182        this->bTriedToEvaluatedArguments_ = true;
     183
     184        // check if there's a command to execute
    137185        if (!this->execCommand_)
    138186        {
    139187            if (bPrintError)
    140                 COUT(1) << "Error: Can't evaluate params, no console command assigned." << std::endl;
     188                COUT(1) << "Error: Can't evaluate arguments, no console command assigned." << std::endl;
    141189            return CommandExecutor::Error;
    142190        }
    143191
    144192        int error;
    145         this->numberOfEvaluatedParams_ = this->execCommand_->getExecutor()->evaluateParams(this->tokens_.subSet(this->execArgumentsOffset_), this->param_, &error, " ");
     193
     194        // try to evaluate the arguments using the executor of the evaluated command.
     195        // the arguments are currently stored as strings in token_, but afterwards they will be converted to the right type and stored in arguments_
     196        this->numberOfEvaluatedArguments_ = this->execCommand_->getExecutor()->evaluateArguments(this->tokens_.subSet(this->execArgumentsOffset_), this->arguments_, &error, " ");
     197
     198        // check if an error occurred
    146199        if (!error)
    147             this->bEvaluatedParams_ = true;
     200            this->bEvaluatedArguments_ = true;
    148201        else if (bPrintError)
    149             COUT(1) << "Error: Can't evaluate params, not enough arguments given." << std::endl;
     202            COUT(1) << "Error: Can't evaluate arguments, not enough arguments given." << std::endl;
    150203
    151204        return error;
    152205    }
    153206
    154     void CommandEvaluation::setEvaluatedParameter(unsigned int index, const MultiType& param)
     207    /**
     208        @brief Replaces an evaluated argument with a new value.
     209        @param index The index of the parameter (the first argument has index 0)
     210        @param arg The new value of the parameter
     211    */
     212    void CommandEvaluation::setEvaluatedArgument(unsigned int index, const MultiType& arg)
    155213    {
    156214        if (index < MAX_FUNCTOR_ARGUMENTS)
    157             this->param_[index] = param;
    158     }
    159 
    160     MultiType CommandEvaluation::getEvaluatedParameter(unsigned int index) const
     215            this->arguments_[index] = arg;
     216    }
     217
     218    /**
     219        @brief Returns the evaluated argument with given index.
     220        @param index The index of the argument (the first argument has index 0)
     221    */
     222    MultiType CommandEvaluation::getEvaluatedArgument(unsigned int index) const
    161223    {
    162224        if (index < MAX_FUNCTOR_ARGUMENTS)
    163             return this->param_[index];
     225            return this->arguments_[index];
    164226
    165227        return MT_Type::Null;
    166228    }
    167229
     230    /**
     231        @brief Completes the given command string using the list of possible arguments.
     232        @return Returns the completed command string
     233
     234        This is called by the shell if the user presses the @a tab key. The currently entered
     235        argument will be completed as good as possible by using the argument completion list
     236        of the evaluated command.
     237    */
    168238    std::string CommandEvaluation::complete()
    169239    {
     240        // check if it's possible to complete the command
    170241        if (!this->hintCommand_ || !this->hintCommand_->isActive())
    171242            return this->string_;
    172243
     244        // get the list of possible arguments
    173245        if (!this->bPossibleArgumentsRetrieved_)
    174246            this->retrievePossibleArguments();
    175247
     248        // if the list is empty, return the current command string
    176249        if (CommandEvaluation::getSize(this->possibleArguments_) == 0)
    177250        {
     
    180253        else
    181254        {
     255            // get the first part of the command string from the beginning up to the last space character
    182256            std::string output = this->string_.substr(0, this->string_.find_last_of(' ') + 1);
     257
     258            // add the common begin of all possible arguments
    183259            output += CommandEvaluation::getCommonBegin(this->possibleArguments_);
     260
     261            // return the resulting string
    184262            return output;
    185263        }
    186264    }
    187265
     266    /**
     267        @brief Returns a string containing hints or possible arguments for the evaluated command.
     268
     269        This is called by the shell if the user presses the @a tab key. It prints a list of
     270        possible arguments or other hints, returned by the argument completion list of the
     271        evaluated command. If there's no such list, the syntax of the command is returned.
     272    */
    188273    std::string CommandEvaluation::hint()
    189274    {
     275        // check if it's possible to get hints for this command
    190276        if (!this->hintCommand_ || !this->hintCommand_->isActive())
    191277            return "";
    192278
     279        // get the list of possible arguments
    193280        if (!this->bPossibleArgumentsRetrieved_)
    194281            this->retrievePossibleArguments();
    195282
     283        // return the list of possible arguments if:
     284        //   a) it contains at least one non-empty argument
     285        //   b) it contains an entry that may be empty (not an actual argument, just a helping text) AND the command is valid
    196286        if (CommandEvaluation::getSize(this->possibleArguments_) > 0 || (!this->possibleArguments_.empty() && this->isValid()))
    197287            return CommandEvaluation::dump(this->possibleArguments_);
    198288
     289        // at this point there's no valid argument in the list, so check if the command is actually valid
    199290        if (this->isValid())
    200291        {
     292            // yes it is - return the syntax of the command
    201293            return CommandEvaluation::dump(this->hintCommand_);
    202294        }
    203295        else
    204296        {
     297            // no the command is not valid
    205298            if (this->getNumberOfArguments() > 2)
    206299            {
     300                // the user typed 2+ arguments, but they don't name a command - print an error
    207301                return std::string("Error: There is no command with name \"") + this->getToken(0) + " " + this->getToken(1) + "\".";
    208302            }
    209303            else
    210304            {
     305                // the user typed 1-2 arguments, check what he tried to type and print a suitable error
    211306                std::string groupLC = getLowercase(this->getToken(0));
    212307                for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandsLC().begin(); it_group != ConsoleCommand::getCommandsLC().end(); ++it_group)
     
    219314    }
    220315
     316    /**
     317        @brief If the command couln't be evaluated because it doesn't exist, print a suggestion for
     318        a command that looks close to the entered command (useful if the user mistyped the command).
     319    */
    221320    std::string CommandEvaluation::getCommandSuggestion() const
    222321    {
     
    227326        unsigned int nearestDistance = (unsigned int)-1;
    228327
     328        // iterate through all groups and their commands and calculate the distance to the current command. keep the best.
    229329        for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandsLC().begin(); it_group != ConsoleCommand::getCommandsLC().end(); ++it_group)
    230330        {
     
    244344        }
    245345
     346        // now also iterate through all shortcuts and keep the best if it's better than the one found above.
    246347        std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandsLC().find("");
    247348        if (it_group !=  ConsoleCommand::getCommandsLC().end())
     
    259360        }
    260361
     362        // return the command that's closest to the current one.
    261363        return nearestCommand;
    262364    }
    263365
     366    /**
     367        @brief Gets the possible arguments for the command in its current state.
     368    */
    264369    void CommandEvaluation::retrievePossibleArguments()
    265370    {
    266371        this->bPossibleArgumentsRetrieved_ = true;
     372
     373        // we use the hintCommand_ to get possible arguments. get the index of the last argument. limit the index if its greater than the number of arguments supported by the command.
    267374        unsigned int argumentID = std::min(this->getNumberOfArguments() - this->hintArgumentsOffset_, this->hintCommand_->getExecutor()->getParamCount());
     375
     376        // get the argument completer for the given argument index
    268377        ArgumentCompleter* ac = this->hintCommand_->getArgumentCompleter(argumentID - 1);
    269378
     379        // check if an argument completer exists
    270380        if (ac)
    271381        {
    272             MultiType param[MAX_FUNCTOR_ARGUMENTS];
    273 
     382            MultiType arg[MAX_FUNCTOR_ARGUMENTS];
     383
     384            // the index of the last argument in the command string that is supported by this argument completer
    274385            size_t max = this->hintArgumentsOffset_ + this->hintCommand_->getExecutor()->getParamCount();
    275386
     387            // write the argument strings to the argument array (in reversed order, as required by the argument completion function)
    276388            for (size_t i = 0; i < argumentID; ++i)
    277                 param[i] = this->getToken(std::min(this->getNumberOfArguments(), (unsigned int)max) - i - 1);
    278 
     389                arg[i] = this->getToken(std::min(this->getNumberOfArguments(), (unsigned int)max) - i - 1);
     390
     391            // check if there are more arguments given by the user than supported
    279392            if (this->getNumberOfArguments() > max)
    280393            {
     394                // yes - now check if multiple words are supported by the argument completer
    281395                if (ac->useMultipleWords())
    282396                {
     397                    // yes - join the surplus arguments
    283398                    std::string surplusArguments = this->tokens_.subSet(max - 1).join();
    284399                    if (this->string_[this->string_.size() - 1] == ' ')
    285400                        surplusArguments += ' ';
    286401
    287                     this->possibleArguments_ = (*ac)(surplusArguments, param[1], param[2], param[3], param[4]);
     402                    // pass all surplus arguments as the first argument to the argument completer
     403                    this->possibleArguments_ = (*ac)(surplusArguments, arg[1], arg[2], arg[3], arg[4]);
     404
     405                    // strip the list using the last argument
    288406                    CommandEvaluation::strip(this->possibleArguments_, this->getToken(this->getNumberOfArguments() - 1));
    289407                }
     408                else
     409                {
     410                    // no - the user typed more arguments than supported, no action
     411                }
    290412            }
    291413            else
    292414            {
    293                 this->possibleArguments_ = (*ac)(param[0], param[1], param[2], param[3], param[4]);
    294                 CommandEvaluation::strip(this->possibleArguments_, param[0]);
    295             }
    296         }
    297     }
    298 
     415                // no - so simply call the argument completer and get the list of arguments
     416                this->possibleArguments_ = (*ac)(arg[0], arg[1], arg[2], arg[3], arg[4]);
     417
     418                // strip the list using the last argument (stored arg[0])
     419                CommandEvaluation::strip(this->possibleArguments_, arg[0]);
     420            }
     421        }
     422    }
     423
     424    /**
     425        @brief Returns the size of an argument completion list - empty ("") arguments are not counted.
     426    */
    299427    /* static */ size_t CommandEvaluation::getSize(const ArgumentCompletionList& list)
    300428    {
     
    306434    }
    307435
     436    /**
     437        @brief Removes all elements from the list that don't start with @a fragment.
     438        @param list The argument completion list
     439        @param fragment The argument that is currently entered by the user and that needs to be completed
     440    */
    308441    /* static */ void CommandEvaluation::strip(ArgumentCompletionList& list, const std::string& fragment)
    309442    {
    310443        std::string fragmentLC = getLowercase(fragment);
    311444
     445        // iterate through the list
    312446        for (ArgumentCompletionList::iterator it = list.begin(); it != list.end(); )
    313447        {
    314448            const std::string& entry = it->getComparable();
    315449
     450            // check if the argument is empty - if yes, keep it always in the list
    316451            if (entry == "")
    317452            {
     
    320455            }
    321456
     457            // check the length of the argument - arguments smaller than 'fragment' are always erased
    322458            if (entry.size() < fragmentLC.size())
    323459            {
     
    326462            else
    327463            {
     464                // compare the argument char by char with 'fragment'
    328465                bool bErase = false;
    329466                for (size_t i = 0; i < fragmentLC.size(); ++i)
     
    344481    }
    345482
     483    /**
     484        @brief Returns the commond begin of all arguments in the list.
     485    */
    346486    /* static */ std::string CommandEvaluation::getCommonBegin(const ArgumentCompletionList& list)
    347487    {
    348488        if (CommandEvaluation::getSize(list) == 0)
    349489        {
     490            // no (non-empty) values in the list, return an empty string
    350491            return "";
    351492        }
    352493        else if (CommandEvaluation::getSize(list) == 1)
    353494        {
     495            // only one (non-empty) value in the list - search it and return it
    354496            for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
    355497            {
    356498                if (it->getComparable() != "")
    357499                {
     500                    // arguments that have a separate string to be displayed need a little more care - just return them without modification. add a space character to the others.
    358501                    if (it->hasDisplay())
    359502                        return (it->getString());
     
    367510        else
    368511        {
     512            // multiple arguments in the list - iterate through it and find the common begin of all arguments
    369513            std::string output;
    370514            for (unsigned int i = 0; true; i++)
    371515            {
    372                 char tempComparable = 0;
    373                 char temp = 0;
     516                char tempComparable = '\0';
     517                char temp = '\0';
    374518                for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
    375519                {
     
    377521                    const std::string& argument = it->getString();
    378522
     523                    // ignore empty arguments
    379524                    if (argumentComparable == "")
    380525                        continue;
     
    382527                    if (argument.size() > i)
    383528                    {
    384                         if (tempComparable == 0)
     529                        if (tempComparable == '\0')
    385530                        {
     531                            // the first entry is always taken
    386532                            tempComparable = argumentComparable[i];
    387533                            temp = argument[i];
     
    389535                        else
    390536                        {
     537                            // all other entries need comparison to the first entry
    391538                            if (tempComparable != argumentComparable[i])
    392539                                return output;
    393                             else if (temp != argument[i])
     540                            else if (temp != argument[i]) // the comparables match, but the normal chars don't - switch to comparable only
    394541                                temp = tempComparable;
    395542                        }
     
    406553    }
    407554
     555    /**
     556        @brief Joins the elements of the given list to a string.
     557    */
    408558    /* static */ std::string CommandEvaluation::dump(const ArgumentCompletionList& list)
    409559    {
     
    413563            output += it->getDisplay();
    414564
     565            // add a space character between two elements for all non-empty arguments
    415566            if (it->getComparable() != "")
    416567                output += ' ';
     
    419570    }
    420571
     572    /**
     573        @brief Returns a string that explains the syntax of the given command.
     574    */
    421575    /* static */ std::string CommandEvaluation::dump(const ConsoleCommand* command)
    422576    {
     577        // get the name of the command
    423578        std::string output = command->getName();
     579
     580        // check if there are parameters
    424581        if (command->getExecutor()->getParamCount() > 0)
    425582            output += ": ";
    426583
     584        // iterate through the parameters
    427585        for (unsigned int i = 0; i < command->getExecutor()->getParamCount(); i++)
    428586        {
     587            // separate the parameters with a space character
    429588            if (i != 0)
    430589                output += ' ';
    431590
     591            // print default values in [], others in {} braces
    432592            if (command->getExecutor()->defaultValueSet(i))
    433593                output += '[';
     
    435595                output += '{';
    436596
     597            // add the type-name of the parameter
    437598            output += command->getExecutor()->getTypenameParam(i);
    438599
     600            // print the default value if available
    439601            if (command->getExecutor()->defaultValueSet(i))
    440602                output += '=' + command->getExecutor()->getDefaultValue(i).getString() + ']';
  • code/trunk/src/libraries/core/command/CommandEvaluation.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @defgroup CommandExecEval Command execution and evaluation
     31    @ingroup Command
     32*/
     33
     34/**
     35    @file
     36    @ingroup Command CommandExecEval
     37    @brief Declaration of the orxonox::CommandEvaluation class which is returned by orxonox::CommandExecutor::evaluate().
     38
     39    The orxonox::CommandEvaluation class gathers all information about a command-string. It is used
     40    internally by orxonox::CommandExecutor and can also be returned by it to provide more information
     41    about a command. It's also possible to evaluate the arguments of a command to execute it faster.
     42
     43    @see See @ref CommandExecutorExample "this description" for an example.
     44*/
     45
    2946#ifndef _CommandEvaluation_H__
    3047#define _CommandEvaluation_H__
     
    4158namespace orxonox
    4259{
     60    /**
     61        @brief CommandEvaluation is used to gather information about a command and to evaluate its arguments
     62
     63        This class provides several information about a command-string, for example the
     64        evaluated ConsoleCommand, but also other information like hints if the command
     65        is not yet finished.
     66
     67        @note You don't have to call evaluateArguments() manually, it's also done automatically
     68        if you call the command the first time. However you can of course do it at any earlier
     69        time, for example to return an error message if it doesn't work.
     70
     71        @remarks execCommand_ and hintCommand_ can be different in this case: There are multiple
     72        commands avaliable, let's say "tcl", "tclexecute", and "tclquery". The user enters
     73        "tcl", which is already a valid command. Now execCommand_ points to the "tcl"-command,
     74        but hintCommand_ still points to the autocompletion command of CommandExecutor, because
     75        the auto-completion list must still return the three possible commands, "tcl tclexecute tclquery"
     76        because the user may want to execute "tclquery" and needs auto-completion.
     77
     78        @see See @ref CommandExecutorExample "this description" for an example.
     79    */
    4380    class _CoreExport CommandEvaluation
    4481    {
     
    5693            std::string getCommandSuggestion() const;
    5794
    58             int evaluateParams(bool bPrintError = false);
     95            int evaluateArguments(bool bPrintError = false);
    5996
     97            /// Returns true if the command evaluation contains a valid command that can be executed.
    6098            inline bool isValid() const
    6199                { return (this->execCommand_ != 0); }
    62100
     101            /// Returns the console command that was evaluated by this object.
    63102            inline const ConsoleCommand* getConsoleCommand() const
    64103                { return this->execCommand_; }
    65104
    66             void setEvaluatedParameter(unsigned int index, const MultiType& param);
    67             MultiType getEvaluatedParameter(unsigned int index) const;
     105            void setEvaluatedArgument(unsigned int index, const MultiType& arg);
     106            MultiType getEvaluatedArgument(unsigned int index) const;
    68107
     108            /**
     109                @brief Returns a list of possible arguments for the given command.
     110
     111                Note that the command's arguments may not be complete yet, so in this case
     112                this list returns the possibilities. They can then be used to display a list
     113                of the possible arguments or to apply auto-completion.
     114            */
    69115            const ArgumentCompletionList& getPossibleArguments() const
    70116                { return this->possibleArguments_; }
    71117
     118            /// Returns the number of possible arguments. Empty ("") arguments are not counted.
    72119            size_t getPossibleArgumentsSize() const
    73120                { return CommandEvaluation::getSize(this->possibleArguments_); }
     
    90137            static std::string getCommonBegin(const ArgumentCompletionList& list);
    91138
    92             const ConsoleCommand* execCommand_;
    93             const ConsoleCommand* hintCommand_;
    94             SubString tokens_;
    95             std::string string_;
    96             unsigned int execArgumentsOffset_;
    97             unsigned int hintArgumentsOffset_;
    98             bool bPossibleArgumentsRetrieved_;
    99             ArgumentCompletionList possibleArguments_;
     139            const ConsoleCommand* execCommand_;             ///< The command that will be executed (can be NULL if the command is not valid)
     140            const ConsoleCommand* hintCommand_;             ///< The command that is used to display hints and argument lists (can be different to execCommand_ in some cases)
     141            SubString tokens_;                              ///< The single words of the command string, split into tokens
     142            std::string string_;                            ///< The original command string, entered by the user in the shell
     143            unsigned int execArgumentsOffset_;              ///< The index of the first argument in tokens_ used to execute the command
     144            unsigned int hintArgumentsOffset_;              ///< The index of the first argument in tokens_ used to display hints and argument lists
     145            bool bPossibleArgumentsRetrieved_;              ///< True if the list of possible arguments was already retrieved
     146            ArgumentCompletionList possibleArguments_;      ///< List of possible arguments for the command in the current state
    100147
    101             bool bEvaluatedParams_;
    102             bool bTriedToEvaluatedParams_;
    103             unsigned int numberOfEvaluatedParams_;
    104             MultiType param_[MAX_FUNCTOR_ARGUMENTS];
     148            bool bEvaluatedArguments_;                      ///< True if the arguments of the command have been evaluated (and stored in arguments_)
     149            bool bTriedToEvaluatedArguments_;               ///< True if an attempt was started to evaluate the arguments (but not necessarily successful)
     150            unsigned int numberOfEvaluatedArguments_;       ///< The number of evaluated arguments (ranges from 0 to MAX_FUNCTOR_ARGUMENTS)
     151            MultiType arguments_[MAX_FUNCTOR_ARGUMENTS];    ///< The evaluated arguments (the arguments from string_ or tokens_ converted to the right type)
    105152    };
    106153}
  • code/trunk/src/libraries/core/command/CommandExecutor.cc

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @brief Implementation of CommandExecutor
     32*/
     33
    2934#include "CommandExecutor.h"
    3035
     
    4954        .argumentCompleter(1, autocompletion::command());
    5055
     56    /**
     57        @brief Returns a reference to the only instance of CommandExecutor.
     58    */
    5159    /* static */ CommandExecutor& CommandExecutor::getInstance()
    5260    {
     
    5563    }
    5664
     65    /**
     66        @brief Executes a command.
     67        @param command A string containing the command
     68        @param useTcl If true, the command is passed to tcl (see TclBind)
     69        @return Returns the error-code (see @ref CommandExecutorErrorCodes "error codes")
     70    */
    5771    /* static */ int CommandExecutor::execute(const std::string& command, bool useTcl)
    5872    {
     
    6276    }
    6377
     78    /**
     79        @brief Executes a command and returns its return-value.
     80        @param command A string containing the command
     81        @param error A pointer to a value (or NULL) where the error-code should be written to (see @ref CommandExecutorErrorCodes "error codes")
     82        @param useTcl If true, the command is passed to tcl (see TclBind)
     83        @return Returns the return-value of the command (if any - MT_Type::Null otherwise)
     84    */
    6485    /* static */ MultiType CommandExecutor::queryMT(const std::string& command, int* error, bool useTcl)
    6586    {
    6687        if (useTcl)
     88        {
     89            // pass the command to tcl
    6790            return TclBind::eval(command, error);
     91        }
    6892        else
    6993        {
    7094            CommandEvaluation evaluation;
     95
     96            // try to get the command evaluation from the cache
    7197            if (!CommandExecutor::getInstance().getCached(command, evaluation))
    7298            {
     99                // it wasn't in the cache - evaluate the command
    73100                evaluation = CommandExecutor::evaluate(command);
    74                 evaluation.evaluateParams();
     101
     102                // evaluate its arguments
     103                evaluation.evaluateArguments();
     104
     105                // write the evaluation to the cache
    75106                CommandExecutor::getInstance().cache(command, evaluation);
    76107            }
    77108
     109            // query the command and return its return-value
    78110            return evaluation.query(error);
    79111        }
    80112    }
    81113
     114    /**
     115        @brief Executes a command and returns its return-value as string.
     116        @param command A string containing the command
     117        @param error A pointer to a value (or NULL) where the error-code should be written to (see @ref CommandExecutorErrorCodes "error codes")
     118        @param useTcl If true, the command is passed to tcl (see TclBind)
     119        @return Returns the return-value of the command converted to a string (or "" if there's no return value)
     120    */
    82121    /* static */ std::string CommandExecutor::query(const std::string& command, int* error, bool useTcl)
    83122    {
     
    85124    }
    86125
     126    /**
     127        @brief Evaluates the given command.
     128        @param command A string containing the command
     129        @return Returns an instance of CommandEvaluation, which contains the evaluated ConsoleCommand, if the command is valid.
     130
     131        Evaluates the given command string and returns an instance of CommandEvaluation.
     132        If the command is valid, this contains the evaluated ConsoleCommand. Otherwise it
     133        can still be used to print hints or complete the command.
     134
     135        @note Tcl commands can not be evaluated. You have to pass them to execute() or to
     136        TclBind directly.
     137    */
    87138    /* static */ CommandEvaluation CommandExecutor::evaluate(const std::string& command)
    88139    {
     140        // initialize the command evaluation
    89141        CommandEvaluation evaluation;
    90142        evaluation.initialize(command);
    91143
     144        // assign the fallback-command to get hints about the possible commands and groups
    92145        evaluation.hintCommand_ = ConsoleCommand::getCommand(__CC_CommandExecutor_name, __CC_autocomplete_name);
    93146
     147        // check if there's at least one argument
    94148        if (evaluation.getNumberOfArguments() >= 1)
    95149        {
     150            // try to get a command from the first token
    96151            evaluation.execCommand_ = ConsoleCommand::getCommandLC(evaluation.getToken(0));
    97152            if (evaluation.execCommand_)
     
    99154            else if (evaluation.getNumberOfArguments() >= 2)
    100155            {
     156                // try to get a command from the first two tokens
    101157                evaluation.execCommand_ = ConsoleCommand::getCommandLC(evaluation.getToken(0), evaluation.getToken(1));
    102158                if (evaluation.execCommand_)
     
    105161        }
    106162
     163        // if a valid command was found and the user is already entering arguments, overwrite hintCommand_ with execCommand_
    107164        if (evaluation.execCommand_ && evaluation.getNumberOfArguments() > evaluation.execArgumentsOffset_)
    108165        {
     
    114171    }
    115172
     173    /**
     174        @brief Gets an evaluated command from the cache.
     175        @param command The command that should be looked up in the cache
     176        @param evaluation Reference to a CommandEvaluation that will be used to return the cached evaluation.
     177        @return Returns true if the command was found in the cache
     178    */
    116179    bool CommandExecutor::getCached(const std::string& command, CommandEvaluation& evaluation)
    117180    {
     
    119182            return false;
    120183
     184        // check if the command is in the cache
    121185        std::map<std::string, CacheEntry>::iterator it = this->cache_.find(command);
    122186        if (it != this->cache_.end())
     
    134198    }
    135199
     200    /**
     201        @brief Writes a command evaluation for a given command to the cache.
     202    */
    136203    void CommandExecutor::cache(const std::string& command, const CommandEvaluation& evaluation)
    137204    {
     
    156223    }
    157224
     225    /**
     226        @brief This function is used as console command which executes commands that are usually hidden.
     227
     228        The argument completion function of this console commands is used to find
     229        and enter hidden commands and their arguments.
     230    */
    158231    /* static */ MultiType CommandExecutor::unhide(const std::string& command)
    159232    {
     
    161234    }
    162235
     236    /**
     237        @brief This function is used as console command which saves a command and optionally also it's arguments as a new console command with a new name.
     238        @param alias The name of the new command alias
     239        @param command The existing command and (optionally) its arguments
     240    */
    163241    /* static */ void CommandExecutor::alias(const std::string& alias, const std::string& command)
    164242    {
     243        // first check if the given command is valid, else print an error
    165244        CommandEvaluation evaluation = CommandExecutor::evaluate(command);
    166245        if (evaluation.isValid())
    167246        {
     247            // it is valid - copy the executor of this command
    168248            ExecutorPtr executor = new Executor(*evaluation.getConsoleCommand()->getExecutor().get());
    169249
    170             if (!evaluation.evaluateParams())
     250            // evaluate the arguments and if this returns no error, store them as default values
     251            if (!evaluation.evaluateArguments())
    171252            {
    172253                for (size_t i = 0; i < MAX_FUNCTOR_ARGUMENTS; ++i)
    173                     executor->setDefaultValue(i, evaluation.getEvaluatedParameter(i));
    174             }
    175 
     254                    executor->setDefaultValue(i, evaluation.getEvaluatedArgument(i));
     255            }
     256
     257            // split the alias in tokens
    176258            SubString tokens(alias, " ");
    177259
     260            // check if the alias already exists - print an error and return if it does
    178261            if ((tokens.size() == 1 && ConsoleCommand::getCommand(tokens[0])) || (tokens.size() == 2 && ConsoleCommand::getCommand(tokens[0], tokens[1])))
    179262            {
     
    182265            }
    183266
     267            // create a new console command with the given alias as its name
    184268            if (tokens.size() == 1)
    185269                createConsoleCommand(tokens[0], executor);
  • code/trunk/src/libraries/core/command/CommandExecutor.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command CommandExecEval
     32    @brief Declaration of the orxonox::CommandExecutor class which is used to execute and evaluate @ref orxonox::ConsoleCommand "console commands".
     33
     34    @anchor CommandExecutorExample
     35
     36    orxonox::CommandExecutor can be used to execute console commands (see orxonox::ConsoleCommand).
     37    Commands are strings that can be entered by the user in the shell or they can be part of a
     38    script.
     39
     40    A command can be passed to orxonox::CommandExecutor::execute() which will execute them - eiter
     41    directly, or - if requested - passes it to Tcl. See orxonox::TclBind for more information.
     42    Appart from execute() the command can also be passed to orxonox::CommandExecutor::query() which
     43    behaves the same except for that it returns the return value of the command.
     44
     45    If you don't want to execute the command, but rather gather more information about it, pass it
     46    to orxonox::CommandExecutor::evaluate(). This function returns an instance of
     47    orxonox::CommandEvaluation. This class provides more information about the command, for example
     48    the evaluated instance of orxonox::ConsoleCommand. Its also possible to gather hints about the
     49    command or to complete the command-string by using argument completion functions. More than that
     50    the command evaluation can also evaluate the arguments, which allows faster execution of the
     51    command.
     52
     53    Example:
     54    @code
     55    CommandExecutor::execute("log test");               // writes "test" to the console
     56    CommandExecutor::execute("log [expr 1+1]");         // writes "2" to the console - expr is a Tcl command
     57
     58    CommandExecutor::query("expr 1+1");                 // returns "2"
     59    CommandExecutor::queryMT("expr 1+1");               // returns 2
     60    @endcode
     61
     62    And another example about how to use evaluate():
     63    @code
     64    CommandEvaluation evaluation;
     65    evaluation = CommandExecutor::evaluate("log test"); // returns an evaluation of "log test"
     66
     67    evaluation.execute();                               // writes "test" to the console
     68    evaluation.hint();                                  // returns "log: {string}"
     69    @endcode
     70
     71    @anchor CommandExecutorErrorCodes
     72
     73    @b Error @b codes:
     74
     75    orxonox::CommandExecutor defines a number of error codes that are returned
     76    by different functions that operate with commands:
     77
     78     - CommandExecutor::Success: No error
     79     - CommandExecutor::Error: The command doesn't exist
     80     - CommandExecutor::Incomplete: The command needs more arguments
     81     - CommandExecutor::Deactivated: The command is not active
     82     - CommandExecutor::Denied: The command needs a different @ref orxonox::AccessLevel "access level"
     83*/
     84
    2985#ifndef _CommandExecutor_H__
    3086#define _CommandExecutor_H__
     
    4298namespace orxonox
    4399{
     100    /**
     101        @brief This class is used to execute and evaluate command-strings.
     102
     103        CommandExecutor executes command-strings and returns evaluated commands. It's
     104        also possible to execute Tcl commands if the corresponding argument of execute()
     105        is true.
     106
     107        @see See @ref CommandExecutorExample "this description" for more information and some examples.
     108    */
    44109    class _CoreExport CommandExecutor
    45110    {
     
    53118            static CommandEvaluation evaluate(const std::string& command);
    54119
    55             static const int Success = 0;
    56             static const int Error = 1;
    57             static const int Incomplete = 2;
    58             static const int Deactivated = 3;
    59             static const int Denied = 4;
     120            static const int Success = 0;       ///< Error code for "success" (or no error)
     121            static const int Error = 1;         ///< Error code if the command doesn't exist
     122            static const int Incomplete = 2;    ///< Error code if the command needs more arguments
     123            static const int Deactivated = 3;   ///< Error code if the command is not active
     124            static const int Denied = 4;        ///< Error code if the command needs a different access level
    60125
    61126            static MultiType unhide(const std::string& command);
    62127            static void alias(const std::string& alias, const std::string& command);
    63             static void _autocomplete(const std::string& group, const std::string& name) {}
     128            static void _autocomplete(const std::string& group, const std::string& name) {} ///< Pseudo console command used whenever no real command is available. In these cases this command provides auto-completion for console commands and groups.
    64129
    65130        private:
    66             CommandExecutor() {}
    67             CommandExecutor(const CommandExecutor& other);
    68             ~CommandExecutor() {}
     131            CommandExecutor() {}                            ///< Empty constructor
     132            CommandExecutor(const CommandExecutor& other);  ///< Not implemented copy-constructor
     133            ~CommandExecutor() {}                           ///< Empty destructor
    69134
    70135            static CommandExecutor& getInstance();
     
    73138            void cache(const std::string& command, const CommandEvaluation& evaluation);
    74139
     140            /// Helper struct, used to store cached entries
    75141            struct CacheEntry
    76142            {
    77                 CommandEvaluation evaluation_;
    78                 std::list<std::string>::iterator iterator_;
     143                CommandEvaluation evaluation_;                  ///< The command evaluation which is stored in the cache
     144                std::list<std::string>::iterator iterator_;     ///< The iterator of the corresponding element in cachelist_, used for faster access
    79145            };
    80146
    81             std::map<std::string, CacheEntry> cache_;
    82             std::list<std::string> cachelist_;
     147            std::map<std::string, CacheEntry> cache_;   ///< A map that connects command strings and evaluated commands in the cache
     148            std::list<std::string> cachelist_;          ///< A list used to sort the elements in the cache by their age
    83149    }; // tolua_export
    84150} // tolua_export
  • code/trunk/src/libraries/core/command/ConsoleCommand.cc

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @brief Implementation of the ConsoleCommand class.
     32*/
     33
    2934#include "ConsoleCommand.h"
    3035
     
    3641namespace orxonox
    3742{
     43    /**
     44        @brief Constructor: Initializes all values and registers the command.
     45        @param group The group of the command
     46        @param name The name of the command
     47        @param executor The executor of the command
     48        @param bInitialized If true, the executor is used for both, the definition of the function-header AND to executute the command. If false, the command is inactive and needs to be assigned a function before it can be used.
     49    */
    3850    ConsoleCommand::ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized)
    3951    {
     
    4557        this->baseFunctor_ = executor->getFunctor();
    4658
    47         this->argumentCompleter_[0] = 0;
    48         this->argumentCompleter_[1] = 0;
    49         this->argumentCompleter_[2] = 0;
    50         this->argumentCompleter_[3] = 0;
    51         this->argumentCompleter_[4] = 0;
     59        for (size_t i = 0; i < MAX_FUNCTOR_ARGUMENTS; ++i)
     60            this->argumentCompleter_[i] = 0;
    5261
    5362        this->keybindMode_ = KeybindMode::OnPress;
     
    6069    }
    6170
     71    /**
     72        @brief Destructor: Unregisters the command.
     73    */
    6274    ConsoleCommand::~ConsoleCommand()
    6375    {
     
    6577    }
    6678
     79    /**
     80        @brief Registers the command with the same name, but without group, as shortcut.
     81    */
    6782    ConsoleCommand& ConsoleCommand::addShortcut()
    6883    {
     
    7186    }
    7287
     88    /**
     89        @brief Registers the command with an alias as shortcut.
     90    */
    7391    ConsoleCommand& ConsoleCommand::addShortcut(const std::string&  name)
    7492    {
     
    7795    }
    7896
     97    /**
     98        @brief Registers the command in a different group but with the same name.
     99    */
    79100    ConsoleCommand& ConsoleCommand::addGroup(const std::string& group)
    80101    {
     
    83104    }
    84105
     106    /**
     107        @brief Registers an alias of the command in a different group with a different name.
     108    */
    85109    ConsoleCommand& ConsoleCommand::addGroup(const std::string& group, const std::string&  name)
    86110    {
     
    89113    }
    90114
     115    /**
     116        @brief Returns true if the command can be executed right now.
     117
     118        This returns only true, if the following conditions are met:
     119         - The command is active
     120         - The command has an executor
     121         - The executor has a functor
     122         - The functor is static or has an object
     123    */
    91124    bool ConsoleCommand::isActive() const
    92125    {
     
    94127    }
    95128
     129    /**
     130        @brief Returns true if the current state of the game matches the required access level.
     131    */
    96132    bool ConsoleCommand::hasAccess() const
    97133    {
     
    101137            case AccessLevel::Standalone: return GameMode::isStandalone();
    102138            case AccessLevel::Master:     return GameMode::isMaster();
    103             case AccessLevel::Server:     return GameMode::hasServer();
     139            case AccessLevel::Server:     return GameMode::isServer();
    104140            case AccessLevel::Client:     return GameMode::isClient();
    105             case AccessLevel::Online:     return (GameMode::hasServer() || GameMode::isClient());
     141            case AccessLevel::Online:     return (GameMode::isServer() || GameMode::isClient());
    106142            case AccessLevel::Offline:    return GameMode::isStandalone();
    107143            case AccessLevel::None:       return false;
     
    110146    }
    111147
     148    /**
     149        @brief Returns true if the headers of the given functor match the declaration of this command.
     150    */
    112151    bool ConsoleCommand::headersMatch(const FunctorPtr& functor)
    113152    {
     153        // get the minimum of the number of parameters of both commands
    114154        unsigned int minparams = std::min(this->baseFunctor_->getParamCount(), functor->getParamCount());
    115155
     156        // if the reduced headers don't match -> return false
    116157        if (this->baseFunctor_->getHeaderIdentifier(minparams) != functor->getHeaderIdentifier(minparams))
    117158            return false;
     159        // if the reduced headers match and the new functor has less or equal parameters -> return true
    118160        else if (functor->getParamCount() <= this->baseFunctor_->getParamCount())
    119161            return true;
     162        // the headers match but the new functor has more arguments and there is no executor with default-values -> return false
    120163        else if (!this->executor_)
    121164            return false;
     165        // the headers match but the new functor has more arguments, check if the executor has enough default-values
    122166        else
    123167        {
     
    135179    }
    136180
     181    /**
     182        @brief Returns true if the headers of the given executor match the declaration of this command.
     183    */
    137184    bool ConsoleCommand::headersMatch(const ExecutorPtr& executor)
    138185    {
     186        // get the minimum of the number of parameters of both commands
    139187        unsigned int minparams = std::min(this->baseFunctor_->getParamCount(), executor->getParamCount());
    140188
     189        // if the reduced headers don't match -> return false
    141190        if (this->baseFunctor_->getHeaderIdentifier(minparams) != executor->getFunctor()->getHeaderIdentifier(minparams))
    142191            return false;
     192        // if the reduced headers match and the new functor has less or equal parameters -> return true
    143193        else if (executor->getParamCount() <= this->baseFunctor_->getParamCount())
    144194            return true;
     195        // the headers match but the new functor has more arguments, check if the new executor has enough default-values
    145196        else
    146197        {
     
    158209    }
    159210
     211    /**
     212        @brief Changes the executor.
     213        @param executor The new executor
     214        @param bForce If true, the executor is always assigned, even if the headers don't match
     215        @return Returns true if the assignment was successful
     216    */
    160217    bool ConsoleCommand::setFunction(const ExecutorPtr& executor, bool bForce)
    161218    {
     219        // assign the executor if a) it's a null-pointer, b) its functor is a null-pointer, c) it's forced, d) the headers match
    162220        if (!executor || !executor->getFunctor() || bForce || this->headersMatch(executor))
    163221        {
     222            // assign the executor and clear the object stack (because it's also a new function)
    164223            this->executor_ = executor;
    165224            this->objectStack_.clear();
     
    173232    }
    174233
     234    /**
     235        @brief Changes the functor of the current executor.
     236        @param functor The new functor
     237        @param bForce If true, the functor is always assigned, even if the headers don't match
     238        @return Returns true if the assignment was successful
     239    */
    175240    bool ConsoleCommand::setFunction(const FunctorPtr& functor, bool bForce)
    176241    {
     242        // assign the functor if a) it's a null-pointer, b) it's forced, c) the headers match
    177243        if (!functor || bForce || this->headersMatch(functor))
    178244        {
     245            // assign the functor (create a new executor if necessary) and clear the object stack
    179246            if (this->executor_)
    180247                this->executor_->setFunctor(functor);
     
    192259    }
    193260
     261    /**
     262        @brief Pushes a new executor to the command-stack.
     263        @param executor The new executor
     264        @param bForce If true, the executor is always assigned, even if the headers don't match
     265    */
    194266    void ConsoleCommand::pushFunction(const ExecutorPtr& executor, bool bForce)
    195267    {
     268        // prepare the old function to be put on the stack
    196269        Command command;
    197270        command.executor_ = this->executor_;
     
    200273        command.objectStack_ = this->objectStack_;
    201274
     275        // check if the new executor can be assigned and push the old function to the stack
    202276        if (this->setFunction(executor, bForce))
    203277            this->commandStack_.push(command);
    204278    }
    205279
     280    /**
     281        @brief Pushes a new functor to the command-stack.
     282        @param functor The new functor
     283        @param bForce If true, the functor is always assigned, even if the headers don't match
     284    */
    206285    void ConsoleCommand::pushFunction(const FunctorPtr& functor, bool bForce)
    207286    {
     287        // prepare the old function to be put on the stack
    208288        Command command;
    209289        command.executor_ = this->executor_;
     
    212292        command.objectStack_ = this->objectStack_;
    213293
     294        // check if the new functor can be assigned and push the old function to the stack
    214295        if (this->setFunction(functor, bForce))
    215296            this->commandStack_.push(command);
    216297    }
    217298
     299    /**
     300        @brief Pushes a copy of the current executor and functor on the stack.
     301    */
    218302    void ConsoleCommand::pushFunction()
    219303    {
     
    224308    }
    225309
     310    /**
     311        @brief Removes the current function from the stack and restores the old state.
     312    */
    226313    void ConsoleCommand::popFunction()
    227314    {
    228315        Command command;
     316
     317        // check if there's a function on the stack
    229318        if (!this->commandStack_.empty())
    230319        {
     320            // yes it is - assign it to command and remove it from the stack
    231321            command = this->commandStack_.top();
    232322            this->commandStack_.pop();
    233323        }
    234324
     325        // restore the old executor (and also restore its functor in case this was changed in the meantime)
    235326        this->executor_ = command.executor_;
    236327        if (command.executor_)
     
    239330    }
    240331
     332    /**
     333        @brief Sets the functor to NULL (which also deactivates the command).
     334    */
    241335    void ConsoleCommand::resetFunction()
    242336    {
     
    246340    }
    247341
     342    /**
     343        @brief Returns the current executor which can be used to execute the command.
     344    */
    248345    const ExecutorPtr& ConsoleCommand::getExecutor() const
    249346    {
     
    251348    }
    252349
     350    /**
     351        @brief Changes the current object that is used to execute member-functions.
     352        @return Returns true if the object was successfully changed
     353    */
    253354    bool ConsoleCommand::setObject(void* object)
    254355    {
    255         if (this->executor_)
    256         {
     356        // check if there's an executor
     357        if (this->executor_)
     358        {
     359            // check if there's a functor
    257360            if (this->executor_->getFunctor())
    258361            {
     362                // change the object
    259363                this->executor_->getFunctor()->setRawObjectPointer(object);
    260364                return true;
     
    269373    }
    270374
     375    /**
     376        @brief Push a new object to the object-stack.
     377    */
    271378    void ConsoleCommand::pushObject(void* object)
    272379    {
     
    276383    }
    277384
     385    /**
     386        @brief Removes the current object from the stack an restores the old object.
     387    */
    278388    void ConsoleCommand::popObject()
    279389    {
     
    287397    }
    288398
     399    /**
     400        @brief Returns the current object pointer that is used to execute member-functions.
     401    */
    289402    void* ConsoleCommand::getObject() const
    290403    {
     
    295408    }
    296409
    297     ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& param1)
    298     {
    299         if (this->executor_)
    300             this->executor_->setDefaultValues(param1);
     410    /**
     411        @brief Changes the default values of the current executor.
     412    */
     413    ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& arg1)
     414    {
     415        if (this->executor_)
     416            this->executor_->setDefaultValues(arg1);
    301417        else
    302418            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     
    305421    }
    306422
    307     ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& param1, const MultiType& param2)
    308     {
    309         if (this->executor_)
    310             this->executor_->setDefaultValues(param1, param2);
     423    /**
     424        @brief Changes the default values of the current executor.
     425    */
     426    ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& arg1, const MultiType& arg2)
     427    {
     428        if (this->executor_)
     429            this->executor_->setDefaultValues(arg1, arg2);
    311430        else
    312431            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     
    315434    }
    316435
    317     ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
    318     {
    319         if (this->executor_)
    320             this->executor_->setDefaultValues(param1, param2, param3);
     436    /**
     437        @brief Changes the default values of the current executor.
     438    */
     439    ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3)
     440    {
     441        if (this->executor_)
     442            this->executor_->setDefaultValues(arg1, arg2, arg3);
    321443        else
    322444            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     
    325447    }
    326448
    327     ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
    328     {
    329         if (this->executor_)
    330             this->executor_->setDefaultValues(param1, param2, param3, param4);
     449    /**
     450        @brief Changes the default values of the current executor.
     451    */
     452    ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4)
     453    {
     454        if (this->executor_)
     455            this->executor_->setDefaultValues(arg1, arg2, arg3, arg4);
    331456        else
    332457            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     
    335460    }
    336461
    337     ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
    338     {
    339         if (this->executor_)
    340             this->executor_->setDefaultValues(param1, param2, param3, param4, param5);
     462    /**
     463        @brief Changes the default values of the current executor.
     464    */
     465    ConsoleCommand& ConsoleCommand::defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5)
     466    {
     467        if (this->executor_)
     468            this->executor_->setDefaultValues(arg1, arg2, arg3, arg4, arg5);
    341469        else
    342470            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     
    345473    }
    346474
    347     ConsoleCommand& ConsoleCommand::defaultValue(unsigned int index, const MultiType& param)
    348     {
    349         if (this->executor_)
    350             this->executor_->setDefaultValue(index, param);
     475    /**
     476        @brief Changes the default value of the argument with given index of the current executor.
     477        @param index The index of the argument (the first argument has index 0)
     478        @param arg The new default value
     479    */
     480    ConsoleCommand& ConsoleCommand::defaultValue(unsigned int index, const MultiType& arg)
     481    {
     482        if (this->executor_)
     483            this->executor_->setDefaultValue(index, arg);
    351484        else
    352485            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
     
    355488    }
    356489
    357     ConsoleCommand& ConsoleCommand::argumentCompleter(unsigned int param, ArgumentCompleter* completer)
    358     {
    359         if (param < 5)
    360             this->argumentCompleter_[param] = completer;
    361         else
    362             COUT(2) << "Warning: Couldn't add autocompletion-function for param " << param << " in console command \"" << this->baseName_ << "\": index out of bound." << std::endl;
    363 
    364         return *this;
    365     }
    366 
    367     ArgumentCompleter* ConsoleCommand::getArgumentCompleter(unsigned int param) const
    368     {
    369         if (param < 5)
    370             return this->argumentCompleter_[param];
     490    /**
     491        @brief Changes the argument completer for the given argument.
     492        @param index The index of the argument (the first argument has index 0)
     493        @param completer The new argument completer
     494    */
     495    ConsoleCommand& ConsoleCommand::argumentCompleter(unsigned int index, ArgumentCompleter* completer)
     496    {
     497        if (index < 5)
     498            this->argumentCompleter_[index] = completer;
     499        else
     500            COUT(2) << "Warning: Couldn't add autocompletion-function for index " << index << " in console command \"" << this->baseName_ << "\": index out of bound." << std::endl;
     501
     502        return *this;
     503    }
     504
     505    /**
     506        @brief Returns the argument completer for the argument with given index.
     507    */
     508    ArgumentCompleter* ConsoleCommand::getArgumentCompleter(unsigned int index) const
     509    {
     510        if (index < 5)
     511            return this->argumentCompleter_[index];
    371512        else
    372513            return 0;
    373514    }
    374515
     516    /**
     517        @brief Sets the description of this command.
     518    */
    375519    ConsoleCommand& ConsoleCommand::description(const std::string& description)
    376520    {
     
    380524    }
    381525
     526    /**
     527        @brief Returns the description of this command.
     528    */
    382529    const std::string& ConsoleCommand::getDescription() const
    383530    {
     
    385532    }
    386533
    387     ConsoleCommand& ConsoleCommand::descriptionParam(unsigned int param, const std::string& description)
    388     {
    389         if (param < MAX_FUNCTOR_ARGUMENTS)
    390         {
    391             this->descriptionParam_[param] = std::string("ConsoleCommandDescription::" + this->baseName_ + "::param" + multi_cast<std::string>(param));
    392             AddLanguageEntry(this->descriptionParam_[param], description);
    393         }
    394         return *this;
    395     }
    396 
    397     const std::string& ConsoleCommand::getDescriptionParam(unsigned int param) const
    398     {
    399         if (param < MAX_FUNCTOR_ARGUMENTS)
    400             return GetLocalisation_noerror(this->descriptionParam_[param]);
     534    /**
     535        @brief Sets the description for an argument with given index.
     536    */
     537    ConsoleCommand& ConsoleCommand::descriptionParam(unsigned int index, const std::string& description)
     538    {
     539        if (index < MAX_FUNCTOR_ARGUMENTS)
     540        {
     541            this->descriptionParam_[index] = std::string("ConsoleCommandDescription::" + this->baseName_ + "::param" + multi_cast<std::string>(index));
     542            AddLanguageEntry(this->descriptionParam_[index], description);
     543        }
     544        return *this;
     545    }
     546
     547    /**
     548        @brief Returns the description for the argument with given index.
     549    */
     550    const std::string& ConsoleCommand::getDescriptionParam(unsigned int index) const
     551    {
     552        if (index < MAX_FUNCTOR_ARGUMENTS)
     553            return GetLocalisation_noerror(this->descriptionParam_[index]);
    401554
    402555        return this->descriptionParam_[0];
    403556    }
    404557
     558    /**
     559        @brief Sets the description for the return-value.
     560    */
    405561    ConsoleCommand& ConsoleCommand::descriptionReturnvalue(const std::string& description)
    406562    {
     
    410566    }
    411567
    412     const std::string& ConsoleCommand::getDescriptionReturnvalue(int param) const
     568    /**
     569        @brief Returns the description for the return-value.
     570    */
     571    const std::string& ConsoleCommand::getDescriptionReturnvalue(int index) const
    413572    {
    414573        return GetLocalisation_noerror(this->descriptionReturnvalue_);
    415574    }
    416575
     576    /**
     577        @brief Returns the command with given group an name.
     578        @param group The group of the requested command
     579        @param name The group of the requested command
     580        @param bPrintError If true, an error is printed if the command doesn't exist
     581    */
    417582    /* static */ const ConsoleCommand* ConsoleCommand::getCommand(const std::string& group, const std::string& name, bool bPrintError)
    418583    {
     584        // find the group
    419585        std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandMap().find(group);
    420586        if (it_group != ConsoleCommand::getCommandMap().end())
    421587        {
     588            // find the name
    422589            std::map<std::string, ConsoleCommand*>::const_iterator it_name = it_group->second.find(name);
    423590            if (it_name != it_group->second.end())
    424591            {
     592                // return the pointer
    425593                return it_name->second;
    426594            }
     
    436604    }
    437605
     606    /**
     607        @brief Returns the command with given group an name in lowercase.
     608        @param group The group of the requested command in lowercase
     609        @param name The group of the requested command in lowercase
     610        @param bPrintError If true, an error is printed if the command doesn't exist
     611    */
    438612    /* static */ const ConsoleCommand* ConsoleCommand::getCommandLC(const std::string& group, const std::string& name, bool bPrintError)
    439613    {
     
    441615        std::string nameLC = getLowercase(name);
    442616
     617        // find the group
    443618        std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandMapLC().find(groupLC);
    444619        if (it_group != ConsoleCommand::getCommandMapLC().end())
    445620        {
     621            // find the name
    446622            std::map<std::string, ConsoleCommand*>::const_iterator it_name = it_group->second.find(nameLC);
    447623            if (it_name != it_group->second.end())
    448624            {
     625                // return the pointer
    449626                return it_name->second;
    450627            }
     
    460637    }
    461638
     639    /**
     640        @brief Returns the static map that stores all console commands.
     641    */
    462642    /* static */ std::map<std::string, std::map<std::string, ConsoleCommand*> >& ConsoleCommand::getCommandMap()
    463643    {
     
    466646    }
    467647
     648    /**
     649        @brief Returns the static map that stores all console commands in lowercase.
     650    */
    468651    /* static */ std::map<std::string, std::map<std::string, ConsoleCommand*> >& ConsoleCommand::getCommandMapLC()
    469652    {
     
    472655    }
    473656
     657    /**
     658        @brief Registers a new command with given group an name by adding it to the command map.
     659    */
    474660    /* static */ void ConsoleCommand::registerCommand(const std::string& group, const std::string& name, ConsoleCommand* command)
    475661    {
     
    477663            return;
    478664
     665        // check if a command with this name already exists
    479666        if (ConsoleCommand::getCommand(group, name) != 0)
    480667        {
     
    486673        else
    487674        {
     675            // add the command to the map
    488676            ConsoleCommand::getCommandMap()[group][name] = command;
    489677            ConsoleCommand::getCommandMapLC()[getLowercase(group)][getLowercase(name)] = command;
     
    491679    }
    492680
     681    /**
     682        @brief Removes the command from the command map.
     683    */
    493684    /* static */ void ConsoleCommand::unregisterCommand(ConsoleCommand* command)
    494685    {
     686        // iterate through all groups
    495687        for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::iterator it_group = ConsoleCommand::getCommandMap().begin(); it_group != ConsoleCommand::getCommandMap().end(); )
    496688        {
     689            // iterate through all commands of each group
    497690            for (std::map<std::string, ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); )
    498691            {
     692                // erase the command
    499693                if (it_name->second == command)
    500694                    it_group->second.erase(it_name++);
     
    503697            }
    504698
     699            // erase the group if it is empty now
    505700            if (it_group->second.empty())
    506701                ConsoleCommand::getCommandMap().erase(it_group++);
     
    509704        }
    510705
     706        // now the same for the lowercase-map:
     707
     708        // iterate through all groups
    511709        for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::iterator it_group = ConsoleCommand::getCommandMapLC().begin(); it_group != ConsoleCommand::getCommandMapLC().end(); )
    512710        {
     711            // iterate through all commands of each group
    513712            for (std::map<std::string, ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); )
    514713            {
     714                // erase the command
    515715                if (it_name->second == command)
    516716                    it_group->second.erase(it_name++);
     
    519719            }
    520720
     721            // erase the group if it is empty now
    521722            if (it_group->second.empty())
    522723                ConsoleCommand::getCommandMapLC().erase(it_group++);
     
    526727    }
    527728
     729    /**
     730        @brief Deletes all commands
     731    */
    528732    /* static */ void ConsoleCommand::destroyAll()
    529733    {
     734        // delete entries until the map is empty
    530735        while (!ConsoleCommand::getCommandMap().empty() && !ConsoleCommand::getCommandMap().begin()->second.empty())
    531736            delete ConsoleCommand::getCommandMap().begin()->second.begin()->second;
  • code/trunk/src/libraries/core/command/ConsoleCommand.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @defgroup ConsoleCommand Console commands
     31    @ingroup Command
     32*/
     33
     34/**
     35    @file
     36    @ingroup Command ConsoleCommand
     37    @brief Declaration of the orxonox::ConsoleCommand class and the SetConsoleCommand() macro.
     38
     39    @anchor ConsoleCommandExample
     40
     41    Console commands can be used to write scripts, use key-bindings or simply to be
     42    entered into the shell by the user. Instances of orxonox::ConsoleCommand define
     43    the function of a command, and also more information like, for example, if it is
     44    active, default values, and possible arguments.
     45
     46    Commands need to be registered to the system statically on startup by using the
     47    SetConsoleCommand() or DeclareConsoleCommand() macros outside of a function.
     48    This ensures that commands are known to the system at any time, so they can be
     49    evaluated (see orxonox::CommandExecutor::evaluate()), for example for key-bindings.
     50
     51    Example:
     52    @code
     53    void myCoutFunction(const std::string& text)        // Define a static function
     54    {
     55        COUT(0) << "Text: " << text << std::endl;       // Print the text to the console
     56    }
     57
     58    SetConsoleCommand("cout", &myCoutFunction);         // Register the function as command with name "cout"
     59    @endcode
     60
     61    Now you can open the shell and execute the command:
     62    @code
     63    $ cout Hello World
     64    @endcode
     65
     66    Internally this command is now passed to orxonox::CommandExecutor::execute():
     67    @code
     68    CommandExecutor::execute("cout HelloWorld");
     69    @endcode
     70
     71    CommandExecutor searches for a command with name "cout" and passes the arguments
     72    "Hello World" to it. Because we registered myCoutFunction() with this command,
     73    as a result the following text will be printed to the console:
     74    @code
     75    Text: Hello World
     76    @endcode
     77
     78    You can add more attributes to the ConsoleCommand, by using the command-chain feature
     79    of SetConsoleCommand(). For example like this:
     80    @code
     81    SetConsoleCommand("cout", &myCoutFunction)
     82        .addGroup("output", "text")
     83        .accessLevel(AccessLevel::Offline)
     84        .defaultValues("no text");
     85    @endcode
     86
     87    Open the shell again and try it:
     88    @code
     89    $ cout Hello World
     90    Text: Hello World
     91    $ output text Hello World
     92    Text: Hello World
     93    $ cout
     94    Text: no text
     95    @endcode
     96
     97    If you execute it online (note: the access level is "Offline"), you will see the
     98    following (or something similar):
     99    @code
     100    $ cout Hello World
     101    Error: Can't execute command "cout", access denied.
     102    @endcode
     103
     104    If a command is executed, the arguments are passed to an underlying function,
     105    whitch is wrapped by an orxonox::Functor which again is wrapped by an orxonox::Executor.
     106    The Functor contains the function-pointer, as well as the object-pointer in
     107    case of a non-static member-function. The executor stores possible default-values
     108    for each argument of the function.
     109
     110    The function of a command can be changed at any time. It's possible to just exchange
     111    the function-pointer of the underlying Functor if the headers of the functions are
     112    exactly the same. But you can also exchange the Functor itself or even completely
     113    replace the Executor. Also the other attributes of a ConsoleCommand can be modified
     114    during the game, for example it can be activated or deactivated.
     115
     116    To do so, the function ModifyConsoleCommand() has to be used. It returns an instance
     117    of orxonox::ConsoleCommand::ConsoleCommandManipulator which has an interface similar to
     118    orxonox::ConsoleCommand, but with slight differences. You can use it the same way like
     119    SetConsoleCommand(), meaning you can use command-chains to change different attributes at
     120    the same time. ModifyConsoleCommand() must not be executed statically, but rather in a
     121    function at some point of the execution of the program.
     122
     123    Example:
     124    @code
     125    void myOtherCoutFunction(const std::string& text)                       // Define a new static function
     126    {
     127        COUT(0) << "Uppercase: " << getUppercase(text) << std::endl;        // Print the text in uppercase to the console
     128    }
     129
     130    {
     131        // ...                                                              // somewhere in the code
     132
     133        ModifyConsoleCommand("cout").setFunction(&myOtherCoutFunction);     // Modify the underlying function of the command
     134
     135        // ...
     136    }
     137    @endcode
     138
     139    If you now enter the command into the shell, you'll see a different behavior:
     140    @code
     141    $ cout Hello World
     142    Uppercase: HELLO WORLD
     143    $ cout
     144    Uppercase: NO TEXT
     145    @endcode
     146
     147    A few important notes about changing functions:
     148
     149    Instead of changing the function with setFunction(), you can also create a command-stack
     150    by using pushFunction() and popFunction(). It's important to note a few things about that,
     151    because the underlying structure of Executor and Functor has a few pitfalls:
     152     - If you push a new function-pointer, the same executor as before will be used (and, if
     153       the headers match, even the same functor can be used, which is very fast)
     154     - If you push a new Functor, the same executor as before will be used
     155     - If you push a new Executor, everything is changed
     156
     157    Note that the executor contains the @b default @b values, so if you just exchange the
     158    Functor, the default values remain the same. However if you decide to change the default
     159    values at any point of the stack, <b>this will also change the default values on all
     160    other stack-levels</b> that share the same executor. If you don't like this behavior,
     161    you have to explicitly push a new executor before changing the default values, either by
     162    calling pushFunction(executor) or by calling pushFunction(void) which pushes a copy of
     163    the current executor to the stack.
     164
     165    Another important point are object pointers in case of non-static member-functions.
     166    Whenever you set or push a new function, <b>you must add the object pointer again</b>
     167    because objects are stored in the Functor which is usually exchanged if you change
     168    the function.
     169
     170    You can also use a stack for objects, but note that this <b>object-stack is different for each
     171    function</b> - so if you set a new function, the object-stack will be cleared. If you push
     172    a new function, the old object-stack is stored in the stack, so it can be restored if
     173    you pop the function.
     174
     175    %DeclareConsoleCommand():
     176
     177    Appart from SetConsoleCommand() you can also call DeclareConsoleCommand(). In contrast
     178    to SetConsoleCommand(), this doesn't assign a function to the command. Indeed you have
     179    to pass a function-pointer to DeclareConsoleCommand(), but it is only used to determine
     180    the header of the future command-function. This allows to declare a command statically,
     181    thus it's possible to evaluate key-bindings of this command, but the actual function
     182    can be assigned at a later point.
     183
     184    Example:
     185    @code
     186    DeclareConsoleCommand("cout", &prototype::void__string);
     187    @endcode
     188
     189    If you try to execute the command now, you see the following (or something similar):
     190    @code
     191    $ cout Hello World
     192    Error: Can't execute command "cout", command is not active.
     193    @endcode
     194
     195    You first have to assign a function to use the command:
     196    @code
     197    {
     198        // ...
     199
     200        ModifyConsoleCommand("cout").setFunction(&myCoutFunction);
     201
     202        // ...
     203    }
     204    @endcode
     205
     206    Now you can use it:
     207    @code
     208    $ cout Hello World
     209    Text: Hello World
     210    @endcode
     211
     212    Note that the initial function prototype::void__string is defined in the namespace
     213    orxonox::prototype. If there's no function with the desired header, you can extend
     214    the collection of functions or simply use another function that has the same header.
     215*/
     216
    29217#ifndef _ConsoleCommand_H__
    30218#define _ConsoleCommand_H__
     
    42230
    43231
     232/**
     233    @brief Defines a console command. The macro is overloaded for 2-4 parameters.
     234
     235    This is an overloaded macro. Depending on the number of arguments a different
     236    overloaded implementation of the macro will be chosen.
     237
     238    Console commands created with SetConsoleCommand() become active immediately and
     239    the given function-pointer (and optionally the object) will be used to execute
     240    the command.
     241*/
    44242#define SetConsoleCommand(...) \
    45243    BOOST_PP_EXPAND(BOOST_PP_CAT(SetConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__))
     244/**
     245    @brief This macro is executed if you call SetConsoleCommand() with 2 arguments.
     246    @param name The name (string) of the console command
     247    @param functionpointer The function-pointer of the corresponding command-function
     248*/
    46249#define SetConsoleCommand2(name, functionpointer) \
    47250    SetConsoleCommandGeneric("", name, orxonox::createFunctor(functionpointer))
     251/**
     252    @brief This macro is executed if you call SetConsoleCommand() with 3 arguments.
     253    @param group The group (string) of the console command
     254    @param name The name (string) of the console command
     255    @param functionpointer The function-pointer of the corresponding command-function
     256*/
    48257#define SetConsoleCommand3(group, name, functionpointer) \
    49258    SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))
     259/**
     260    @brief This macro is executed if you call SetConsoleCommand() with 4 arguments.
     261    @param group The group (string) of the console command
     262    @param name The name (string) of the console command
     263    @param functionpointer The function-pointer of the corresponding command-function
     264    @param object The object that will be assigned to the command. Used for member-functions.
     265*/
    50266#define SetConsoleCommand4(group, name, functionpointer, object) \
    51267    SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object))
    52268
     269/// Internal macro
    53270#define SetConsoleCommandGeneric(group, name, functor) \
    54271    static orxonox::ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::createConsoleCommand(group, name, orxonox::createExecutor(functor)))
    55272
    56273
     274/**
     275    @brief Declares a console command. The macro is overloaded for 2-3 parameters.
     276
     277    This is an overloaded macro. Depending on the number of arguments a different
     278    overloaded implementation of the macro will be chosen.
     279
     280    Console commands created with DeclareConsoleCommand() don't use the the given
     281    function-pointer to execute the command, it is only used to define the header
     282    of the future command-function. The command is inactive until you manually
     283    set a function with orxonox::ModifyConsoleCommand(). You can use a different
     284    function-pointer than in the final command, as long as it has the same header.
     285*/
    57286#define DeclareConsoleCommand(...) \
    58287    BOOST_PP_EXPAND(BOOST_PP_CAT(DeclareConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__))
     288/**
     289    @brief This macro is executed if you call DeclareConsoleCommand() with 2 arguments.
     290    @param name The name (string) of the console command
     291    @param functionpointer The function-pointer of an arbitrary function that has the same header as the final function
     292*/
    59293#define DeclareConsoleCommand2(name, functionpointer) \
    60294    DeclareConsoleCommandGeneric("", name, orxonox::createFunctor(functionpointer))
     295/**
     296    @brief This macro is executed if you call DeclareConsoleCommand() with 3 arguments.
     297    @param group The group (string) of the console command
     298    @param name The name (string) of the console command
     299    @param functionpointer The function-pointer of an arbitrary function that has the same header as the final function
     300*/
    61301#define DeclareConsoleCommand3(group, name, functionpointer) \
    62302    DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))
    63 #define DeclareConsoleCommand4(group, name, functionpointer, object) \
    64     DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object))
    65 
     303
     304/// Internal macro
    66305#define DeclareConsoleCommandGeneric(group, name, functor) \
    67306    static orxonox::ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::createConsoleCommand(group, name, orxonox::createExecutor(functor), false))
     
    70309namespace orxonox
    71310{
     311    /**
     312        @brief A small collection of functions that can be used in DeclareConsoleCommand() if
     313        you don't want to use the real function-pointer.
     314    */
    72315    namespace prototype
    73316    {
     
    78321    namespace AccessLevel
    79322    {
     323        /**
     324            @brief Possible access levels: A command can only be executed if the program is in the state which is requested by the access level.
     325        */
    80326        enum Enum
    81327        {
     
    91337    }
    92338
     339    /**
     340        @brief The ConsoleCommand class stores all information about a console command which can be executed by CommandExecutor.
     341
     342        Console commands can be entered by the user into the shell, called in scripts, or
     343        used for key-bindings. They are simple text strings that can be executed by
     344        CommandExecutor. CommandExecutor will search for a ConsoleCommand with the given
     345        group and name and will execute it's Executor (which again calls the Functor and
     346        this finally calls the command-function).
     347
     348        @see See @ref ConsoleCommandExample "ConsoleCommand.h" for more information and some examples.
     349    */
    93350    class _CoreExport ConsoleCommand
    94351    {
    95352        friend struct ConsoleCommandManipulator;
    96353
     354        /**
     355            @brief Helper class that is used to put the current state of the ConsoleCommand on a stack.
     356        */
    97357        struct Command
    98358        {
    99             ExecutorPtr executor_;
    100             FunctorPtr functor_;
    101             std::vector<void*> objectStack_;
     359            ExecutorPtr executor_;              ///< The executor
     360            FunctorPtr functor_;                ///< The function that is used with the executor - has to be stored separatley because the executor is often used with different functors
     361            std::vector<void*> objectStack_;    ///< The object stack
    102362        };
    103363
    104364        public:
     365            /**
     366                @brief Helper class that is used to manipulate console commands.
     367
     368                An instance of this class is returned if you call the ModifyConsoleCommand macro.
     369                This class provides an interface which wraps some functions of ConsoleCommand. It
     370                allows access to some private functions like setFunction() (that can't be called
     371                right after SetConsoleCommand()) but it also hides some functions that shouln't be
     372                called after the static declaration like addShortcut() or description().
     373
     374                @see See @ref ConsoleCommandExample "ConsoleCommand.h" for more information and examples.
     375            */
    105376            struct ConsoleCommandManipulator
    106377            {
    107378                public:
     379                    /// Constructor: Creates a manipulator for a given ConsoleCommand.
    108380                    ConsoleCommandManipulator(const ConsoleCommand* command) : command_(const_cast<ConsoleCommand*>(command)) {}
    109381
     382                    /// Changes the current function of the command. @param function The new function-pointer @param bForce If true, the new function-pointer is always assigned, even if the headers don't match
    110383                    template <class F>
    111384                    inline ConsoleCommandManipulator& setFunction(F function, bool bForce = false)
     
    113386                            if (this->command_)
    114387                            {
     388                                // check if the headers match. If they do, only change the function-pointer of the current Functor instead of creating a new Functor
    115389                                if (this->command_->getExecutor() && this->command_->getExecutor()->getFunctor() && this->command_->getExecutor()->getFunctor()->getFullIdentifier() == typeid(F))
    116390                                {
     
    123397                            return *this;
    124398                        }
     399                    /// Changes the current function of the command. @param function The new function-pointer @param object The new object-pointer (for member-functions) @param bForce If true, the new function-pointer is always assigned, even if the headers don't match
    125400                    template <class F, class O>
    126401                    inline ConsoleCommandManipulator& setFunction(F function, O* object, bool bForce = false)
     
    128403                            if (this->command_)
    129404                            {
     405                                // check if the headers match. If they do, only change the function-pointer of the current Functor instead of creating a new Functor
    130406                                if (this->command_->getExecutor() && this->command_->getExecutor()->getFunctor() && this->command_->getExecutor()->getFunctor()->getFullIdentifier() == typeid(F))
    131407                                {
     
    139415                            return *this;
    140416                        }
     417                    /// Changes the current Functor of the command. @param functor The new Functor @param bForce If true, the new Functor is always assigned, even if the headers don't match
    141418                    inline ConsoleCommandManipulator& setFunction(const FunctorPtr& functor, bool bForce = false)
    142419                        { if (this->command_) { this->command_->setFunction(functor, bForce); } return *this; }
     420                    /// Changes the current Executor of the command. @param executor The new Executor @param bForce If true, the new Executor is always assigned, even if the headers don't match
    143421                    inline ConsoleCommandManipulator& setFunction(const ExecutorPtr& executor, bool bForce = false)
    144422                        { if (this->command_) { this->command_->setFunction(executor, bForce); } return *this; }
    145423
     424                    /// Pushes a copy of the current Executor on the command-stack, that can be altered without changing the old Executor. @details This function is especially useful if you don't wan't to change the function, but only the default values of the executor.
    146425                    inline ConsoleCommandManipulator& pushFunction()
    147426                        { if (this->command_) { this->command_->pushFunction(); } return *this; }
     427                    /// Pushes a new function on the command-stack. @param function The new function-pointer @param bForce If true, the new function-pointer is always assigned, even if the headers don't match
    148428                    template <class F>
    149429                    inline ConsoleCommandManipulator& pushFunction(F function, bool bForce = false)
    150430                        { if (this->command_) { this->command_->pushFunction(createFunctor(function), bForce); } return *this; }
     431                    /// Pushes a new function on the command-stack. @param function The new function-pointer @param object The new object-pointer (for member-functions) @param bForce If true, the new function-pointer is always assigned, even if the headers don't match
    151432                    template <class F, class O>
    152433                    inline ConsoleCommandManipulator& pushFunction(F function, O* object, bool bForce = false)
    153434                        { if (this->command_) { this->command_->pushFunction(createFunctor(function, object), bForce); } return *this; }
     435                    /// Pushes a new Functor on the command-stack. @param functor The new Functor @param bForce If true, the new Functor is always assigned, even if the headers don't match
    154436                    inline ConsoleCommandManipulator& pushFunction(const FunctorPtr& functor, bool bForce = false)
    155437                        { if (this->command_) { this->command_->pushFunction(functor, bForce); } return *this; }
     438                    /// Pushes a new Executor on the command-stack. @param executor The new Executor @param bForce If true, the new Executor is always assigned, even if the headers don't match
    156439                    inline ConsoleCommandManipulator& pushFunction(const ExecutorPtr& executor, bool bForce = false)
    157440                        { if (this->command_) { this->command_->pushFunction(executor, bForce); } return *this; }
    158441
     442                    /// Removes the current function from the stack and restores the old state. If there's no other function on the stack, the command is deactivated.
    159443                    inline ConsoleCommandManipulator& popFunction()
    160444                        { if (this->command_) { this->command_->popFunction(); } return *this; }
    161445
     446                    /// Sets the current function-pointer to NULL, which also deactivates the command.
    162447                    inline ConsoleCommandManipulator& resetFunction()
    163448                        { if (this->command_) { this->command_->resetFunction(); } return *this; }
    164449
     450                    /// Changes the current object (used for member-functions).
    165451                    inline ConsoleCommandManipulator& setObject(void* object)
    166452                        { if (this->command_) { this->command_->setObject(object); } return *this; }
     453                    /// Pushes a new object on the object-stack.
    167454                    inline ConsoleCommandManipulator& pushObject(void* object)
    168455                        { if (this->command_) { this->command_->pushObject(object); } return *this; }
     456                    /// Removes the current object from the object-stack and restores the old object (or NULL if there's no object left on the stack).
    169457                    inline ConsoleCommandManipulator& popObject()
    170458                        { if (this->command_) { this->command_->popObject(); } return *this; }
    171459
     460                    /// Changes the activity of the command.
    172461                    inline ConsoleCommandManipulator& setActive(bool bActive)
    173462                        { if (this->command_) { this->command_->setActive(bActive); } return *this; }
     463                    /// Activates the command.
    174464                    inline ConsoleCommandManipulator& activate()
    175465                        { return this->setActive(true); }
     466                    /// Deactivates the command.
    176467                    inline ConsoleCommandManipulator& deactivate()
    177468                        { return this->setActive(false); }
    178469
     470                    /// Changes the visibility of the command.
    179471                    inline ConsoleCommandManipulator& setHidden(bool bHidden)
    180472                        { if (this->command_) { this->command_->setHidden(bHidden); } return *this; }
     473                    /// Hides the command (can still be executed, but is not visible in the list of available commands).
    181474                    inline ConsoleCommandManipulator& hide()
    182475                        { return this->setHidden(true); }
     476                    /// Makes the command visible.
    183477                    inline ConsoleCommandManipulator& show()
    184478                        { return this->setHidden(false); }
    185479
    186                     inline ConsoleCommandManipulator& defaultValues(const MultiType& param1)
    187                         { if (this->command_) { this->command_->defaultValues(param1); } return *this; }
    188                     inline ConsoleCommandManipulator& defaultValues(const MultiType& param1, const MultiType& param2)
    189                         { if (this->command_) { this->command_->defaultValues(param1, param2); } return *this; }
    190                     inline ConsoleCommandManipulator& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
    191                         { if (this->command_) { this->command_->defaultValues(param1, param2, param3); } return *this; }
    192                     inline ConsoleCommandManipulator& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
    193                         { if (this->command_) { this->command_->defaultValues(param1, param2, param3, param4); } return *this; }
    194                     inline ConsoleCommandManipulator& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
    195                         { if (this->command_) { this->command_->defaultValues(param1, param2, param3, param4, param5); } return *this; }
    196                     inline ConsoleCommandManipulator& defaultValue(unsigned int index, const MultiType& param)
    197                         { if (this->command_) { this->command_->defaultValue(index, param); } return *this; }
    198 
     480                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
     481                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1)
     482                        { if (this->command_) { this->command_->defaultValues(arg1); } return *this; }
     483                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
     484                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1, const MultiType& arg2)
     485                        { if (this->command_) { this->command_->defaultValues(arg1, arg2); } return *this; }
     486                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
     487                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3)
     488                        { if (this->command_) { this->command_->defaultValues(arg1, arg2, arg3); } return *this; }
     489                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
     490                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4)
     491                        { if (this->command_) { this->command_->defaultValues(arg1, arg2, arg3, arg4); } return *this; }
     492                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
     493                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5)
     494                        { if (this->command_) { this->command_->defaultValues(arg1, arg2, arg3, arg4, arg5); } return *this; }
     495                    /// Changes the default value of the argument with given index of the current executor (doesn't modify executors on deeper levels of the command-stack).
     496                    inline ConsoleCommandManipulator& defaultValue(unsigned int index, const MultiType& arg)
     497                        { if (this->command_) { this->command_->defaultValue(index, arg); } return *this; }
     498
     499                    /// Changes the access level of the command.
    199500                    inline ConsoleCommandManipulator& accessLevel(AccessLevel::Enum level)
    200501                        { if (this->command_) { this->command_->accessLevel(level); } return *this; }
    201502
    202                     inline ConsoleCommandManipulator& argumentCompleter(unsigned int param, ArgumentCompleter* completer)
    203                         { if (this->command_) { this->command_->argumentCompleter(param, completer); } return *this; }
    204 
     503                    /// Changes the argument completer for the given parameter.
     504                    inline ConsoleCommandManipulator& argumentCompleter(unsigned int index, ArgumentCompleter* completer)
     505                        { if (this->command_) { this->command_->argumentCompleter(index, completer); } return *this; }
     506
     507                    /// Defines the command to be an input command.
    205508                    inline ConsoleCommandManipulator& setAsInputCommand()
    206509                        { if (this->command_) { this->command_->setAsInputCommand(); } return *this; }
     510                    /// Changes the keybind mode of the command.
    207511                    inline ConsoleCommandManipulator& keybindMode(KeybindMode::Value mode)
    208512                        { if (this->command_) { this->command_->keybindMode(mode); } return *this; }
     513                    /// Sets the input configured param to the given index.
    209514                    inline ConsoleCommandManipulator& inputConfiguredParam(int index)
    210515                        { if (this->command_) { this->command_->inputConfiguredParam(index); } return *this; }
    211516
    212517                private:
    213                     ConsoleCommand* command_;
     518                    ConsoleCommand* command_;   ///< The command which is being manipulated by this object
    214519            };
    215520
     
    223528            ConsoleCommand& addGroup(const std::string& group, const std::string&  name);
    224529
     530            /// Returns the name that was first used for this command.
    225531            inline const std::string& getName() const
    226532                { return this->baseName_; }
    227533
    228534            const ExecutorPtr& getExecutor() const;
     535            /// Returns the functor that defines the required header for this command (but isn't necessarily executed).
    229536            inline const FunctorPtr& getBaseFunctor() const
    230537                { return this->baseFunctor_; }
    231538
     539            /// Changes the activity of the command.
    232540            inline ConsoleCommand& setActive(bool bActive)
    233541                { this->bActive_ = bActive; return *this; }
     542            /// Activates the command.
    234543            inline ConsoleCommand& activate()
    235544                { return this->setActive(true); }
     545            /// Deactivates the command.
    236546            inline ConsoleCommand& deactivate()
    237547                { return this->setActive(false); }
    238548
     549            /// Changes the visibility of the command.
    239550            inline ConsoleCommand& setHidden(bool bHidden)
    240551                { this->bHidden_ = bHidden; return *this; }
     552            /// Hides the command (can still be executed, but is not visible in the list of available commands).
    241553            inline ConsoleCommand& hide()
    242554                { return this->setHidden(true); }
     555            /// Makes the command visible.
    243556            inline ConsoleCommand& show()
    244557                { return this->setHidden(false); }
     
    246559            bool isActive() const;
    247560            bool hasAccess() const;
     561            /// Returns true if the command is currently hidden.
    248562            inline bool isHidden() const
    249563                { return this->bHidden_; }
     
    252566            const std::string& getDescription() const;
    253567
    254             ConsoleCommand& descriptionParam(unsigned int param, const std::string& description);
    255             const std::string& getDescriptionParam(unsigned int param) const;
     568            ConsoleCommand& descriptionParam(unsigned int index, const std::string& description);
     569            const std::string& getDescriptionParam(unsigned int index) const;
    256570
    257571            ConsoleCommand& descriptionReturnvalue(const std::string& description);
    258             const std::string& getDescriptionReturnvalue(int param) const;
    259 
    260             ConsoleCommand& defaultValues(const MultiType& param1);
    261             ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2);
    262             ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3);
    263             ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4);
    264             ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5);
    265             ConsoleCommand& defaultValue(unsigned int index, const MultiType& param);
    266 
     572            const std::string& getDescriptionReturnvalue(int index) const;
     573
     574            ConsoleCommand& defaultValues(const MultiType& arg1);
     575            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2);
     576            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3);
     577            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4);
     578            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5);
     579            ConsoleCommand& defaultValue(unsigned int index, const MultiType& arg);
     580
     581            /// Changes the access level of the command.
    267582            inline ConsoleCommand& accessLevel(AccessLevel::Enum level)
    268583                { this->accessLevel_ = level; return *this; }
     584            /// Returns the access level of the command.
    269585            inline AccessLevel::Enum getAccessLevel() const
    270586                { return this->accessLevel_; }
    271587
    272             ConsoleCommand& argumentCompleter(unsigned int param, ArgumentCompleter* completer);
    273             ArgumentCompleter* getArgumentCompleter(unsigned int param) const;
    274 
     588            ConsoleCommand& argumentCompleter(unsigned int index, ArgumentCompleter* completer);
     589            ArgumentCompleter* getArgumentCompleter(unsigned int index) const;
     590
     591            /// Defines the command to be an input command
    275592            inline ConsoleCommand& setAsInputCommand()
    276593            {
     
    281598            }
    282599
     600            /// Changes the keybind mode.
    283601            inline ConsoleCommand& keybindMode(KeybindMode::Value mode)
    284602                { this->keybindMode_ = mode; return *this; }
     603            /// Returns the keybind mode
    285604            inline KeybindMode::Value getKeybindMode() const
    286605                { return this->keybindMode_; }
    287606
     607            /// Changes the input configured param to the given index.
    288608            inline ConsoleCommand& inputConfiguredParam(int index)
    289609                { this->inputConfiguredParam_ = index; return *this; }
     610            /// Returns the input configured param.
    290611            inline int getInputConfiguredParam_() const
    291612                { return this->inputConfiguredParam_; }
    292613
     614            /// Returns a manipulator for this command.
    293615            inline ConsoleCommandManipulator getManipulator() const
    294616                { return this; }
     
    311633            void* getObject() const;
    312634
    313             bool bActive_;
    314             bool bHidden_;
    315             AccessLevel::Enum accessLevel_;
    316             std::string baseName_;
    317             FunctorPtr baseFunctor_;
    318 
    319             ExecutorPtr executor_;
    320             std::stack<Command> commandStack_;
    321             std::vector<void*> objectStack_;
    322 
    323             ArgumentCompleter* argumentCompleter_[5];
    324 
    325             KeybindMode::Value keybindMode_;
    326             int inputConfiguredParam_;
    327 
    328             LanguageEntryLabel description_;
    329             LanguageEntryLabel descriptionReturnvalue_;
    330             LanguageEntryLabel descriptionParam_[MAX_FUNCTOR_ARGUMENTS];
     635            bool bActive_;                                                  ///< True if the command should be active (it can still be inactive, for example if the function is missing)
     636            bool bHidden_;                                                  ///< True if the command is hidden (it is still executable, but not visible in the list of available commands)
     637            AccessLevel::Enum accessLevel_;                                 ///< The access level (the state of the game in which you can access the command)
     638            std::string baseName_;                                          ///< The name that was first assigned to the command
     639            FunctorPtr baseFunctor_;                                        ///< The functor that defines the header of the command-function
     640
     641            ExecutorPtr executor_;                                          ///< The Executor that is used to execute the command
     642            std::stack<Command> commandStack_;                              ///< A stack of commands, used to push and pop different functions
     643            std::vector<void*> objectStack_;                                ///< A stack of objects, used to push and pop different objects for a function
     644
     645            ArgumentCompleter* argumentCompleter_[MAX_FUNCTOR_ARGUMENTS];   ///< ArgumentCompleter for each argument
     646
     647            KeybindMode::Value keybindMode_;                                ///< The keybind mode
     648            int inputConfiguredParam_;                                      ///< The input configured param
     649
     650            LanguageEntryLabel description_;                                ///< The description of the command
     651            LanguageEntryLabel descriptionReturnvalue_;                     ///< A description of the return-value
     652            LanguageEntryLabel descriptionParam_[MAX_FUNCTOR_ARGUMENTS];    ///< A description for each argument
    331653
    332654        public:
     655            /// Returns the map with all groups and commands.
    333656            static inline const std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommands()
    334657                { return ConsoleCommand::getCommandMap(); }
     658            /// Returns the map with all groups and commands in lowercase.
    335659            static inline const std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommandsLC()
    336660                { return ConsoleCommand::getCommandMapLC(); }
    337661
     662            /// Returns a command (shortcut) with given name. @param name The name of the command shortcut @param bPrintError If true, an error is printed if the command doesn't exist
    338663            static inline const ConsoleCommand* getCommand(const std::string& name, bool bPrintError = false)
    339664                { return ConsoleCommand::getCommand("", name, bPrintError); }
     665            /// Returns a command (shortcut) with given name in lowercase. @param name The lowercase name of the command shortcut @param bPrintError If true, an error is printed if the command doesn't exist
    340666            static inline const ConsoleCommand* getCommandLC(const std::string& name, bool bPrintError = false)
    341667                { return ConsoleCommand::getCommandLC("", name, bPrintError); }
     
    354680    };
    355681
     682    /**
     683        @brief Creates a new ConsoleCommand.
     684        @param name The name of the command
     685        @param executor The executor of the command
     686        @param bInitialized If true, the command is ready to be executed, otherwise it has to be activated first.
     687    */
    356688    inline ConsoleCommand* createConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)
    357689        { return new ConsoleCommand("", name, executor, bInitialized); }
     690    /**
     691        @brief Creates a new ConsoleCommand.
     692        @param group The group of the command
     693        @param name The name of the command
     694        @param executor The executor of the command
     695        @param bInitialized If true, the command is ready to be executed, otherwise it has to be activated first.
     696    */
    358697    inline ConsoleCommand* createConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)
    359698        { return new ConsoleCommand(group, name, executor, bInitialized); }
    360699
     700
     701    /**
     702        @brief Returns a manipulator for a command with the given name.
     703
     704        @note If the command doesn't exist, the manipulator contains a NULL pointer to the command,
     705        but it can still be used without checks, because all functions of ConsoleCommandManipulator
     706        check internally if the command exists.
     707    */
    361708    inline ConsoleCommand::ConsoleCommandManipulator ModifyConsoleCommand(const std::string& name)
    362709        { return ConsoleCommand::getCommand(name, true); }
     710    /**
     711        @brief Returns a manipulator for a command with the given group and name.
     712
     713        @note If the command doesn't exist, the manipulator contains a NULL pointer to the command,
     714        but it can still be used without checks, because all functions of ConsoleCommandManipulator
     715        check internally if the command exists.
     716    */
    363717    inline ConsoleCommand::ConsoleCommandManipulator ModifyConsoleCommand(const std::string& group, const std::string& name)
    364718        { return ConsoleCommand::getCommand(group, name, true); }
  • code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc

    r7284 r7401  
    2626 *
    2727 */
     28
     29/**
     30    @file
     31    @brief Implementation of some console commands.
     32*/
    2833
    2934#include "ConsoleCommandCompilation.h"
     
    5156    SetConsoleCommand("calculate", calculate);
    5257
     58    /**
     59        @brief Reads the content of a file and executes the commands in it line by line.
     60    */
    5361    void source(const std::string& filename)
    5462    {
     
    8694    }
    8795
     96    /**
     97        @brief Simply returns the arguments.
     98    */
    8899    std::string echo(const std::string& text)
    89100    {
     
    91102    }
    92103
     104    /**
     105        @brief Writes text to the console, depending on the first argument with or without a line-break after it.
     106    */
    93107    void puts(bool newline, const std::string& text)
    94108    {
     
    103117    }
    104118
     119    /**
     120        @brief Writes text to a file.
     121    */
    105122    void write(const std::string& filename, const std::string& text)
    106123    {
     
    118135    }
    119136
     137    /**
     138        @brief Appends text to a file.
     139    */
    120140    void append(const std::string& filename, const std::string& text)
    121141    {
     
    133153    }
    134154
     155    /**
     156        @brief Reads text from a file
     157    */
    135158    std::string read(const std::string& filename)
    136159    {
     
    158181    }
    159182
     183    /**
     184        @brief Parses the mathematical expression and returns the result.
     185    */
    160186    float calculate(const std::string& calculation)
    161187    {
  • code/trunk/src/libraries/core/command/ConsoleCommandCompilation.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command ConsoleCommand
     32    @brief Declaration of some console commands.
     33*/
     34
    2935#ifndef _ConsoleCommandCompilation_H__
    3036#define _ConsoleCommandCompilation_H__
  • code/trunk/src/libraries/core/command/Executor.cc

    r7284 r7401  
    2727 *   Inspiration: Executor by Benjamin Grauer
    2828 */
     29
     30/**
     31    @file
     32    @brief Implementation of orxonox::Executor
     33*/
    2934
    3035#include "Executor.h"
     
    4045namespace orxonox
    4146{
     47    /**
     48        @brief Constructor: Creates an executor.
     49        @param functor The wrapped functor
     50        @param name The name of the executor (optional, used mostly for debug output)
     51    */
    4252    Executor::Executor(const FunctorPtr& functor, const std::string& name)
    4353    {
     
    4656    }
    4757
     58    /**
     59        @brief Copy-constructor: Creates a new executor with the same values and a clone of the wrapped Functor.
     60    */
    4861    Executor::Executor(const Executor& other) : name_(other.name_)
    4962    {
     
    5366    }
    5467
     68    /**
     69        @brief Destructor
     70    */
    5571    Executor::~Executor()
    5672    {
    5773    }
    5874
     75    /**
     76        @brief Calls the wrapped function with arguments that are passed in a string.
     77        @param arguments The arguments that should be passed to the function, separated by @a delimiter
     78        @param error A pointer to a variable (or NULL) that is used to store the error code (see @ref CommandExecutorErrorCodes "CommandExecutor error codes")
     79        @param delimiter The delimiter that is used to separate the arguments in the string @a arguments
     80        @param bPrintError If true, errors are printed to the console if the function couldn't be executed with the given arguments
     81        @return Returns the return value of the function (or MT_Type::Null if there is no return value)
     82    */
    5983    MultiType Executor::parse(const std::string& arguments, int* error, const std::string& delimiter, bool bPrintError) const
    6084    {
     
    6286    }
    6387
     88    /**
     89        @brief Calls the wrapped function with arguments that are passed as tokens in a SubString
     90        @param arguments The arguments that should be passed to the function
     91        @param error A pointer to a variable (or NULL) that is used to store the error code (see @ref CommandExecutorErrorCodes "CommandExecutor error codes")
     92        @param delimiter The delimiter that was used to separate the arguments in the SubString @a arguments (used to join the surplus arguments)
     93        @param bPrintError If true, errors are printed to the console if the function couldn't be executed with the given arguments
     94        @return Returns the return value of the function (or MT_Type::Null if there is no return value)
     95    */
    6496    MultiType Executor::parse(const SubString& arguments, int* error, const std::string& delimiter, bool bPrintError) const
    6597    {
    66         MultiType param[MAX_FUNCTOR_ARGUMENTS];
    67         unsigned int paramCount = this->evaluateParams(arguments, param, error, delimiter);
    68 
     98        // evaluate the arguments
     99        MultiType arg[MAX_FUNCTOR_ARGUMENTS];
     100        unsigned int argCount = this->evaluateArguments(arguments, arg, error, delimiter);
     101
     102        // check if an error occurred
    69103        if (error && *error)
    70104        {
    71105            if (bPrintError)
    72                 COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << arguments.join() << ")." << std::endl;
     106                COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough arguments or default values given (input: " << arguments.join() << ")." << std::endl;
    73107            return MT_Type::Null;
    74108        }
    75109
    76         COUT(5) << "Executor::parse: \"" << arguments.join(delimiter) << "\" -> " << paramCount << " params: " << param[0] << " / " << param[1] << " / " << param[2] << " / " << param[3] << " / " << param[4] << std::endl;
    77 
    78         switch (paramCount)
     110        COUT(5) << "Executor::parse: \"" << arguments.join(delimiter) << "\" -> " << argCount << " arguments: " << arg[0] << " / " << arg[1] << " / " << arg[2] << " / " << arg[3] << " / " << arg[4] << std::endl;
     111
     112        // execute the function with the evaluated arguments (the default values of the executor are also included in these arguments)
     113        switch (argCount)
    79114        {
    80115            case 0:  return (*this->functor_)();
    81             case 1:  return (*this->functor_)(param[0]);
    82             case 2:  return (*this->functor_)(param[0], param[1]);
    83             case 3:  return (*this->functor_)(param[0], param[1], param[2]);
    84             case 4:  return (*this->functor_)(param[0], param[1], param[2], param[3]);
     116            case 1:  return (*this->functor_)(arg[0]);
     117            case 2:  return (*this->functor_)(arg[0], arg[1]);
     118            case 3:  return (*this->functor_)(arg[0], arg[1], arg[2]);
     119            case 4:  return (*this->functor_)(arg[0], arg[1], arg[2], arg[3]);
    85120            case 5:
    86             default: return (*this->functor_)(param[0], param[1], param[2], param[3], param[4]);
     121            default: return (*this->functor_)(arg[0], arg[1], arg[2], arg[3], arg[4]);
    87122        }
    88123    }
    89124
    90     int Executor::evaluateParams(const SubString& arguments, MultiType param[MAX_FUNCTOR_ARGUMENTS], int* error, const std::string& delimiter) const
     125    /**
     126        @brief Converts the arguments in a SubString to the right type, so they can be used to execute the function without further conversions.
     127        @param arguments The arguments that should be converted
     128        @param arg An array of MultiType where the converted arguments will be stored
     129        @param error A pointer to a variable (or NULL) that is used to store the error code (see @ref CommandExecutorErrorCodes "CommandExecutor error codes")
     130        @param delimiter The delimiter that was used to separate the arguments in the SubString @a arguments (used to join the surplus arguments)
     131        @return Returns the number of evaluated arguments
     132    */
     133    int Executor::evaluateArguments(const SubString& arguments, MultiType arg[MAX_FUNCTOR_ARGUMENTS], int* error, const std::string& delimiter) const
    91134    {
    92135        unsigned int paramCount = this->functor_->getParamCount();
     
    106149        // assign all given arguments to the multitypes
    107150        for (unsigned int i = 0; i < std::min(std::min(argumentCount, paramCount), MAX_FUNCTOR_ARGUMENTS); i++)
    108             param[i] = arguments[i];
     151            arg[i] = arguments[i];
    109152
    110153        // fill the remaining multitypes with default values
    111154        for (unsigned int i = argumentCount; i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++)
    112             param[i] = this->defaultValue_[i];
     155            arg[i] = this->defaultValue_[i];
    113156
    114157        // assign the remaining arguments all to the last parameter if it is a string
    115158        if ((paramCount <= MAX_FUNCTOR_ARGUMENTS) &&(argumentCount > paramCount) && (paramCount == 1 || this->functor_->getTypenameParam(paramCount - 1) == "string"))
    116             param[paramCount - 1] = arguments.subSet(paramCount - 1).join(delimiter);
    117 
    118         // evaluate the param types through the functor
     159            arg[paramCount - 1] = arguments.subSet(paramCount - 1).join(delimiter);
     160
     161        // evaluate the parameter types through the functor
    119162        for (unsigned int i = 0; i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++)
    120             this->functor_->evaluateParam(i, param[i]);
     163            this->functor_->evaluateArgument(i, arg[i]);
    121164
    122165        if (error)
     
    125168    }
    126169
    127     void Executor::setDefaultValues(const MultiType& param1)
    128     {
    129         this->defaultValue_[0] = param1;
    130     }
    131 
    132     void Executor::setDefaultValues(const MultiType& param1, const MultiType& param2)
    133     {
    134         this->defaultValue_[0] = param1;
    135         this->defaultValue_[1] = param2;
    136     }
    137 
    138     void Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
    139     {
    140         this->defaultValue_[0] = param1;
    141         this->defaultValue_[1] = param2;
    142         this->defaultValue_[2] = param3;
    143     }
    144 
    145     void Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
    146     {
    147         this->defaultValue_[0] = param1;
    148         this->defaultValue_[1] = param2;
    149         this->defaultValue_[2] = param3;
    150         this->defaultValue_[3] = param4;
    151     }
    152 
    153     void Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
    154     {
    155         this->defaultValue_[0] = param1;
    156         this->defaultValue_[1] = param2;
    157         this->defaultValue_[2] = param3;
    158         this->defaultValue_[3] = param4;
    159         this->defaultValue_[4] = param5;
    160     }
    161 
    162     void Executor::setDefaultValue(unsigned int index, const MultiType& param)
     170    /// Defines the default value for the first parameter.
     171    void Executor::setDefaultValues(const MultiType& arg1)
     172    {
     173        this->defaultValue_[0] = arg1;
     174    }
     175
     176    /// Defines the default value for the first two parameters.
     177    void Executor::setDefaultValues(const MultiType& arg1, const MultiType& arg2)
     178    {
     179        this->defaultValue_[0] = arg1;
     180        this->defaultValue_[1] = arg2;
     181    }
     182
     183    /// Defines the default value for the first three parameters.
     184    void Executor::setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3)
     185    {
     186        this->defaultValue_[0] = arg1;
     187        this->defaultValue_[1] = arg2;
     188        this->defaultValue_[2] = arg3;
     189    }
     190
     191    /// Defines the default value for the first four parameters.
     192    void Executor::setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4)
     193    {
     194        this->defaultValue_[0] = arg1;
     195        this->defaultValue_[1] = arg2;
     196        this->defaultValue_[2] = arg3;
     197        this->defaultValue_[3] = arg4;
     198    }
     199
     200    /// Defines the default value for the first five parameters.
     201    void Executor::setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5)
     202    {
     203        this->defaultValue_[0] = arg1;
     204        this->defaultValue_[1] = arg2;
     205        this->defaultValue_[2] = arg3;
     206        this->defaultValue_[3] = arg4;
     207        this->defaultValue_[4] = arg5;
     208    }
     209
     210    /// Defines the default value for a parameter with given index (the first parameter has index 0).
     211    void Executor::setDefaultValue(unsigned int index, const MultiType& arg)
    163212    {
    164213        if (index < MAX_FUNCTOR_ARGUMENTS)
    165             this->defaultValue_[index] = param;
    166     }
    167 
     214            this->defaultValue_[index] = arg;
     215    }
     216
     217    /// Returns true if the executor has a default value for each parameter of the wrapped function, so it can be called without passing additional arguments.
    168218    bool Executor::allDefaultValuesSet() const
    169219    {
  • code/trunk/src/libraries/core/command/Executor.h

    r7284 r7401  
    2828 */
    2929
     30/**
     31    @defgroup FunctorExecutor Functor and Executor
     32    @ingroup Command
     33*/
     34
     35/**
     36    @file
     37    @ingroup Command FunctorExecutor
     38    @brief Declaration of the orxonox::Executor class and the createExecutor() functions.
     39
     40    @anchor ExecutorExample
     41
     42    orxonox::Executor is used to wrap an orxonox::Functor and to store default values for
     43    its parameters. Usually one uses the function createExecutor() to create a new executor.
     44    This function returns an orxonox::ExecutorPtr which is a typedef of @ref orxonox::SharedPtr
     45    "SharedPtr<Executor>", used to manage the pointer to the executor.
     46
     47    Executors are mostly used to execute callbacks. Because some callback functions need arguments,
     48    Executor provides an easy interface to store these arguments as default values, so the
     49    executor can also be executed without arguments because it will use these default values.
     50
     51    The Executor doesn't contain the function-pointer directly. Instead it wraps an instance
     52    of orxonox::Functor. See @ref FunctorExample "Functor.h" for more information and some
     53    examples.
     54
     55    Example:
     56    @code
     57    void myFunction(int a, int b)                           // declare a static function
     58    {
     59        COUT(0) << "The sum is " << (a + b) << std::endl;   // print the sum of a and b to the console
     60    }
     61
     62    FunctorPtr functor = createFunctor(&myFunction);        // create a functor that wraps the function-pointer
     63    ExecutorPtr executor = createExecutor(functor);         // create an executor that wraps the functor
     64
     65    (*executor)(2, 5);                                      // calls the executor with arguments 2 and 5, prints "The sum is 7" to the console
     66
     67    executor->setDefaultValue(1, 10);                       // sets the default-value for the second parameter (note: paramters start at index 0) to 10
     68
     69    (*executor)(2);                                         // calls the executor with argument 2 and default-value 10, prints "The sum is 12"
     70
     71    executor->setDefaultValue(0, 5);                        // sets the default-value for the first parameter to 5
     72
     73    (*executor)();                                          // calls the executor with default-values only, prints "The sum is 15"
     74    @endcode
     75
     76    Because executors that were created with createExecutor() are managed by an orxonox::SharedPtr,
     77    they don't need to be deleted after usage.
     78*/
     79
    3080#ifndef _Executor_H__
    3181#define _Executor_H__
     
    4090namespace orxonox
    4191{
     92    /**
     93        @brief This class is used to wrap a Functor and to store default values for any of its parameters.
     94
     95        @see See @ref ExecutorExample "Executor.h" for an example.
     96    */
    4297    class _CoreExport Executor
    4398    {
     
    47102            virtual ~Executor();
    48103
     104            /// Calls the wrapped function with 0 arguments. If the function needs more arguments, the executor's default values are used.
    49105            inline MultiType operator()() const
    50106                { return (*this->functor_)(this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    51             inline MultiType operator()(const MultiType& param1) const
    52                 { return (*this->functor_)(param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    53             inline MultiType operator()(const MultiType& param1, const MultiType& param2) const
    54                 { return (*this->functor_)(param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    55             inline MultiType operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3) const
    56                 { return (*this->functor_)(param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
    57             inline MultiType operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
    58                 { return (*this->functor_)(param1, param2, param3, param4, this->defaultValue_[4]); }
    59             inline MultiType operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
    60                 { return (*this->functor_)(param1, param2, param3, param4, param5); }
     107            /// Calls the wrapped function with 1 argument. If the function needs more arguments, the executor's default values are used.
     108            inline MultiType operator()(const MultiType& arg1) const
     109                { return (*this->functor_)(arg1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
     110            /// Calls the wrapped function with 2 arguments. If the function needs more arguments, the executor's default values are used.
     111            inline MultiType operator()(const MultiType& arg1, const MultiType& arg2) const
     112                { return (*this->functor_)(arg1, arg2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
     113            /// Calls the wrapped function with 3 arguments. If the function needs more arguments, the executor's default values are used.
     114            inline MultiType operator()(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3) const
     115                { return (*this->functor_)(arg1, arg2, arg3, this->defaultValue_[3], this->defaultValue_[4]); }
     116            /// Calls the wrapped function with 4 arguments. If the function needs more arguments, the executor's default values are used.
     117            inline MultiType operator()(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4) const
     118                { return (*this->functor_)(arg1, arg2, arg3, arg4, this->defaultValue_[4]); }
     119            /// Calls the wrapped function with 5 arguments. If the function needs more arguments, the executor's default values are used.
     120            inline MultiType operator()(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5) const
     121                { return (*this->functor_)(arg1, arg2, arg3, arg4, arg5); }
    61122
    62123            MultiType parse(const std::string& arguments, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const;
    63124            MultiType parse(const SubString& arguments, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const;
    64125
    65             int evaluateParams(const SubString& arguments, MultiType param[MAX_FUNCTOR_ARGUMENTS], int* error = 0, const std::string& delimiter = " ") const;
    66 
     126            int evaluateArguments(const SubString& arguments, MultiType arg[MAX_FUNCTOR_ARGUMENTS], int* error = 0, const std::string& delimiter = " ") const;
     127
     128            /// Changes the functor.
    67129            inline void setFunctor(const FunctorPtr& functor)
    68130                { this->functor_ = functor; }
     131            /// Returns the functor.
    69132            inline const FunctorPtr& getFunctor() const
    70133                { return this->functor_; }
    71134
     135            /// Changes the name of the executor.
    72136            inline void setName(const std::string& name)
    73137                { this->name_ = name; }
     138            /// Returns the name of the executor.
    74139            inline const std::string& getName() const
    75140                { return this->name_; }
    76141
     142            /// Returns the number of parameters of the wrapped function.
    77143            inline unsigned int getParamCount() const
    78144                { return this->functor_->getParamCount(); }
     145            /// Returns true if the wrapped function returns a value.
    79146            inline bool hasReturnvalue() const
    80147                { return this->functor_->hasReturnvalue(); }
     148            /// Returns the type of the wrapped function (static or member).
    81149            inline Functor::Type::Enum getType() const
    82150                { return this->functor_->getType(); }
     151            /// Returns the name of the type of a parameter with given index (the first parameter has index 0).
    83152            inline std::string getTypenameParam(unsigned int param) const
    84153                { return this->functor_->getTypenameParam(param); }
     154            /// Returns the name of the type of the return value.
    85155            inline std::string getTypenameReturnvalue() const
    86156                { return this->functor_->getTypenameReturnvalue(); }
    87157
    88             void setDefaultValues(const MultiType& param1);
    89             void setDefaultValues(const MultiType& param1, const MultiType& param2);
    90             void setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3);
    91             void setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4);
    92             void setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5);
    93             void setDefaultValue(unsigned int index, const MultiType& param);
    94 
     158            void setDefaultValues(const MultiType& arg1);
     159            void setDefaultValues(const MultiType& arg1, const MultiType& arg2);
     160            void setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3);
     161            void setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4);
     162            void setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5);
     163            void setDefaultValue(unsigned int index, const MultiType& arg);
     164
     165            /// Returns the default value for a parameter with given index (the first parameter has index 0).
    95166            inline MultiType getDefaultValue(unsigned int index) const
    96167            {
     
    102173
    103174            bool allDefaultValuesSet() const;
     175
     176            /// Returns true if the executor contains a default value for the parameter with given index (the first parameter has index 0).
    104177            inline bool defaultValueSet(unsigned int index) const
    105178            {
     
    111184
    112185        protected:
    113             FunctorPtr functor_;
    114             std::string name_;
    115             MultiType defaultValue_[MAX_FUNCTOR_ARGUMENTS];
     186            FunctorPtr functor_;                                ///< The underlying Functor that wraps a function
     187            std::string name_;                                  ///< The name of the executor
     188            MultiType defaultValue_[MAX_FUNCTOR_ARGUMENTS];     ///< The default values, one for each parameter
    116189    };
    117190
     191    /**
     192        @brief A child class of Executor, used to distinguish executors that wrap static functions from executors that wrap member-functions.
     193
     194        Behaves exactly like Executor, because static functions need no special treatment.
     195    */
    118196    class _CoreExport ExecutorStatic : public Executor
    119197    {
    120198        public:
     199            /// Constructor: Initializes the parent class
    121200            ExecutorStatic(const FunctorStaticPtr& functor, const std::string& name = "") : Executor(functor, name) {}
     201            /// Destructor
    122202            virtual ~ExecutorStatic() {}
    123203    };
    124204
     205    /**
     206        @brief A child class of Executor, used for easier handling of non-static member-functions.
     207
     208        Overloads some functions that call the underlying FunctorMember and additionally pass
     209        an object-pointer that is needed for non-static member-functions.
     210    */
    125211    template <class T>
    126212    class ExecutorMember : public Executor
    127213    {
    128214        public:
     215            /// Constructor: Initializes the parent class and the pointer to the member-functor.
    129216            ExecutorMember(const FunctorMemberPtr<T>& functor, const std::string& name = "") : Executor(functor, name), functorMember_(functor) {}
     217            /// Destructor
    130218            virtual ~ExecutorMember() {}
    131219
    132220            using Executor::operator();
    133221
     222            /// Calls the wrapped function with 0 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
    134223            inline MultiType operator()(T* object) const
    135224                { return (*this->functorMember_)(object, this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    136             inline MultiType operator()(T* object, const MultiType& param1) const
    137                 { return (*this->functorMember_)(object, param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    138             inline MultiType operator()(T* object, const MultiType& param1, const MultiType& param2) const
    139                 { return (*this->functorMember_)(object, param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    140             inline MultiType operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3) const
    141                 { return (*this->functorMember_)(object, param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
    142             inline MultiType operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
    143                 { return (*this->functorMember_)(object, param1, param2, param3, param4, this->defaultValue_[4]); }
    144             inline MultiType operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
    145                 { return (*this->functorMember_)(object, param1, param2, param3, param4, param5); }
    146 
    147 
    148             inline MultiType operator()(const T* object) const
    149                 { return (*this->functorMember_)(object, this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    150             inline MultiType operator()(const T* object, const MultiType& param1) const
    151                 { return (*this->functorMember_)(object, param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    152             inline MultiType operator()(const T* object, const MultiType& param1, const MultiType& param2) const
    153                 { return (*this->functorMember_)(object, param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
    154             inline MultiType operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3) const
    155                 { return (*this->functorMember_)(object, param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
    156             inline MultiType operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
    157                 { return (*this->functorMember_)(object, param1, param2, param3, param4, this->defaultValue_[4]); }
    158             inline MultiType operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
    159                 { return (*this->functorMember_)(object, param1, param2, param3, param4, param5); }
    160 
     225            /// Calls the wrapped function with 1 argument and an object-pointer. If the function needs more arguments, the executor's default values are used.
     226            inline MultiType operator()(T* object, const MultiType& arg1) const
     227                { return (*this->functorMember_)(object, arg1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
     228            /// Calls the wrapped function with 2 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
     229            inline MultiType operator()(T* object, const MultiType& arg1, const MultiType& arg2) const
     230                { return (*this->functorMember_)(object, arg1, arg2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
     231            /// Calls the wrapped function with 3 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
     232            inline MultiType operator()(T* object, const MultiType& arg1, const MultiType& arg2, const MultiType& arg3) const
     233                { return (*this->functorMember_)(object, arg1, arg2, arg3, this->defaultValue_[3], this->defaultValue_[4]); }
     234            /// Calls the wrapped function with 4 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
     235            inline MultiType operator()(T* object, const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4) const
     236                { return (*this->functorMember_)(object, arg1, arg2, arg3, arg4, this->defaultValue_[4]); }
     237            /// Calls the wrapped function with 5 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
     238            inline MultiType operator()(T* object, const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5) const
     239                { return (*this->functorMember_)(object, arg1, arg2, arg3, arg4, arg5); }
     240
     241            /// Changes the object-pointer of the underlying FunctorMember.
    161242            inline void setObject(T* object) const
    162243                { this->functorMember_->setObject(object); }
    163             inline void setObject(const T* object) const
    164                 { this->functorMember_->setObject(object); }
     244            /// Returns the object-pointer of the underlying FunctorMember.
     245            inline T* getObject() const
     246                { return this->functorMember_->getObject(); }
    165247
    166248            using Executor::parse;
    167249
    168             MultiType parse(T* object, const std::string& params, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const
     250            /// Overloads Executor::parse() with an additional object-pointer.
     251            MultiType parse(T* object, const std::string& arguments, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const
    169252            {
    170253                T* oldobject = this->functorMember_->getObject();
    171254
    172255                this->functorMember_->setObject(object);
    173                 const MultiType& result = this->Executor::parse(params, error, delimiter, bPrintError);
     256                const MultiType& result = this->Executor::parse(arguments, error, delimiter, bPrintError);
    174257                this->functorMember_->setObject(oldobject);
    175258
     
    177260            }
    178261
    179             MultiType parse(const T* object, const std::string& params, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const
    180             {
    181                 T* oldobject = this->functorMember_->getObject();
    182 
    183                 this->functorMember_->setObject(object);
    184                 const MultiType& result = this->Executor::parse(params, error, delimiter, bPrintError);
    185                 this->functorMember_->setObjects(oldobject);
    186 
    187                 return result;
    188             }
    189 
    190262        protected:
    191             FunctorMemberPtr<T> functorMember_;
     263            FunctorMemberPtr<T> functorMember_;     ///< A pointer to the FunctorMember is stored separately to avoid casting when executing the function.
    192264    };
    193265
     266    /// Creates a new Executor that wraps a given Functor.
    194267    inline ExecutorPtr createExecutor(const FunctorPtr& functor, const std::string& name = "")
    195268    {
     
    197270    }
    198271
     272    /// Creates a new ExecutorMember that wraps a given FunctorMember.
    199273    template <class T>
    200274    inline ExecutorMemberPtr<T> createExecutor(const FunctorMemberPtr<T>& functor, const std::string& name = "")
     
    203277    }
    204278
     279    /// Creates a new ExecutorStatic that wraps a given FunctorStatic.
    205280    inline ExecutorStaticPtr createExecutor(const FunctorStaticPtr& functor, const std::string& name = "")
    206281    {
  • code/trunk/src/libraries/core/command/ExecutorPtr.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command FunctorExecutor
     32    @brief Typedefs and definitions of ExecutorPtr, ExecutorStaticPtr, and ExecutorMemberPtr
     33
     34    Instances of orxonox::Executor are usually managed by an orxonox::SharedPtr. This ensures
     35    that Executors will be destroyed after usage. To make things easier, there's a typedef
     36    that defines ExecutorPtr as SharedPtr<Executor>.
     37
     38    Because there's not only orxonox::Executor, but also orxonox::ExecutorStatic, and
     39    orxonox::ExecutorMember, the shared pointers need to store them all and also reflect
     40    their hierarchy - ExecutorStatic and ExecutorMember should not be mixed, but both can
     41    be converted to Executor. This is achieved by using orxonox::SharedChildPtr.
     42
     43    Because it's not possible to use a typedef for a template, we have to define the
     44    helper class ExecutorMemberPtr<T> that makes it easier to use ExecutorMember.
     45*/
     46
    2947#ifndef _ExecutorPtr_H__
    3048#define _ExecutorPtr_H__
     
    3553namespace orxonox
    3654{
     55    /// ExecutorPtr is just a typedef of SharedPtr
    3756    typedef SharedPtr<Executor> ExecutorPtr;
    3857
     58    /// ExecutorStaticPtr is just a typedef of SharedChildPtr
    3959    typedef SharedChildPtr<ExecutorStatic, ExecutorPtr> ExecutorStaticPtr;
    4060
     61    /// It's not possible to use a typedef for ExecutorMemberPtr<T>, so we have to create a child-class instead. It inherits all functions from SharedChildPtr, but needs to (re-)implement some constructors.
    4162    template <class T>
    4263    class ExecutorMemberPtr : public SharedChildPtr<ExecutorMember<T>, ExecutorPtr>
  • code/trunk/src/libraries/core/command/Functor.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command FunctorExecutor
     32    @brief Definition of orxonox::Functor and its specialized subclasses, as well as the createFunctor() functions.
     33
     34    @anchor FunctorExample
     35
     36    Functors can be used to wrap function-pointers. While function-pointers have a very
     37    complicated syntax in C++, Functors are always the same and you can call the wrapped
     38    function-pointer independently of its parameter with arguments of type MultiType. These
     39    arguments are then automatically converted to the right type.
     40
     41    To create a Functor, the helper function createFunctor() is used. It returns an instance
     42    of orxonox::FunctorPtr which is simply a typedef of @ref orxonox::SharedPtr "SharedPtr<Functor>".
     43    This means you don't have to delete the Functor after using it, because it is managed
     44    by the SharedPtr.
     45
     46    Example:
     47    @code
     48    int myStaticFunction(int value)                         // Definition of a static function
     49    {
     50        return (value * 2);                                 // Return the double of the value
     51    }
     52
     53    FunctorPtr functor = createFunctor(&myStaticFunction);  // Create a Functor
     54
     55    int result = (*functor)(5);                             // Calls the functor with value = 5, result == 10
     56
     57    int result = (*functor)("7");                           // Calls the functor with a string which is converted to an integer, result == 14
     58    @endcode
     59
     60    Functors can also be used if you work with member-functions. In this case createFunctor()
     61    returns an instance of orxonox::FunctorMemberPtr - this allows you to define the object
     62    that will be used to call the function.
     63
     64    Example:
     65    @code
     66    class MyClass                                                   // Define a class
     67    {
     68        public:
     69            MyClass(const std::string& text)                        // Constructor
     70            {
     71                this->text_ = text;
     72            }
     73
     74            bool contains(const std::string& word)                  // Function that searches for "word" in "text"
     75            {
     76                return (this->text_.find(word) != std::string::npos);
     77            }
     78
     79        private:
     80            std::string text_;                                      // Member variable
     81    };
     82
     83    MyClass* object = new MyClass("Hello World");                   // Create an object of type MyClass and set its text to "Hello World"
     84
     85    FunctorPtr functor = createFunctor(&MyClass:contains, object);  // Create a Functor (note the object!)
     86
     87    bool result = (*functor)("World");                              // result == true
     88    bool result = (*functor)("test");                               // result == false
     89    @endcode
     90
     91    Instead of assigning the object directly to the functor when creating it, you can also define
     92    it at any later point or when you call the functor. Note however that this works only with
     93    orxonox::FunctorMember.
     94
     95    @code
     96    MyClass* object1 = new MyClass("Hello World");                  // Create an object
     97    MyClass* object2 = new MyClass("this is a test");               // Create another object
     98
     99    FunctorMemberPtr functor = createFunctor(&MyClass:contains);    // Create a FunctorMember (note: no object this time)
     100
     101    bool result = (*functor)("World");                              // result == false and an error: "Error: Can't execute FunctorMember, no object set."
     102
     103    bool result = (*functor)(object1, "World");                     // result == true
     104    bool result = (*functor)(object1, "test");                      // result == false
     105    bool result = (*functor)(object2, "test");                      // result == true
     106
     107    functor->setObject(object1);                                    // Assign an object to the FunctorMember
     108
     109    bool result = (*functor)("World");                              // result == true (no error this time, because the object was set using setObject())
     110    @endcode
     111*/
     112
    29113#ifndef _Functor_H__
    30114#define _Functor_H__
     
    40124namespace orxonox
    41125{
    42     const unsigned int MAX_FUNCTOR_ARGUMENTS = 5;
    43 
     126    const unsigned int MAX_FUNCTOR_ARGUMENTS = 5;   ///< The maximum number of parameters of a function that is supported by Functor
     127
     128    namespace detail
     129    {
     130        template <class T>
     131        inline std::string _typeToString() { return "unknown"; }
     132
     133        template <> inline std::string _typeToString<void>()               { return "void"; }
     134        template <> inline std::string _typeToString<int>()                { return "int"; }
     135        template <> inline std::string _typeToString<unsigned int>()       { return "uint"; }
     136        template <> inline std::string _typeToString<char>()               { return "char"; }
     137        template <> inline std::string _typeToString<unsigned char>()      { return "uchar"; }
     138        template <> inline std::string _typeToString<short>()              { return "short"; }
     139        template <> inline std::string _typeToString<unsigned short>()     { return "ushort"; }
     140        template <> inline std::string _typeToString<long>()               { return "long"; }
     141        template <> inline std::string _typeToString<unsigned long>()      { return "ulong"; }
     142        template <> inline std::string _typeToString<long long>()          { return "longlong"; }
     143        template <> inline std::string _typeToString<unsigned long long>() { return "ulonglong"; }
     144        template <> inline std::string _typeToString<float>()              { return "float"; }
     145        template <> inline std::string _typeToString<double>()             { return "double"; }
     146        template <> inline std::string _typeToString<long double>()        { return "longdouble"; }
     147        template <> inline std::string _typeToString<bool>()               { return "bool"; }
     148        template <> inline std::string _typeToString<std::string>()        { return "string"; }
     149        template <> inline std::string _typeToString<Vector2>()            { return "Vector2"; }
     150        template <> inline std::string _typeToString<Vector3>()            { return "Vector3"; }
     151        template <> inline std::string _typeToString<Quaternion>()         { return "Quaternion"; }
     152        template <> inline std::string _typeToString<ColourValue>()        { return "ColourValue"; }
     153        template <> inline std::string _typeToString<Radian>()             { return "Radian"; }
     154        template <> inline std::string _typeToString<Degree>()             { return "Degree"; }
     155    }
     156
     157    /// Returns the name of type @a T as string.
    44158    template <class T>
    45     inline std::string _typeToString() { return "unknown"; }
    46 
    47     template <> inline std::string _typeToString<void>()               { return ""; }
    48     template <> inline std::string _typeToString<int>()                { return "int"; }
    49     template <> inline std::string _typeToString<unsigned int>()       { return "uint"; }
    50     template <> inline std::string _typeToString<char>()               { return "char"; }
    51     template <> inline std::string _typeToString<unsigned char>()      { return "uchar"; }
    52     template <> inline std::string _typeToString<short>()              { return "short"; }
    53     template <> inline std::string _typeToString<unsigned short>()     { return "ushort"; }
    54     template <> inline std::string _typeToString<long>()               { return "long"; }
    55     template <> inline std::string _typeToString<unsigned long>()      { return "ulong"; }
    56     template <> inline std::string _typeToString<long long>()          { return "longlong"; }
    57     template <> inline std::string _typeToString<unsigned long long>() { return "ulonglong"; }
    58     template <> inline std::string _typeToString<float>()              { return "float"; }
    59     template <> inline std::string _typeToString<double>()             { return "double"; }
    60     template <> inline std::string _typeToString<long double>()        { return "longdouble"; }
    61     template <> inline std::string _typeToString<bool>()               { return "bool"; }
    62     template <> inline std::string _typeToString<std::string>()        { return "string"; }
    63     template <> inline std::string _typeToString<Vector2>()            { return "Vector2"; }
    64     template <> inline std::string _typeToString<Vector3>()            { return "Vector3"; }
    65     template <> inline std::string _typeToString<Quaternion>()         { return "Quaternion"; }
    66     template <> inline std::string _typeToString<ColourValue>()        { return "ColourValue"; }
    67     template <> inline std::string _typeToString<Radian>()             { return "Radian"; }
    68     template <> inline std::string _typeToString<Degree>()             { return "Degree"; }
    69 
    70     template <class T>
    71     inline std::string typeToString() { return _typeToString<typename Loki::TypeTraits<T>::UnqualifiedReferredType>(); }
    72 
     159    inline std::string typeToString() { return detail::_typeToString<typename Loki::TypeTraits<T>::UnqualifiedReferredType>(); }
     160
     161    /**
     162        @brief The Functor classes are used to wrap function pointers.
     163
     164        Function-pointers in C++ have a pretty complicated syntax and you can't store
     165        and call them unless you know the exact type. A Functor can be used to wrap
     166        a function-pointer and to store it independent of its type. You can also call
     167        it independently of its parameters by passing the arguments as MultiType. They
     168        are converted automatically to the right type.
     169
     170        Functor is a pure virtual base class.
     171
     172        @see See @ref FunctorExample "Functor.h" for some examples.
     173    */
    73174    class _CoreExport Functor
    74175    {
     
    76177            struct Type
    77178            {
     179                /// Defines the type of a function (static or member)
    78180                enum Enum
    79181                {
     
    84186
    85187        public:
     188            /// Calls the function-pointer with up to five arguments. In case of a member-function, the assigned object-pointer is used to call the function. @return Returns the return-value of the function (if any; MT_Type::Null otherwise)
    86189            virtual MultiType 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) = 0;
    87190
     191            /// Creates a new instance of Functor with the same values like this (used instead of a copy-constructor)
    88192            virtual FunctorPtr clone() = 0;
    89193
     194            /// Returns the type of the function: static or member.
    90195            virtual Type::Enum getType() const = 0;
     196            /// Returns the number of parameters of the function.
    91197            virtual unsigned int getParamCount() const = 0;
     198            /// Returns true if the function has a return-value.
    92199            virtual bool hasReturnvalue() const = 0;
    93200
    94             virtual std::string getTypenameParam(unsigned int param) const = 0;
     201            /// Returns the type-name of the parameter with given index (the first parameter has index 0).
     202            virtual std::string getTypenameParam(unsigned int index) const = 0;
     203            /// Returns the type-name of the return-value.
    95204            virtual std::string getTypenameReturnvalue() const = 0;
    96205
    97             virtual void evaluateParam(unsigned int index, MultiType& param) const = 0;
    98 
    99             virtual void setRawObjectPointer(void* object) {}
    100             virtual void* getRawObjectPointer() const { return 0; }
    101 
    102             template <class F>
    103             inline bool setFunction(F* function)
    104             {
    105                 if (this->getFullIdentifier() == typeid(F*))
    106                 {
    107                     modifyFunctor(this, function);
    108                     return true;
    109                 }
    110                 return false;
    111             }
    112 
     206            /// Converts a given argument to the type of the parameter with given index (the first parameter has index 0).
     207            virtual void evaluateArgument(unsigned int index, MultiType& argument) const = 0;
     208
     209            /// Assigns an object-pointer to the functor which is used to execute a member-function.
     210            virtual void setRawObjectPointer(void* object) = 0;
     211            /// Returns the object-pointer.
     212            virtual void* getRawObjectPointer() const = 0;
     213
     214            /// Returns the full identifier of the function-pointer which is defined as typeid(@a F), where @a F is the type of the stored function-pointer. Used to compare functors.
    113215            virtual const std::type_info& getFullIdentifier() const = 0;
     216            /// Returns an identifier of the header of the function (doesn't include the function's class). Used to compare functors.
    114217            virtual const std::type_info& getHeaderIdentifier() const = 0;
     218            /// Returns an identifier of the header of the function (doesn't include the function's class), but regards only the first @a params parameters. Used to compare functions if an Executor provides default-values for the other parameters.
    115219            virtual const std::type_info& getHeaderIdentifier(unsigned int params) const = 0;
    116220    };
     
    118222    namespace detail
    119223    {
     224        // helper class to determine if a functor is static or not
    120225        template <class O>
    121226        struct FunctorTypeStatic
     
    126231    }
    127232
     233    /**
     234        @brief FunctorMember is a child class of Functor and expands it with an object-pointer, that
     235        is used for member-functions, as well as an overloaded execution operator.
     236
     237        @param O The type of the function's class (or void if it's a static function)
     238
     239        Note that FunctorMember is also used for static functions, but with T = void. FunctorStatic
     240        is a typedef of FunctorMember<void>. The void* object-pointer is ignored in this case.
     241
     242        @see See @ref FunctorExample "Functor.h" for some examples.
     243    */
    128244    template <class O>
    129245    class FunctorMember : public Functor
    130246    {
    131247        public:
     248            /// Constructor: Stores the object-pointer.
    132249            FunctorMember(O* object = 0) : object_(object) {}
    133250
     251            /// Calls the function-pointer with up to five arguments and an object. In case of a static-function, the object can be NULL. @return Returns the return-value of the function (if any; MT_Type::Null otherwise)
    134252            virtual MultiType operator()(O* object, 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) = 0;
    135253
     254            // see Functor::operator()()
    136255            MultiType 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)
    137256            {
     257                // call the function if it is static or if an object was assigned
    138258                if (detail::FunctorTypeStatic<O>::result || this->object_)
    139259                    return (*this)(this->object_, param1, param2, param3, param4, param5);
     
    145265            }
    146266
     267            // see Functor::getType()
    147268            Functor::Type::Enum getType() const
    148269                { return detail::FunctorTypeStatic<O>::result ? Functor::Type::Static : Functor::Type::Member; }
    149270
     271            /// Assigns an object-pointer to the functor which is used to execute a member-function.
    150272            inline void setObject(O* object)
    151273                { this->object_ = object;}
     274            /// Returns the object-pointer.
    152275            inline O* getObject() const
    153276                { return this->object_; }
    154277
     278            // see Functor::setRawObjectPointer()
    155279            inline void setRawObjectPointer(void* object)
    156280                { this->object_ = (O*)object; }
     281            // see Functor::getRawObjectPointer()
    157282            inline void* getRawObjectPointer() const
    158283                { return this->object_; }
    159284
    160285        protected:
    161             O* object_;
     286            O* object_;     ///< The stored object-pointer, used to execute a member-function (or NULL for static functions)
    162287    };
    163288
     289    /// FunctorStatic is just a typedef of FunctorMember with @a T = void.
    164290    typedef FunctorMember<void> FunctorStatic;
    165291
     292    /**
     293        @brief FunctorPointer is a child class of FunctorMember and expands it with a function-pointer.
     294        @param F The type of the function-pointer
     295        @param O The type of the function's class (or void if it's a static function)
     296
     297        The template FunctorPointer has an additional template parameter that defines the type
     298        of the function-pointer. This can be handy if you want to get or set the function-pointer.
     299        You can then use a static_cast to cast a Functor to FunctorPointer if you know the type
     300        of the function-pointer.
     301
     302        However FunctorPointer is not aware of the types of the different parameters or the
     303        return value.
     304    */
    166305    template <class F, class O = void>
    167306    class FunctorPointer : public FunctorMember<O>
    168307    {
    169308        public:
     309            /// Constructor: Initializes the base class and stores the function-pointer.
    170310            FunctorPointer(F functionPointer, O* object = 0) : FunctorMember<O>(object), functionPointer_(functionPointer) {}
    171311
     312            /// Changes the function-pointer.
    172313            inline void setFunction(F functionPointer)
    173314                { this->functionPointer_ = functionPointer; }
     315            /// Returns the function-pointer.
    174316            inline F getFunction() const
    175317                { return this->functionPointer_; }
    176318
     319            // see Functor::getFullIdentifier()
    177320            const std::type_info& getFullIdentifier() const
    178321                { return typeid(F); }
    179322
    180323        protected:
    181             F functionPointer_;
     324            F functionPointer_;     ///< The stored function-pointer
    182325    };
    183326
    184327    namespace detail
    185328    {
     329        // Helper class to get the type of the function pointer with the given class, parameters, return-value, and constness
    186330        template <class R, class O, bool isconst, class P1, class P2, class P3, class P4, class P5> struct FunctionPointer                                            { typedef R (O::*Type)(P1, P2, P3, P4, P5); };
    187331        template <class R, class O, class P1, class P2, class P3, class P4, class P5>               struct FunctionPointer<R, O, false, P1, P2, P3, P4, P5>           { typedef R (O::*Type)(P1, P2, P3, P4, P5); };
     
    204348        template <class R>                                                   struct FunctionPointer<R, void, false, void, void, void, void, void> { typedef R (*Type)(); };
    205349
     350        // Helper class, used to call a function-pointer with a given object and parameters and to return its return-value (if available)
    206351        template <class R, class O, bool isconst, class P1, class P2, class P3, class P4, class P5> struct FunctorCaller                                              { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, P5>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) { return (object->*functionPointer)(param1, param2, param3, param4, param5); } };
    207352        template <class R, class O, bool isconst, class P1, class P2, class P3, class P4>           struct FunctorCaller<R, O, isconst, P1, P2, P3, P4, void>         { static inline MultiType call(typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, void>::Type functionPointer, O* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) { return (object->*functionPointer)(param1, param2, param3, param4); } };
     
    229374        template <bool isconst>                                                   struct FunctorCaller<void, void, isconst, void, void, void, void, void> { static inline MultiType call(typename detail::FunctionPointer<void, void, isconst, void, void, void, void, void>::Type functionPointer, void*, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) { (*functionPointer)(); return MT_Type::Null; } };
    230375
     376        // Helper class, used to identify the header of a function-pointer (independent of its class)
    231377        template <class R, class P1, class P2, class P3, class P4, class P5>
    232378        struct FunctorHeaderIdentifier
    233379        {};
    234380
     381        // Helper class to determine if a function has a returnvalue
    235382        template <class T>
    236383        struct FunctorHasReturnvalue
     
    240387        { enum { result = false }; };
    241388
     389        // Helper class to count the number of parameters
    242390        template <class P1, class P2, class P3, class P4, class P5>
    243391        struct FunctorParamCount
     
    260408    }
    261409
     410    /**
     411        @brief FunctorTemplate is a child class of FunctorPointer and implements all functions
     412        that need to know the exact types of the parameters, return-value, and class.
     413
     414        @param R The type of the return-value of the function
     415        @param O The class of the function
     416        @param isconst True if the function is a const member-function
     417        @param P1 The type of the first parameter
     418        @param P2 The type of the second parameter
     419        @param P3 The type of the third parameter
     420        @param P4 The type of the fourth parameter
     421        @param P5 The type of the fifth parameter
     422
     423        This template has many parameters and is usually not used directly. It is created by
     424        createFunctor(), but only the base-classes Functor, FunctorMember, and FunctorPointer
     425        are used directly. It implements all the virtual functions that are declared by its
     426        base classes.
     427
     428        All template arguments can be void.
     429    */
    262430    template <class R, class O, bool isconst, class P1, class P2, class P3, class P4, class P5>
    263431    class FunctorTemplate : public FunctorPointer<typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, P5>::Type, O>
    264432    {
    265433        public:
     434            /// Constructor: Initializes the base class.
    266435            FunctorTemplate(typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, P5>::Type functionPointer, O* object = 0) : FunctorPointer<typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, P5>::Type, O>(functionPointer, object) {}
    267436
     437            // see FunctorMember::operator()()
    268438            MultiType operator()(O* object, 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)
    269439            {
     
    271441            }
    272442
     443            // see Functor::clone()
    273444            FunctorPtr clone()
    274445            {
     
    276447            }
    277448
    278             void evaluateParam(unsigned int index, MultiType& param) const
     449            // see Functor::evaluateArgument()
     450            void evaluateArgument(unsigned int index, MultiType& argument) const
    279451            {
    280452                switch (index)
    281453                {
    282                     case 0: param.convert<P1>(); break;
    283                     case 1: param.convert<P2>(); break;
    284                     case 2: param.convert<P3>(); break;
    285                     case 3: param.convert<P4>(); break;
    286                     case 4: param.convert<P5>(); break;
     454                    case 0: argument.convert<P1>(); break;
     455                    case 1: argument.convert<P2>(); break;
     456                    case 2: argument.convert<P3>(); break;
     457                    case 3: argument.convert<P4>(); break;
     458                    case 4: argument.convert<P5>(); break;
    287459                }
    288460            }
    289461
     462            // see Functor::getParamCount()
    290463            unsigned int getParamCount() const
    291464            {
     
    293466            }
    294467
     468            // see Functor::hasReturnvalue()
    295469            bool hasReturnvalue() const
    296470            {
     
    298472            }
    299473
    300             std::string getTypenameParam(unsigned int param) const
    301             {
    302                 switch (param)
     474            // see Functor::getTypenameParam()
     475            std::string getTypenameParam(unsigned int index) const
     476            {
     477                switch (index)
    303478                {
    304479                    case 0:  return typeToString<P1>();
     
    311486            }
    312487
     488            // see Functor::getTypenameReturnvalue()
    313489            std::string getTypenameReturnvalue() const
    314490            {
     
    316492            }
    317493
     494            // see Functor::getHeaderIdentifier()
    318495            const std::type_info& getHeaderIdentifier() const
    319496            {
     
    321498            }
    322499
     500            // see Functor::getHeaderIdentifier(unsigned int)
    323501            const std::type_info& getHeaderIdentifier(unsigned int params) const
    324502            {
     
    335513    };
    336514
    337     template <class R, class O, class OO, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5), OO* object) { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, P5>(functionPointer, object); }
    338     template <class R, class O, class OO, class P1, class P2, class P3, class P4>           inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4), OO* object)     { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, void>(functionPointer, object); }
    339     template <class R, class O, class OO, class P1, class P2, class P3>                     inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3), OO* object)         { return new FunctorTemplate<R, O, false, P1, P2, P3, void, void>(functionPointer, object); }
    340     template <class R, class O, class OO, class P1, class P2>                               inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2), OO* object)             { return new FunctorTemplate<R, O, false, P1, P2, void, void, void>(functionPointer, object); }
    341     template <class R, class O, class OO, class P1>                                         inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1), OO* object)                 { return new FunctorTemplate<R, O, false, P1, void, void, void, void>(functionPointer, object); }
    342     template <class R, class O, class OO>                                                   inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(), OO* object)                   { return new FunctorTemplate<R, O, false, void, void, void, void, void>(functionPointer, object); }
    343     template <class R, class O, class OO, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5) const, OO* object) { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, P5>(functionPointer, object); }
    344     template <class R, class O, class OO, class P1, class P2, class P3, class P4>           inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4) const, OO* object)     { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, void>(functionPointer, object); }
    345     template <class R, class O, class OO, class P1, class P2, class P3>                     inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3) const, OO* object)         { return new FunctorTemplate<R, O, true, P1, P2, P3, void, void>(functionPointer, object); }
    346     template <class R, class O, class OO, class P1, class P2>                               inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2) const, OO* object)             { return new FunctorTemplate<R, O, true, P1, P2, void, void, void>(functionPointer, object); }
    347     template <class R, class O, class OO, class P1>                                         inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1) const, OO* object)                 { return new FunctorTemplate<R, O, true, P1, void, void, void, void>(functionPointer, object); }
    348     template <class R, class O, class OO>                                                   inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)() const, OO* object)                   { return new FunctorTemplate<R, O, true, void, void, void, void, void>(functionPointer, object); }
    349 
    350     template <class R, class O, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5)) { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, P5>(functionPointer); }
    351     template <class R, class O, class P1, class P2, class P3, class P4>           inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4))     { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, void>(functionPointer); }
    352     template <class R, class O, class P1, class P2, class P3>                     inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3))         { return new FunctorTemplate<R, O, false, P1, P2, P3, void, void>(functionPointer); }
    353     template <class R, class O, class P1, class P2>                               inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2))             { return new FunctorTemplate<R, O, false, P1, P2, void, void, void>(functionPointer); }
    354     template <class R, class O, class P1>                                         inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1))                 { return new FunctorTemplate<R, O, false, P1, void, void, void, void>(functionPointer); }
    355     template <class R, class O>                                                   inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)())                   { return new FunctorTemplate<R, O, false, void, void, void, void, void>(functionPointer); }
    356     template <class R, class O, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5) const) { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, P5>(functionPointer); }
    357     template <class R, class O, class P1, class P2, class P3, class P4>           inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4) const)     { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, void>(functionPointer); }
    358     template <class R, class O, class P1, class P2, class P3>                     inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3) const)         { return new FunctorTemplate<R, O, true, P1, P2, P3, void, void>(functionPointer); }
    359     template <class R, class O, class P1, class P2>                               inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2) const)             { return new FunctorTemplate<R, O, true, P1, P2, void, void, void>(functionPointer); }
    360     template <class R, class O, class P1>                                         inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1) const)                 { return new FunctorTemplate<R, O, true, P1, void, void, void, void>(functionPointer); }
    361     template <class R, class O>                                                   inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)() const)                   { return new FunctorTemplate<R, O, true, void, void, void, void, void>(functionPointer); }
    362 
    363     template <class R, class P1, class P2, class P3, class P4, class P5> inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3, P4, P5)) { return new FunctorTemplate<R, void, false, P1, P2, P3, P4, P5>(functionPointer); }
    364     template <class R, class P1, class P2, class P3, class P4>           inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3, P4))     { return new FunctorTemplate<R, void, false, P1, P2, P3, P4, void>(functionPointer); }
    365     template <class R, class P1, class P2, class P3>                     inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3))         { return new FunctorTemplate<R, void, false, P1, P2, P3, void, void>(functionPointer); }
    366     template <class R, class P1, class P2>                               inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2))             { return new FunctorTemplate<R, void, false, P1, P2, void, void, void>(functionPointer); }
    367     template <class R, class P1>                                         inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1))                 { return new FunctorTemplate<R, void, false, P1, void, void, void, void>(functionPointer); }
    368     template <class R>                                                   inline FunctorStaticPtr createFunctor(R (*functionPointer)())                   { return new FunctorTemplate<R, void, false, void, void, void, void, void>(functionPointer); }
     515    template <class R, class O, class OO, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5), OO* object) { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, P5>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     516    template <class R, class O, class OO, class P1, class P2, class P3, class P4>           inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4), OO* object)     { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     517    template <class R, class O, class OO, class P1, class P2, class P3>                     inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3), OO* object)         { return new FunctorTemplate<R, O, false, P1, P2, P3, void, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     518    template <class R, class O, class OO, class P1, class P2>                               inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2), OO* object)             { return new FunctorTemplate<R, O, false, P1, P2, void, void, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     519    template <class R, class O, class OO, class P1>                                         inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1), OO* object)                 { return new FunctorTemplate<R, O, false, P1, void, void, void, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     520    template <class R, class O, class OO>                                                   inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(), OO* object)                   { return new FunctorTemplate<R, O, false, void, void, void, void, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     521    template <class R, class O, class OO, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5) const, OO* object) { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, P5>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     522    template <class R, class O, class OO, class P1, class P2, class P3, class P4>           inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4) const, OO* object)     { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     523    template <class R, class O, class OO, class P1, class P2, class P3>                     inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3) const, OO* object)         { return new FunctorTemplate<R, O, true, P1, P2, P3, void, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     524    template <class R, class O, class OO, class P1, class P2>                               inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2) const, OO* object)             { return new FunctorTemplate<R, O, true, P1, P2, void, void, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     525    template <class R, class O, class OO, class P1>                                         inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1) const, OO* object)                 { return new FunctorTemplate<R, O, true, P1, void, void, void, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     526    template <class R, class O, class OO>                                                   inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)() const, OO* object)                   { return new FunctorTemplate<R, O, true, void, void, void, void, void>(functionPointer, object); }   ///< Creates a new FunctorMember with the given function-pointer and an assigned object
     527
     528    template <class R, class O, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5)) { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, P5>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     529    template <class R, class O, class P1, class P2, class P3, class P4>           inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4))     { return new FunctorTemplate<R, O, false, P1, P2, P3, P4, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     530    template <class R, class O, class P1, class P2, class P3>                     inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3))         { return new FunctorTemplate<R, O, false, P1, P2, P3, void, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     531    template <class R, class O, class P1, class P2>                               inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2))             { return new FunctorTemplate<R, O, false, P1, P2, void, void, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     532    template <class R, class O, class P1>                                         inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1))                 { return new FunctorTemplate<R, O, false, P1, void, void, void, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     533    template <class R, class O>                                                   inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)())                   { return new FunctorTemplate<R, O, false, void, void, void, void, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     534    template <class R, class O, class P1, class P2, class P3, class P4, class P5> inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4, P5) const) { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, P5>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     535    template <class R, class O, class P1, class P2, class P3, class P4>           inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3, P4) const)     { return new FunctorTemplate<R, O, true, P1, P2, P3, P4, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     536    template <class R, class O, class P1, class P2, class P3>                     inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2, P3) const)         { return new FunctorTemplate<R, O, true, P1, P2, P3, void, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     537    template <class R, class O, class P1, class P2>                               inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1, P2) const)             { return new FunctorTemplate<R, O, true, P1, P2, void, void, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     538    template <class R, class O, class P1>                                         inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)(P1) const)                 { return new FunctorTemplate<R, O, true, P1, void, void, void, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     539    template <class R, class O>                                                   inline FunctorMemberPtr<O> createFunctor(R (O::*functionPointer)() const)                   { return new FunctorTemplate<R, O, true, void, void, void, void, void>(functionPointer); }   ///< Creates a new FunctorMember with the given function-pointer
     540
     541    template <class R, class P1, class P2, class P3, class P4, class P5> inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3, P4, P5)) { return new FunctorTemplate<R, void, false, P1, P2, P3, P4, P5>(functionPointer); }   ///< Creates a new Functor with the given function-pointer
     542    template <class R, class P1, class P2, class P3, class P4>           inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3, P4))     { return new FunctorTemplate<R, void, false, P1, P2, P3, P4, void>(functionPointer); }   ///< Creates a new Functor with the given function-pointer
     543    template <class R, class P1, class P2, class P3>                     inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2, P3))         { return new FunctorTemplate<R, void, false, P1, P2, P3, void, void>(functionPointer); }   ///< Creates a new Functor with the given function-pointer
     544    template <class R, class P1, class P2>                               inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1, P2))             { return new FunctorTemplate<R, void, false, P1, P2, void, void, void>(functionPointer); }   ///< Creates a new Functor with the given function-pointer
     545    template <class R, class P1>                                         inline FunctorStaticPtr createFunctor(R (*functionPointer)(P1))                 { return new FunctorTemplate<R, void, false, P1, void, void, void, void>(functionPointer); }   ///< Creates a new Functor with the given function-pointer
     546    template <class R>                                                   inline FunctorStaticPtr createFunctor(R (*functionPointer)())                   { return new FunctorTemplate<R, void, false, void, void, void, void, void>(functionPointer); }   ///< Creates a new Functor with the given function-pointer
    369547}
    370548
  • code/trunk/src/libraries/core/command/FunctorPtr.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command FunctorExecutor
     32    @brief Typedefs and definitions of FunctorPtr, FunctorMemberPtr, FunctorStaticPtr, and FunctorPointerPtr
     33
     34    Instances of orxonox::Functor are usually managed by an orxonox::SharedPtr. This ensures
     35    that Functors will be destroyed after usage. To make things easier, there's a typedef
     36    that defines FunctorPtr as SharedPtr<Functor>.
     37
     38    Because there's not only orxonox::Functor, but also orxonox::FunctorStatic, and
     39    orxonox::FunctorMember, the shared pointers need to store them all and also reflect
     40    their hierarchy - FunctorStatic and FunctorMember should not be mixed, but both can
     41    be converted to Functor. This is achieved by using orxonox::SharedChildPtr.
     42
     43    Because it's not possible to use a typedef for a template, we have to define the
     44    helper class FunctorMemberPtr<T> that makes it easier to use FunctorMember. The
     45    same is also done for FunctorPointerPtr<T>, which can be converted to both,
     46    FunctorMemberPtr<T> as well as FunctorPtr.
     47*/
     48
    2949#ifndef _FunctorPtr_H__
    3050#define _FunctorPtr_H__
     
    3555namespace orxonox
    3656{
     57    /// FunctorPtr is just a typedef of SharedPtr
    3758    typedef SharedPtr<Functor> FunctorPtr;
    3859
     60    /// It's not possible to use a typedef for FunctorMemberPtr<T>, so we have to create a child-class instead. It inherits all functions from SharedChildPtr, but needs to (re-)implement some constructors.
    3961    template <class T>
    4062    class FunctorMemberPtr : public SharedChildPtr<FunctorMember<T>, FunctorPtr>
     
    4668    };
    4769
     70    /// FunctorStaticPtr is just FunctorMemberPtr with @a T = void
    4871    typedef FunctorMemberPtr<void> FunctorStaticPtr;
    4972
     73    /// It's not possible to use a typedef for FunctorPointerPtr<T>, so we have to create a child-class instead. It inherits all functions from SharedChildPtr, but needs to (re-)implement some constructors.
    5074    template <class F, class T>
    5175    class FunctorPointerPtr : public SharedChildPtr<FunctorPointer<F, T>, FunctorMemberPtr<T> >
  • code/trunk/src/libraries/core/command/IOConsole.h

    r7287 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command ShellConsole
     32*/
     33
    2934#include "OrxonoxConfig.h"
    3035
  • code/trunk/src/libraries/core/command/IOConsolePOSIX.h

    r7287 r7401  
    2727 *
    2828 */
     29
     30/**
     31    @file
     32    @ingroup Command ShellConsole
     33*/
    2934
    3035#ifndef _IOConsole_H__
  • code/trunk/src/libraries/core/command/IOConsoleWindows.h

    r7287 r7401  
    2626 *
    2727 */
     28
     29/**
     30    @file
     31    @ingroup Command ShellConsole
     32*/
    2833
    2934#ifndef _IOConsole_H__
  • code/trunk/src/libraries/core/command/IRC.cc

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @brief Implementation of the IRC class and the IRC console commands.
     32*/
     33
    2934#include "IRC.h"
    3035
     
    3944namespace orxonox
    4045{
    41     static const unsigned int IRC_TCL_THREADID  = 1421421421;
     46    static const unsigned int IRC_TCL_THREADID  = 1421421421;   ///< The ID of the thread in TclThreadManager that is used for the IRC connection
    4247
    4348    SetConsoleCommand("IRC", "say",  &IRC::say);
     
    4550    SetConsoleCommand("IRC", "nick", &IRC::nick);
    4651
     52    /**
     53        @brief Returns the only existing instance of IRC.
     54    */
     55    IRC& IRC::getInstance()
     56    {
     57        static IRC instance;
     58        return instance;
     59    }
     60
     61    /**
     62        @brief Constructor: Doesn't yet connect to IRC nor does it create a Tcl interpreter.
     63        The IRC object will automatically connect to the IRC server if one of the registered
     64        console commands is used the first time.
     65    */
    4766    IRC::IRC()
    4867    {
     
    5069    }
    5170
     71    /**
     72        @brief Creates and initializes a new multithreaded Tcl-interpreter and defines some callbacks to display IRC-messages in the console.
     73    */
    5274    void IRC::initialize()
    5375    {
     
    7092    }
    7193
    72     IRC& IRC::getInstance()
    73     {
    74         static IRC instance;
    75         return instance;
    76     }
    77 
     94    /**
     95        @brief Executes a Tcl-command on the Tcl-interpreter.
     96    */
    7897    bool IRC::eval(const std::string& command)
    7998    {
     
    96115    }
    97116
     117    /// Console command: Sends a message to the current channel on the IRC server.
    98118    void IRC::say(const std::string& message)
    99119    {
     
    102122    }
    103123
     124    /// Console command: Sends a message to a given channel or nickname on the IRC server.
    104125    void IRC::msg(const std::string& channel, const std::string& message)
    105126    {
     
    108129    }
    109130
     131    /// Console command: Changes the nickname on the IRC server.
    110132    void IRC::nick(const std::string& nickname)
    111133    {
     
    114136    }
    115137
     138    /// Tcl-callback: Prints a message that was received from the current IRC channel to the console.
    116139    void IRC::tcl_say(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
    117140    {
     
    119142    }
    120143
     144    /// Tcl-callback: Prints a private message that was received from a user to the console.
    121145    void IRC::tcl_privmsg(Tcl::object const &query, Tcl::object const &nick, Tcl::object const &args)
    122146    {
     
    124148    }
    125149
     150    /// Tcl-callback: Prints an action-message (usually /me ...) that was received from the current IRC channel to the console.
    126151    void IRC::tcl_action(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args)
    127152    {
     
    129154    }
    130155
     156    /// Tcl-callback: Prints all kinds of information that were received from the IRC server or channel (connection info, join, part, modes, ...) to the console.
    131157    void IRC::tcl_info(Tcl::object const &channel, Tcl::object const &args)
    132158    {
  • code/trunk/src/libraries/core/command/IRC.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command Tcl
     32    @brief Declaration of IRC helper class, used for IRC connections using Tcl.
     33*/
     34
    2935#ifndef _IRC_H__
    3036#define _IRC_H__
     
    3642namespace orxonox
    3743{
     44    /**
     45        @brief The IRC class creates a Tcl-thread (see TclThreadManager) and connects to an IRC server.
     46        It provides different console commands to send messages and to perform other actions on the IRC server.
     47    */
    3848    class _CoreExport IRC
    3949    {
     
    5565
    5666            IRC();
    57             IRC(const IRC& other);
    58             ~IRC() {}
     67            IRC(const IRC& other);              ///< Copy-constructor: Not implemented
     68            ~IRC() {}                           ///< Destructor
    5969
    60             Tcl::interpreter* interpreter_;
    61             std::string nickname_;
     70            Tcl::interpreter* interpreter_;     ///< The Tcl interpreter that is used for the IRC connection
     71            std::string nickname_;              ///< The user's nickname on the IRC server
    6272    };
    6373}
  • code/trunk/src/libraries/core/command/Shell.cc

    r7284 r7401  
    2626 *
    2727 */
     28
     29/**
     30    @file
     31    @brief Implementation of the Shell class.
     32*/
    2833
    2934#include "Shell.h"
     
    4853    unsigned int Shell::cacheSize_s;
    4954
     55    /**
     56        @brief Constructor: Initializes the values and registers itself at OutputHandler.
     57        @param consoleName The name of the shell - used to define the name of the soft-debug-level config-value
     58        @param bScrollable If true, the user is allowed to scroll through the output-lines
     59    */
    5060    Shell::Shell(const std::string& consoleName, bool bScrollable)
    5161        : OutputListener(consoleName)
     
    8898    }
    8999
     100    /**
     101        @brief Destructor: Unregisters the shell from OutputHandler.
     102    */
    90103    Shell::~Shell()
    91104    {
     
    94107    }
    95108
     109    /**
     110        @brief Defines the config values.
     111    */
    96112    void Shell::setConfigValues()
    97113    {
     
    113129    }
    114130
     131    /**
     132        @brief Config-value callback: Called when the history offset has changed in the config-file.
     133    */
    115134    void Shell::commandHistoryOffsetChanged()
    116135    {
     
    119138    }
    120139
     140    /**
     141        @brief Config-value callback: Called when the length of the command history has changed in the config-file.
     142    */
    121143    void Shell::commandHistoryLengthChanged()
    122144    {
     
    131153    }
    132154
     155    /**
     156        @brief Registers this object as listener for different key-events at the input buffer.
     157    */
    133158    void Shell::configureInputBuffer()
    134159    {
     
    159184    }
    160185
    161     /*
    162     void Shell::history()
    163     {
    164         Shell& instance = Shell::getInstance();
    165 
    166         for (unsigned int i = instance.historyOffset_; i < instance.commandHistory_.size(); ++i)
    167             instance.addOutput(instance.commandHistory_[i] + '\n', -1);
    168         for (unsigned int i =  0; i < instance.historyOffset_; ++i)
    169             instance.addOutput(instance.commandHistory_[i] + '\n', -1);
    170     }
    171     */
    172 
     186    /**
     187        @brief Registers a shell listener which listens for changes in this shell.
     188    */
    173189    void Shell::registerListener(ShellListener* listener)
    174190    {
     
    176192    }
    177193
     194    /**
     195        @brief Unregisters a shell listener.
     196    */
    178197    void Shell::unregisterListener(ShellListener* listener)
    179198    {
     
    187206    }
    188207
     208    /**
     209        @brief Changes the position of the cursor in the input buffer.
     210    */
    189211    void Shell::setCursorPosition(unsigned int cursor)
    190212    {
     
    193215    }
    194216
     217    /**
     218        @brief Sends output to the internal output buffer.
     219    */
    195220    void Shell::addOutput(const std::string& text, LineType type)
    196221    {
     
    199224    }
    200225
     226    /**
     227        @brief Clears the list of output-lines.
     228    */
    201229    void Shell::clearOutput()
    202230    {
     
    210238    }
    211239
     240    /**
     241        @brief Returns an iterator to the newest line of output (except if the user is currently scrolling through the output).
     242    */
    212243    Shell::LineList::const_iterator Shell::getNewestLineIterator() const
    213244    {
     
    218249    }
    219250
     251    /**
     252        @brief Returns the end() iterator of the list of output-lines.
     253    */
    220254    Shell::LineList::const_iterator Shell::getEndIterator() const
    221255    {
     
    223257    }
    224258
     259    /**
     260        @brief Adds a command to the history of entered commands and writes it to the config-file.
     261    */
    225262    void Shell::addToHistory(const std::string& command)
    226263    {
     
    237274    }
    238275
     276    /**
     277        @brief Returns a command from the history of entered commands (usually the most recent history entry, but the user can scroll through the history).
     278    */
    239279    const std::string& Shell::getFromHistory() const
    240280    {
     
    246286    }
    247287
     288    /**
     289        @brief Called by OutputHandler or internally whenever output was sent to the output buffer. Reads from the buffer and writes the new output-lines to the list.
     290    */
    248291    void Shell::outputChanged(int lineType)
    249292    {
     
    251294        do
    252295        {
     296            // get the first line from the buffer
    253297            std::string output;
    254298            std::getline(this->outputBuffer_, output);
    255299
     300            // check the state of the buffer
    256301            bool eof = this->outputBuffer_.eof();
    257302            bool fail = this->outputBuffer_.fail();
    258303            if (eof)
    259                 this->outputBuffer_.flush();
     304                this->outputBuffer_.flush(); // check if more output was received in the meantime
    260305            if (eof || fail)
    261                 this->outputBuffer_.clear();
     306                this->outputBuffer_.clear(); // clear the error flags
     307
     308            // the line is terminated with a line-break if neither an error occurred nor the end of the file was reached
    262309            newline = (!eof && !fail);
    263310
     311            // no output retrieved - break the loop
    264312            if (!newline && output.empty())
    265313                break;
    266314
     315            // check if the last line was terminated with a line-break
    267316            if (this->bFinishedLastLine_)
    268317            {
     318                // yes it was - push the new line to the list
    269319                this->outputLines_.push_front(std::make_pair(output, static_cast<LineType>(lineType)));
    270320
     321                // adjust the scroll position if needed
    271322                if (this->scrollPosition_)
    272323                    this->scrollPosition_++;
    273324                else
    274325                    this->scrollIterator_ = this->outputLines_.begin();
    275 
    276                 this->bFinishedLastLine_ = newline;
    277326
    278327                if (!this->scrollPosition_)
     
    281330            else
    282331            {
     332                // no it wasn't - add the new output to the last line
    283333                this->outputLines_.front().first += output;
    284                 this->bFinishedLastLine_ = newline;
    285334                this->updateListeners<&ShellListener::onlyLastLineChanged>();
    286335            }
     336
     337            // remember if the last line was terminated with a line-break
    287338            this->bFinishedLastLine_ = newline;
    288339
    289         } while (newline);
    290     }
    291 
     340        } while (newline); // loop as long as more lines are in the buffer
     341    }
     342
     343    /**
     344        @brief Clears the text in the input buffer.
     345    */
    292346    void Shell::clearInput()
    293347    {
     
    298352    }
    299353
    300     void Shell::setPromptPrefix(const std::string& str)
    301     {
    302     }
    303 
    304354
    305355    // ##########################################
     
    307357    // ##########################################
    308358
     359    /// InputBuffer callback: Called if the input changes.
    309360    void Shell::inputChanged()
    310361    {
     
    313364    }
    314365
     366    /// InputBuffer callback: Called if a key was pressed that executes a command (usually [return]).
    315367    void Shell::execute()
    316368    {
     
    340392    }
    341393
     394    /// InputBuffer callback: Called if a key was pressed that shows hints and completes a command (usually [tab]).
    342395    void Shell::hintAndComplete()
    343396    {
     
    349402    }
    350403
     404    /// InputBuffer callback: Called if a key was pressed that deletes the character before the cursor (usually [backspace]).
    351405    void Shell::backspace()
    352406    {
     
    356410    }
    357411
    358     void Shell::exit()
    359     {
    360         if (this->inputBuffer_->getSize() > 0)
    361         {
    362             this->clearInput();
    363             return;
    364         }
    365 
    366         this->clearInput();
    367         this->scrollPosition_ = 0;
    368         this->scrollIterator_ = this->outputLines_.begin();
    369 
    370         this->updateListeners<&ShellListener::exit>();
    371     }
    372 
     412    /// InputBuffer callback: Called if a key was pressed that deletes the character after the cursor (usually [delete]).
    373413    void Shell::deleteChar()
    374414    {
     
    377417    }
    378418
     419    /// InputBuffer callback: Called if a key was pressed that moves the input cursor the right (usually [arrow right]).
    379420    void Shell::cursorRight()
    380421    {
     
    383424    }
    384425
     426    /// InputBuffer callback: Called if a key was pressed that moves the input cursor the left (usually [arrow left]).
    385427    void Shell::cursorLeft()
    386428    {
     
    389431    }
    390432
     433    /// InputBuffer callback: Called if a key was pressed that moves the input cursor the end of the input line (usually [end]).
    391434    void Shell::cursorEnd()
    392435    {
     
    395438    }
    396439
     440    /// InputBuffer callback: Called if a key was pressed that moves the input cursor the beginning of the input line (usually [home]).
    397441    void Shell::cursorHome()
    398442    {
     
    401445    }
    402446
     447    /// InputBuffer callback: Called if a key was pressed that scrolls upwards through the history of entered commands (usually [arrow up]).
    403448    void Shell::historyUp()
    404449    {
     
    410455    }
    411456
     457    /// InputBuffer callback: Called if a key was pressed that scrolls downwards through the history of entered commands (usually [arrow down]).
    412458    void Shell::historyDown()
    413459    {
     
    419465    }
    420466
     467    /// InputBuffer callback: Called if a key was pressed that searches upwards through the history for a command stat starts like the one the user is currently typing (usually [page up]). Only if the shell is not scrollable.
    421468    void Shell::historySearchUp()
    422469    {
     
    437484    }
    438485
     486    /// InputBuffer callback: Called if a key was pressed that searches downwards through the history for a command stat starts like the one the user is currently typing (usually [page down]). Only if the shell is not scrollable.
    439487    void Shell::historySearchDown()
    440488    {
     
    455503    }
    456504
     505    /// InputBuffer callback: Called if a key was pressed that scrolls upwards through the output history (usually [page up]). Only if the shell is scrollable.
    457506    void Shell::scrollUp()
    458507    {
     
    466515    }
    467516
     517    /// InputBuffer callback: Called if a key was pressed that scrolls downwards through the output history (usually [page down]). Only if the shell is scrollable.
    468518    void Shell::scrollDown()
    469519    {
     
    476526        }
    477527    }
     528
     529    /// InputBuffer callback: Called if a key was pressed that clears the text in the input buffer or closes the shell (usually [esc]).
     530    void Shell::exit()
     531    {
     532        if (this->inputBuffer_->getSize() > 0)
     533        {
     534            this->clearInput();
     535            return;
     536        }
     537
     538        this->clearInput();
     539        this->scrollPosition_ = 0;
     540        this->scrollIterator_ = this->outputLines_.begin();
     541
     542        this->updateListeners<&ShellListener::exit>();
     543    }
    478544}
  • code/trunk/src/libraries/core/command/Shell.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @defgroup ShellConsole Shell and console
     31    @ingroup Command
     32*/
     33
     34/**
     35    @file
     36    @ingroup Command ShellConsole
     37    @brief Declaration of the Shell and ShellListener classes.
     38*/
     39
    2940#ifndef _Shell_H__
    3041#define _Shell_H__
     
    4354namespace orxonox
    4455{
     56    /**
     57        @brief An interface, used to get a notification if the state of the Shell changes.
     58    */
    4559    class _CoreExport ShellListener
    4660    {
     
    5165
    5266        private:
    53             virtual void linesChanged() {}
    54             virtual void onlyLastLineChanged() {}
    55             virtual void lineAdded() {}
    56             virtual void inputChanged() {}
    57             virtual void cursorChanged() {}
    58             virtual void executed() {}
    59             virtual void exit() {}
     67            virtual void linesChanged() {}          ///< Called if all output-lines have changed
     68            virtual void onlyLastLineChanged() {}   ///< Called if only the last output-line has changed
     69            virtual void lineAdded() {}             ///< Called if a new line was added to the output
     70            virtual void inputChanged() {}          ///< Called if the input has changed
     71            virtual void cursorChanged() {}         ///< Called if the cursor in the input line has changed
     72            virtual void executed() {}              ///< Called if a command from the input line was executed
     73            virtual void exit() {}                  ///< Called if the console should be closed
    6074    };
    6175
    6276
     77    /**
     78        @brief The Shell is the logical component of the console that displays output to the user and allows him to enter commands.
     79
     80        The Shell gathers output sent from OutputHandler by inheriting from OutputListener.
     81        The output-lines are stored in the shell, so they can be displayed in a graphical
     82        console. Additionally the Shell has an InputBuffer which is needed by the user to
     83        enter commands.
     84
     85        Different graphical consoles build upon a Shell, for example InGameConsole and IOConsole.
     86    */
    6387    class _CoreExport Shell : virtual public OrxonoxClass, public OutputListener
    6488    {
    6589        public:
     90            /// Defines the type of a line of text in the Shell - some types depend on the output level, others are of internal use.
    6691            enum LineType
    6792            {
     
    88113            void unregisterListener(ShellListener* listener);
    89114
     115            /// Returns the input buffer which is needed by the user to enter text into the shell.
    90116            inline InputBuffer* getInputBuffer()
    91117                { return this->inputBuffer_; }
    92118
    93119            void setCursorPosition(unsigned int cursor);
     120            /// Returns the current position of the cursor in the input buffer.
    94121            inline unsigned int getCursorPosition() const
    95122                { return this->inputBuffer_->getCursorPosition(); }
    96123
     124            /// Returns the current content of the input buffer (the text which was entered by the user)
    97125            inline const std::string& getInput() const
    98126                { return this->inputBuffer_->get(); }
     
    105133            void clearOutput();
    106134
     135            /// Returns the number of output-lines that are displayed in the shell.
    107136            inline unsigned int getNumLines() const
    108137                { return this->outputLines_.size(); }
     138            /// Returns the line which is currently viewed if the user scrolls through the older output-lines in the shell.
    109139            inline unsigned int getScrollPosition() const
    110140                { return this->scrollPosition_; }
    111141
    112             inline const std::string& getPromptPrefix() const { return this->promptPrefix_; }
    113             void setPromptPrefix(const std::string& str);
    114 
     142            /// Returns the cache size that is actually used in CommandExecutor, but placed here for better readability of the config file.
    115143            static inline unsigned int getCacheSize()
    116144                { return Shell::cacheSize_s; }
     
    145173            void exit();
    146174
     175            /// Iterates through all registered @ref ShellListener "shell listeners" and calls the function @a F.
    147176            template <void (ShellListener::*F)()>
    148177            void updateListeners()
     
    152181            }
    153182
    154             std::list<ShellListener*> listeners_;
    155             InputBuffer*              inputBuffer_;
    156             std::stringstream         outputBuffer_;
    157             bool                      bFinishedLastLine_;
    158             LineList                  outputLines_;
    159             LineList::const_iterator  scrollIterator_;
    160             unsigned int              scrollPosition_;
    161             unsigned int              historyPosition_;
    162 
    163             std::string               promptPrefix_;
    164             const std::string         consoleName_;
    165             const bool                bScrollable_;
     183            std::list<ShellListener*> listeners_;           ///< The registered shell listeners
     184            InputBuffer*              inputBuffer_;         ///< The input buffer that is needed by the user to enter text
     185            std::stringstream         outputBuffer_;        ///< The output buffer that is used to retrieve lines of output from OutputListener
     186            bool                      bFinishedLastLine_;   ///< Stores if the most recent output-line was terminated with a line-break or if more output is expected for this line
     187            LineList                  outputLines_;         ///< A list of all output-lines that were displayed in the shell so far
     188            LineList::const_iterator  scrollIterator_;      ///< An iterator to an entry of the list of output-lines, changes if the user scrolls through the output in the shell
     189            unsigned int              scrollPosition_;      ///< The number of the line that is currently being referenced by scrollIterator_
     190            unsigned int              historyPosition_;     ///< If the user scrolls through the history of entered commands (stored in commandHistory_), this contains the currently viewed history entry
     191
     192            const std::string         consoleName_;         ///< The name of this shell - used to define the name of the soft-debug-level config-value
     193            const bool                bScrollable_;         ///< If true, the user can scroll through the output-lines
    166194
    167195            // Config values
    168             unsigned int              maxHistoryLength_;
    169             unsigned int              historyOffset_;
    170             std::vector<std::string>  commandHistory_;
    171             int                       softDebugLevel_;
    172             static unsigned int       cacheSize_s;
     196            unsigned int              maxHistoryLength_;    ///< The maximum number of saved commands
     197            unsigned int              historyOffset_;       ///< The command history is a circular buffer, this variable defines the current write-offset
     198            std::vector<std::string>  commandHistory_;      ///< The history of commands that were entered by the user
     199            int                       softDebugLevel_;      ///< The maximum level of output that is displayed in the shell (will be passed to OutputListener to filter output)
     200            static unsigned int       cacheSize_s;          ///< The maximum cache size of the CommandExecutor - this is stored here for better readability of the config file and because CommandExecutor is no OrxonoxClass
    173201    };
    174202}
  • code/trunk/src/libraries/core/command/TclBind.cc

    r7284 r7401  
    4949    TclBind* TclBind::singletonPtr_s = 0;
    5050
     51    /**
     52        @brief Constructor: Initializes the Tcl-interpreter with a given data path.
     53        @param datapath Path to the directory that contains the Orxonox-specific Tcl-files
     54    */
    5155    TclBind::TclBind(const std::string& datapath)
    5256    {
     
    5660    }
    5761
     62    /**
     63        @brief Destructor: Deletes the Tcl-interpreter.
     64    */
    5865    TclBind::~TclBind()
    5966    {
     
    6269    }
    6370
     71    /**
     72        @brief Defines the path to the directory that contains the Orxonox-specific Tcl-files and initializes the Tcl-interpreter accordingly.
     73    */
    6474    void TclBind::setDataPath(const std::string& datapath)
    6575    {
     
    7181    }
    7282
     83    /**
     84        @brief Creates and initializes the Tcl-interpreter by registering all callbacks and defining some useful functions.
     85    */
    7386    void TclBind::initializeTclInterpreter()
    7487    {
     
    96109    }
    97110
     111    /**
     112        @brief Creates and initializes a new Tcl-interpreter and calls the Orxonox-specific
     113        init.tcl script that defines some special functions which are required by Orxonox.
     114    */
    98115    Tcl::interpreter* TclBind::createTclInterpreter()
    99116    {
     
    116133    }
    117134
     135    /**
     136        @brief Returns the path to the Tcl-library (not the Orxonox-specific Tcl-files).
     137    */
    118138    std::string TclBind::getTclLibraryPath()
    119139    {
     
    128148    }
    129149
     150    /**
     151        @brief Callback: Used to send an Orxonox-command from Tcl to the CommandExecutor and to send its result back to Tcl.
     152    */
    130153    std::string TclBind::tcl_query(Tcl::object const &args)
    131154    {
     
    151174    }
    152175
     176    /**
     177        @brief Callback: Used to send an Orxonox-command from Tcl to the CommandExecutor.
     178    */
    153179    void TclBind::tcl_execute(Tcl::object const &args)
    154180    {
     
    162188    }
    163189
     190    /**
     191        @brief Console command, executes Tcl code. Can be used to bind Tcl-commands to a key, because native
     192        Tcl-commands can not be evaluated and are thus not supported by the key-binder.
     193    */
    164194    std::string TclBind::tcl(const std::string& tclcode)
    165195    {
     
    182212    }
    183213
     214    /**
     215        @brief Console command and implementation of the Tcl-feature "bgerror" which is called if an error
     216        occurred in the background of a Tcl-script.
     217    */
    184218    void TclBind::bgerror(const std::string& error)
    185219    {
     
    187221    }
    188222
     223    /**
     224        @brief Executes Tcl-code and returns the return-value.
     225        @param tclcode A string that contains Tcl-code
     226        @param error A pointer to an integer (or NULL) that is used to write an error-code (see @ref CommandExecutorErrorCodes "CommandExecutor error codes")
     227        @return Returns the return-value of the executed code (or an empty string if there's no return-value)
     228    */
    189229    std::string TclBind::eval(const std::string& tclcode, int* error)
    190230    {
     
    194234        try
    195235        {
     236            // execute the code
    196237            return TclBind::getInstance().interpreter_->eval(tclcode);
    197238        }
  • code/trunk/src/libraries/core/command/TclBind.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @defgroup Tcl Tcl
     31    @ingroup Command
     32*/
     33
     34/**
     35    @file
     36    @ingroup Command Tcl
     37    @brief Declaration of the TclBind class.
     38
     39    @anchor TclBindExample
     40
     41    orxonox::TclBind is a wrapper class for a Tcl interpreter. It is implemented as
     42    singleton, so it can be accessed by everyone, but all share the same static
     43    Tcl interpreter. If you need a Tcl interpreter at your own, see orxonox::TclThreadManager
     44    for more information.
     45
     46    orxonox::TclBind is used by orxonox::CommandExecutor to execute Tcl commands. It can
     47    also be used to execute Tcl commands from different sources, but note that they may
     48    interfer with the ingame console if used improperly. By no means execute blocking
     49    commands such as endless loops or the tcl command @c vwait. Use orxonox::TclThreadManager
     50    and execute these commands in a multithreaded Tcl interpreter instead.
     51
     52    TclBind also defines different callback functions to return commands from the
     53    Tcl interpreter back to Orxonox. Because of that it's possible to send a mixture
     54    of Orxonox- and Tcl-commands to TclBind::eval() and still get the desired behavior.
     55
     56    Example:
     57    @code
     58    TclBind::eval("puts \"Hello World\"");                              // calls the tcl command "puts", prints "Hello World" to the console
     59    TclBind::eval("log Hello World");                                   // calls the orxonox command "log", prints "Hello World" to the console
     60
     61    TclBind::eval("log [expr 1+1]");                                    // prints "2" to the console (which is the result of the tcl command "expr")
     62
     63    TclBind::eval("puts -nonewline Hello; log World");                  // prints "HelloWorld" to the console
     64
     65    TclBind::eval("for {set i 0} {$i < 10} {incr i} {log test: $i}");   // prints "test: 0", ..., "test: 9" to the console
     66    @endcode
     67
     68    Note that @c puts and @c log behave slightly different, even though both can print
     69    text to the console. @c puts needs quotation marks around multi-word output, while
     70    @c log doesn't. @c puts on the other hand supports the flag @c -nonewline.
     71
     72    TclBind::eval() can also be used to obtain the return-value of a Tcl command:
     73    @code
     74    std::string result = TclBind::eval("expr 1+1");                     // result == "2"
     75    @endcode
     76*/
     77
    2978#ifndef _TclBind_H__
    3079#define _TclBind_H__
     
    3887namespace orxonox
    3988{
     89    /**
     90        @brief A wrapper class for a Tcl interpreter. Used to execute Tcl commands.
     91
     92        TclBind is used to execute Tcl commands, for example if sent to CommandExecutor::execute().
     93        It also defines different callbacks for Tcl, which allows to combine Orxonox-console-commands
     94        and Tcl-function without problems.
     95
     96        @see See @ref TclBindExample "TclBind.h" for more information and an example.
     97    */
    4098    class _CoreExport TclBind : public Singleton<TclBind>
    4199    {
     
    49107
    50108            void setDataPath(const std::string& datapath);
    51             const std::string& getTclDataPath() const { return this->tclDataPath_; }
    52109            static std::string getTclLibraryPath();
     110            /// Returns the path to the Orxonox-specific Tcl-files.
     111            inline const std::string& getTclDataPath() const
     112                { return this->tclDataPath_; }
    53113
    54114            void initializeTclInterpreter();
    55115            static Tcl::interpreter* createTclInterpreter();
    56             Tcl::interpreter* getTclInterpreter() const { return this->interpreter_; }
     116            /// Returns the Tcl-interpreter
     117            inline Tcl::interpreter* getTclInterpreter() const
     118                { return this->interpreter_; }
    57119
    58120            static std::string tcl_query(Tcl::object const &args);
     
    62124
    63125        private:
    64             TclBind(const TclBind& other);
     126            TclBind(const TclBind& other);      ///< Copy-constructor, not implemented
    65127
    66             Tcl::interpreter* interpreter_;
    67             std::string tclDataPath_;
    68             bool bSetTclDataPath_;
     128            Tcl::interpreter* interpreter_;     ///< The wrapped Tcl interpreter
     129            std::string tclDataPath_;           ///< The path to the directory that contains the Orxonox-specific Tcl-files
     130            bool bSetTclDataPath_;              ///< True if tclDataPath_ was defined (after a call to setDataPath())
    69131
    70             static TclBind* singletonPtr_s;
     132            static TclBind* singletonPtr_s;     ///< The singleton pointer
    71133    };
    72134}
  • code/trunk/src/libraries/core/command/TclThreadList.h

    r7284 r7401  
    2727 */
    2828
     29/**
     30    @file
     31    @ingroup Command Tcl
     32    @brief Definition of TclThreadList.
     33*/
     34
    2935#ifndef _TclThreadList_H__
    3036#define _TclThreadList_H__
     
    4046namespace orxonox
    4147{
     48    /**
     49        @brief A thread-safe implementation of a message queue, used by TclThreadManager.
     50    */
    4251    template <class T>
    4352    class TclThreadList
     
    7180
    7281            /**
    73                 @brief Returns a reference to the mutex which might be useful if you want to iterate through the list (see @ref begin and @ref end).
     82                @brief Returns a reference to the mutex which might be useful if you want to iterate through the list (see @ref getList()).
    7483            */
    7584            inline boost::shared_mutex& getMutex() const
  • code/trunk/src/libraries/core/command/TclThreadManager.cc

    r7284 r7401  
    2626 *
    2727 */
     28
     29/**
     30    @file
     31    @brief Implementation of TclThreadManager.
     32*/
    2833
    2934#include "TclThreadManager.h"
     
    251256    void TclThreadManager::initialize(TclInterpreterBundle* bundle)
    252257    {
    253         const std::string& id_string = getConvertedValue<unsigned int, std::string>(bundle->id_);
     258        const std::string& id_string = multi_cast<std::string>(bundle->id_);
    254259
    255260        // Initialize the new interpreter
     
    303308    /**
    304309        @brief Sends a command to the queue of a given Tcl-interpreter
    305         @param id The id of the target interpreter
     310        @param target_id The id of the target interpreter
    306311        @param command The command to be sent
    307312    */
     
    326331        @brief This function can be called from Tcl to send a command to the queue of any interpreter.
    327332        @param target_id The id of the target thread
     333        @param args Contains the content of the command
    328334    */
    329335    void TclThreadManager::tcl_crossexecute(int target_id, const Tcl::object& args)
     
    334340    /**
    335341        @brief Sends a command to the queue of a given Tcl-interpreter
    336         @param id The id of the target interpreter
     342        @param target_id The id of the target interpreter
    337343        @param command The command to be sent
    338344    */
     
    347353    /**
    348354        @brief Sends a query to a given Tcl-interpreter and waits for the result
    349         @param id The id of the target interpreter
     355        @param target_id The id of the target interpreter
    350356        @param command The command to be sent
    351357        @return The result of the command
     
    359365        @brief This function can be called from Tcl to send a query to the main thread.
    360366        @param source_id The id of the calling thread
     367        @param args Contains the content of the query
    361368
    362369        A query waits for the result of the command. This means, the calling thread will be blocked until
     
    373380        @param source_id The id of the calling thread
    374381        @param target_id The id of the target thread
     382        @param args Contains the content of the query
    375383    */
    376384    std::string TclThreadManager::tcl_crossquery(int source_id, int target_id, const Tcl::object& args)
     
    384392        @param target_id The id of the target thread
    385393        @param command The command to send as a query
    386         @param bUseCommandExecutor Only used if the target_id is 0 (which references the main interpreter). In this case it means if the command should be passed to the CommandExecutor (true) or to the main Tcl interpreter (false). This is true when called by tcl_query and false when called by tcl_crossquery.
     394        @param bUseCommandExecutor Only used if the target_id is 0 (which references the main interpreter). In this case it means if the command should be passed to the CommandExecutor (true) or to the main Tcl interpreter (false). This is true when called by tcl_query() and false when called by tcl_crossquery().
    387395    */
    388396    std::string TclThreadManager::_query(unsigned int source_id, unsigned int target_id, const std::string& command, bool bUseCommandExecutor)
     
    400408            {
    401409                // This query would lead to a deadlock - return with an error
    402                 TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + ' ' + getConvertedValue<unsigned int, std::string>(source_bundle->id_) \
    403                             + " -> " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
    404                             + "), couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) \
    405                             + " from other interpreter with ID " + getConvertedValue<unsigned int, std::string>(source_bundle->id_) + '.');
     410                TclThreadManager::error("Error: Circular query (" + this->dumpList(source_bundle->queriers_.getList()) + ' ' + multi_cast<std::string>(source_bundle->id_) \
     411                            + " -> " + multi_cast<std::string>(target_bundle->id_) \
     412                            + "), couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(target_bundle->id_) \
     413                            + " from other interpreter with ID " + multi_cast<std::string>(source_bundle->id_) + '.');
    406414            }
    407415            else
     
    469477                    // This happens if the main thread tries to query a busy interpreter
    470478                    // To avoid a lock of the main thread, we simply don't proceed with the query in this case
    471                     TclThreadManager::error("Error: Couldn't query Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(target_bundle->id_) + ", interpreter is busy right now.");
     479                    TclThreadManager::error("Error: Couldn't query Tcl-interpreter with ID " + multi_cast<std::string>(target_bundle->id_) + ", interpreter is busy right now.");
    472480                }
    473481            }
     
    515523        else
    516524        {
    517             TclThreadManager::error("Error: No Tcl-interpreter with ID " + getConvertedValue<unsigned int, std::string>(id) + " existing.");
     525            TclThreadManager::error("Error: No Tcl-interpreter with ID " + multi_cast<std::string>(id) + " existing.");
    518526            return 0;
    519527        }
     
    531539                output += ' ';
    532540
    533             output += getConvertedValue<unsigned int, std::string>(*it);
     541            output += multi_cast<std::string>(*it);
    534542        }
    535543        return output;
     
    583591        if (cc != TCL_OK)
    584592        {
    585             TclThreadManager::error("Tcl error (" + action + ", ID " + getConvertedValue<unsigned int, std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
     593            TclThreadManager::error("Tcl error (" + action + ", ID " + multi_cast<std::string>(bundle->id_) + "): " + static_cast<std::string>(result));
    586594            return "";
    587595        }
  • code/trunk/src/libraries/core/command/TclThreadManager.h

    r7284 r7401  
    2626 *
    2727 */
     28
     29/**
     30    @file
     31    @ingroup Command Tcl
     32    @brief Declaration of TclThreadManager, used to create multithreaded Tcl interpreters.
     33*/
    2834
    2935#ifndef _TclThreadManager_H__
Note: See TracChangeset for help on using the changeset viewer.