Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/ConsoleCommand.cc @ 7186

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

Moved ability to possess descriptions from Executor to ConsoleCommand, since no other executors use this feature. Also simplified this code a little by introducing a new shortcut in Language.h. XMLPort has to use a temporary solution for descriptions without Language support atm.

  • Property svn:eol-style set to native
File size: 9.7 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#include "ConsoleCommand.h"
30#include <cassert>
31
32#include "Language.h"
33
34namespace orxonox
35{
36    ConsoleCommand::ConsoleCommand(Functor* functor, const std::string& name) : Executor(functor, name)
37    {
38        this->accessLevel_ = AccessLevel::None;
39        this->argumentCompleter_[0] = 0;
40        this->argumentCompleter_[1] = 0;
41        this->argumentCompleter_[2] = 0;
42        this->argumentCompleter_[3] = 0;
43        this->argumentCompleter_[4] = 0;
44
45        this->keybindMode_ = KeybindMode::OnPress;
46        this->inputConfiguredParam_ = -1;
47    }
48
49    ConsoleCommand& ConsoleCommand::argumentCompleter(unsigned int param, ArgumentCompleter* completer)
50    {
51        if (param < 5)
52            this->argumentCompleter_[param] = completer;
53        else
54        {
55            COUT(2) << "Warning: Couldn't add autocompletion-function for param " << param << ": index out of bound." << std::endl;
56        }
57        return (*this);
58    }
59
60    ArgumentCompleter* ConsoleCommand::getArgumentCompleter(unsigned int param) const
61    {
62        if (param < 5)
63            return this->argumentCompleter_[param];
64        else
65            return 0;
66    }
67
68    void ConsoleCommand::createArgumentCompletionList(unsigned int param, const std::string& param1, const std::string& param2, const std::string& param3, const std::string& param4, const std::string& param5)
69    {
70        if (param < 5 && this->argumentCompleter_[param])
71            this->argumentList_ = (*this->argumentCompleter_[param])(param1, param2, param3, param4, param5);
72        else
73            this->argumentList_.clear();
74    }
75
76    ConsoleCommand& ConsoleCommand::description(const std::string& description)
77    {
78        this->description_ = std::string("ConsoleCommandDescription::" + this->name_ + "::function");
79        AddLanguageEntry(this->description_, description);
80        return (*this);
81    }
82
83    const std::string& ConsoleCommand::getDescription() const
84    {
85        return GetLocalisation_noerror(this->description_);
86    }
87
88    ConsoleCommand& ConsoleCommand::descriptionParam(unsigned int param, const std::string& description)
89    {
90        if (param < MAX_FUNCTOR_ARGUMENTS)
91        {
92            this->descriptionParam_[param] = std::string("ConsoleCommandDescription::" + this->name_ + "::param" + multi_cast<std::string>(param));
93            AddLanguageEntry(this->descriptionParam_[param], description);
94        }
95        return (*this);
96    }
97
98    const std::string& ConsoleCommand::getDescriptionParam(unsigned int param) const
99    {
100        if (param < MAX_FUNCTOR_ARGUMENTS)
101            return GetLocalisation_noerror(this->descriptionParam_[param]);
102
103        return this->descriptionParam_[0];
104    }
105
106    ConsoleCommand& ConsoleCommand::descriptionReturnvalue(const std::string& description)
107    {
108        this->descriptionReturnvalue_ = std::string("ConsoleCommandDescription::" + this->name_ + "::returnvalue");
109        AddLanguageEntry(this->descriptionReturnvalue_, description);
110        return (*this);
111    }
112
113    const std::string& ConsoleCommand::getDescriptionReturnvalue(int param) const
114    {
115        return GetLocalisation_noerror(this->descriptionReturnvalue_);
116    }
117}
118
119#include "BaseObject.h" // remove this
120
121namespace orxonox
122{
123    _SetConsoleCommand("BaseObject", "setName", &BaseObject::setName, (BaseObject*)0);
124    _ConsoleCommand::_ConsoleCommandManipulator test(_ModifyConsoleCommand("BaseObject", "setName").setFunction(&BaseObject::setActive));
125
126    _ConsoleCommand::_ConsoleCommand(const std::string& group, const std::string& name, Functor* functor, bool bInitialized) : Executor(functor, name), functionHeader_(functor->getHeaderIdentifier())
127    {
128        this->bActive_ = true;
129        this->bInitialized_ = bInitialized;
130        _ConsoleCommand::registerCommand(group, name, this);
131    }
132
133    _ConsoleCommand& _ConsoleCommand::addShortcut()
134    {
135        _ConsoleCommand::registerCommand("", this->getName(), this);
136        return *this;
137    }
138
139    _ConsoleCommand& _ConsoleCommand::addShortcut(const std::string&  name)
140    {
141        _ConsoleCommand::registerCommand("", name, this);
142        return *this;
143    }
144
145    _ConsoleCommand& _ConsoleCommand::addGroup(const std::string& group)
146    {
147        _ConsoleCommand::registerCommand(group, this->getName(), this);
148        return *this;
149    }
150
151    _ConsoleCommand& _ConsoleCommand::addGroup(const std::string& group, const std::string&  name)
152    {
153        _ConsoleCommand::registerCommand(group, name, this);
154        return *this;
155    }
156
157    bool _ConsoleCommand::setFunctor(Functor* functor, bool bForce)
158    {
159        if (!functor)
160        {
161            this->bInitialized_ = false;
162            return true;
163        }
164
165        if (!bForce && !this->functionHeaderMatches(functor))
166        {
167            COUT(1) << "Error: Couldn't assign new function to console command with name \"" << this->getName() << "\", headers don't match." << std::endl;
168            return false;
169        }
170
171        this->functor_ = functor;
172        this->bInitialized_ = true;
173        return true;
174    }
175
176    void _ConsoleCommand::pushFunctor(Functor* functor, bool bForce)
177    {
178        Functor* oldfunctor = this->getFunctor();
179
180        if (this->setFunctor(functor, bForce));
181            this->functorStack_.push(oldfunctor);
182    }
183
184    void _ConsoleCommand::popFunctor()
185    {
186        Functor* newfunctor = 0;
187        if (!this->functorStack_.empty())
188        {
189            newfunctor = this->functorStack_.top();
190            this->functorStack_.pop();
191        }
192        this->setFunctor(newfunctor);
193    }
194
195    Functor* _ConsoleCommand::getFunctor() const
196    {
197        if (this->bInitialized_)
198            return this->functor_;
199        else
200            return 0;
201    }
202
203    bool _ConsoleCommand::functionHeaderMatches(Functor* functor) const
204    {
205        if (!this->functor_)
206        {
207            assert(false);
208            return true;
209        }
210        return (functor->getHeaderIdentifier() == this->functionHeader_);
211    }
212
213    void _ConsoleCommand::setObject(void* object)
214    {
215        if (this->functor_)
216            this->functor_->setRawObjectPointer(object);
217        else if (object)
218            COUT(0) << "Error: Can't set object in console command \"" << this->getName() << "\", no functor set." << std::endl;
219    }
220
221    void _ConsoleCommand::pushObject(void* object)
222    {
223        if (this->functor_)
224        {
225            this->objectStack_.push(this->getObject());
226            this->setObject(object);
227        }
228        else
229            COUT(0) << "Error: Can't set object in console command \"" << this->getName() << "\", no functor set." << std::endl;
230    }
231
232    void _ConsoleCommand::popObject()
233    {
234        void* newobject = 0;
235        if (!this->objectStack_.empty())
236        {
237            newobject = this->objectStack_.top();
238            this->objectStack_.pop();
239        }
240        this->setObject(newobject);
241    }
242
243    void* _ConsoleCommand::getObject() const
244    {
245        if (this->functor_)
246            return this->functor_->getRawObjectPointer();
247        else
248            return 0;
249    }
250
251    /* static */ const _ConsoleCommand* _ConsoleCommand::getCommand(const std::string& group, const std::string& name, bool bPrintError)
252    {
253        std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommandMap().find(group);
254        if (it_group != _ConsoleCommand::getCommandMap().end())
255        {
256            std::map<std::string, _ConsoleCommand*>::const_iterator it_name = it_group->second.find(name);
257            if (it_name != it_group->second.end())
258            {
259                return it_name->second;
260            }
261        }
262        if (bPrintError)
263        {
264            if (group == "")
265                COUT(0) << "Error: Couldn't find console command with shortcut \"" << name << "\"" << std::endl;
266            else
267                COUT(0) << "Error: Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << std::endl;
268        }
269        return 0;
270    }
271
272    /* static */ std::map<std::string, std::map<std::string, _ConsoleCommand*> >& _ConsoleCommand::getCommandMap()
273    {
274        static std::map<std::string, std::map<std::string, _ConsoleCommand*> > commandMap;
275        return commandMap;
276    }
277
278    /* static */ void _ConsoleCommand::registerCommand(const std::string& group, const std::string& name, _ConsoleCommand* command)
279    {
280        if (name == "")
281            return;
282
283        if (_ConsoleCommand::getCommand(group, name) != 0)
284        {
285            if (group == "")
286                COUT(2) << "Warning: A console command with shortcut name \"" << name << "\" already exists." << std::endl;
287            else
288                COUT(2) << "Warning: A console command with group \"" << group << "\" and name \"" << name << "\" already exists." << std::endl;
289        }
290        else
291        {
292            _ConsoleCommand::getCommandMap()[group][name] = command;
293        }
294    }
295}
Note: See TracBrowser for help on using the repository browser.