Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

progress on the new console command interface.
enhanced possibilities to compare Functors and to manipulate Executors

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