Changeset 7401 for code/trunk/src/libraries/core/command
- Timestamp:
- Sep 11, 2010, 12:34:00 AM (14 years ago)
- Location:
- code/trunk
- Files:
-
- 30 edited
Legend:
- Unmodified
- Added
- Removed
-
code/trunk
- Property svn:mergeinfo changed
/code/branches/doc (added) merged: 7290-7292,7296-7300,7302-7304,7306-7312,7315-7318,7323,7325,7327,7331-7332,7334-7335,7345-7347,7352-7353,7356-7357,7361,7363-7367,7371-7375,7388
- Property svn:mergeinfo changed
-
code/trunk/src/libraries/core/command/ArgumentCompleter.h
r7284 r7401 27 27 */ 28 28 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 29 52 #ifndef _ArgumentCompleter_H__ 30 53 #define _ArgumentCompleter_H__ … … 35 58 namespace orxonox 36 59 { 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 */ 37 70 class _CoreExport ArgumentCompleter 38 71 { 39 72 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. 46 79 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 */ 47 84 ArgumentCompletionList operator()(const std::string& param1 = "", const std::string& param2 = "", const std::string& param3 = "", const std::string& param4 = "", const std::string& param5 = "") 48 85 { … … 66 103 } 67 104 105 /// Returns true if the argument completion list supports multiple words. 68 106 inline bool useMultipleWords() const 69 107 { return this->bUseMultipleWords_; } 70 108 71 109 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 80 118 }; 81 119 } -
code/trunk/src/libraries/core/command/ArgumentCompletionFunctions.cc
r7284 r7401 26 26 * 27 27 */ 28 29 /** 30 @file 31 @brief Implementation of all argument completion functions 32 */ 28 33 29 34 #include "ArgumentCompletionFunctions.h" … … 53 58 namespace autocompletion 54 59 { 60 /** 61 @brief Fallback implementation, returns an empty list. 62 */ 55 63 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(fallback)() 56 64 { … … 60 68 namespace detail 61 69 { 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 */ 62 73 bool groupIsVisible(const std::map<std::string, ConsoleCommand*>& group, bool bOnlyShowHidden) 63 74 { … … 69 80 } 70 81 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 */ 71 87 ArgumentCompletionList _groupsandcommands(const std::string& fragment, bool bOnlyShowHidden) 72 88 { 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 73 93 ArgumentCompletionList groupList; 74 94 std::string fragmentLC = getLowercase(fragment); 75 95 96 // get all the groups that are visible (except the shortcut group "") 76 97 const std::map<std::string, std::map<std::string, ConsoleCommand*> >& commands = ConsoleCommand::getCommands(); 77 98 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = commands.begin(); it_group != commands.end(); ++it_group) … … 79 100 groupList.push_back(ArgumentCompletionListElement(it_group->first, getLowercase(it_group->first))); 80 101 102 // now add all shortcuts (in group "") 81 103 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = commands.find(""); 82 104 if (it_group != commands.end()) 83 105 { 106 // add a line-break if the list isn't empty 84 107 if (!groupList.empty()) 85 108 groupList.push_back(ArgumentCompletionListElement("", "", "\n")); 86 109 110 // add the shortcuts 87 111 for (std::map<std::string, ConsoleCommand*>::const_iterator it_command = it_group->second.begin(); it_command != it_group->second.end(); ++it_command) 88 112 if (it_command->second->isActive() && it_command->second->hasAccess() && (!it_command->second->isHidden())^bOnlyShowHidden && (fragmentLC == "" || getLowercase(it_command->first).find_first_of(fragmentLC) == 0)) … … 90 114 } 91 115 116 // if no shortcut was added, remove the line-break again 92 117 if (!groupList.empty() && groupList.back().getDisplay() == "\n") 93 118 groupList.pop_back(); … … 96 121 } 97 122 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 */ 98 129 ArgumentCompletionList _subcommands(const std::string& fragment, const std::string& group, bool bOnlyShowHidden) 99 130 { … … 102 133 std::string groupLC = getLowercase(group); 103 134 135 // find the iterator of the given group 104 136 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommands().begin(); 105 137 for ( ; it_group != ConsoleCommand::getCommands().end(); ++it_group) … … 107 139 break; 108 140 141 // add all commands in the group to the list 109 142 if (it_group != ConsoleCommand::getCommands().end()) 110 143 { … … 118 151 } 119 152 153 /** 154 @brief Returns a list of all console command groups AND all console command shortcuts. 155 */ 120 156 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(groupsandcommands)(const std::string& fragment) 121 157 { … … 123 159 } 124 160 161 /** 162 @brief Returns a list of all console commands in a given group. 163 */ 125 164 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(subcommands)(const std::string& fragment, const std::string& group) 126 165 { … … 128 167 } 129 168 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 */ 130 174 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(command)(const std::string& fragment) 131 175 { … … 145 189 } 146 190 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 */ 147 198 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(hiddencommand)(const std::string& fragment) 148 199 { … … 170 221 } 171 222 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 */ 172 230 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(files)(const std::string& fragment) 173 231 { … … 211 269 } 212 270 271 /** 272 @brief Returns the sections of the config file. 273 */ 213 274 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingssections)() 214 275 { … … 222 283 } 223 284 285 /** 286 @brief Returns the entries in a given section of the config file. 287 */ 224 288 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsentries)(const std::string& fragment, const std::string& section) 225 289 { … … 235 299 } 236 300 301 /** 302 @brief Returns the current value of a given value in a given section of the config file. 303 */ 237 304 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(settingsvalue)(const std::string& fragment, const std::string& entry, const std::string& section) 238 305 { … … 255 322 } 256 323 324 /** 325 @brief Returns a list of indexes of the available Tcl threads (see TclThreadManager). 326 */ 257 327 ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(tclthreads)() 258 328 { -
code/trunk/src/libraries/core/command/ArgumentCompletionFunctions.h
r7284 r7401 27 27 */ 28 28 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 29 149 #ifndef _ArgumentCompletionFunctions_H__ 30 150 #define _ArgumentCompletionFunctions_H__ … … 33 153 #include "ArgumentCompleter.h" 34 154 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 */ 36 162 #define ARGUMENT_COMPLETION_FUNCTION_DECLARATION(functionname) \ 37 163 _CoreExport ArgumentCompleter* functionname(); \ 38 164 _CoreExport ArgumentCompletionList acf_##functionname 39 165 166 /** 167 @brief Used to implement an argument completion function. 168 @param functionname The name of the function 169 */ 40 170 #define ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION(functionname) \ 41 171 _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 */ 42 177 #define ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_MULTI(functionname) \ 43 178 _ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_INTERNAL(functionname, true) 44 179 180 /// Internal macro 45 181 #define _ARGUMENT_COMPLETION_FUNCTION_IMPLEMENTATION_INTERNAL(functionname, bUseMultipleWords) \ 46 182 ArgumentCompleter* functionname() \ … … 52 188 ArgumentCompletionList acf_##functionname 53 189 190 /// Calls an argument completion function. Used for functions that return the results of another argument completion function. 54 191 #define ARGUMENT_COMPLETION_FUNCTION_CALL(functionname) acf_##functionname 55 192 -
code/trunk/src/libraries/core/command/ArgumentCompletionListElement.h
r7284 r7401 27 27 */ 28 28 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 29 35 #ifndef _ArgumentCompletionListElement_H__ 30 36 #define _ArgumentCompletionListElement_H__ … … 37 43 namespace orxonox 38 44 { 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 42 48 43 49 typedef std::list<ArgumentCompletionListElement> ArgumentCompletionList; 44 50 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 */ 45 66 class _CoreExport ArgumentCompletionListElement 46 67 { 47 68 public: 69 /// Constructor: Normal, comparable, and display string are all the same. 48 70 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. 49 72 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. 50 74 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) {} 51 75 76 /// Returns the normal string which is used as the actual argument. 52 77 const std::string& getString() const 53 78 { return this->normal_; } 79 /// Returns the comparable string which is used to compare arguments and user input 54 80 const std::string& getComparable() const 55 81 { 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 56 83 const std::string& getDisplay() const 57 84 { return (this->mode_ & ACL_MODE_DISPLAY) ? this->display_ : this->normal_; } 58 85 86 /// Returns true if there's a different string for comparison. 59 87 bool hasComparable() const 60 88 { return (this->mode_ & ACL_MODE_COMPARABLE); } 89 /// Returns true if there's a different string to display. 61 90 bool hasDisplay() const 62 91 { return (this->mode_ & ACL_MODE_DISPLAY); } 63 92 93 /// Overloaded operator for usage in maps and sets. 64 94 bool operator<(const ArgumentCompletionListElement& other) const 65 95 { return (this->getComparable() < other.getComparable()); } 66 96 67 97 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 72 102 }; 73 103 } -
code/trunk/src/libraries/core/command/CommandEvaluation.cc
r7286 r7401 27 27 */ 28 28 29 /** 30 @file 31 @brief Implementation of CommandEvaluation 32 */ 33 29 34 #include "CommandEvaluation.h" 30 35 … … 35 40 namespace orxonox 36 41 { 42 /** 43 @brief Constructor: Initializes the command evaluation with an empty command. 44 */ 37 45 CommandEvaluation::CommandEvaluation() 38 46 { … … 40 48 } 41 49 50 /** 51 @brief Initializes all values. 52 */ 42 53 void CommandEvaluation::initialize(const std::string& command) 43 54 { … … 49 60 this->bPossibleArgumentsRetrieved_ = false; 50 61 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 55 67 this->tokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', true, '"', true, '{', '}', true, '\0'); 56 68 } 57 69 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 */ 58 73 unsigned int CommandEvaluation::getNumberOfArguments() const 59 74 { 60 75 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 62 81 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; 63 92 else 64 return count + 1;65 }66 67 const std::string& CommandEvaluation::getLastArgument() const68 {69 if (this->tokens_.size() > 0 && this->string_[this->string_.size() - 1] != ' ')70 93 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 */ 75 99 const std::string& CommandEvaluation::getToken(unsigned int i) const 76 100 { … … 81 105 } 82 106 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 */ 83 111 int CommandEvaluation::execute() 84 112 { … … 88 116 } 89 117 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 */ 90 123 MultiType CommandEvaluation::query(int* error) 91 124 { 125 // check if an error value was passed by reference 92 126 if (error) 93 127 { 128 // Determine the error-code and return if it is not Success 129 94 130 *error = CommandExecutor::Success; 95 131 … … 105 141 } 106 142 143 // check if it's possible to execute the command 107 144 if (this->execCommand_ && this->execCommand_->isActive() && this->execCommand_->hasAccess()) 108 145 { 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_) 116 157 { 117 158 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]); 122 163 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]); 124 165 } 125 166 } … … 128 169 } 129 170 171 // return a null value in case of an error 130 172 return MT_Type::Null; 131 173 } 132 174 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 137 185 if (!this->execCommand_) 138 186 { 139 187 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; 141 189 return CommandExecutor::Error; 142 190 } 143 191 144 192 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 146 199 if (!error) 147 this->bEvaluated Params_ = true;200 this->bEvaluatedArguments_ = true; 148 201 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; 150 203 151 204 return error; 152 205 } 153 206 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) 155 213 { 156 214 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 161 223 { 162 224 if (index < MAX_FUNCTOR_ARGUMENTS) 163 return this-> param_[index];225 return this->arguments_[index]; 164 226 165 227 return MT_Type::Null; 166 228 } 167 229 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 */ 168 238 std::string CommandEvaluation::complete() 169 239 { 240 // check if it's possible to complete the command 170 241 if (!this->hintCommand_ || !this->hintCommand_->isActive()) 171 242 return this->string_; 172 243 244 // get the list of possible arguments 173 245 if (!this->bPossibleArgumentsRetrieved_) 174 246 this->retrievePossibleArguments(); 175 247 248 // if the list is empty, return the current command string 176 249 if (CommandEvaluation::getSize(this->possibleArguments_) == 0) 177 250 { … … 180 253 else 181 254 { 255 // get the first part of the command string from the beginning up to the last space character 182 256 std::string output = this->string_.substr(0, this->string_.find_last_of(' ') + 1); 257 258 // add the common begin of all possible arguments 183 259 output += CommandEvaluation::getCommonBegin(this->possibleArguments_); 260 261 // return the resulting string 184 262 return output; 185 263 } 186 264 } 187 265 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 */ 188 273 std::string CommandEvaluation::hint() 189 274 { 275 // check if it's possible to get hints for this command 190 276 if (!this->hintCommand_ || !this->hintCommand_->isActive()) 191 277 return ""; 192 278 279 // get the list of possible arguments 193 280 if (!this->bPossibleArgumentsRetrieved_) 194 281 this->retrievePossibleArguments(); 195 282 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 196 286 if (CommandEvaluation::getSize(this->possibleArguments_) > 0 || (!this->possibleArguments_.empty() && this->isValid())) 197 287 return CommandEvaluation::dump(this->possibleArguments_); 198 288 289 // at this point there's no valid argument in the list, so check if the command is actually valid 199 290 if (this->isValid()) 200 291 { 292 // yes it is - return the syntax of the command 201 293 return CommandEvaluation::dump(this->hintCommand_); 202 294 } 203 295 else 204 296 { 297 // no the command is not valid 205 298 if (this->getNumberOfArguments() > 2) 206 299 { 300 // the user typed 2+ arguments, but they don't name a command - print an error 207 301 return std::string("Error: There is no command with name \"") + this->getToken(0) + " " + this->getToken(1) + "\"."; 208 302 } 209 303 else 210 304 { 305 // the user typed 1-2 arguments, check what he tried to type and print a suitable error 211 306 std::string groupLC = getLowercase(this->getToken(0)); 212 307 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandsLC().begin(); it_group != ConsoleCommand::getCommandsLC().end(); ++it_group) … … 219 314 } 220 315 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 */ 221 320 std::string CommandEvaluation::getCommandSuggestion() const 222 321 { … … 227 326 unsigned int nearestDistance = (unsigned int)-1; 228 327 328 // iterate through all groups and their commands and calculate the distance to the current command. keep the best. 229 329 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandsLC().begin(); it_group != ConsoleCommand::getCommandsLC().end(); ++it_group) 230 330 { … … 244 344 } 245 345 346 // now also iterate through all shortcuts and keep the best if it's better than the one found above. 246 347 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandsLC().find(""); 247 348 if (it_group != ConsoleCommand::getCommandsLC().end()) … … 259 360 } 260 361 362 // return the command that's closest to the current one. 261 363 return nearestCommand; 262 364 } 263 365 366 /** 367 @brief Gets the possible arguments for the command in its current state. 368 */ 264 369 void CommandEvaluation::retrievePossibleArguments() 265 370 { 266 371 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. 267 374 unsigned int argumentID = std::min(this->getNumberOfArguments() - this->hintArgumentsOffset_, this->hintCommand_->getExecutor()->getParamCount()); 375 376 // get the argument completer for the given argument index 268 377 ArgumentCompleter* ac = this->hintCommand_->getArgumentCompleter(argumentID - 1); 269 378 379 // check if an argument completer exists 270 380 if (ac) 271 381 { 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 274 385 size_t max = this->hintArgumentsOffset_ + this->hintCommand_->getExecutor()->getParamCount(); 275 386 387 // write the argument strings to the argument array (in reversed order, as required by the argument completion function) 276 388 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 279 392 if (this->getNumberOfArguments() > max) 280 393 { 394 // yes - now check if multiple words are supported by the argument completer 281 395 if (ac->useMultipleWords()) 282 396 { 397 // yes - join the surplus arguments 283 398 std::string surplusArguments = this->tokens_.subSet(max - 1).join(); 284 399 if (this->string_[this->string_.size() - 1] == ' ') 285 400 surplusArguments += ' '; 286 401 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 288 406 CommandEvaluation::strip(this->possibleArguments_, this->getToken(this->getNumberOfArguments() - 1)); 289 407 } 408 else 409 { 410 // no - the user typed more arguments than supported, no action 411 } 290 412 } 291 413 else 292 414 { 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 */ 299 427 /* static */ size_t CommandEvaluation::getSize(const ArgumentCompletionList& list) 300 428 { … … 306 434 } 307 435 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 */ 308 441 /* static */ void CommandEvaluation::strip(ArgumentCompletionList& list, const std::string& fragment) 309 442 { 310 443 std::string fragmentLC = getLowercase(fragment); 311 444 445 // iterate through the list 312 446 for (ArgumentCompletionList::iterator it = list.begin(); it != list.end(); ) 313 447 { 314 448 const std::string& entry = it->getComparable(); 315 449 450 // check if the argument is empty - if yes, keep it always in the list 316 451 if (entry == "") 317 452 { … … 320 455 } 321 456 457 // check the length of the argument - arguments smaller than 'fragment' are always erased 322 458 if (entry.size() < fragmentLC.size()) 323 459 { … … 326 462 else 327 463 { 464 // compare the argument char by char with 'fragment' 328 465 bool bErase = false; 329 466 for (size_t i = 0; i < fragmentLC.size(); ++i) … … 344 481 } 345 482 483 /** 484 @brief Returns the commond begin of all arguments in the list. 485 */ 346 486 /* static */ std::string CommandEvaluation::getCommonBegin(const ArgumentCompletionList& list) 347 487 { 348 488 if (CommandEvaluation::getSize(list) == 0) 349 489 { 490 // no (non-empty) values in the list, return an empty string 350 491 return ""; 351 492 } 352 493 else if (CommandEvaluation::getSize(list) == 1) 353 494 { 495 // only one (non-empty) value in the list - search it and return it 354 496 for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it) 355 497 { 356 498 if (it->getComparable() != "") 357 499 { 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. 358 501 if (it->hasDisplay()) 359 502 return (it->getString()); … … 367 510 else 368 511 { 512 // multiple arguments in the list - iterate through it and find the common begin of all arguments 369 513 std::string output; 370 514 for (unsigned int i = 0; true; i++) 371 515 { 372 char tempComparable = 0;373 char temp = 0;516 char tempComparable = '\0'; 517 char temp = '\0'; 374 518 for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it) 375 519 { … … 377 521 const std::string& argument = it->getString(); 378 522 523 // ignore empty arguments 379 524 if (argumentComparable == "") 380 525 continue; … … 382 527 if (argument.size() > i) 383 528 { 384 if (tempComparable == 0)529 if (tempComparable == '\0') 385 530 { 531 // the first entry is always taken 386 532 tempComparable = argumentComparable[i]; 387 533 temp = argument[i]; … … 389 535 else 390 536 { 537 // all other entries need comparison to the first entry 391 538 if (tempComparable != argumentComparable[i]) 392 539 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 394 541 temp = tempComparable; 395 542 } … … 406 553 } 407 554 555 /** 556 @brief Joins the elements of the given list to a string. 557 */ 408 558 /* static */ std::string CommandEvaluation::dump(const ArgumentCompletionList& list) 409 559 { … … 413 563 output += it->getDisplay(); 414 564 565 // add a space character between two elements for all non-empty arguments 415 566 if (it->getComparable() != "") 416 567 output += ' '; … … 419 570 } 420 571 572 /** 573 @brief Returns a string that explains the syntax of the given command. 574 */ 421 575 /* static */ std::string CommandEvaluation::dump(const ConsoleCommand* command) 422 576 { 577 // get the name of the command 423 578 std::string output = command->getName(); 579 580 // check if there are parameters 424 581 if (command->getExecutor()->getParamCount() > 0) 425 582 output += ": "; 426 583 584 // iterate through the parameters 427 585 for (unsigned int i = 0; i < command->getExecutor()->getParamCount(); i++) 428 586 { 587 // separate the parameters with a space character 429 588 if (i != 0) 430 589 output += ' '; 431 590 591 // print default values in [], others in {} braces 432 592 if (command->getExecutor()->defaultValueSet(i)) 433 593 output += '['; … … 435 595 output += '{'; 436 596 597 // add the type-name of the parameter 437 598 output += command->getExecutor()->getTypenameParam(i); 438 599 600 // print the default value if available 439 601 if (command->getExecutor()->defaultValueSet(i)) 440 602 output += '=' + command->getExecutor()->getDefaultValue(i).getString() + ']'; -
code/trunk/src/libraries/core/command/CommandEvaluation.h
r7284 r7401 27 27 */ 28 28 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 29 46 #ifndef _CommandEvaluation_H__ 30 47 #define _CommandEvaluation_H__ … … 41 58 namespace orxonox 42 59 { 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 */ 43 80 class _CoreExport CommandEvaluation 44 81 { … … 56 93 std::string getCommandSuggestion() const; 57 94 58 int evaluate Params(bool bPrintError = false);95 int evaluateArguments(bool bPrintError = false); 59 96 97 /// Returns true if the command evaluation contains a valid command that can be executed. 60 98 inline bool isValid() const 61 99 { return (this->execCommand_ != 0); } 62 100 101 /// Returns the console command that was evaluated by this object. 63 102 inline const ConsoleCommand* getConsoleCommand() const 64 103 { return this->execCommand_; } 65 104 66 void setEvaluated Parameter(unsigned int index, const MultiType& param);67 MultiType getEvaluated Parameter(unsigned int index) const;105 void setEvaluatedArgument(unsigned int index, const MultiType& arg); 106 MultiType getEvaluatedArgument(unsigned int index) const; 68 107 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 */ 69 115 const ArgumentCompletionList& getPossibleArguments() const 70 116 { return this->possibleArguments_; } 71 117 118 /// Returns the number of possible arguments. Empty ("") arguments are not counted. 72 119 size_t getPossibleArgumentsSize() const 73 120 { return CommandEvaluation::getSize(this->possibleArguments_); } … … 90 137 static std::string getCommonBegin(const ArgumentCompletionList& list); 91 138 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 100 147 101 bool bEvaluated Params_;102 bool bTriedToEvaluated Params_;103 unsigned int numberOfEvaluated Params_;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) 105 152 }; 106 153 } -
code/trunk/src/libraries/core/command/CommandExecutor.cc
r7284 r7401 27 27 */ 28 28 29 /** 30 @file 31 @brief Implementation of CommandExecutor 32 */ 33 29 34 #include "CommandExecutor.h" 30 35 … … 49 54 .argumentCompleter(1, autocompletion::command()); 50 55 56 /** 57 @brief Returns a reference to the only instance of CommandExecutor. 58 */ 51 59 /* static */ CommandExecutor& CommandExecutor::getInstance() 52 60 { … … 55 63 } 56 64 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 */ 57 71 /* static */ int CommandExecutor::execute(const std::string& command, bool useTcl) 58 72 { … … 62 76 } 63 77 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 */ 64 85 /* static */ MultiType CommandExecutor::queryMT(const std::string& command, int* error, bool useTcl) 65 86 { 66 87 if (useTcl) 88 { 89 // pass the command to tcl 67 90 return TclBind::eval(command, error); 91 } 68 92 else 69 93 { 70 94 CommandEvaluation evaluation; 95 96 // try to get the command evaluation from the cache 71 97 if (!CommandExecutor::getInstance().getCached(command, evaluation)) 72 98 { 99 // it wasn't in the cache - evaluate the command 73 100 evaluation = CommandExecutor::evaluate(command); 74 evaluation.evaluateParams(); 101 102 // evaluate its arguments 103 evaluation.evaluateArguments(); 104 105 // write the evaluation to the cache 75 106 CommandExecutor::getInstance().cache(command, evaluation); 76 107 } 77 108 109 // query the command and return its return-value 78 110 return evaluation.query(error); 79 111 } 80 112 } 81 113 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 */ 82 121 /* static */ std::string CommandExecutor::query(const std::string& command, int* error, bool useTcl) 83 122 { … … 85 124 } 86 125 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 */ 87 138 /* static */ CommandEvaluation CommandExecutor::evaluate(const std::string& command) 88 139 { 140 // initialize the command evaluation 89 141 CommandEvaluation evaluation; 90 142 evaluation.initialize(command); 91 143 144 // assign the fallback-command to get hints about the possible commands and groups 92 145 evaluation.hintCommand_ = ConsoleCommand::getCommand(__CC_CommandExecutor_name, __CC_autocomplete_name); 93 146 147 // check if there's at least one argument 94 148 if (evaluation.getNumberOfArguments() >= 1) 95 149 { 150 // try to get a command from the first token 96 151 evaluation.execCommand_ = ConsoleCommand::getCommandLC(evaluation.getToken(0)); 97 152 if (evaluation.execCommand_) … … 99 154 else if (evaluation.getNumberOfArguments() >= 2) 100 155 { 156 // try to get a command from the first two tokens 101 157 evaluation.execCommand_ = ConsoleCommand::getCommandLC(evaluation.getToken(0), evaluation.getToken(1)); 102 158 if (evaluation.execCommand_) … … 105 161 } 106 162 163 // if a valid command was found and the user is already entering arguments, overwrite hintCommand_ with execCommand_ 107 164 if (evaluation.execCommand_ && evaluation.getNumberOfArguments() > evaluation.execArgumentsOffset_) 108 165 { … … 114 171 } 115 172 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 */ 116 179 bool CommandExecutor::getCached(const std::string& command, CommandEvaluation& evaluation) 117 180 { … … 119 182 return false; 120 183 184 // check if the command is in the cache 121 185 std::map<std::string, CacheEntry>::iterator it = this->cache_.find(command); 122 186 if (it != this->cache_.end()) … … 134 198 } 135 199 200 /** 201 @brief Writes a command evaluation for a given command to the cache. 202 */ 136 203 void CommandExecutor::cache(const std::string& command, const CommandEvaluation& evaluation) 137 204 { … … 156 223 } 157 224 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 */ 158 231 /* static */ MultiType CommandExecutor::unhide(const std::string& command) 159 232 { … … 161 234 } 162 235 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 */ 163 241 /* static */ void CommandExecutor::alias(const std::string& alias, const std::string& command) 164 242 { 243 // first check if the given command is valid, else print an error 165 244 CommandEvaluation evaluation = CommandExecutor::evaluate(command); 166 245 if (evaluation.isValid()) 167 246 { 247 // it is valid - copy the executor of this command 168 248 ExecutorPtr executor = new Executor(*evaluation.getConsoleCommand()->getExecutor().get()); 169 249 170 if (!evaluation.evaluateParams()) 250 // evaluate the arguments and if this returns no error, store them as default values 251 if (!evaluation.evaluateArguments()) 171 252 { 172 253 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 176 258 SubString tokens(alias, " "); 177 259 260 // check if the alias already exists - print an error and return if it does 178 261 if ((tokens.size() == 1 && ConsoleCommand::getCommand(tokens[0])) || (tokens.size() == 2 && ConsoleCommand::getCommand(tokens[0], tokens[1]))) 179 262 { … … 182 265 } 183 266 267 // create a new console command with the given alias as its name 184 268 if (tokens.size() == 1) 185 269 createConsoleCommand(tokens[0], executor); -
code/trunk/src/libraries/core/command/CommandExecutor.h
r7284 r7401 27 27 */ 28 28 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 29 85 #ifndef _CommandExecutor_H__ 30 86 #define _CommandExecutor_H__ … … 42 98 namespace orxonox 43 99 { 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 */ 44 109 class _CoreExport CommandExecutor 45 110 { … … 53 118 static CommandEvaluation evaluate(const std::string& command); 54 119 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 60 125 61 126 static MultiType unhide(const std::string& command); 62 127 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. 64 129 65 130 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 69 134 70 135 static CommandExecutor& getInstance(); … … 73 138 void cache(const std::string& command, const CommandEvaluation& evaluation); 74 139 140 /// Helper struct, used to store cached entries 75 141 struct CacheEntry 76 142 { 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 79 145 }; 80 146 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 83 149 }; // tolua_export 84 150 } // tolua_export -
code/trunk/src/libraries/core/command/ConsoleCommand.cc
r7284 r7401 27 27 */ 28 28 29 /** 30 @file 31 @brief Implementation of the ConsoleCommand class. 32 */ 33 29 34 #include "ConsoleCommand.h" 30 35 … … 36 41 namespace orxonox 37 42 { 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 */ 38 50 ConsoleCommand::ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized) 39 51 { … … 45 57 this->baseFunctor_ = executor->getFunctor(); 46 58 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; 52 61 53 62 this->keybindMode_ = KeybindMode::OnPress; … … 60 69 } 61 70 71 /** 72 @brief Destructor: Unregisters the command. 73 */ 62 74 ConsoleCommand::~ConsoleCommand() 63 75 { … … 65 77 } 66 78 79 /** 80 @brief Registers the command with the same name, but without group, as shortcut. 81 */ 67 82 ConsoleCommand& ConsoleCommand::addShortcut() 68 83 { … … 71 86 } 72 87 88 /** 89 @brief Registers the command with an alias as shortcut. 90 */ 73 91 ConsoleCommand& ConsoleCommand::addShortcut(const std::string& name) 74 92 { … … 77 95 } 78 96 97 /** 98 @brief Registers the command in a different group but with the same name. 99 */ 79 100 ConsoleCommand& ConsoleCommand::addGroup(const std::string& group) 80 101 { … … 83 104 } 84 105 106 /** 107 @brief Registers an alias of the command in a different group with a different name. 108 */ 85 109 ConsoleCommand& ConsoleCommand::addGroup(const std::string& group, const std::string& name) 86 110 { … … 89 113 } 90 114 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 */ 91 124 bool ConsoleCommand::isActive() const 92 125 { … … 94 127 } 95 128 129 /** 130 @brief Returns true if the current state of the game matches the required access level. 131 */ 96 132 bool ConsoleCommand::hasAccess() const 97 133 { … … 101 137 case AccessLevel::Standalone: return GameMode::isStandalone(); 102 138 case AccessLevel::Master: return GameMode::isMaster(); 103 case AccessLevel::Server: return GameMode:: hasServer();139 case AccessLevel::Server: return GameMode::isServer(); 104 140 case AccessLevel::Client: return GameMode::isClient(); 105 case AccessLevel::Online: return (GameMode:: hasServer() || GameMode::isClient());141 case AccessLevel::Online: return (GameMode::isServer() || GameMode::isClient()); 106 142 case AccessLevel::Offline: return GameMode::isStandalone(); 107 143 case AccessLevel::None: return false; … … 110 146 } 111 147 148 /** 149 @brief Returns true if the headers of the given functor match the declaration of this command. 150 */ 112 151 bool ConsoleCommand::headersMatch(const FunctorPtr& functor) 113 152 { 153 // get the minimum of the number of parameters of both commands 114 154 unsigned int minparams = std::min(this->baseFunctor_->getParamCount(), functor->getParamCount()); 115 155 156 // if the reduced headers don't match -> return false 116 157 if (this->baseFunctor_->getHeaderIdentifier(minparams) != functor->getHeaderIdentifier(minparams)) 117 158 return false; 159 // if the reduced headers match and the new functor has less or equal parameters -> return true 118 160 else if (functor->getParamCount() <= this->baseFunctor_->getParamCount()) 119 161 return true; 162 // the headers match but the new functor has more arguments and there is no executor with default-values -> return false 120 163 else if (!this->executor_) 121 164 return false; 165 // the headers match but the new functor has more arguments, check if the executor has enough default-values 122 166 else 123 167 { … … 135 179 } 136 180 181 /** 182 @brief Returns true if the headers of the given executor match the declaration of this command. 183 */ 137 184 bool ConsoleCommand::headersMatch(const ExecutorPtr& executor) 138 185 { 186 // get the minimum of the number of parameters of both commands 139 187 unsigned int minparams = std::min(this->baseFunctor_->getParamCount(), executor->getParamCount()); 140 188 189 // if the reduced headers don't match -> return false 141 190 if (this->baseFunctor_->getHeaderIdentifier(minparams) != executor->getFunctor()->getHeaderIdentifier(minparams)) 142 191 return false; 192 // if the reduced headers match and the new functor has less or equal parameters -> return true 143 193 else if (executor->getParamCount() <= this->baseFunctor_->getParamCount()) 144 194 return true; 195 // the headers match but the new functor has more arguments, check if the new executor has enough default-values 145 196 else 146 197 { … … 158 209 } 159 210 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 */ 160 217 bool ConsoleCommand::setFunction(const ExecutorPtr& executor, bool bForce) 161 218 { 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 162 220 if (!executor || !executor->getFunctor() || bForce || this->headersMatch(executor)) 163 221 { 222 // assign the executor and clear the object stack (because it's also a new function) 164 223 this->executor_ = executor; 165 224 this->objectStack_.clear(); … … 173 232 } 174 233 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 */ 175 240 bool ConsoleCommand::setFunction(const FunctorPtr& functor, bool bForce) 176 241 { 242 // assign the functor if a) it's a null-pointer, b) it's forced, c) the headers match 177 243 if (!functor || bForce || this->headersMatch(functor)) 178 244 { 245 // assign the functor (create a new executor if necessary) and clear the object stack 179 246 if (this->executor_) 180 247 this->executor_->setFunctor(functor); … … 192 259 } 193 260 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 */ 194 266 void ConsoleCommand::pushFunction(const ExecutorPtr& executor, bool bForce) 195 267 { 268 // prepare the old function to be put on the stack 196 269 Command command; 197 270 command.executor_ = this->executor_; … … 200 273 command.objectStack_ = this->objectStack_; 201 274 275 // check if the new executor can be assigned and push the old function to the stack 202 276 if (this->setFunction(executor, bForce)) 203 277 this->commandStack_.push(command); 204 278 } 205 279 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 */ 206 285 void ConsoleCommand::pushFunction(const FunctorPtr& functor, bool bForce) 207 286 { 287 // prepare the old function to be put on the stack 208 288 Command command; 209 289 command.executor_ = this->executor_; … … 212 292 command.objectStack_ = this->objectStack_; 213 293 294 // check if the new functor can be assigned and push the old function to the stack 214 295 if (this->setFunction(functor, bForce)) 215 296 this->commandStack_.push(command); 216 297 } 217 298 299 /** 300 @brief Pushes a copy of the current executor and functor on the stack. 301 */ 218 302 void ConsoleCommand::pushFunction() 219 303 { … … 224 308 } 225 309 310 /** 311 @brief Removes the current function from the stack and restores the old state. 312 */ 226 313 void ConsoleCommand::popFunction() 227 314 { 228 315 Command command; 316 317 // check if there's a function on the stack 229 318 if (!this->commandStack_.empty()) 230 319 { 320 // yes it is - assign it to command and remove it from the stack 231 321 command = this->commandStack_.top(); 232 322 this->commandStack_.pop(); 233 323 } 234 324 325 // restore the old executor (and also restore its functor in case this was changed in the meantime) 235 326 this->executor_ = command.executor_; 236 327 if (command.executor_) … … 239 330 } 240 331 332 /** 333 @brief Sets the functor to NULL (which also deactivates the command). 334 */ 241 335 void ConsoleCommand::resetFunction() 242 336 { … … 246 340 } 247 341 342 /** 343 @brief Returns the current executor which can be used to execute the command. 344 */ 248 345 const ExecutorPtr& ConsoleCommand::getExecutor() const 249 346 { … … 251 348 } 252 349 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 */ 253 354 bool ConsoleCommand::setObject(void* object) 254 355 { 255 if (this->executor_) 256 { 356 // check if there's an executor 357 if (this->executor_) 358 { 359 // check if there's a functor 257 360 if (this->executor_->getFunctor()) 258 361 { 362 // change the object 259 363 this->executor_->getFunctor()->setRawObjectPointer(object); 260 364 return true; … … 269 373 } 270 374 375 /** 376 @brief Push a new object to the object-stack. 377 */ 271 378 void ConsoleCommand::pushObject(void* object) 272 379 { … … 276 383 } 277 384 385 /** 386 @brief Removes the current object from the stack an restores the old object. 387 */ 278 388 void ConsoleCommand::popObject() 279 389 { … … 287 397 } 288 398 399 /** 400 @brief Returns the current object pointer that is used to execute member-functions. 401 */ 289 402 void* ConsoleCommand::getObject() const 290 403 { … … 295 408 } 296 409 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); 301 417 else 302 418 COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl; … … 305 421 } 306 422 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); 311 430 else 312 431 COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl; … … 315 434 } 316 435 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); 321 443 else 322 444 COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl; … … 325 447 } 326 448 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); 331 456 else 332 457 COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl; … … 335 460 } 336 461 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); 341 469 else 342 470 COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl; … … 345 473 } 346 474 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); 351 484 else 352 485 COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl; … … 355 488 } 356 489 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]; 371 512 else 372 513 return 0; 373 514 } 374 515 516 /** 517 @brief Sets the description of this command. 518 */ 375 519 ConsoleCommand& ConsoleCommand::description(const std::string& description) 376 520 { … … 380 524 } 381 525 526 /** 527 @brief Returns the description of this command. 528 */ 382 529 const std::string& ConsoleCommand::getDescription() const 383 530 { … … 385 532 } 386 533 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]); 401 554 402 555 return this->descriptionParam_[0]; 403 556 } 404 557 558 /** 559 @brief Sets the description for the return-value. 560 */ 405 561 ConsoleCommand& ConsoleCommand::descriptionReturnvalue(const std::string& description) 406 562 { … … 410 566 } 411 567 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 413 572 { 414 573 return GetLocalisation_noerror(this->descriptionReturnvalue_); 415 574 } 416 575 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 */ 417 582 /* static */ const ConsoleCommand* ConsoleCommand::getCommand(const std::string& group, const std::string& name, bool bPrintError) 418 583 { 584 // find the group 419 585 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandMap().find(group); 420 586 if (it_group != ConsoleCommand::getCommandMap().end()) 421 587 { 588 // find the name 422 589 std::map<std::string, ConsoleCommand*>::const_iterator it_name = it_group->second.find(name); 423 590 if (it_name != it_group->second.end()) 424 591 { 592 // return the pointer 425 593 return it_name->second; 426 594 } … … 436 604 } 437 605 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 */ 438 612 /* static */ const ConsoleCommand* ConsoleCommand::getCommandLC(const std::string& group, const std::string& name, bool bPrintError) 439 613 { … … 441 615 std::string nameLC = getLowercase(name); 442 616 617 // find the group 443 618 std::map<std::string, std::map<std::string, ConsoleCommand*> >::const_iterator it_group = ConsoleCommand::getCommandMapLC().find(groupLC); 444 619 if (it_group != ConsoleCommand::getCommandMapLC().end()) 445 620 { 621 // find the name 446 622 std::map<std::string, ConsoleCommand*>::const_iterator it_name = it_group->second.find(nameLC); 447 623 if (it_name != it_group->second.end()) 448 624 { 625 // return the pointer 449 626 return it_name->second; 450 627 } … … 460 637 } 461 638 639 /** 640 @brief Returns the static map that stores all console commands. 641 */ 462 642 /* static */ std::map<std::string, std::map<std::string, ConsoleCommand*> >& ConsoleCommand::getCommandMap() 463 643 { … … 466 646 } 467 647 648 /** 649 @brief Returns the static map that stores all console commands in lowercase. 650 */ 468 651 /* static */ std::map<std::string, std::map<std::string, ConsoleCommand*> >& ConsoleCommand::getCommandMapLC() 469 652 { … … 472 655 } 473 656 657 /** 658 @brief Registers a new command with given group an name by adding it to the command map. 659 */ 474 660 /* static */ void ConsoleCommand::registerCommand(const std::string& group, const std::string& name, ConsoleCommand* command) 475 661 { … … 477 663 return; 478 664 665 // check if a command with this name already exists 479 666 if (ConsoleCommand::getCommand(group, name) != 0) 480 667 { … … 486 673 else 487 674 { 675 // add the command to the map 488 676 ConsoleCommand::getCommandMap()[group][name] = command; 489 677 ConsoleCommand::getCommandMapLC()[getLowercase(group)][getLowercase(name)] = command; … … 491 679 } 492 680 681 /** 682 @brief Removes the command from the command map. 683 */ 493 684 /* static */ void ConsoleCommand::unregisterCommand(ConsoleCommand* command) 494 685 { 686 // iterate through all groups 495 687 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::iterator it_group = ConsoleCommand::getCommandMap().begin(); it_group != ConsoleCommand::getCommandMap().end(); ) 496 688 { 689 // iterate through all commands of each group 497 690 for (std::map<std::string, ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); ) 498 691 { 692 // erase the command 499 693 if (it_name->second == command) 500 694 it_group->second.erase(it_name++); … … 503 697 } 504 698 699 // erase the group if it is empty now 505 700 if (it_group->second.empty()) 506 701 ConsoleCommand::getCommandMap().erase(it_group++); … … 509 704 } 510 705 706 // now the same for the lowercase-map: 707 708 // iterate through all groups 511 709 for (std::map<std::string, std::map<std::string, ConsoleCommand*> >::iterator it_group = ConsoleCommand::getCommandMapLC().begin(); it_group != ConsoleCommand::getCommandMapLC().end(); ) 512 710 { 711 // iterate through all commands of each group 513 712 for (std::map<std::string, ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); ) 514 713 { 714 // erase the command 515 715 if (it_name->second == command) 516 716 it_group->second.erase(it_name++); … … 519 719 } 520 720 721 // erase the group if it is empty now 521 722 if (it_group->second.empty()) 522 723 ConsoleCommand::getCommandMapLC().erase(it_group++); … … 526 727 } 527 728 729 /** 730 @brief Deletes all commands 731 */ 528 732 /* static */ void ConsoleCommand::destroyAll() 529 733 { 734 // delete entries until the map is empty 530 735 while (!ConsoleCommand::getCommandMap().empty() && !ConsoleCommand::getCommandMap().begin()->second.empty()) 531 736 delete ConsoleCommand::getCommandMap().begin()->second.begin()->second; -
code/trunk/src/libraries/core/command/ConsoleCommand.h
r7284 r7401 27 27 */ 28 28 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 29 217 #ifndef _ConsoleCommand_H__ 30 218 #define _ConsoleCommand_H__ … … 42 230 43 231 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 */ 44 242 #define SetConsoleCommand(...) \ 45 243 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 */ 46 249 #define SetConsoleCommand2(name, functionpointer) \ 47 250 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 */ 48 257 #define SetConsoleCommand3(group, name, functionpointer) \ 49 258 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 */ 50 266 #define SetConsoleCommand4(group, name, functionpointer, object) \ 51 267 SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object)) 52 268 269 /// Internal macro 53 270 #define SetConsoleCommandGeneric(group, name, functor) \ 54 271 static orxonox::ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::createConsoleCommand(group, name, orxonox::createExecutor(functor))) 55 272 56 273 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 */ 57 286 #define DeclareConsoleCommand(...) \ 58 287 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 */ 59 293 #define DeclareConsoleCommand2(name, functionpointer) \ 60 294 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 */ 61 301 #define DeclareConsoleCommand3(group, name, functionpointer) \ 62 302 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 66 305 #define DeclareConsoleCommandGeneric(group, name, functor) \ 67 306 static orxonox::ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::createConsoleCommand(group, name, orxonox::createExecutor(functor), false)) … … 70 309 namespace orxonox 71 310 { 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 */ 72 315 namespace prototype 73 316 { … … 78 321 namespace AccessLevel 79 322 { 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 */ 80 326 enum Enum 81 327 { … … 91 337 } 92 338 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 */ 93 350 class _CoreExport ConsoleCommand 94 351 { 95 352 friend struct ConsoleCommandManipulator; 96 353 354 /** 355 @brief Helper class that is used to put the current state of the ConsoleCommand on a stack. 356 */ 97 357 struct Command 98 358 { 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 102 362 }; 103 363 104 364 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 */ 105 376 struct ConsoleCommandManipulator 106 377 { 107 378 public: 379 /// Constructor: Creates a manipulator for a given ConsoleCommand. 108 380 ConsoleCommandManipulator(const ConsoleCommand* command) : command_(const_cast<ConsoleCommand*>(command)) {} 109 381 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 110 383 template <class F> 111 384 inline ConsoleCommandManipulator& setFunction(F function, bool bForce = false) … … 113 386 if (this->command_) 114 387 { 388 // check if the headers match. If they do, only change the function-pointer of the current Functor instead of creating a new Functor 115 389 if (this->command_->getExecutor() && this->command_->getExecutor()->getFunctor() && this->command_->getExecutor()->getFunctor()->getFullIdentifier() == typeid(F)) 116 390 { … … 123 397 return *this; 124 398 } 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 125 400 template <class F, class O> 126 401 inline ConsoleCommandManipulator& setFunction(F function, O* object, bool bForce = false) … … 128 403 if (this->command_) 129 404 { 405 // check if the headers match. If they do, only change the function-pointer of the current Functor instead of creating a new Functor 130 406 if (this->command_->getExecutor() && this->command_->getExecutor()->getFunctor() && this->command_->getExecutor()->getFunctor()->getFullIdentifier() == typeid(F)) 131 407 { … … 139 415 return *this; 140 416 } 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 141 418 inline ConsoleCommandManipulator& setFunction(const FunctorPtr& functor, bool bForce = false) 142 419 { 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 143 421 inline ConsoleCommandManipulator& setFunction(const ExecutorPtr& executor, bool bForce = false) 144 422 { if (this->command_) { this->command_->setFunction(executor, bForce); } return *this; } 145 423 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. 146 425 inline ConsoleCommandManipulator& pushFunction() 147 426 { 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 148 428 template <class F> 149 429 inline ConsoleCommandManipulator& pushFunction(F function, bool bForce = false) 150 430 { 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 151 432 template <class F, class O> 152 433 inline ConsoleCommandManipulator& pushFunction(F function, O* object, bool bForce = false) 153 434 { 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 154 436 inline ConsoleCommandManipulator& pushFunction(const FunctorPtr& functor, bool bForce = false) 155 437 { 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 156 439 inline ConsoleCommandManipulator& pushFunction(const ExecutorPtr& executor, bool bForce = false) 157 440 { if (this->command_) { this->command_->pushFunction(executor, bForce); } return *this; } 158 441 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. 159 443 inline ConsoleCommandManipulator& popFunction() 160 444 { if (this->command_) { this->command_->popFunction(); } return *this; } 161 445 446 /// Sets the current function-pointer to NULL, which also deactivates the command. 162 447 inline ConsoleCommandManipulator& resetFunction() 163 448 { if (this->command_) { this->command_->resetFunction(); } return *this; } 164 449 450 /// Changes the current object (used for member-functions). 165 451 inline ConsoleCommandManipulator& setObject(void* object) 166 452 { if (this->command_) { this->command_->setObject(object); } return *this; } 453 /// Pushes a new object on the object-stack. 167 454 inline ConsoleCommandManipulator& pushObject(void* object) 168 455 { 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). 169 457 inline ConsoleCommandManipulator& popObject() 170 458 { if (this->command_) { this->command_->popObject(); } return *this; } 171 459 460 /// Changes the activity of the command. 172 461 inline ConsoleCommandManipulator& setActive(bool bActive) 173 462 { if (this->command_) { this->command_->setActive(bActive); } return *this; } 463 /// Activates the command. 174 464 inline ConsoleCommandManipulator& activate() 175 465 { return this->setActive(true); } 466 /// Deactivates the command. 176 467 inline ConsoleCommandManipulator& deactivate() 177 468 { return this->setActive(false); } 178 469 470 /// Changes the visibility of the command. 179 471 inline ConsoleCommandManipulator& setHidden(bool bHidden) 180 472 { 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). 181 474 inline ConsoleCommandManipulator& hide() 182 475 { return this->setHidden(true); } 476 /// Makes the command visible. 183 477 inline ConsoleCommandManipulator& show() 184 478 { return this->setHidden(false); } 185 479 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. 199 500 inline ConsoleCommandManipulator& accessLevel(AccessLevel::Enum level) 200 501 { if (this->command_) { this->command_->accessLevel(level); } return *this; } 201 502 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. 205 508 inline ConsoleCommandManipulator& setAsInputCommand() 206 509 { if (this->command_) { this->command_->setAsInputCommand(); } return *this; } 510 /// Changes the keybind mode of the command. 207 511 inline ConsoleCommandManipulator& keybindMode(KeybindMode::Value mode) 208 512 { if (this->command_) { this->command_->keybindMode(mode); } return *this; } 513 /// Sets the input configured param to the given index. 209 514 inline ConsoleCommandManipulator& inputConfiguredParam(int index) 210 515 { if (this->command_) { this->command_->inputConfiguredParam(index); } return *this; } 211 516 212 517 private: 213 ConsoleCommand* command_; 518 ConsoleCommand* command_; ///< The command which is being manipulated by this object 214 519 }; 215 520 … … 223 528 ConsoleCommand& addGroup(const std::string& group, const std::string& name); 224 529 530 /// Returns the name that was first used for this command. 225 531 inline const std::string& getName() const 226 532 { return this->baseName_; } 227 533 228 534 const ExecutorPtr& getExecutor() const; 535 /// Returns the functor that defines the required header for this command (but isn't necessarily executed). 229 536 inline const FunctorPtr& getBaseFunctor() const 230 537 { return this->baseFunctor_; } 231 538 539 /// Changes the activity of the command. 232 540 inline ConsoleCommand& setActive(bool bActive) 233 541 { this->bActive_ = bActive; return *this; } 542 /// Activates the command. 234 543 inline ConsoleCommand& activate() 235 544 { return this->setActive(true); } 545 /// Deactivates the command. 236 546 inline ConsoleCommand& deactivate() 237 547 { return this->setActive(false); } 238 548 549 /// Changes the visibility of the command. 239 550 inline ConsoleCommand& setHidden(bool bHidden) 240 551 { this->bHidden_ = bHidden; return *this; } 552 /// Hides the command (can still be executed, but is not visible in the list of available commands). 241 553 inline ConsoleCommand& hide() 242 554 { return this->setHidden(true); } 555 /// Makes the command visible. 243 556 inline ConsoleCommand& show() 244 557 { return this->setHidden(false); } … … 246 559 bool isActive() const; 247 560 bool hasAccess() const; 561 /// Returns true if the command is currently hidden. 248 562 inline bool isHidden() const 249 563 { return this->bHidden_; } … … 252 566 const std::string& getDescription() const; 253 567 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; 256 570 257 571 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. 267 582 inline ConsoleCommand& accessLevel(AccessLevel::Enum level) 268 583 { this->accessLevel_ = level; return *this; } 584 /// Returns the access level of the command. 269 585 inline AccessLevel::Enum getAccessLevel() const 270 586 { return this->accessLevel_; } 271 587 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 275 592 inline ConsoleCommand& setAsInputCommand() 276 593 { … … 281 598 } 282 599 600 /// Changes the keybind mode. 283 601 inline ConsoleCommand& keybindMode(KeybindMode::Value mode) 284 602 { this->keybindMode_ = mode; return *this; } 603 /// Returns the keybind mode 285 604 inline KeybindMode::Value getKeybindMode() const 286 605 { return this->keybindMode_; } 287 606 607 /// Changes the input configured param to the given index. 288 608 inline ConsoleCommand& inputConfiguredParam(int index) 289 609 { this->inputConfiguredParam_ = index; return *this; } 610 /// Returns the input configured param. 290 611 inline int getInputConfiguredParam_() const 291 612 { return this->inputConfiguredParam_; } 292 613 614 /// Returns a manipulator for this command. 293 615 inline ConsoleCommandManipulator getManipulator() const 294 616 { return this; } … … 311 633 void* getObject() const; 312 634 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 331 653 332 654 public: 655 /// Returns the map with all groups and commands. 333 656 static inline const std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommands() 334 657 { return ConsoleCommand::getCommandMap(); } 658 /// Returns the map with all groups and commands in lowercase. 335 659 static inline const std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommandsLC() 336 660 { return ConsoleCommand::getCommandMapLC(); } 337 661 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 338 663 static inline const ConsoleCommand* getCommand(const std::string& name, bool bPrintError = false) 339 664 { 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 340 666 static inline const ConsoleCommand* getCommandLC(const std::string& name, bool bPrintError = false) 341 667 { return ConsoleCommand::getCommandLC("", name, bPrintError); } … … 354 680 }; 355 681 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 */ 356 688 inline ConsoleCommand* createConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized = true) 357 689 { 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 */ 358 697 inline ConsoleCommand* createConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true) 359 698 { return new ConsoleCommand(group, name, executor, bInitialized); } 360 699 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 */ 361 708 inline ConsoleCommand::ConsoleCommandManipulator ModifyConsoleCommand(const std::string& name) 362 709 { 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 */ 363 717 inline ConsoleCommand::ConsoleCommandManipulator ModifyConsoleCommand(const std::string& group, const std::string& name) 364 718 { return ConsoleCommand::getCommand(group, name, true); } -
code/trunk/src/libraries/core/command/ConsoleCommandCompilation.cc
r7284 r7401 26 26 * 27 27 */ 28 29 /** 30 @file 31 @brief Implementation of some console commands. 32 */ 28 33 29 34 #include "ConsoleCommandCompilation.h" … … 51 56 SetConsoleCommand("calculate", calculate); 52 57 58 /** 59 @brief Reads the content of a file and executes the commands in it line by line. 60 */ 53 61 void source(const std::string& filename) 54 62 { … … 86 94 } 87 95 96 /** 97 @brief Simply returns the arguments. 98 */ 88 99 std::string echo(const std::string& text) 89 100 { … … 91 102 } 92 103 104 /** 105 @brief Writes text to the console, depending on the first argument with or without a line-break after it. 106 */ 93 107 void puts(bool newline, const std::string& text) 94 108 { … … 103 117 } 104 118 119 /** 120 @brief Writes text to a file. 121 */ 105 122 void write(const std::string& filename, const std::string& text) 106 123 { … … 118 135 } 119 136 137 /** 138 @brief Appends text to a file. 139 */ 120 140 void append(const std::string& filename, const std::string& text) 121 141 { … … 133 153 } 134 154 155 /** 156 @brief Reads text from a file 157 */ 135 158 std::string read(const std::string& filename) 136 159 { … … 158 181 } 159 182 183 /** 184 @brief Parses the mathematical expression and returns the result. 185 */ 160 186 float calculate(const std::string& calculation) 161 187 { -
code/trunk/src/libraries/core/command/ConsoleCommandCompilation.h
r7284 r7401 27 27 */ 28 28 29 /** 30 @file 31 @ingroup Command ConsoleCommand 32 @brief Declaration of some console commands. 33 */ 34 29 35 #ifndef _ConsoleCommandCompilation_H__ 30 36 #define _ConsoleCommandCompilation_H__ -
code/trunk/src/libraries/core/command/Executor.cc
r7284 r7401 27 27 * Inspiration: Executor by Benjamin Grauer 28 28 */ 29 30 /** 31 @file 32 @brief Implementation of orxonox::Executor 33 */ 29 34 30 35 #include "Executor.h" … … 40 45 namespace orxonox 41 46 { 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 */ 42 52 Executor::Executor(const FunctorPtr& functor, const std::string& name) 43 53 { … … 46 56 } 47 57 58 /** 59 @brief Copy-constructor: Creates a new executor with the same values and a clone of the wrapped Functor. 60 */ 48 61 Executor::Executor(const Executor& other) : name_(other.name_) 49 62 { … … 53 66 } 54 67 68 /** 69 @brief Destructor 70 */ 55 71 Executor::~Executor() 56 72 { 57 73 } 58 74 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 */ 59 83 MultiType Executor::parse(const std::string& arguments, int* error, const std::string& delimiter, bool bPrintError) const 60 84 { … … 62 86 } 63 87 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 */ 64 96 MultiType Executor::parse(const SubString& arguments, int* error, const std::string& delimiter, bool bPrintError) const 65 97 { 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 69 103 if (error && *error) 70 104 { 71 105 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; 73 107 return MT_Type::Null; 74 108 } 75 109 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) 79 114 { 80 115 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]); 85 120 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]); 87 122 } 88 123 } 89 124 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 91 134 { 92 135 unsigned int paramCount = this->functor_->getParamCount(); … … 106 149 // assign all given arguments to the multitypes 107 150 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]; 109 152 110 153 // fill the remaining multitypes with default values 111 154 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]; 113 156 114 157 // assign the remaining arguments all to the last parameter if it is a string 115 158 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 functor159 arg[paramCount - 1] = arguments.subSet(paramCount - 1).join(delimiter); 160 161 // evaluate the parameter types through the functor 119 162 for (unsigned int i = 0; i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++) 120 this->functor_->evaluate Param(i, param[i]);163 this->functor_->evaluateArgument(i, arg[i]); 121 164 122 165 if (error) … … 125 168 } 126 169 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) 163 212 { 164 213 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. 168 218 bool Executor::allDefaultValuesSet() const 169 219 { -
code/trunk/src/libraries/core/command/Executor.h
r7284 r7401 28 28 */ 29 29 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 30 80 #ifndef _Executor_H__ 31 81 #define _Executor_H__ … … 40 90 namespace orxonox 41 91 { 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 */ 42 97 class _CoreExport Executor 43 98 { … … 47 102 virtual ~Executor(); 48 103 104 /// Calls the wrapped function with 0 arguments. If the function needs more arguments, the executor's default values are used. 49 105 inline MultiType operator()() const 50 106 { 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); } 61 122 62 123 MultiType parse(const std::string& arguments, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const; 63 124 MultiType parse(const SubString& arguments, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const; 64 125 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. 67 129 inline void setFunctor(const FunctorPtr& functor) 68 130 { this->functor_ = functor; } 131 /// Returns the functor. 69 132 inline const FunctorPtr& getFunctor() const 70 133 { return this->functor_; } 71 134 135 /// Changes the name of the executor. 72 136 inline void setName(const std::string& name) 73 137 { this->name_ = name; } 138 /// Returns the name of the executor. 74 139 inline const std::string& getName() const 75 140 { return this->name_; } 76 141 142 /// Returns the number of parameters of the wrapped function. 77 143 inline unsigned int getParamCount() const 78 144 { return this->functor_->getParamCount(); } 145 /// Returns true if the wrapped function returns a value. 79 146 inline bool hasReturnvalue() const 80 147 { return this->functor_->hasReturnvalue(); } 148 /// Returns the type of the wrapped function (static or member). 81 149 inline Functor::Type::Enum getType() const 82 150 { return this->functor_->getType(); } 151 /// Returns the name of the type of a parameter with given index (the first parameter has index 0). 83 152 inline std::string getTypenameParam(unsigned int param) const 84 153 { return this->functor_->getTypenameParam(param); } 154 /// Returns the name of the type of the return value. 85 155 inline std::string getTypenameReturnvalue() const 86 156 { return this->functor_->getTypenameReturnvalue(); } 87 157 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). 95 166 inline MultiType getDefaultValue(unsigned int index) const 96 167 { … … 102 173 103 174 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). 104 177 inline bool defaultValueSet(unsigned int index) const 105 178 { … … 111 184 112 185 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 116 189 }; 117 190 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 */ 118 196 class _CoreExport ExecutorStatic : public Executor 119 197 { 120 198 public: 199 /// Constructor: Initializes the parent class 121 200 ExecutorStatic(const FunctorStaticPtr& functor, const std::string& name = "") : Executor(functor, name) {} 201 /// Destructor 122 202 virtual ~ExecutorStatic() {} 123 203 }; 124 204 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 */ 125 211 template <class T> 126 212 class ExecutorMember : public Executor 127 213 { 128 214 public: 215 /// Constructor: Initializes the parent class and the pointer to the member-functor. 129 216 ExecutorMember(const FunctorMemberPtr<T>& functor, const std::string& name = "") : Executor(functor, name), functorMember_(functor) {} 217 /// Destructor 130 218 virtual ~ExecutorMember() {} 131 219 132 220 using Executor::operator(); 133 221 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. 134 223 inline MultiType operator()(T* object) const 135 224 { 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. 161 242 inline void setObject(T* object) const 162 243 { 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(); } 165 247 166 248 using Executor::parse; 167 249 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 169 252 { 170 253 T* oldobject = this->functorMember_->getObject(); 171 254 172 255 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); 174 257 this->functorMember_->setObject(oldobject); 175 258 … … 177 260 } 178 261 179 MultiType parse(const T* object, const std::string& params, int* error = 0, const std::string& delimiter = " ", bool bPrintError = false) const180 {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 190 262 protected: 191 FunctorMemberPtr<T> functorMember_; 263 FunctorMemberPtr<T> functorMember_; ///< A pointer to the FunctorMember is stored separately to avoid casting when executing the function. 192 264 }; 193 265 266 /// Creates a new Executor that wraps a given Functor. 194 267 inline ExecutorPtr createExecutor(const FunctorPtr& functor, const std::string& name = "") 195 268 { … … 197 270 } 198 271 272 /// Creates a new ExecutorMember that wraps a given FunctorMember. 199 273 template <class T> 200 274 inline ExecutorMemberPtr<T> createExecutor(const FunctorMemberPtr<T>& functor, const std::string& name = "") … … 203 277 } 204 278 279 /// Creates a new ExecutorStatic that wraps a given FunctorStatic. 205 280 inline ExecutorStaticPtr createExecutor(const FunctorStaticPtr& functor, const std::string& name = "") 206 281 { -
code/trunk/src/libraries/core/command/ExecutorPtr.h
r7284 r7401 27 27 */ 28 28 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 29 47 #ifndef _ExecutorPtr_H__ 30 48 #define _ExecutorPtr_H__ … … 35 53 namespace orxonox 36 54 { 55 /// ExecutorPtr is just a typedef of SharedPtr 37 56 typedef SharedPtr<Executor> ExecutorPtr; 38 57 58 /// ExecutorStaticPtr is just a typedef of SharedChildPtr 39 59 typedef SharedChildPtr<ExecutorStatic, ExecutorPtr> ExecutorStaticPtr; 40 60 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. 41 62 template <class T> 42 63 class ExecutorMemberPtr : public SharedChildPtr<ExecutorMember<T>, ExecutorPtr> -
code/trunk/src/libraries/core/command/Functor.h
r7284 r7401 27 27 */ 28 28 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 29 113 #ifndef _Functor_H__ 30 114 #define _Functor_H__ … … 40 124 namespace orxonox 41 125 { 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. 44 158 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 */ 73 174 class _CoreExport Functor 74 175 { … … 76 177 struct Type 77 178 { 179 /// Defines the type of a function (static or member) 78 180 enum Enum 79 181 { … … 84 186 85 187 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) 86 189 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; 87 190 191 /// Creates a new instance of Functor with the same values like this (used instead of a copy-constructor) 88 192 virtual FunctorPtr clone() = 0; 89 193 194 /// Returns the type of the function: static or member. 90 195 virtual Type::Enum getType() const = 0; 196 /// Returns the number of parameters of the function. 91 197 virtual unsigned int getParamCount() const = 0; 198 /// Returns true if the function has a return-value. 92 199 virtual bool hasReturnvalue() const = 0; 93 200 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. 95 204 virtual std::string getTypenameReturnvalue() const = 0; 96 205 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. 113 215 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. 114 217 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. 115 219 virtual const std::type_info& getHeaderIdentifier(unsigned int params) const = 0; 116 220 }; … … 118 222 namespace detail 119 223 { 224 // helper class to determine if a functor is static or not 120 225 template <class O> 121 226 struct FunctorTypeStatic … … 126 231 } 127 232 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 */ 128 244 template <class O> 129 245 class FunctorMember : public Functor 130 246 { 131 247 public: 248 /// Constructor: Stores the object-pointer. 132 249 FunctorMember(O* object = 0) : object_(object) {} 133 250 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) 134 252 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; 135 253 254 // see Functor::operator()() 136 255 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) 137 256 { 257 // call the function if it is static or if an object was assigned 138 258 if (detail::FunctorTypeStatic<O>::result || this->object_) 139 259 return (*this)(this->object_, param1, param2, param3, param4, param5); … … 145 265 } 146 266 267 // see Functor::getType() 147 268 Functor::Type::Enum getType() const 148 269 { return detail::FunctorTypeStatic<O>::result ? Functor::Type::Static : Functor::Type::Member; } 149 270 271 /// Assigns an object-pointer to the functor which is used to execute a member-function. 150 272 inline void setObject(O* object) 151 273 { this->object_ = object;} 274 /// Returns the object-pointer. 152 275 inline O* getObject() const 153 276 { return this->object_; } 154 277 278 // see Functor::setRawObjectPointer() 155 279 inline void setRawObjectPointer(void* object) 156 280 { this->object_ = (O*)object; } 281 // see Functor::getRawObjectPointer() 157 282 inline void* getRawObjectPointer() const 158 283 { return this->object_; } 159 284 160 285 protected: 161 O* object_; 286 O* object_; ///< The stored object-pointer, used to execute a member-function (or NULL for static functions) 162 287 }; 163 288 289 /// FunctorStatic is just a typedef of FunctorMember with @a T = void. 164 290 typedef FunctorMember<void> FunctorStatic; 165 291 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 */ 166 305 template <class F, class O = void> 167 306 class FunctorPointer : public FunctorMember<O> 168 307 { 169 308 public: 309 /// Constructor: Initializes the base class and stores the function-pointer. 170 310 FunctorPointer(F functionPointer, O* object = 0) : FunctorMember<O>(object), functionPointer_(functionPointer) {} 171 311 312 /// Changes the function-pointer. 172 313 inline void setFunction(F functionPointer) 173 314 { this->functionPointer_ = functionPointer; } 315 /// Returns the function-pointer. 174 316 inline F getFunction() const 175 317 { return this->functionPointer_; } 176 318 319 // see Functor::getFullIdentifier() 177 320 const std::type_info& getFullIdentifier() const 178 321 { return typeid(F); } 179 322 180 323 protected: 181 F functionPointer_; 324 F functionPointer_; ///< The stored function-pointer 182 325 }; 183 326 184 327 namespace detail 185 328 { 329 // Helper class to get the type of the function pointer with the given class, parameters, return-value, and constness 186 330 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); }; 187 331 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); }; … … 204 348 template <class R> struct FunctionPointer<R, void, false, void, void, void, void, void> { typedef R (*Type)(); }; 205 349 350 // Helper class, used to call a function-pointer with a given object and parameters and to return its return-value (if available) 206 351 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); } }; 207 352 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); } }; … … 229 374 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; } }; 230 375 376 // Helper class, used to identify the header of a function-pointer (independent of its class) 231 377 template <class R, class P1, class P2, class P3, class P4, class P5> 232 378 struct FunctorHeaderIdentifier 233 379 {}; 234 380 381 // Helper class to determine if a function has a returnvalue 235 382 template <class T> 236 383 struct FunctorHasReturnvalue … … 240 387 { enum { result = false }; }; 241 388 389 // Helper class to count the number of parameters 242 390 template <class P1, class P2, class P3, class P4, class P5> 243 391 struct FunctorParamCount … … 260 408 } 261 409 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 */ 262 430 template <class R, class O, bool isconst, class P1, class P2, class P3, class P4, class P5> 263 431 class FunctorTemplate : public FunctorPointer<typename detail::FunctionPointer<R, O, isconst, P1, P2, P3, P4, P5>::Type, O> 264 432 { 265 433 public: 434 /// Constructor: Initializes the base class. 266 435 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) {} 267 436 437 // see FunctorMember::operator()() 268 438 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) 269 439 { … … 271 441 } 272 442 443 // see Functor::clone() 273 444 FunctorPtr clone() 274 445 { … … 276 447 } 277 448 278 void evaluateParam(unsigned int index, MultiType& param) const 449 // see Functor::evaluateArgument() 450 void evaluateArgument(unsigned int index, MultiType& argument) const 279 451 { 280 452 switch (index) 281 453 { 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; 287 459 } 288 460 } 289 461 462 // see Functor::getParamCount() 290 463 unsigned int getParamCount() const 291 464 { … … 293 466 } 294 467 468 // see Functor::hasReturnvalue() 295 469 bool hasReturnvalue() const 296 470 { … … 298 472 } 299 473 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) 303 478 { 304 479 case 0: return typeToString<P1>(); … … 311 486 } 312 487 488 // see Functor::getTypenameReturnvalue() 313 489 std::string getTypenameReturnvalue() const 314 490 { … … 316 492 } 317 493 494 // see Functor::getHeaderIdentifier() 318 495 const std::type_info& getHeaderIdentifier() const 319 496 { … … 321 498 } 322 499 500 // see Functor::getHeaderIdentifier(unsigned int) 323 501 const std::type_info& getHeaderIdentifier(unsigned int params) const 324 502 { … … 335 513 }; 336 514 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 369 547 } 370 548 -
code/trunk/src/libraries/core/command/FunctorPtr.h
r7284 r7401 27 27 */ 28 28 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 29 49 #ifndef _FunctorPtr_H__ 30 50 #define _FunctorPtr_H__ … … 35 55 namespace orxonox 36 56 { 57 /// FunctorPtr is just a typedef of SharedPtr 37 58 typedef SharedPtr<Functor> FunctorPtr; 38 59 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. 39 61 template <class T> 40 62 class FunctorMemberPtr : public SharedChildPtr<FunctorMember<T>, FunctorPtr> … … 46 68 }; 47 69 70 /// FunctorStaticPtr is just FunctorMemberPtr with @a T = void 48 71 typedef FunctorMemberPtr<void> FunctorStaticPtr; 49 72 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. 50 74 template <class F, class T> 51 75 class FunctorPointerPtr : public SharedChildPtr<FunctorPointer<F, T>, FunctorMemberPtr<T> > -
code/trunk/src/libraries/core/command/IOConsole.h
r7287 r7401 27 27 */ 28 28 29 /** 30 @file 31 @ingroup Command ShellConsole 32 */ 33 29 34 #include "OrxonoxConfig.h" 30 35 -
code/trunk/src/libraries/core/command/IOConsolePOSIX.h
r7287 r7401 27 27 * 28 28 */ 29 30 /** 31 @file 32 @ingroup Command ShellConsole 33 */ 29 34 30 35 #ifndef _IOConsole_H__ -
code/trunk/src/libraries/core/command/IOConsoleWindows.h
r7287 r7401 26 26 * 27 27 */ 28 29 /** 30 @file 31 @ingroup Command ShellConsole 32 */ 28 33 29 34 #ifndef _IOConsole_H__ -
code/trunk/src/libraries/core/command/IRC.cc
r7284 r7401 27 27 */ 28 28 29 /** 30 @file 31 @brief Implementation of the IRC class and the IRC console commands. 32 */ 33 29 34 #include "IRC.h" 30 35 … … 39 44 namespace orxonox 40 45 { 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 42 47 43 48 SetConsoleCommand("IRC", "say", &IRC::say); … … 45 50 SetConsoleCommand("IRC", "nick", &IRC::nick); 46 51 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 */ 47 66 IRC::IRC() 48 67 { … … 50 69 } 51 70 71 /** 72 @brief Creates and initializes a new multithreaded Tcl-interpreter and defines some callbacks to display IRC-messages in the console. 73 */ 52 74 void IRC::initialize() 53 75 { … … 70 92 } 71 93 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 */ 78 97 bool IRC::eval(const std::string& command) 79 98 { … … 96 115 } 97 116 117 /// Console command: Sends a message to the current channel on the IRC server. 98 118 void IRC::say(const std::string& message) 99 119 { … … 102 122 } 103 123 124 /// Console command: Sends a message to a given channel or nickname on the IRC server. 104 125 void IRC::msg(const std::string& channel, const std::string& message) 105 126 { … … 108 129 } 109 130 131 /// Console command: Changes the nickname on the IRC server. 110 132 void IRC::nick(const std::string& nickname) 111 133 { … … 114 136 } 115 137 138 /// Tcl-callback: Prints a message that was received from the current IRC channel to the console. 116 139 void IRC::tcl_say(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args) 117 140 { … … 119 142 } 120 143 144 /// Tcl-callback: Prints a private message that was received from a user to the console. 121 145 void IRC::tcl_privmsg(Tcl::object const &query, Tcl::object const &nick, Tcl::object const &args) 122 146 { … … 124 148 } 125 149 150 /// Tcl-callback: Prints an action-message (usually /me ...) that was received from the current IRC channel to the console. 126 151 void IRC::tcl_action(Tcl::object const &channel, Tcl::object const &nick, Tcl::object const &args) 127 152 { … … 129 154 } 130 155 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. 131 157 void IRC::tcl_info(Tcl::object const &channel, Tcl::object const &args) 132 158 { -
code/trunk/src/libraries/core/command/IRC.h
r7284 r7401 27 27 */ 28 28 29 /** 30 @file 31 @ingroup Command Tcl 32 @brief Declaration of IRC helper class, used for IRC connections using Tcl. 33 */ 34 29 35 #ifndef _IRC_H__ 30 36 #define _IRC_H__ … … 36 42 namespace orxonox 37 43 { 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 */ 38 48 class _CoreExport IRC 39 49 { … … 55 65 56 66 IRC(); 57 IRC(const IRC& other); 58 ~IRC() {} 67 IRC(const IRC& other); ///< Copy-constructor: Not implemented 68 ~IRC() {} ///< Destructor 59 69 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 62 72 }; 63 73 } -
code/trunk/src/libraries/core/command/Shell.cc
r7284 r7401 26 26 * 27 27 */ 28 29 /** 30 @file 31 @brief Implementation of the Shell class. 32 */ 28 33 29 34 #include "Shell.h" … … 48 53 unsigned int Shell::cacheSize_s; 49 54 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 */ 50 60 Shell::Shell(const std::string& consoleName, bool bScrollable) 51 61 : OutputListener(consoleName) … … 88 98 } 89 99 100 /** 101 @brief Destructor: Unregisters the shell from OutputHandler. 102 */ 90 103 Shell::~Shell() 91 104 { … … 94 107 } 95 108 109 /** 110 @brief Defines the config values. 111 */ 96 112 void Shell::setConfigValues() 97 113 { … … 113 129 } 114 130 131 /** 132 @brief Config-value callback: Called when the history offset has changed in the config-file. 133 */ 115 134 void Shell::commandHistoryOffsetChanged() 116 135 { … … 119 138 } 120 139 140 /** 141 @brief Config-value callback: Called when the length of the command history has changed in the config-file. 142 */ 121 143 void Shell::commandHistoryLengthChanged() 122 144 { … … 131 153 } 132 154 155 /** 156 @brief Registers this object as listener for different key-events at the input buffer. 157 */ 133 158 void Shell::configureInputBuffer() 134 159 { … … 159 184 } 160 185 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 */ 173 189 void Shell::registerListener(ShellListener* listener) 174 190 { … … 176 192 } 177 193 194 /** 195 @brief Unregisters a shell listener. 196 */ 178 197 void Shell::unregisterListener(ShellListener* listener) 179 198 { … … 187 206 } 188 207 208 /** 209 @brief Changes the position of the cursor in the input buffer. 210 */ 189 211 void Shell::setCursorPosition(unsigned int cursor) 190 212 { … … 193 215 } 194 216 217 /** 218 @brief Sends output to the internal output buffer. 219 */ 195 220 void Shell::addOutput(const std::string& text, LineType type) 196 221 { … … 199 224 } 200 225 226 /** 227 @brief Clears the list of output-lines. 228 */ 201 229 void Shell::clearOutput() 202 230 { … … 210 238 } 211 239 240 /** 241 @brief Returns an iterator to the newest line of output (except if the user is currently scrolling through the output). 242 */ 212 243 Shell::LineList::const_iterator Shell::getNewestLineIterator() const 213 244 { … … 218 249 } 219 250 251 /** 252 @brief Returns the end() iterator of the list of output-lines. 253 */ 220 254 Shell::LineList::const_iterator Shell::getEndIterator() const 221 255 { … … 223 257 } 224 258 259 /** 260 @brief Adds a command to the history of entered commands and writes it to the config-file. 261 */ 225 262 void Shell::addToHistory(const std::string& command) 226 263 { … … 237 274 } 238 275 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 */ 239 279 const std::string& Shell::getFromHistory() const 240 280 { … … 246 286 } 247 287 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 */ 248 291 void Shell::outputChanged(int lineType) 249 292 { … … 251 294 do 252 295 { 296 // get the first line from the buffer 253 297 std::string output; 254 298 std::getline(this->outputBuffer_, output); 255 299 300 // check the state of the buffer 256 301 bool eof = this->outputBuffer_.eof(); 257 302 bool fail = this->outputBuffer_.fail(); 258 303 if (eof) 259 this->outputBuffer_.flush(); 304 this->outputBuffer_.flush(); // check if more output was received in the meantime 260 305 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 262 309 newline = (!eof && !fail); 263 310 311 // no output retrieved - break the loop 264 312 if (!newline && output.empty()) 265 313 break; 266 314 315 // check if the last line was terminated with a line-break 267 316 if (this->bFinishedLastLine_) 268 317 { 318 // yes it was - push the new line to the list 269 319 this->outputLines_.push_front(std::make_pair(output, static_cast<LineType>(lineType))); 270 320 321 // adjust the scroll position if needed 271 322 if (this->scrollPosition_) 272 323 this->scrollPosition_++; 273 324 else 274 325 this->scrollIterator_ = this->outputLines_.begin(); 275 276 this->bFinishedLastLine_ = newline;277 326 278 327 if (!this->scrollPosition_) … … 281 330 else 282 331 { 332 // no it wasn't - add the new output to the last line 283 333 this->outputLines_.front().first += output; 284 this->bFinishedLastLine_ = newline;285 334 this->updateListeners<&ShellListener::onlyLastLineChanged>(); 286 335 } 336 337 // remember if the last line was terminated with a line-break 287 338 this->bFinishedLastLine_ = newline; 288 339 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 */ 292 346 void Shell::clearInput() 293 347 { … … 298 352 } 299 353 300 void Shell::setPromptPrefix(const std::string& str)301 {302 }303 304 354 305 355 // ########################################## … … 307 357 // ########################################## 308 358 359 /// InputBuffer callback: Called if the input changes. 309 360 void Shell::inputChanged() 310 361 { … … 313 364 } 314 365 366 /// InputBuffer callback: Called if a key was pressed that executes a command (usually [return]). 315 367 void Shell::execute() 316 368 { … … 340 392 } 341 393 394 /// InputBuffer callback: Called if a key was pressed that shows hints and completes a command (usually [tab]). 342 395 void Shell::hintAndComplete() 343 396 { … … 349 402 } 350 403 404 /// InputBuffer callback: Called if a key was pressed that deletes the character before the cursor (usually [backspace]). 351 405 void Shell::backspace() 352 406 { … … 356 410 } 357 411 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]). 373 413 void Shell::deleteChar() 374 414 { … … 377 417 } 378 418 419 /// InputBuffer callback: Called if a key was pressed that moves the input cursor the right (usually [arrow right]). 379 420 void Shell::cursorRight() 380 421 { … … 383 424 } 384 425 426 /// InputBuffer callback: Called if a key was pressed that moves the input cursor the left (usually [arrow left]). 385 427 void Shell::cursorLeft() 386 428 { … … 389 431 } 390 432 433 /// InputBuffer callback: Called if a key was pressed that moves the input cursor the end of the input line (usually [end]). 391 434 void Shell::cursorEnd() 392 435 { … … 395 438 } 396 439 440 /// InputBuffer callback: Called if a key was pressed that moves the input cursor the beginning of the input line (usually [home]). 397 441 void Shell::cursorHome() 398 442 { … … 401 445 } 402 446 447 /// InputBuffer callback: Called if a key was pressed that scrolls upwards through the history of entered commands (usually [arrow up]). 403 448 void Shell::historyUp() 404 449 { … … 410 455 } 411 456 457 /// InputBuffer callback: Called if a key was pressed that scrolls downwards through the history of entered commands (usually [arrow down]). 412 458 void Shell::historyDown() 413 459 { … … 419 465 } 420 466 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. 421 468 void Shell::historySearchUp() 422 469 { … … 437 484 } 438 485 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. 439 487 void Shell::historySearchDown() 440 488 { … … 455 503 } 456 504 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. 457 506 void Shell::scrollUp() 458 507 { … … 466 515 } 467 516 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. 468 518 void Shell::scrollDown() 469 519 { … … 476 526 } 477 527 } 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 } 478 544 } -
code/trunk/src/libraries/core/command/Shell.h
r7284 r7401 27 27 */ 28 28 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 29 40 #ifndef _Shell_H__ 30 41 #define _Shell_H__ … … 43 54 namespace orxonox 44 55 { 56 /** 57 @brief An interface, used to get a notification if the state of the Shell changes. 58 */ 45 59 class _CoreExport ShellListener 46 60 { … … 51 65 52 66 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 60 74 }; 61 75 62 76 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 */ 63 87 class _CoreExport Shell : virtual public OrxonoxClass, public OutputListener 64 88 { 65 89 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. 66 91 enum LineType 67 92 { … … 88 113 void unregisterListener(ShellListener* listener); 89 114 115 /// Returns the input buffer which is needed by the user to enter text into the shell. 90 116 inline InputBuffer* getInputBuffer() 91 117 { return this->inputBuffer_; } 92 118 93 119 void setCursorPosition(unsigned int cursor); 120 /// Returns the current position of the cursor in the input buffer. 94 121 inline unsigned int getCursorPosition() const 95 122 { return this->inputBuffer_->getCursorPosition(); } 96 123 124 /// Returns the current content of the input buffer (the text which was entered by the user) 97 125 inline const std::string& getInput() const 98 126 { return this->inputBuffer_->get(); } … … 105 133 void clearOutput(); 106 134 135 /// Returns the number of output-lines that are displayed in the shell. 107 136 inline unsigned int getNumLines() const 108 137 { return this->outputLines_.size(); } 138 /// Returns the line which is currently viewed if the user scrolls through the older output-lines in the shell. 109 139 inline unsigned int getScrollPosition() const 110 140 { return this->scrollPosition_; } 111 141 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. 115 143 static inline unsigned int getCacheSize() 116 144 { return Shell::cacheSize_s; } … … 145 173 void exit(); 146 174 175 /// Iterates through all registered @ref ShellListener "shell listeners" and calls the function @a F. 147 176 template <void (ShellListener::*F)()> 148 177 void updateListeners() … … 152 181 } 153 182 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 166 194 167 195 // 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 173 201 }; 174 202 } -
code/trunk/src/libraries/core/command/TclBind.cc
r7284 r7401 49 49 TclBind* TclBind::singletonPtr_s = 0; 50 50 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 */ 51 55 TclBind::TclBind(const std::string& datapath) 52 56 { … … 56 60 } 57 61 62 /** 63 @brief Destructor: Deletes the Tcl-interpreter. 64 */ 58 65 TclBind::~TclBind() 59 66 { … … 62 69 } 63 70 71 /** 72 @brief Defines the path to the directory that contains the Orxonox-specific Tcl-files and initializes the Tcl-interpreter accordingly. 73 */ 64 74 void TclBind::setDataPath(const std::string& datapath) 65 75 { … … 71 81 } 72 82 83 /** 84 @brief Creates and initializes the Tcl-interpreter by registering all callbacks and defining some useful functions. 85 */ 73 86 void TclBind::initializeTclInterpreter() 74 87 { … … 96 109 } 97 110 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 */ 98 115 Tcl::interpreter* TclBind::createTclInterpreter() 99 116 { … … 116 133 } 117 134 135 /** 136 @brief Returns the path to the Tcl-library (not the Orxonox-specific Tcl-files). 137 */ 118 138 std::string TclBind::getTclLibraryPath() 119 139 { … … 128 148 } 129 149 150 /** 151 @brief Callback: Used to send an Orxonox-command from Tcl to the CommandExecutor and to send its result back to Tcl. 152 */ 130 153 std::string TclBind::tcl_query(Tcl::object const &args) 131 154 { … … 151 174 } 152 175 176 /** 177 @brief Callback: Used to send an Orxonox-command from Tcl to the CommandExecutor. 178 */ 153 179 void TclBind::tcl_execute(Tcl::object const &args) 154 180 { … … 162 188 } 163 189 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 */ 164 194 std::string TclBind::tcl(const std::string& tclcode) 165 195 { … … 182 212 } 183 213 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 */ 184 218 void TclBind::bgerror(const std::string& error) 185 219 { … … 187 221 } 188 222 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 */ 189 229 std::string TclBind::eval(const std::string& tclcode, int* error) 190 230 { … … 194 234 try 195 235 { 236 // execute the code 196 237 return TclBind::getInstance().interpreter_->eval(tclcode); 197 238 } -
code/trunk/src/libraries/core/command/TclBind.h
r7284 r7401 27 27 */ 28 28 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 29 78 #ifndef _TclBind_H__ 30 79 #define _TclBind_H__ … … 38 87 namespace orxonox 39 88 { 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 */ 40 98 class _CoreExport TclBind : public Singleton<TclBind> 41 99 { … … 49 107 50 108 void setDataPath(const std::string& datapath); 51 const std::string& getTclDataPath() const { return this->tclDataPath_; }52 109 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_; } 53 113 54 114 void initializeTclInterpreter(); 55 115 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_; } 57 119 58 120 static std::string tcl_query(Tcl::object const &args); … … 62 124 63 125 private: 64 TclBind(const TclBind& other); 126 TclBind(const TclBind& other); ///< Copy-constructor, not implemented 65 127 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()) 69 131 70 static TclBind* singletonPtr_s; 132 static TclBind* singletonPtr_s; ///< The singleton pointer 71 133 }; 72 134 } -
code/trunk/src/libraries/core/command/TclThreadList.h
r7284 r7401 27 27 */ 28 28 29 /** 30 @file 31 @ingroup Command Tcl 32 @brief Definition of TclThreadList. 33 */ 34 29 35 #ifndef _TclThreadList_H__ 30 36 #define _TclThreadList_H__ … … 40 46 namespace orxonox 41 47 { 48 /** 49 @brief A thread-safe implementation of a message queue, used by TclThreadManager. 50 */ 42 51 template <class T> 43 52 class TclThreadList … … 71 80 72 81 /** 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()). 74 83 */ 75 84 inline boost::shared_mutex& getMutex() const -
code/trunk/src/libraries/core/command/TclThreadManager.cc
r7284 r7401 26 26 * 27 27 */ 28 29 /** 30 @file 31 @brief Implementation of TclThreadManager. 32 */ 28 33 29 34 #include "TclThreadManager.h" … … 251 256 void TclThreadManager::initialize(TclInterpreterBundle* bundle) 252 257 { 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_); 254 259 255 260 // Initialize the new interpreter … … 303 308 /** 304 309 @brief Sends a command to the queue of a given Tcl-interpreter 305 @param id The id of the target interpreter310 @param target_id The id of the target interpreter 306 311 @param command The command to be sent 307 312 */ … … 326 331 @brief This function can be called from Tcl to send a command to the queue of any interpreter. 327 332 @param target_id The id of the target thread 333 @param args Contains the content of the command 328 334 */ 329 335 void TclThreadManager::tcl_crossexecute(int target_id, const Tcl::object& args) … … 334 340 /** 335 341 @brief Sends a command to the queue of a given Tcl-interpreter 336 @param id The id of the target interpreter342 @param target_id The id of the target interpreter 337 343 @param command The command to be sent 338 344 */ … … 347 353 /** 348 354 @brief Sends a query to a given Tcl-interpreter and waits for the result 349 @param id The id of the target interpreter355 @param target_id The id of the target interpreter 350 356 @param command The command to be sent 351 357 @return The result of the command … … 359 365 @brief This function can be called from Tcl to send a query to the main thread. 360 366 @param source_id The id of the calling thread 367 @param args Contains the content of the query 361 368 362 369 A query waits for the result of the command. This means, the calling thread will be blocked until … … 373 380 @param source_id The id of the calling thread 374 381 @param target_id The id of the target thread 382 @param args Contains the content of the query 375 383 */ 376 384 std::string TclThreadManager::tcl_crossquery(int source_id, int target_id, const Tcl::object& args) … … 384 392 @param target_id The id of the target thread 385 393 @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(). 387 395 */ 388 396 std::string TclThreadManager::_query(unsigned int source_id, unsigned int target_id, const std::string& command, bool bUseCommandExecutor) … … 400 408 { 401 409 // 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_) + '.'); 406 414 } 407 415 else … … 469 477 // This happens if the main thread tries to query a busy interpreter 470 478 // 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."); 472 480 } 473 481 } … … 515 523 else 516 524 { 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."); 518 526 return 0; 519 527 } … … 531 539 output += ' '; 532 540 533 output += getConvertedValue<unsigned int,std::string>(*it);541 output += multi_cast<std::string>(*it); 534 542 } 535 543 return output; … … 583 591 if (cc != TCL_OK) 584 592 { 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)); 586 594 return ""; 587 595 } -
code/trunk/src/libraries/core/command/TclThreadManager.h
r7284 r7401 26 26 * 27 27 */ 28 29 /** 30 @file 31 @ingroup Command Tcl 32 @brief Declaration of TclThreadManager, used to create multithreaded Tcl interpreters. 33 */ 28 34 29 35 #ifndef _TclThreadManager_H__
Note: See TracChangeset
for help on using the changeset viewer.