Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core7/src/libraries/core/command/ConsoleCommand.h @ 10347

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

moved console command macros to a new file (ConsoleCommandIncludes.h)

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