Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 10950 was 10624, checked in by landauf, 9 years ago

merged branch core7 back to trunk

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