Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/command/ConsoleCommand.h @ 7270

Last change on this file since 7270 was 7270, checked in by landauf, 14 years ago

pushFunction() (which explicitly adds a new level to the console command stack) was not forwarded to ConsoleCommandManipulator

also fixed a bug which was caused by pushFunction() with a subsequent call to setFunction(…) because it may have unexpectedly changed the functor of the lower stack levels. now pushFunction() not only copyconstructs the executor, but also the Functor (with a clone() function)

  • Property svn:eol-style set to native
File size: 18.7 KB
RevLine 
[1505]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#ifndef _ConsoleCommand_H__
30#define _ConsoleCommand_H__
31
[7203]32#include "core/CorePrereqs.h"
[1505]33
[7185]34#include <stack>
[3304]35#include <boost/preprocessor/cat.hpp>
[7179]36#include <boost/preprocessor/facilities/expand.hpp>
[3304]37
[7179]38#include "util/VA_NARGS.h"
[3196]39#include "ArgumentCompletionFunctions.h"
[1505]40#include "Executor.h"
41
42
[7236]43#define SetConsoleCommand(...) \
44    BOOST_PP_EXPAND(BOOST_PP_CAT(SetConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__))
45#define SetConsoleCommand2(name, functionpointer) \
46    SetConsoleCommandGeneric("", name, orxonox::createFunctor(functionpointer))
47#define SetConsoleCommand3(group, name, functionpointer) \
48    SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))
49#define SetConsoleCommand4(group, name, functionpointer, object) \
50    SetConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object))
[7179]51
[7236]52#define SetConsoleCommandGeneric(group, name, functor) \
53    static orxonox::ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::createConsoleCommand(group, name, orxonox::createExecutor(functor)))
[7179]54
55
[7236]56#define DeclareConsoleCommand(...) \
[7239]57    BOOST_PP_EXPAND(BOOST_PP_CAT(DeclareConsoleCommand, ORXONOX_VA_NARGS(__VA_ARGS__))(__VA_ARGS__))
[7236]58#define DeclareConsoleCommand2(name, functionpointer) \
59    DeclareConsoleCommandGeneric("", name, orxonox::createFunctor(functionpointer))
60#define DeclareConsoleCommand3(group, name, functionpointer) \
61    DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer))
62#define DeclareConsoleCommand4(group, name, functionpointer, object) \
63    DeclareConsoleCommandGeneric(group, name, orxonox::createFunctor(functionpointer, object))
[7179]64
[7236]65#define DeclareConsoleCommandGeneric(group, name, functor) \
66    static orxonox::ConsoleCommand& BOOST_PP_CAT(__consolecommand_, __LINE__) = (*orxonox::createConsoleCommand(group, name, orxonox::createExecutor(functor), false))
[7179]67
68
69namespace orxonox
70{
[7218]71    namespace prototype
72    {
73        inline void void__void(void) {}
74        inline void void__string(const std::string&) {}
75    }
76
77    namespace AccessLevel
78    {
79        enum Enum
80        {
81            All,
82            Standalone,
83            Master,
84            Server,
85            Client,
86            Online,
87            Offline,
88            None
89        };
90    }
91
[7236]92    class _CoreExport ConsoleCommand
[7179]93    {
[7236]94        friend struct ConsoleCommandManipulator;
[7179]95
[7214]96        struct Command
97        {
98            ExecutorPtr executor_;
99            FunctorPtr functor_;
100        };
101
[7179]102        public:
[7236]103            struct ConsoleCommandManipulator
[7179]104            {
105                public:
[7236]106                    ConsoleCommandManipulator(const ConsoleCommand* command) : command_(const_cast<ConsoleCommand*>(command)) {}
[7179]107
108                    template <class F>
[7236]109                    inline ConsoleCommandManipulator& setFunction(F function, bool bForce = false)
[7214]110                        {
111                            if (this->command_)
112                            {
[7215]113                                if (this->command_->getExecutor() && this->command_->getExecutor()->getFunctor() && this->command_->getExecutor()->getFunctor()->getFullIdentifier() == typeid(F))
[7214]114                                {
[7215]115                                    FunctorPointer<F>* functor = static_cast<FunctorPointer<F>*>(this->command_->getExecutor()->getFunctor().get());
[7214]116                                    functor->setFunction(function);
117                                    return *this;
118                                }
119                                this->command_->setFunction(createFunctor(function), bForce);
120                            }
121                            return *this;
122                        }
[7179]123                    template <class F, class O>
[7236]124                    inline ConsoleCommandManipulator& setFunction(F function, O* object, bool bForce = false)
[7214]125                        {
126                            if (this->command_)
127                            {
[7215]128                                if (this->command_->getExecutor() && this->command_->getExecutor()->getFunctor() && this->command_->getExecutor()->getFunctor()->getFullIdentifier() == typeid(F))
[7214]129                                {
[7215]130                                    FunctorPointer<F, O>* functor = static_cast<FunctorPointer<F, O>*>(this->command_->getExecutor()->getFunctor().get());
[7214]131                                    functor->setFunction(function);
132                                    functor->setObject(object);
133                                    return *this;
134                                }
135                                this->command_->setFunction(createFunctor(function, object), bForce);
136                            }
137                            return *this;
138                        }
[7236]139                    inline ConsoleCommandManipulator& setFunction(const FunctorPtr& functor, bool bForce = false)
[7214]140                        { if (this->command_) { this->command_->setFunction(functor, bForce); } return *this; }
[7236]141                    inline ConsoleCommandManipulator& setFunction(const ExecutorPtr& executor, bool bForce = false)
[7214]142                        { if (this->command_) { this->command_->setFunction(executor, bForce); } return *this; }
[7179]143
[7270]144                    inline ConsoleCommandManipulator& pushFunction()
145                        { if (this->command_) { this->command_->pushFunction(); } return *this; }
[7179]146                    template <class F>
[7236]147                    inline ConsoleCommandManipulator& pushFunction(F function, bool bForce = false)
[7214]148                        { if (this->command_) { this->command_->pushFunction(createFunctor(function), bForce); } return *this; }
[7179]149                    template <class F, class O>
[7236]150                    inline ConsoleCommandManipulator& pushFunction(F function, O* object, bool bForce = false)
[7214]151                        { if (this->command_) { this->command_->pushFunction(createFunctor(function, object), bForce); } return *this; }
[7236]152                    inline ConsoleCommandManipulator& pushFunction(const FunctorPtr& functor, bool bForce = false)
[7214]153                        { if (this->command_) { this->command_->pushFunction(functor, bForce); } return *this; }
[7236]154                    inline ConsoleCommandManipulator& pushFunction(const ExecutorPtr& executor, bool bForce = false)
[7214]155                        { if (this->command_) { this->command_->pushFunction(executor, bForce); } return *this; }
[7179]156
[7236]157                    inline ConsoleCommandManipulator& popFunction()
[7214]158                        { if (this->command_) { this->command_->popFunction(); } return *this; }
[7179]159
[7236]160                    inline ConsoleCommandManipulator& resetFunction()
[7218]161                        { if (this->command_) { this->command_->resetFunction(); } return *this; }
162
[7236]163                    inline ConsoleCommandManipulator& setObject(void* object)
[7179]164                        { if (this->command_) { this->command_->setObject(object); } return *this; }
[7236]165                    inline ConsoleCommandManipulator& pushObject(void* object)
[7185]166                        { if (this->command_) { this->command_->pushObject(object); } return *this; }
[7236]167                    inline ConsoleCommandManipulator& popObject()
[7185]168                        { if (this->command_) { this->command_->popObject(); } return *this; }
[7179]169
[7236]170                    inline ConsoleCommandManipulator& setActive(bool bActive)
[7179]171                        { if (this->command_) { this->command_->setActive(bActive); } return *this; }
[7236]172                    inline ConsoleCommandManipulator& activate()
[7214]173                        { return this->setActive(true); }
[7236]174                    inline ConsoleCommandManipulator& deactivate()
[7214]175                        { return this->setActive(false); }
[7179]176
[7236]177                    inline ConsoleCommandManipulator& setHidden(bool bHidden)
[7215]178                        { if (this->command_) { this->command_->setHidden(bHidden); } return *this; }
[7236]179                    inline ConsoleCommandManipulator& hide()
[7215]180                        { return this->setHidden(true); }
[7236]181                    inline ConsoleCommandManipulator& show()
[7215]182                        { return this->setHidden(false); }
[7214]183
[7236]184                    inline ConsoleCommandManipulator& defaultValues(const MultiType& param1)
[7215]185                        { if (this->command_) { this->command_->defaultValues(param1); } return *this; }
[7236]186                    inline ConsoleCommandManipulator& defaultValues(const MultiType& param1, const MultiType& param2)
[7215]187                        { if (this->command_) { this->command_->defaultValues(param1, param2); } return *this; }
[7236]188                    inline ConsoleCommandManipulator& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
[7215]189                        { if (this->command_) { this->command_->defaultValues(param1, param2, param3); } return *this; }
[7236]190                    inline ConsoleCommandManipulator& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
[7215]191                        { if (this->command_) { this->command_->defaultValues(param1, param2, param3, param4); } return *this; }
[7236]192                    inline ConsoleCommandManipulator& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
[7215]193                        { if (this->command_) { this->command_->defaultValues(param1, param2, param3, param4, param5); } return *this; }
[7236]194                    inline ConsoleCommandManipulator& defaultValue(unsigned int index, const MultiType& param)
[7215]195                        { if (this->command_) { this->command_->defaultValue(index, param); } return *this; }
196
[7236]197                    inline ConsoleCommandManipulator& accessLevel(AccessLevel::Enum level)
[7215]198                        { if (this->command_) { this->command_->accessLevel(level); } return *this; }
199
[7236]200                    inline ConsoleCommandManipulator& argumentCompleter(unsigned int param, ArgumentCompleter* completer)
[7215]201                        { if (this->command_) { this->command_->argumentCompleter(param, completer); } return *this; }
202
[7236]203                    inline ConsoleCommandManipulator& setAsInputCommand()
[7215]204                        { if (this->command_) { this->command_->setAsInputCommand(); } return *this; }
[7236]205                    inline ConsoleCommandManipulator& keybindMode(KeybindMode::Value mode)
[7215]206                        { if (this->command_) { this->command_->keybindMode(mode); } return *this; }
[7236]207                    inline ConsoleCommandManipulator& inputConfiguredParam(int index)
[7215]208                        { if (this->command_) { this->command_->inputConfiguredParam(index); } return *this; }
209
[7179]210                private:
[7236]211                    ConsoleCommand* command_;
[7179]212            };
213
214        public:
[7236]215            ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true);
216            ~ConsoleCommand();
[7179]217
[7236]218            ConsoleCommand& addShortcut();
219            ConsoleCommand& addShortcut(const std::string&  name);
220            ConsoleCommand& addGroup(const std::string& group);
221            ConsoleCommand& addGroup(const std::string& group, const std::string&  name);
[7179]222
[7218]223            inline const std::string& getName() const
224                { return this->baseName_; }
225
226            const ExecutorPtr& getExecutor() const;
[7267]227            inline const FunctorPtr& getBaseFunctor() const
228                { return this->baseFunctor_; }
[7218]229
[7236]230            inline ConsoleCommand& setActive(bool bActive)
[7215]231                { this->bActive_ = bActive; return *this; }
[7236]232            inline ConsoleCommand& activate()
[7215]233                { return this->setActive(true); }
[7236]234            inline ConsoleCommand& deactivate()
[7215]235                { return this->setActive(false); }
236
[7236]237            inline ConsoleCommand& setHidden(bool bHidden)
[7215]238                { this->bHidden_ = bHidden; return *this; }
[7236]239            inline ConsoleCommand& hide()
[7215]240                { return this->setHidden(true); }
[7236]241            inline ConsoleCommand& show()
[7215]242                { return this->setHidden(false); }
243
[7214]244            bool isActive() const;
[7215]245            bool hasAccess() const;
[7222]246            inline bool isHidden() const
247                { return this->bHidden_; }
[7179]248
[7236]249            ConsoleCommand& description(const std::string& description);
[7215]250            const std::string& getDescription() const;
251
[7236]252            ConsoleCommand& descriptionParam(unsigned int param, const std::string& description);
[7215]253            const std::string& getDescriptionParam(unsigned int param) const;
254
[7236]255            ConsoleCommand& descriptionReturnvalue(const std::string& description);
[7215]256            const std::string& getDescriptionReturnvalue(int param) const;
257
[7236]258            ConsoleCommand& defaultValues(const MultiType& param1);
259            ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2);
260            ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3);
261            ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4);
262            ConsoleCommand& defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5);
263            ConsoleCommand& defaultValue(unsigned int index, const MultiType& param);
[7215]264
[7236]265            inline ConsoleCommand& accessLevel(AccessLevel::Enum level)
[7215]266                { this->accessLevel_ = level; return *this; }
267            inline AccessLevel::Enum getAccessLevel() const
268                { return this->accessLevel_; }
269
[7236]270            ConsoleCommand& argumentCompleter(unsigned int param, ArgumentCompleter* completer);
[7215]271            ArgumentCompleter* getArgumentCompleter(unsigned int param) const;
272
[7236]273            inline ConsoleCommand& setAsInputCommand()
[7215]274            {
275                this->keybindMode(KeybindMode::OnHold);
276                this->defaultValue(0, Vector2(0.0f, 0.0f));
277                this->inputConfiguredParam(0);
278                return *this;
279            }
280
[7236]281            inline ConsoleCommand& keybindMode(KeybindMode::Value mode)
[7215]282                { this->keybindMode_ = mode; return *this; }
283            inline KeybindMode::Value getKeybindMode() const
284                { return this->keybindMode_; }
285
[7236]286            inline ConsoleCommand& inputConfiguredParam(int index)
[7215]287                { this->inputConfiguredParam_ = index; return *this; }
288            inline int getInputConfiguredParam_() const
289                { return this->inputConfiguredParam_; }
290
[7236]291            inline ConsoleCommandManipulator getManipulator() const
[7185]292                { return this; }
293
[7179]294        private:
[7214]295            bool headersMatch(const FunctorPtr& functor);
296            bool headersMatch(const ExecutorPtr& executor);
297
298            bool setFunction(const ExecutorPtr& executor, bool bForce = false);
299            bool setFunction(const FunctorPtr& functor, bool bForce = false);
300            void pushFunction(const ExecutorPtr& executor, bool bForce = false);
301            void pushFunction(const FunctorPtr& functor, bool bForce = false);
302            void pushFunction();
303            void popFunction();
[7218]304            void resetFunction();
[7179]305
[7214]306            bool setObject(void* object);
[7185]307            void pushObject(void* object);
308            void popObject();
309            void* getObject() const;
[7179]310
[7185]311            bool bActive_;
[7215]312            bool bHidden_;
313            AccessLevel::Enum accessLevel_;
[7214]314            std::string baseName_;
[7267]315            FunctorPtr baseFunctor_;
[7214]316
317            ExecutorPtr executor_;
318            std::stack<Command> commandStack_;
[7185]319            std::stack<void*> objectStack_;
[7215]320
321            ArgumentCompleter* argumentCompleter_[5];
322
323            KeybindMode::Value keybindMode_;
324            int inputConfiguredParam_;
325
326            LanguageEntryLabel description_;
327            LanguageEntryLabel descriptionReturnvalue_;
328            LanguageEntryLabel descriptionParam_[MAX_FUNCTOR_ARGUMENTS];
329
330        public:
[7236]331            static inline const std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommands()
332                { return ConsoleCommand::getCommandMap(); }
333            static inline const std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommandsLC()
334                { return ConsoleCommand::getCommandMapLC(); }
[7215]335
[7236]336            static inline ConsoleCommand* getCommand(const std::string& name, bool bPrintError = false)
337                { return ConsoleCommand::getCommand("", name, bPrintError); }
338            static inline ConsoleCommand* getCommandLC(const std::string& name, bool bPrintError = false)
339                { return ConsoleCommand::getCommandLC("", name, bPrintError); }
[7215]340
[7236]341            static ConsoleCommand* getCommand(const std::string& group, const std::string& name, bool bPrintError = false);
342            static ConsoleCommand* getCommandLC(const std::string& group, const std::string& name, bool bPrintError = false);
[7228]343
[7216]344            static void destroyAll();
345
[7215]346        private:
[7236]347            static std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommandMap();
348            static std::map<std::string, std::map<std::string, ConsoleCommand*> >& getCommandMapLC();
[7228]349
[7236]350            static void registerCommand(const std::string& group, const std::string& name, ConsoleCommand* command);
351            static void unregisterCommand(ConsoleCommand* command);
[7179]352    };
353
[7236]354    inline ConsoleCommand* createConsoleCommand(const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)
355        { return new ConsoleCommand("", name, executor, bInitialized); }
356    inline ConsoleCommand* createConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized = true)
357        { return new ConsoleCommand(group, name, executor, bInitialized); }
[7179]358
[7236]359    inline ConsoleCommand::ConsoleCommandManipulator ModifyConsoleCommand(const std::string& name)
360        { return ConsoleCommand::getCommand(name, true); }
361    inline ConsoleCommand::ConsoleCommandManipulator ModifyConsoleCommand(const std::string& group, const std::string& name)
362        { return ConsoleCommand::getCommand(group, name, true); }
[7179]363}
364
[1505]365#endif /* _ConsoleCommand_H__ */
Note: See TracBrowser for help on using the repository browser.