Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

removed unnecessary helper functions

  • Property svn:eol-style set to native
File size: 24.3 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& name, const ExecutorPtr& executor, bool bInitialized = true);
264            ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true);
265            ~ConsoleCommand();
266
267            ConsoleCommand& addShortcut();
268            ConsoleCommand& addShortcut(const std::string&  name);
269            ConsoleCommand& addGroup(const std::string& group);
270            ConsoleCommand& addGroup(const std::string& group, const std::string&  name);
271
272            /// Returns the name that was first used for this command.
273            inline const std::string& getName() const
274                { return this->baseName_; }
275
276            const ExecutorPtr& getExecutor() const;
277            /// Returns the functor that defines the required header for this command (but isn't necessarily executed).
278            inline const FunctorPtr& getBaseFunctor() const
279                { return this->baseFunctor_; }
280
281            /// Changes the activity of the command.
282            inline ConsoleCommand& setActive(bool bActive)
283                { this->bActive_ = bActive; return *this; }
284            /// Activates the command.
285            inline ConsoleCommand& activate()
286                { return this->setActive(true); }
287            /// Deactivates the command.
288            inline ConsoleCommand& deactivate()
289                { return this->setActive(false); }
290
291            /// Changes the visibility of the command.
292            inline ConsoleCommand& setHidden(bool bHidden)
293                { this->bHidden_ = bHidden; return *this; }
294            /// Hides the command (can still be executed, but is not visible in the list of available commands).
295            inline ConsoleCommand& hide()
296                { return this->setHidden(true); }
297            /// Makes the command visible.
298            inline ConsoleCommand& show()
299                { return this->setHidden(false); }
300
301            bool isActive() const;
302            bool hasAccess() const;
303            /// Returns true if the command is currently hidden.
304            inline bool isHidden() const
305                { return this->bHidden_; }
306
307            ConsoleCommand& description(const std::string& description);
308            const std::string& getDescription() const;
309
310            ConsoleCommand& descriptionParam(unsigned int index, const std::string& description);
311            const std::string& getDescriptionParam(unsigned int index) const;
312
313            ConsoleCommand& descriptionReturnvalue(const std::string& description);
314            const std::string& getDescriptionReturnvalue(int index) const;
315
316            ConsoleCommand& defaultValues(const MultiType& arg1);
317            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2);
318            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3);
319            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4);
320            ConsoleCommand& defaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5);
321            ConsoleCommand& defaultValue(unsigned int index, const MultiType& arg);
322
323            /// Changes the access level of the command.
324            inline ConsoleCommand& accessLevel(AccessLevel::Enum level)
325                { this->accessLevel_ = level; return *this; }
326            /// Returns the access level of the command.
327            inline AccessLevel::Enum getAccessLevel() const
328                { return this->accessLevel_; }
329
330            ConsoleCommand& argumentCompleter(unsigned int index, ArgumentCompleter* completer);
331            ArgumentCompleter* getArgumentCompleter(unsigned int index) const;
332
333            /// Defines the command to be an input command
334            inline ConsoleCommand& setAsInputCommand()
335            {
336                this->keybindMode(KeybindMode::OnHold);
337                this->defaultValue(0, Vector2(0.0f, 0.0f));
338                this->inputConfiguredParam(0);
339                return *this;
340            }
341
342            /// Sets the keybind mode. Note: use changeKeybindMode if you intend to change the mode.
343            inline ConsoleCommand& keybindMode(KeybindMode::Value mode)
344                { this->keybindMode_ = mode; return *this; }
345            /// Returns the keybind mode
346            inline KeybindMode::Value getKeybindMode() const
347                { return this->keybindMode_; }
348
349            ConsoleCommand& changeKeybindMode(KeybindMode::Value mode);
350
351            /// Changes the input configured param to the given index.
352            inline ConsoleCommand& inputConfiguredParam(int index)
353                { this->inputConfiguredParam_ = index; return *this; }
354            /// Returns the input configured param.
355            inline int getInputConfiguredParam() const
356                { return this->inputConfiguredParam_; }
357
358            /// Returns a manipulator for this command.
359            inline ConsoleCommandManipulator getManipulator()
360                { return this; }
361
362        private:
363            void init(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized);
364
365            bool headersMatch(const FunctorPtr& functor);
366            bool headersMatch(const ExecutorPtr& executor);
367
368            bool setFunction(const ExecutorPtr& executor, bool bForce = false);
369            bool setFunction(const FunctorPtr& functor, bool bForce = false);
370            void pushFunction(const ExecutorPtr& executor, bool bForce = false);
371            void pushFunction(const FunctorPtr& functor, bool bForce = false);
372            void pushFunction();
373            void popFunction();
374            void resetFunction();
375
376            bool setObject(void* object);
377            void pushObject(void* object);
378            void popObject();
379            void* getObject() const;
380
381            bool bActive_;                                                  ///< True if the command should be active (it can still be inactive, for example if the function is missing)
382            bool bHidden_;                                                  ///< True if the command is hidden (it is still executable, but not visible in the list of available commands)
383            AccessLevel::Enum accessLevel_;                                 ///< The access level (the state of the game in which you can access the command)
384            std::string baseName_;                                          ///< The name that was first assigned to the command
385            FunctorPtr baseFunctor_;                                        ///< The functor that defines the header of the command-function
386
387            ExecutorPtr executor_;                                          ///< The Executor that is used to execute the command
388            std::stack<Command> commandStack_;                              ///< A stack of commands, used to push and pop different functions
389            std::vector<void*> objectStack_;                                ///< A stack of objects, used to push and pop different objects for a function
390
391            ArgumentCompleter* argumentCompleter_[MAX_FUNCTOR_ARGUMENTS];   ///< ArgumentCompleter for each argument
392
393            KeybindMode::Value keybindMode_;                                ///< The keybind mode
394            int inputConfiguredParam_;                                      ///< The input configured param
395
396            LanguageEntryLabel description_;                                ///< The description of the command
397            LanguageEntryLabel descriptionReturnvalue_;                     ///< A description of the return-value
398            LanguageEntryLabel descriptionParam_[MAX_FUNCTOR_ARGUMENTS];    ///< A description for each argument
399    };
400}
401
402#endif /* _ConsoleCommand_H__ */
Note: See TracBrowser for help on using the repository browser.