Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

adapted CommandExecutor and CommandEvaluation to make it compile again, but it doesn't run yet. ready for refactoring.

  • Property svn:eol-style set to native
File size: 15.9 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
31#include "util/Convert.h"
32#include "core/Language.h"
33#include "core/BaseObject.h" // remove this
34
35namespace orxonox
36{
37    _SetConsoleCommand("BaseObject", "setName", &BaseObject::setName, (BaseObject*)0);
38    _ConsoleCommand::_ConsoleCommandManipulator test(_ModifyConsoleCommand("BaseObject", "setName").setFunction(&BaseObject::setActive));
39
40    _ConsoleCommand::_ConsoleCommand(const std::string& group, const std::string& name, const ExecutorPtr& executor, bool bInitialized)
41    {
42        this->bActive_ = true;
43        this->bHidden_ = false;
44        this->accessLevel_ = AccessLevel::All;
45
46        this->baseName_ = name;
47        this->baseExecutor_ = executor;
48
49        this->argumentCompleter_[0] = 0;
50        this->argumentCompleter_[1] = 0;
51        this->argumentCompleter_[2] = 0;
52        this->argumentCompleter_[3] = 0;
53        this->argumentCompleter_[4] = 0;
54
55        this->keybindMode_ = KeybindMode::OnPress;
56        this->inputConfiguredParam_ = -1;
57
58        if (bInitialized)
59            this->executor_ = executor;
60
61        _ConsoleCommand::registerCommand(group, name, this);
62    }
63
64    _ConsoleCommand::~_ConsoleCommand()
65    {
66        _ConsoleCommand::unregisterCommand(this);
67    }
68
69    _ConsoleCommand& _ConsoleCommand::addShortcut()
70    {
71        _ConsoleCommand::registerCommand("", this->baseName_, this);
72        return *this;
73    }
74
75    _ConsoleCommand& _ConsoleCommand::addShortcut(const std::string&  name)
76    {
77        _ConsoleCommand::registerCommand("", name, this);
78        return *this;
79    }
80
81    _ConsoleCommand& _ConsoleCommand::addGroup(const std::string& group)
82    {
83        _ConsoleCommand::registerCommand(group, this->baseName_, this);
84        return *this;
85    }
86
87    _ConsoleCommand& _ConsoleCommand::addGroup(const std::string& group, const std::string&  name)
88    {
89        _ConsoleCommand::registerCommand(group, name, this);
90        return *this;
91    }
92
93    bool _ConsoleCommand::isActive() const
94    {
95        return (this->bActive_ && this->executor_ && this->executor_->getFunctor() && (this->executor_->getFunctor()->getType() == Functor::Type::Static || this->executor_->getFunctor()->getRawObjectPointer()));
96    }
97
98    bool _ConsoleCommand::headersMatch(const FunctorPtr& functor)
99    {
100        unsigned int minparams = std::min(this->baseExecutor_->getParamCount(), functor->getParamCount());
101
102        if (this->baseExecutor_->getFunctor()->getHeaderIdentifier(minparams) != functor->getHeaderIdentifier(minparams))
103            return false;
104        else if (functor->getParamCount() <= this->baseExecutor_->getParamCount())
105            return true;
106        else if (!this->executor_)
107            return false;
108        else
109        {
110            for (unsigned int i = this->baseExecutor_->getParamCount(); i < functor->getParamCount(); ++i)
111                if (!this->executor_->defaultValueSet(i))
112                    return false;
113
114            return true;
115        }
116    }
117
118    bool _ConsoleCommand::headersMatch(const ExecutorPtr& executor)
119    {
120        unsigned int minparams = std::min(this->baseExecutor_->getParamCount(), executor->getParamCount());
121
122        if (this->baseExecutor_->getFunctor()->getHeaderIdentifier(minparams) != executor->getFunctor()->getHeaderIdentifier(minparams))
123            return false;
124        else if (executor->getParamCount() <= this->baseExecutor_->getParamCount())
125            return true;
126        else
127        {
128            for (unsigned int i = this->baseExecutor_->getParamCount(); i < executor->getParamCount(); ++i)
129                if (!executor->defaultValueSet(i))
130                    return false;
131
132            return true;
133        }
134    }
135
136    bool _ConsoleCommand::setFunction(const ExecutorPtr& executor, bool bForce)
137    {
138        if (!executor || !executor->getFunctor() || bForce || this->headersMatch(executor))
139        {
140            this->executor_ = executor;
141            return true;
142        }
143        else
144        {
145            COUT(1) << "Error: Couldn't assign new executor to console command \"" << this->baseName_ << "\", headers don't match." << std::endl;
146            return false;
147        }
148    }
149
150    bool _ConsoleCommand::setFunction(const FunctorPtr& functor, bool bForce)
151    {
152        if (!functor || bForce || this->headersMatch(functor))
153        {
154            if (this->executor_)
155                this->executor_->setFunctor(functor);
156            else if (functor)
157                this->executor_ = createExecutor(functor);
158
159            return true;
160        }
161        else
162        {
163            COUT(1) << "Error: Couldn't assign new functor to console command \"" << this->baseName_ << "\", headers don't match." << std::endl;
164            return false;
165        }
166    }
167
168    void _ConsoleCommand::pushFunction(const ExecutorPtr& executor, bool bForce)
169    {
170        Command command;
171        command.executor_ = this->getExecutor();
172        if (command.executor_)
173            command.functor_ = this->getExecutor()->getFunctor();
174
175        if (this->setFunction(executor, bForce))
176            this->commandStack_.push(command);
177    }
178
179    void _ConsoleCommand::pushFunction(const FunctorPtr& functor, bool bForce)
180    {
181        Command command;
182        command.executor_ = this->getExecutor();
183        if (command.executor_)
184            command.functor_ = this->getExecutor()->getFunctor();
185
186        if (this->setFunction(functor, bForce))
187            this->commandStack_.push(command);
188    }
189
190    void _ConsoleCommand::pushFunction()
191    {
192        if (this->executor_)
193            this->pushFunction(new Executor(*this->executor_.get()));
194        else
195            COUT(1) << "Error: Couldn't push copy of executor in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
196    }
197
198    void _ConsoleCommand::popFunction()
199    {
200        Command command;
201        if (!this->commandStack_.empty())
202        {
203            command = this->commandStack_.top();
204            this->commandStack_.pop();
205        }
206
207        this->executor_ = command.executor_;
208        if (command.executor_)
209            this->executor_->setFunctor(command.functor_);
210    }
211
212    void _ConsoleCommand::resetFunction()
213    {
214        if (this->executor_)
215            this->executor_->setFunctor(0);
216    }
217
218    const ExecutorPtr& _ConsoleCommand::getExecutor() const
219    {
220        return this->executor_;
221    }
222
223    bool _ConsoleCommand::setObject(void* object)
224    {
225        if (this->executor_)
226        {
227            if (this->executor_->getFunctor())
228            {
229                this->executor_->getFunctor()->setRawObjectPointer(object);
230                return true;
231            }
232            else if (object)
233                COUT(1) << "Error: Can't assign object to console command \"" << this->baseName_ << "\", no functor set." << std::endl;
234        }
235        else if (object)
236            COUT(1) << "Error: Can't assign object to console command \"" << this->baseName_ << "\", no executor set." << std::endl;
237
238        return false;
239    }
240
241    void _ConsoleCommand::pushObject(void* object)
242    {
243        void* oldobject = this->getObject();
244        if (this->setObject(object))
245            this->objectStack_.push(oldobject);
246    }
247
248    void _ConsoleCommand::popObject()
249    {
250        void* newobject = 0;
251        if (!this->objectStack_.empty())
252        {
253            newobject = this->objectStack_.top();
254            this->objectStack_.pop();
255        }
256        this->setObject(newobject);
257    }
258
259    void* _ConsoleCommand::getObject() const
260    {
261        if (this->executor_ && this->executor_->getFunctor())
262            return this->executor_->getFunctor()->getRawObjectPointer();
263        else
264            return 0;
265    }
266
267    _ConsoleCommand& _ConsoleCommand::defaultValues(const MultiType& param1)
268    {
269        if (this->executor_)
270            this->executor_->setDefaultValues(param1);
271        else
272            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
273
274        return *this;
275    }
276
277    _ConsoleCommand& _ConsoleCommand::defaultValues(const MultiType& param1, const MultiType& param2)
278    {
279        if (this->executor_)
280            this->executor_->setDefaultValues(param1, param2);
281        else
282            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
283
284        return *this;
285    }
286
287    _ConsoleCommand& _ConsoleCommand::defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
288    {
289        if (this->executor_)
290            this->executor_->setDefaultValues(param1, param2, param3);
291        else
292            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
293
294        return *this;
295    }
296
297    _ConsoleCommand& _ConsoleCommand::defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
298    {
299        if (this->executor_)
300            this->executor_->setDefaultValues(param1, param2, param3, param4);
301        else
302            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
303
304        return *this;
305    }
306
307    _ConsoleCommand& _ConsoleCommand::defaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
308    {
309        if (this->executor_)
310            this->executor_->setDefaultValues(param1, param2, param3, param4, param5);
311        else
312            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
313
314        return *this;
315    }
316
317    _ConsoleCommand& _ConsoleCommand::defaultValue(unsigned int index, const MultiType& param)
318    {
319        if (this->executor_)
320            this->executor_->setDefaultValue(index, param);
321        else
322            COUT(1) << "Error: Can't set default values in console command \"" << this->baseName_ << "\", no executor set." << std::endl;
323
324        return *this;
325    }
326
327    _ConsoleCommand& _ConsoleCommand::argumentCompleter(unsigned int param, ArgumentCompleter* completer)
328    {
329        if (param < 5)
330            this->argumentCompleter_[param] = completer;
331        else
332            COUT(2) << "Warning: Couldn't add autocompletion-function for param " << param << " in console command \"" << this->baseName_ << "\": index out of bound." << std::endl;
333
334        return *this;
335    }
336
337    ArgumentCompleter* _ConsoleCommand::getArgumentCompleter(unsigned int param) const
338    {
339        if (param < 5)
340            return this->argumentCompleter_[param];
341        else
342            return 0;
343    }
344
345    _ConsoleCommand& _ConsoleCommand::description(const std::string& description)
346    {
347        this->description_ = std::string("ConsoleCommandDescription::" + this->baseName_ + "::function");
348        AddLanguageEntry(this->description_, description);
349        return *this;
350    }
351
352    const std::string& _ConsoleCommand::getDescription() const
353    {
354        return GetLocalisation_noerror(this->description_);
355    }
356
357    _ConsoleCommand& _ConsoleCommand::descriptionParam(unsigned int param, const std::string& description)
358    {
359        if (param < MAX_FUNCTOR_ARGUMENTS)
360        {
361            this->descriptionParam_[param] = std::string("ConsoleCommandDescription::" + this->baseName_ + "::param" + multi_cast<std::string>(param));
362            AddLanguageEntry(this->descriptionParam_[param], description);
363        }
364        return *this;
365    }
366
367    const std::string& _ConsoleCommand::getDescriptionParam(unsigned int param) const
368    {
369        if (param < MAX_FUNCTOR_ARGUMENTS)
370            return GetLocalisation_noerror(this->descriptionParam_[param]);
371
372        return this->descriptionParam_[0];
373    }
374
375    _ConsoleCommand& _ConsoleCommand::descriptionReturnvalue(const std::string& description)
376    {
377        this->descriptionReturnvalue_ = std::string("ConsoleCommandDescription::" + this->baseName_ + "::returnvalue");
378        AddLanguageEntry(this->descriptionReturnvalue_, description);
379        return *this;
380    }
381
382    const std::string& _ConsoleCommand::getDescriptionReturnvalue(int param) const
383    {
384        return GetLocalisation_noerror(this->descriptionReturnvalue_);
385    }
386
387    /* static */ const _ConsoleCommand* _ConsoleCommand::getCommand(const std::string& group, const std::string& name, bool bPrintError)
388    {
389        std::map<std::string, std::map<std::string, _ConsoleCommand*> >::const_iterator it_group = _ConsoleCommand::getCommandMap().find(group);
390        if (it_group != _ConsoleCommand::getCommandMap().end())
391        {
392            std::map<std::string, _ConsoleCommand*>::const_iterator it_name = it_group->second.find(name);
393            if (it_name != it_group->second.end())
394            {
395                return it_name->second;
396            }
397        }
398        if (bPrintError)
399        {
400            if (group == "")
401                COUT(1) << "Error: Couldn't find console command with shortcut \"" << name << "\"" << std::endl;
402            else
403                COUT(1) << "Error: Couldn't find console command with group \"" << group << "\" and name \"" << name << "\"" << std::endl;
404        }
405        return 0;
406    }
407
408    /* static */ std::map<std::string, std::map<std::string, _ConsoleCommand*> >& _ConsoleCommand::getCommandMap()
409    {
410        static std::map<std::string, std::map<std::string, _ConsoleCommand*> > commandMap;
411        return commandMap;
412    }
413
414    /* static */ void _ConsoleCommand::registerCommand(const std::string& group, const std::string& name, _ConsoleCommand* command)
415    {
416        if (name == "")
417            return;
418
419        if (_ConsoleCommand::getCommand(group, name) != 0)
420        {
421            if (group == "")
422                COUT(2) << "Warning: A console command with shortcut \"" << name << "\" already exists." << std::endl;
423            else
424                COUT(2) << "Warning: A console command with name \"" << name << "\" already exists in group \"" << group << "\"." << std::endl;
425        }
426        else
427        {
428            _ConsoleCommand::getCommandMap()[group][name] = command;
429        }
430    }
431
432    /* static */ void _ConsoleCommand::unregisterCommand(_ConsoleCommand* command)
433    {
434        for (std::map<std::string, std::map<std::string, _ConsoleCommand*> >::iterator it_group = _ConsoleCommand::getCommandMap().begin(); it_group != _ConsoleCommand::getCommandMap().end(); )
435        {
436            for (std::map<std::string, _ConsoleCommand*>::iterator it_name = it_group->second.begin(); it_name != it_group->second.end(); )
437            {
438                if (it_name->second == command)
439                    it_group->second.erase(it_name++);
440                else
441                    ++it_name;
442            }
443
444            if (it_group->second.empty())
445                _ConsoleCommand::getCommandMap().erase(it_group++);
446            else
447                ++it_group;
448        }
449    }
450
451    /* static */ void _ConsoleCommand::destroyAll()
452    {
453        while (!_ConsoleCommand::getCommandMap().empty() && !_ConsoleCommand::getCommandMap().begin()->second.empty())
454            delete _ConsoleCommand::getCommandMap().begin()->second.begin()->second;
455    }
456}
Note: See TracBrowser for help on using the repository browser.