Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/CommandEvaluation.cc @ 7189

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

changed passing of the returnvalue in the command execution pipeline:

  • Functor: operator() directly returns the returnvalue of the executed function (if any, otherwise a MultiType whose null() function evaluates to true). The returnvalue is no longer stored in the Functor.
  • Executor: The same behavior of operator() like in Functor. Additionally the parse() function returns the returnvalue of the executed function instead of a boolean status. The status can be retrieved by passing a pointer to a bool to the function.
  • CommandExecutor: execute() works like before (returns only a boolean status), but added a new function query() which returns the returnvalue of the executed command. The status of query() can be retrieved by optionally passing an pointer to a bool.
  • CommandEvaluation: same as for CommandExecutor: execute() like before, added query()
  • TclBind::eval() returns the returnvalue of the evaluated tcl command. The status can also be retrieved by passing a pointer to a bool.
  • The Shell prints the returnvalue (if available) of an executed command
  • added a constructor to MultiType to directly create it from an mbool. The mbool will be converted to a bool, so it loses it's internal state.
  • Property svn:eol-style set to native
File size: 10.4 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#include "CommandEvaluation.h"
[3196]30
31#include "util/Debug.h"
[3280]32#include "util/StringUtils.h"
[1505]33#include "ConsoleCommand.h"
[1543]34#include "Identifier.h"
[1505]35
36namespace orxonox
37{
38    CommandEvaluation::CommandEvaluation()
39    {
40        this->initialize("");
[3280]41        this->state_ = CommandState::Uninitialized;
[1505]42    }
43
44    void CommandEvaluation::initialize(const std::string& command)
45    {
46        this->bNewCommand_ = true;
47        this->bCommandChanged_ = false;
48        this->originalCommand_ = command;
49        this->command_ = command;
50        this->commandTokens_.split(command, " ", SubString::WhiteSpaces, false, '\\', false, '"', false, '(', ')', false, '\0');
51
[6417]52        this->additionalParameter_.clear();
[1505]53
54        this->bEvaluatedParams_ = false;
55
56        this->listOfPossibleIdentifiers_.clear();
57        this->listOfPossibleFunctions_.clear();
58        this->listOfPossibleArguments_.clear();
59
60        this->functionclass_ = 0;
61        this->function_ = 0;
[6417]62        this->possibleArgument_.clear();
63        this->argument_.clear();
[1505]64
[6417]65        this->errorMessage_.clear();
[3280]66        this->state_ = CommandState::Empty;
[1505]67    }
68
69    bool CommandEvaluation::isValid() const
70    {
71        return (this->function_);
72    }
73
74    bool CommandEvaluation::execute() const
75    {
[7189]76        bool success;
77        this->query(&success);
78        return success;
79    }
80
81    MultiType CommandEvaluation::query(bool* success) const
82    {
83        if (success)
84            *success = false;
85
[1505]86        if (!this->isValid())
[7189]87            return MT_Type::Null;
[1505]88
89        if (this->bEvaluatedParams_ && this->function_)
90        {
[7189]91            if (success)
92                *success = true;
[6417]93            COUT(6) << "CE_execute (evaluation): " << this->function_->getName() << ' ' << this->param_[0] << ' ' << this->param_[1] << ' ' << this->param_[2] << ' ' << this->param_[3] << ' ' << this->param_[4] << std::endl;
[7189]94            return (*this->function_)(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]);
[1505]95        }
96
[3296]97        if (!this->bCommandChanged_ || nocaseCmp(removeTrailingWhitespaces(this->command_), removeTrailingWhitespaces(this->originalCommand_)) == 0)
[1505]98        {
99            COUT(4) << "CE_execute: " << this->command_ << "\n";
100
101            unsigned int startindex = this->getStartindex();
102            if (this->commandTokens_.size() > startindex)
[7189]103                return this->function_->parse(removeSlashes(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter()), success);
[1505]104            else
[7189]105                return this->function_->parse(removeSlashes(this->additionalParameter_), success);
[1505]106        }
107
[7189]108        return MT_Type::Null;
[1505]109    }
110
[6417]111    const std::string& CommandEvaluation::complete()
[1505]112    {
113        if (!this->bNewCommand_)
114        {
115            switch (this->state_)
116            {
[3280]117                case CommandState::Uninitialized:
[1505]118                    break;
[3280]119                case CommandState::Empty:
[1505]120                    break;
[3280]121                case CommandState::ShortcutOrIdentifier:
[1505]122                    if (this->function_)
123                    {
124                        if (this->function_->getParamCount() == 0)
125                            return (this->command_ = this->function_->getName());
126                        else
[6417]127                            return (this->command_ = this->function_->getName() + ' ');
[1505]128                    }
129                    else if (this->functionclass_)
[6417]130                        return (this->command_ = this->functionclass_->getName() + ' ');
[1505]131                    break;
[3280]132                case CommandState::Function:
[1505]133                    if (this->function_)
134                    {
135                        if (this->function_->getParamCount() == 0)
[6417]136                            return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName());
[1505]137                        else
[6417]138                            return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName() + ' ');
[1505]139                    }
140                    break;
[3280]141                case CommandState::ParamPreparation:
142                case CommandState::Params:
[1505]143                {
[6417]144                    if (this->argument_.empty() && this->possibleArgument_.empty())
[1505]145                        break;
146
147                    unsigned int maxIndex = this->commandTokens_.size();
148                    if (this->command_[this->command_.size() - 1] != ' ')
149                        maxIndex -= 1;
[6417]150                    std::string whitespace;
[1505]151
[6417]152                    if (!this->possibleArgument_.empty())
[1505]153                    {
154                        this->argument_ = this->possibleArgument_;
155                        if (this->function_->getParamCount() > (maxIndex + 1 - this->getStartindex()))
156                            whitespace = " ";
157                    }
158
[6417]159                    return (this->command_ = this->commandTokens_.subSet(0, maxIndex).join() + ' ' + this->argument_ + whitespace);
[1505]160                    break;
161                }
[3280]162                case CommandState::Finished:
[1505]163                    break;
[3280]164                case CommandState::Error:
[1505]165                    break;
166            }
167        }
168        this->bNewCommand_ = false;
169        return this->command_;
170    }
171
172    std::string CommandEvaluation::hint() const
173    {
174        switch (this->state_)
175        {
[3280]176            case CommandState::Uninitialized:
[1505]177                break;
[3280]178            case CommandState::Empty:
179            case CommandState::ShortcutOrIdentifier:
[1505]180                if (this->listOfPossibleFunctions_.size() == 0)
181                    return CommandEvaluation::dump(this->listOfPossibleIdentifiers_);
182                else if (this->listOfPossibleIdentifiers_.size() == 0)
183                    return CommandEvaluation::dump(this->listOfPossibleFunctions_);
184                else
185                    return (CommandEvaluation::dump(this->listOfPossibleFunctions_) + "\n" + CommandEvaluation::dump(this->listOfPossibleIdentifiers_));
186                break;
[3280]187            case CommandState::Function:
[1505]188                return CommandEvaluation::dump(this->listOfPossibleFunctions_);
189                break;
[3280]190            case CommandState::ParamPreparation:
191            case CommandState::Params:
[1505]192                if (this->listOfPossibleArguments_.size() > 0)
193                    return CommandEvaluation::dump(this->listOfPossibleArguments_);
194                else
195                    return CommandEvaluation::dump(this->function_);
[3280]196            case CommandState::Finished:
[1505]197                if (this->function_)
198                    return CommandEvaluation::dump(this->function_);
199                break;
[3280]200            case CommandState::Error:
[1505]201                return this->errorMessage_;
202                break;
203        }
204
205        return "";
206    }
207
208    void CommandEvaluation::evaluateParams()
209    {
210        this->bEvaluatedParams_ = false;
211
212        for (unsigned int i = 0; i < MAX_FUNCTOR_ARGUMENTS; i++)
[3280]213            this->param_[i] = MT_Type::Null;
[1505]214
215        if (!this->isValid())
216            return;
217
218        unsigned int startindex = this->getStartindex();
219
220        if (this->commandTokens_.size() <= startindex)
221        {
222            if (this->function_->evaluate(this->getAdditionalParameter(), this->param_, " "))
223                this->bEvaluatedParams_ = true;
224        }
225        else if (this->commandTokens_.size() > startindex)
226        {
227            if (this->function_->evaluate(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter(), this->param_, " "))
228                this->bEvaluatedParams_ = true;
229        }
230    }
231
[1747]232    void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiType param)
[1505]233    {
[1879]234        if (index < MAX_FUNCTOR_ARGUMENTS)
[1505]235            this->param_[index] = param;
236    }
237
[1747]238    MultiType CommandEvaluation::getEvaluatedParameter(unsigned int index) const
[1505]239    {
[1879]240        if (index < MAX_FUNCTOR_ARGUMENTS)
[1505]241            return this->param_[index];
242
[3280]243        return MT_Type::Null;
[1505]244    }
245
246    unsigned int CommandEvaluation::getStartindex() const
247    {
248        if (this->functionclass_ && this->function_)
249            return 2;
250        else if (this->function_)
251            return 1;
252        else
253            return 0;
254    }
255
256    std::string CommandEvaluation::dump(const std::list<std::pair<const std::string*, const std::string*> >& list)
257    {
[6417]258        std::string output;
[1505]259        for (std::list<std::pair<const std::string*, const std::string*> >::const_iterator it = list.begin(); it != list.end(); ++it)
260        {
261            if (it != list.begin())
[6417]262                output += ' ';
[1505]263
[6417]264            output += *(it->second);
[1505]265        }
266        return output;
267    }
268
269    std::string CommandEvaluation::dump(const ArgumentCompletionList& list)
270    {
[6417]271        std::string output;
[1505]272        for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
273        {
274            if (it != list.begin())
[6417]275                output += ' ';
[1505]276
[6417]277            output += it->getDisplay();
[1505]278        }
279        return output;
280    }
281
282    std::string CommandEvaluation::dump(const ConsoleCommand* command)
283    {
284        std::string output = command->getName();
285        if (command->getParamCount() > 0)
286            output += ": ";
287
288        for (unsigned int i = 0; i < command->getParamCount(); i++)
289        {
290            if (i != 0)
[6417]291                output += ' ';
[1505]292
293            if (command->defaultValueSet(i))
[6417]294                output += '[';
[1505]295            else
[6417]296                output += '{';
[1505]297
298            output += command->getTypenameParam(i);
299
300            if (command->defaultValueSet(i))
[6417]301                output += '=' + command->getDefaultValue(i).getString() + ']';
[1505]302            else
[6417]303                output += '}';
[1505]304        }
305        return output;
306    }
307}
Note: See TracBrowser for help on using the repository browser.