Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7201 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
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 "CommandEvaluation.h"
30
31#include "util/Debug.h"
32#include "util/StringUtils.h"
33#include "ConsoleCommand.h"
34#include "Identifier.h"
35
36namespace orxonox
37{
38    CommandEvaluation::CommandEvaluation()
39    {
40        this->initialize("");
41        this->state_ = CommandState::Uninitialized;
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
52        this->additionalParameter_.clear();
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;
62        this->possibleArgument_.clear();
63        this->argument_.clear();
64
65        this->errorMessage_.clear();
66        this->state_ = CommandState::Empty;
67    }
68
69    bool CommandEvaluation::isValid() const
70    {
71        return (this->function_);
72    }
73
74    bool CommandEvaluation::execute() const
75    {
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
86        if (!this->isValid())
87            return MT_Type::Null;
88
89        if (this->bEvaluatedParams_ && this->function_)
90        {
91            if (success)
92                *success = true;
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;
94            return (*this->function_)(this->param_[0], this->param_[1], this->param_[2], this->param_[3], this->param_[4]);
95        }
96
97        if (!this->bCommandChanged_ || nocaseCmp(removeTrailingWhitespaces(this->command_), removeTrailingWhitespaces(this->originalCommand_)) == 0)
98        {
99            COUT(4) << "CE_execute: " << this->command_ << "\n";
100
101            unsigned int startindex = this->getStartindex();
102            if (this->commandTokens_.size() > startindex)
103                return this->function_->parse(removeSlashes(this->commandTokens_.subSet(startindex).join() + this->getAdditionalParameter()), success);
104            else
105                return this->function_->parse(removeSlashes(this->additionalParameter_), success);
106        }
107
108        return MT_Type::Null;
109    }
110
111    const std::string& CommandEvaluation::complete()
112    {
113        if (!this->bNewCommand_)
114        {
115            switch (this->state_)
116            {
117                case CommandState::Uninitialized:
118                    break;
119                case CommandState::Empty:
120                    break;
121                case CommandState::ShortcutOrIdentifier:
122                    if (this->function_)
123                    {
124                        if (this->function_->getParamCount() == 0)
125                            return (this->command_ = this->function_->getName());
126                        else
127                            return (this->command_ = this->function_->getName() + ' ');
128                    }
129                    else if (this->functionclass_)
130                        return (this->command_ = this->functionclass_->getName() + ' ');
131                    break;
132                case CommandState::Function:
133                    if (this->function_)
134                    {
135                        if (this->function_->getParamCount() == 0)
136                            return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName());
137                        else
138                            return (this->command_ = this->functionclass_->getName() + ' ' + this->function_->getName() + ' ');
139                    }
140                    break;
141                case CommandState::ParamPreparation:
142                case CommandState::Params:
143                {
144                    if (this->argument_.empty() && this->possibleArgument_.empty())
145                        break;
146
147                    unsigned int maxIndex = this->commandTokens_.size();
148                    if (this->command_[this->command_.size() - 1] != ' ')
149                        maxIndex -= 1;
150                    std::string whitespace;
151
152                    if (!this->possibleArgument_.empty())
153                    {
154                        this->argument_ = this->possibleArgument_;
155                        if (this->function_->getParamCount() > (maxIndex + 1 - this->getStartindex()))
156                            whitespace = " ";
157                    }
158
159                    return (this->command_ = this->commandTokens_.subSet(0, maxIndex).join() + ' ' + this->argument_ + whitespace);
160                    break;
161                }
162                case CommandState::Finished:
163                    break;
164                case CommandState::Error:
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        {
176            case CommandState::Uninitialized:
177                break;
178            case CommandState::Empty:
179            case CommandState::ShortcutOrIdentifier:
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;
187            case CommandState::Function:
188                return CommandEvaluation::dump(this->listOfPossibleFunctions_);
189                break;
190            case CommandState::ParamPreparation:
191            case CommandState::Params:
192                if (this->listOfPossibleArguments_.size() > 0)
193                    return CommandEvaluation::dump(this->listOfPossibleArguments_);
194                else
195                    return CommandEvaluation::dump(this->function_);
196            case CommandState::Finished:
197                if (this->function_)
198                    return CommandEvaluation::dump(this->function_);
199                break;
200            case CommandState::Error:
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++)
213            this->param_[i] = MT_Type::Null;
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
232    void CommandEvaluation::setEvaluatedParameter(unsigned int index, MultiType param)
233    {
234        if (index < MAX_FUNCTOR_ARGUMENTS)
235            this->param_[index] = param;
236    }
237
238    MultiType CommandEvaluation::getEvaluatedParameter(unsigned int index) const
239    {
240        if (index < MAX_FUNCTOR_ARGUMENTS)
241            return this->param_[index];
242
243        return MT_Type::Null;
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    {
258        std::string output;
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())
262                output += ' ';
263
264            output += *(it->second);
265        }
266        return output;
267    }
268
269    std::string CommandEvaluation::dump(const ArgumentCompletionList& list)
270    {
271        std::string output;
272        for (ArgumentCompletionList::const_iterator it = list.begin(); it != list.end(); ++it)
273        {
274            if (it != list.begin())
275                output += ' ';
276
277            output += it->getDisplay();
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)
291                output += ' ';
292
293            if (command->defaultValueSet(i))
294                output += '[';
295            else
296                output += '{';
297
298            output += command->getTypenameParam(i);
299
300            if (command->defaultValueSet(i))
301                output += '=' + command->getDefaultValue(i).getString() + ']';
302            else
303                output += '}';
304        }
305        return output;
306    }
307}
Note: See TracBrowser for help on using the repository browser.