Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/command/ConsoleCommand.h @ 11977

Last change on this file since 11977 was 11071, checked in by landauf, 9 years ago

merged branch cpp11_v3 back to trunk

  • Property svn:eol-style set to native
File size: 24.8 KB
Line 
1/*
2 *   ORXONOX - the hottest 3D action shooter ever to exist
3 *                    > www.orxonox.net <
4 *
5 *
6 *   License notice:
7 *
8 *   This program is free software; you can redistribute it and/or
9 *   modify it under the terms of the GNU General Public License
10 *   as published by the Free Software Foundation; either version 2
11 *   of the License, or (at your option) any later version.
12 *
13 *   This program is distributed in the hope that it will be useful,
14 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
15 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 *   GNU General Public License for more details.
17 *
18 *   You should have received a copy of the GNU General Public License
19 *   along with this program; if not, write to the Free Software
20 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
21 *
22 *   Author:
23 *      Fabian 'x3n' Landau
24 *   Co-authors:
25 *      ...
26 *
27 */
28
29/**
30    @file
31    @ingroup Command ConsoleCommand
32    @brief Declaration of the orxonox::ConsoleCommand class.
33*/
34
35#ifndef _ConsoleCommand_H__
36#define _ConsoleCommand_H__
37
38#include "core/CorePrereqs.h"
39
40#include <stack>
41#include <vector>
42
43#include "ArgumentCompletionFunctions.h"
44#include "Executor.h"
45
46namespace orxonox
47{
48    /**
49        @brief A small collection of functions that can be used in DeclareConsoleCommand() if
50        you don't want to use the real function-pointer.
51    */
52    namespace prototype
53    {
54        inline void void__void(void) {}
55        inline void void__string(const std::string&) {}
56
57        inline std::string string__bool(bool) { return ""; }
58        inline std::string string__string(const std::string&) { return ""; }
59        inline std::string string__uint_uint_bool(unsigned int, unsigned int, bool) { return ""; }
60    }
61
62    /**
63        @brief Possible access levels: A command can only be executed if the program is in the state which is requested by the access level.
64    */
65    enum class AccessLevel
66    {
67        All,
68        Standalone,
69        Master,
70        Server,
71        Client,
72        Online,
73        Offline,
74        None
75    };
76
77    /**
78        @brief The ConsoleCommand class stores all information about a console command which can be executed by CommandExecutor.
79
80        Console commands can be entered by the user into the shell, called in scripts, or
81        used for key-bindings. They are simple text strings that can be executed by
82        CommandExecutor. CommandExecutor will search for a ConsoleCommand with the given
83        group and name and will execute it's Executor (which again calls the Functor and
84        this finally calls the command-function).
85
86        @see See @ref ConsoleCommandExample "ConsoleCommand.h" for more information and some examples.
87    */
88    class _CoreExport ConsoleCommand
89    {
90        friend struct ConsoleCommandManipulator;
91
92        /**
93            @brief Helper class that is used to put the current state of the ConsoleCommand on a stack.
94        */
95        struct Command
96        {
97            ExecutorPtr executor_;              ///< The executor
98            FunctorPtr functor_;                ///< The function that is used with the executor - has to be stored separatley because the executor is often used with different functors
99            std::vector<void*> objectStack_;    ///< The object stack
100        };
101
102        public:
103            /**
104             * @brief Defines the name of a command, consisting of an optional group ("" means no group) and the name itself.
105             */
106            struct CommandName
107            {
108                CommandName(const std::string& group, const std::string& name) : group_(group), name_(name) {}
109                std::string group_;
110                std::string name_;
111            };
112
113            /**
114                @brief Helper class that is used to manipulate console commands.
115
116                An instance of this class is returned if you call the ModifyConsoleCommand macro.
117                This class provides an interface which wraps some functions of ConsoleCommand. It
118                allows access to some private functions like setFunction() (that can't be called
119                right after SetConsoleCommand()) but it also hides some functions that shouln't be
120                called after the static declaration like addShortcut() or description().
121
122                @see See @ref ConsoleCommandExample "ConsoleCommand.h" for more information and examples.
123            */
124            struct ConsoleCommandManipulator
125            {
126                public:
127                    /// Constructor: Creates a manipulator for a given ConsoleCommand.
128                    ConsoleCommandManipulator(ConsoleCommand* command) : command_(command) {}
129
130                    /// 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
131                    template <class F>
132                    inline ConsoleCommandManipulator& setFunction(F function, bool bForce = false)
133                        {
134                            if (this->command_)
135                            {
136                                // check if the headers match. If they do, only change the function-pointer of the current Functor instead of creating a new Functor
137                                if (this->command_->getExecutor() && this->command_->getExecutor()->getFunctor() && this->command_->getExecutor()->getFunctor()->getFullIdentifier() == typeid(F))
138                                {
139                                    FunctorPointer<F>* functor = static_cast<FunctorPointer<F>*>(this->command_->getExecutor()->getFunctor().get());
140                                    functor->setFunction(function);
141                                    return *this;
142                                }
143                                this->command_->setFunction(createFunctor(function), bForce);
144                            }
145                            return *this;
146                        }
147                    /// 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
148                    template <class F, class O>
149                    inline ConsoleCommandManipulator& setFunction(F function, O* object, bool bForce = false)
150                        {
151                            if (this->command_)
152                            {
153                                // check if the headers match. If they do, only change the function-pointer of the current Functor instead of creating a new Functor
154                                if (this->command_->getExecutor() && this->command_->getExecutor()->getFunctor() && this->command_->getExecutor()->getFunctor()->getFullIdentifier() == typeid(F))
155                                {
156                                    FunctorPointer<F, O>* functor = static_cast<FunctorPointer<F, O>*>(this->command_->getExecutor()->getFunctor().get());
157                                    functor->setFunction(function);
158                                    functor->setObject(object);
159                                    return *this;
160                                }
161                                this->command_->setFunction(createFunctor(function, object), bForce);
162                            }
163                            return *this;
164                        }
165                    /// 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
166                    inline ConsoleCommandManipulator& setFunction(const FunctorPtr& functor, bool bForce = false)
167                        { if (this->command_) { this->command_->setFunction(functor, bForce); } return *this; }
168                    /// 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
169                    inline ConsoleCommandManipulator& setFunction(const ExecutorPtr& executor, bool bForce = false)
170                        { if (this->command_) { this->command_->setFunction(executor, bForce); } return *this; }
171
172                    /// 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.
173                    inline ConsoleCommandManipulator& pushFunction()
174                        { if (this->command_) { this->command_->pushFunction(); } return *this; }
175                    /// 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
176                    template <class F>
177                    inline ConsoleCommandManipulator& pushFunction(F function, bool bForce = false)
178                        { if (this->command_) { this->command_->pushFunction(createFunctor(function), bForce); } return *this; }
179                    /// 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
180                    template <class F, class O>
181                    inline ConsoleCommandManipulator& pushFunction(F function, O* object, bool bForce = false)
182                        { if (this->command_) { this->command_->pushFunction(createFunctor(function, object), bForce); } return *this; }
183                    /// 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
184                    inline ConsoleCommandManipulator& pushFunction(const FunctorPtr& functor, bool bForce = false)
185                        { if (this->command_) { this->command_->pushFunction(functor, bForce); } return *this; }
186                    /// 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
187                    inline ConsoleCommandManipulator& pushFunction(const ExecutorPtr& executor, bool bForce = false)
188                        { if (this->command_) { this->command_->pushFunction(executor, bForce); } return *this; }
189
190                    /// 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.
191                    inline ConsoleCommandManipulator& popFunction()
192                        { if (this->command_) { this->command_->popFunction(); } return *this; }
193
194                    /// Sets the current function-pointer to nullptr, which also deactivates the command.
195                    inline ConsoleCommandManipulator& resetFunction()
196                        { if (this->command_) { this->command_->resetFunction(); } return *this; }
197
198                    /// Changes the current object (used for member-functions).
199                    inline ConsoleCommandManipulator& setObject(void* object)
200                        { if (this->command_) { this->command_->setObject(object); } return *this; }
201                    /// Pushes a new object on the object-stack.
202                    inline ConsoleCommandManipulator& pushObject(void* object)
203                        { if (this->command_) { this->command_->pushObject(object); } return *this; }
204                    /// Removes the current object from the object-stack and restores the old object (or nullptr if there's no object left on the stack).
205                    inline ConsoleCommandManipulator& popObject()
206                        { if (this->command_) { this->command_->popObject(); } return *this; }
207
208                    /// Changes the activity of the command.
209                    inline ConsoleCommandManipulator& setActive(bool bActive)
210                        { if (this->command_) { this->command_->setActive(bActive); } return *this; }
211                    /// Activates the command.
212                    inline ConsoleCommandManipulator& activate()
213                        { return this->setActive(true); }
214                    /// Deactivates the command.
215                    inline ConsoleCommandManipulator& deactivate()
216                        { return this->setActive(false); }
217
218                    /// Changes the visibility of the command.
219                    inline ConsoleCommandManipulator& setHidden(bool bHidden)
220                        { if (this->command_) { this->command_->setHidden(bHidden); } return *this; }
221                    /// Hides the command (can still be executed, but is not visible in the list of available commands).
222                    inline ConsoleCommandManipulator& hide()
223                        { return this->setHidden(true); }
224                    /// Makes the command visible.
225                    inline ConsoleCommandManipulator& show()
226                        { return this->setHidden(false); }
227
228                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
229                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1)
230                        { if (this->command_) { this->command_->defaultValues(arg1); } return *this; }
231                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
232                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1, const MultiType& arg2)
233                        { if (this->command_) { this->command_->defaultValues(arg1, arg2); } return *this; }
234                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
235                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3)
236                        { if (this->command_) { this->command_->defaultValues(arg1, arg2, arg3); } return *this; }
237                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
238                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4)
239                        { if (this->command_) { this->command_->defaultValues(arg1, arg2, arg3, arg4); } return *this; }
240                    /// Changes the default values of the current executor (doesn't modify executors on deeper levels of the command-stack).
241                    inline ConsoleCommandManipulator& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5)
242                        { if (this->command_) { this->command_->defaultValues(arg1, arg2, arg3, arg4, arg5); } return *this; }
243                    /// 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).
244                    inline ConsoleCommandManipulator& defaultValue(unsigned int index, const MultiType& arg)
245                        { if (this->command_) { this->command_->defaultValue(index, arg); } return *this; }
246
247                    /// Changes the access level of the command.
248                    inline ConsoleCommandManipulator& accessLevel(AccessLevel level)
249                        { if (this->command_) { this->command_->accessLevel(level); } return *this; }
250
251                    /// Changes the argument completer for the given parameter.
252                    inline ConsoleCommandManipulator& argumentCompleter(unsigned int index, ArgumentCompleter* completer)
253                        { if (this->command_) { this->command_->argumentCompleter(index, completer); } return *this; }
254
255                    /// Defines the command to be an input command.
256                    inline ConsoleCommandManipulator& setAsInputCommand()
257                        { if (this->command_) { this->command_->setAsInputCommand(); } return *this; }
258                    /// Changes the keybind mode of the command.
259                    inline ConsoleCommandManipulator& keybindMode(KeybindMode::Value mode)
260                        { if (this->command_) { this->command_->changeKeybindMode(mode); } return *this; }
261                    /// Sets the input configured param to the given index.
262                    inline ConsoleCommandManipulator& inputConfiguredParam(int index)
263                        { if (this->command_) { this->command_->inputConfiguredParam(index); } return *this; }
264
265                private:
266                    ConsoleCommand* command_;   ///< The command which is being manipulated by this object
267            };
268
269        public:
270            ConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized = true);
271            ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true);
272            ~ConsoleCommand();
273
274            ConsoleCommand& addShortcut();
275            ConsoleCommand& addShortcut(const std::string&  name);
276            ConsoleCommand& addGroup(const std::string& group);
277            ConsoleCommand& addGroup(const std::string& group, const std::string&  name);
278
279            /// Returns the name that was first used for this command.
280            inline const std::string& getName() const
281                { return this->baseName_; }
282
283            const ExecutorPtr& getExecutor() const;
284            /// Returns the functor that defines the required header for this command (but isn't necessarily executed).
285            inline const FunctorPtr& getBaseFunctor() const
286                { return this->baseFunctor_; }
287
288            /// Changes the activity of the command.
289            inline ConsoleCommand& setActive(bool bActive)
290                { this->bActive_ = bActive; return *this; }
291            /// Activates the command.
292            inline ConsoleCommand& activate()
293                { return this->setActive(true); }
294            /// Deactivates the command.
295            inline ConsoleCommand& deactivate()
296                { return this->setActive(false); }
297
298            /// Changes the visibility of the command.
299            inline ConsoleCommand& setHidden(bool bHidden)
300                { this->bHidden_ = bHidden; return *this; }
301            /// Hides the command (can still be executed, but is not visible in the list of available commands).
302            inline ConsoleCommand& hide()
303                { return this->setHidden(true); }
304            /// Makes the command visible.
305            inline ConsoleCommand& show()
306                { return this->setHidden(false); }
307
308            bool isActive() const;
309            bool hasAccess() const;
310            /// Returns true if the command is currently hidden.
311            inline bool isHidden() const
312                { return this->bHidden_; }
313
314            ConsoleCommand& description(const std::string& description);
315            const std::string& getDescription() const;
316
317            ConsoleCommand& descriptionParam(unsigned int index, const std::string& description);
318            const std::string& getDescriptionParam(unsigned int index) const;
319
320            ConsoleCommand& descriptionReturnvalue(const std::string& description);
321            const std::string& getDescriptionReturnvalue(int index) const;
322
323            ConsoleCommand& defaultValues(const MultiType& arg1);
324            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2);
325            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3);
326            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4);
327            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5);
328            ConsoleCommand& defaultValue(unsigned int index, const MultiType& arg);
329
330            /// Changes the access level of the command.
331            inline ConsoleCommand& accessLevel(AccessLevel level)
332                { this->accessLevel_ = level; return *this; }
333            /// Returns the access level of the command.
334            inline AccessLevel getAccessLevel() const
335                { return this->accessLevel_; }
336
337            ConsoleCommand& argumentCompleter(unsigned int index, ArgumentCompleter* completer);
338            ArgumentCompleter* getArgumentCompleter(unsigned int index) const;
339
340            /// Defines the command to be an input command
341            inline ConsoleCommand& setAsInputCommand()
342            {
343                this->keybindMode(KeybindMode::OnHold);
344                this->defaultValue(0, Vector2(0.0f, 0.0f));
345                this->inputConfiguredParam(0);
346                return *this;
347            }
348
349            /// Sets the keybind mode. Note: use changeKeybindMode if you intend to change the mode.
350            inline ConsoleCommand& keybindMode(KeybindMode::Value mode)
351                { this->keybindMode_ = mode; return *this; }
352            /// Returns the keybind mode
353            inline KeybindMode::Value getKeybindMode() const
354                { return this->keybindMode_; }
355
356            ConsoleCommand& changeKeybindMode(KeybindMode::Value mode);
357
358            /// Changes the input configured param to the given index.
359            inline ConsoleCommand& inputConfiguredParam(int index)
360                { this->inputConfiguredParam_ = index; return *this; }
361            /// Returns the input configured param.
362            inline int getInputConfiguredParam() const
363                { return this->inputConfiguredParam_; }
364
365            /// Returns a manipulator for this command.
366            inline ConsoleCommandManipulator getManipulator()
367                { return this; }
368
369            inline const std::vector<CommandName>& getNames()
370                { return this->names_; }
371
372        private:
373            void init(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized);
374
375            bool headersMatch(const FunctorPtr& functor);
376            bool headersMatch(const ExecutorPtr& executor);
377
378            bool setFunction(const ExecutorPtr& executor, bool bForce = false);
379            bool setFunction(const FunctorPtr& functor, bool bForce = false);
380            void pushFunction(const ExecutorPtr& executor, bool bForce = false);
381            void pushFunction(const FunctorPtr& functor, bool bForce = false);
382            void pushFunction();
383            void popFunction();
384            void resetFunction();
385
386            bool setObject(void* object);
387            void pushObject(void* object);
388            void popObject();
389            void* getObject() const;
390
391            bool bActive_;                                                  ///< True if the command should be active (it can still be inactive, for example if the function is missing)
392            bool bHidden_;                                                  ///< True if the command is hidden (it is still executable, but not visible in the list of available commands)
393            AccessLevel accessLevel_;                                       ///< The access level (the state of the game in which you can access the command)
394            std::string baseName_;                                          ///< The name that was first assigned to the command
395            std::vector<CommandName> names_;                                ///< All names and aliases of this command
396            FunctorPtr baseFunctor_;                                        ///< The functor that defines the header of the command-function
397
398            ExecutorPtr executor_;                                          ///< The Executor that is used to execute the command
399            std::stack<Command> commandStack_;                              ///< A stack of commands, used to push and pop different functions
400            std::vector<void*> objectStack_;                                ///< A stack of objects, used to push and pop different objects for a function
401
402            ArgumentCompleter* argumentCompleter_[MAX_FUNCTOR_ARGUMENTS];   ///< ArgumentCompleter for each argument
403
404            KeybindMode::Value keybindMode_;                                ///< The keybind mode
405            int inputConfiguredParam_;                                      ///< The input configured param
406
407            LanguageEntryLabel description_;                                ///< The description of the command
408            LanguageEntryLabel descriptionReturnvalue_;                     ///< A description of the return-value
409            LanguageEntryLabel descriptionParam_[MAX_FUNCTOR_ARGUMENTS];    ///< A description for each argument
410    };
411}
412
413#endif /* _ConsoleCommand_H__ */
Note: See TracBrowser for help on using the repository browser.