Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/Executor.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: 8.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 *   Inspiration: Executor by Benjamin Grauer
28 */
29
30#include "Executor.h"
31
32#include <algorithm>
33
34#include "util/Convert.h"
35#include "util/Debug.h"
36#include "util/StringUtils.h"
37#include "util/SubString.h"
38
39namespace orxonox
40{
41    Executor::Executor(Functor* functor, const std::string& name)
42    {
43        this->functor_ = functor;
44        this->name_ = name;
45    }
46
47    Executor::~Executor()
48    {
49        delete this->functor_;
50    }
51
52    MultiType Executor::parse(const std::string& params, bool* success, const std::string& delimiter) const
53    {
54        if (success)
55            *success = true;
56
57        unsigned int paramCount = this->functor_->getParamCount();
58
59        if (paramCount == 0)
60        {
61            COUT(5) << "Calling Executor " << this->name_ << " through parser without parameters." << std::endl;
62            return (*this->functor_)();
63        }
64        else if (paramCount == 1)
65        {
66            const std::string& temp = getStripped(params);
67            if (!temp.empty())
68            {
69                COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using whole string: " << params << std::endl;
70                return (*this->functor_)(MultiType(params));
71            }
72            else if (!this->defaultValue_[0].null())
73            {
74                COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using default value: " << this->defaultValue_[0] << std::endl;
75                return (*this->functor_)(this->defaultValue_[0]);
76            }
77            else
78            {
79                COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << temp << ")." << std::endl;
80                if (success)
81                    *success = false;
82                return MT_Type::Null;
83            }
84        }
85        else
86        {
87            SubString tokens(params, delimiter, SubString::WhiteSpaces, false, '\\', true, '"', true, '(', ')', true, '\0');
88
89            for (unsigned int i = tokens.size(); i < this->functor_->getParamCount(); i++)
90            {
91                if (this->defaultValue_[i].null())
92                {
93                    COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input:" << params << ")." << std::endl;
94                    if (success)
95                        *success = false;
96                    return MT_Type::Null;
97                }
98            }
99
100            MultiType param[MAX_FUNCTOR_ARGUMENTS];
101            COUT(5) << "Calling Executor " << this->name_ << " through parser with " << paramCount << " parameters, using " << tokens.size() << " tokens (";
102            for (unsigned int i = 0; i < tokens.size() && i < MAX_FUNCTOR_ARGUMENTS; i++)
103            {
104                param[i] = tokens[i];
105                if (i != 0)
106                {
107                    COUT(5) << ", ";
108                }
109                COUT(5) << tokens[i];
110            }
111            COUT(5) << ") and " << std::max((int)paramCount - (int)tokens.size(), 0) << " default values (";
112            for (unsigned int i = tokens.size(); i < paramCount; i++)
113            {
114                param[i] = this->defaultValue_[i];
115                if (i != 0)
116                {
117                    COUT(5) << ", ";
118                }
119                COUT(5) << this->defaultValue_[i];
120            }
121            COUT(5) << ")." << std::endl;
122
123            if ((tokens.size() > paramCount) && (this->functor_->getTypenameParam(paramCount - 1) == "string"))
124                param[paramCount - 1] = tokens.subSet(paramCount - 1).join();
125
126            switch(paramCount)
127            {
128                case 2:
129                    return (*this->functor_)(param[0], param[1]);
130                case 3:
131                    return (*this->functor_)(param[0], param[1], param[2]);
132                case 4:
133                    return (*this->functor_)(param[0], param[1], param[2], param[3]);
134                case 5:
135                    return (*this->functor_)(param[0], param[1], param[2], param[3], param[4]);
136            }
137        }
138
139        return MT_Type::Null;
140    }
141
142    bool Executor::evaluate(const std::string& params, MultiType param[5], const std::string& delimiter) const
143    {
144        unsigned int paramCount = this->functor_->getParamCount();
145
146        if (paramCount == 1)
147        {
148            // only one param: check if there are params given, otherwise try to use default values
149            if (!getStripped(params).empty())
150            {
151                param[0] = params;
152                this->functor_->evaluateParam(0, param[0]);
153                return true;
154            }
155            else if (!this->defaultValue_[0].null())
156            {
157                param[0] = this->defaultValue_[0];
158                this->functor_->evaluateParam(0, param[0]);
159                return true;
160            }
161            return false;
162        }
163        else
164        {
165            // more than one param
166            SubString tokens(params, delimiter, SubString::WhiteSpaces, false, '\\', true, '"', true, '(', ')', true, '\0');
167
168            // if there are not enough params given, check if there are default values
169            for (unsigned int i = tokens.size(); i < this->functor_->getParamCount(); i++)
170                if (this->defaultValue_[i].null())
171                    return false;
172
173            // assign all given arguments to the multitypes
174            for (unsigned int i = 0; i < std::min(tokens.size(), MAX_FUNCTOR_ARGUMENTS); i++)
175                param[i] = tokens[i];
176
177            // fill the remaining multitypes with default values
178            for (unsigned int i = tokens.size(); i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++)
179                param[i] = this->defaultValue_[i];
180
181            // evaluate the param types through the functor
182            for (unsigned int i = 0; i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++)
183                this->functor_->evaluateParam(i, param[i]);
184
185            return true;
186        }
187    }
188
189    Executor& Executor::setDefaultValues(const MultiType& param1)
190    {
191        this->defaultValue_[0] = param1;
192
193        return (*this);
194    }
195
196    Executor& Executor::setDefaultValues(const MultiType& param1, const MultiType& param2)
197    {
198        this->defaultValue_[0] = param1;
199        this->defaultValue_[1] = param2;
200
201        return (*this);
202    }
203
204    Executor& Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
205    {
206        this->defaultValue_[0] = param1;
207        this->defaultValue_[1] = param2;
208        this->defaultValue_[2] = param3;
209
210        return (*this);
211    }
212
213    Executor& Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
214    {
215        this->defaultValue_[0] = param1;
216        this->defaultValue_[1] = param2;
217        this->defaultValue_[2] = param3;
218        this->defaultValue_[3] = param4;
219
220        return (*this);
221    }
222
223    Executor& Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
224    {
225        this->defaultValue_[0] = param1;
226        this->defaultValue_[1] = param2;
227        this->defaultValue_[2] = param3;
228        this->defaultValue_[3] = param4;
229        this->defaultValue_[4] = param5;
230
231        return (*this);
232    }
233
234    Executor& Executor::setDefaultValue(unsigned int index, const MultiType& param)
235    {
236        if (index < MAX_FUNCTOR_ARGUMENTS)
237            this->defaultValue_[index] = param;
238
239        return (*this);
240    }
241
242    bool Executor::allDefaultValuesSet() const
243    {
244        for (unsigned int i = 0; i < this->functor_->getParamCount(); i++)
245            if (this->defaultValue_[i].null())
246                return false;
247
248        return true;
249    }
250}
Note: See TracBrowser for help on using the repository browser.