Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/consolecommands3/src/libraries/core/command/Executor.cc @ 7276

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

until now we could group words and values in console commands and XML values using parentheses (…). now we have to use braces {…}, because that works better in connection with Tcl. in practice however this feature was never used before, so this change shouldn't affect anything.

  • Property svn:eol-style set to native
File size: 6.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 *   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#include "CommandExecutor.h"
39
40namespace orxonox
41{
42    Executor::Executor(const FunctorPtr& functor, const std::string& name)
43    {
44        this->functor_ = functor;
45        this->name_ = name;
46    }
47
48    Executor::Executor(const Executor& other) : name_(other.name_)
49    {
50        for (int i = 0; i < MAX_FUNCTOR_ARGUMENTS; ++i)
51            defaultValue_[i] = other.defaultValue_[i];
52        this->functor_ = other.functor_->clone();
53    }
54
55    Executor::~Executor()
56    {
57    }
58
59    MultiType Executor::parse(const std::string& arguments, int* error, const std::string& delimiter, bool bPrintError) const
60    {
61        return this->parse(SubString(arguments, delimiter, SubString::WhiteSpaces, false, '\\', true, '"', true, '{', '}', true, '\0'), error, delimiter, bPrintError);
62    }
63
64    MultiType Executor::parse(const SubString& arguments, int* error, const std::string& delimiter, bool bPrintError) const
65    {
66        MultiType param[MAX_FUNCTOR_ARGUMENTS];
67        unsigned int paramCount = this->evaluateParams(arguments, param, error, delimiter);
68
69        if (error && *error)
70        {
71            if (bPrintError)
72                COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << arguments.join() << ")." << std::endl;
73            return MT_Type::Null;
74        }
75
76        COUT(5) << "Executor::parse: \"" << arguments.join(delimiter) << "\" -> " << paramCount << " params: " << param[0] << " / " << param[1] << " / " << param[2] << " / " << param[3] << " / " << param[4] << std::endl;
77
78        switch (paramCount)
79        {
80            case 0:  return (*this->functor_)();
81            case 1:  return (*this->functor_)(param[0]);
82            case 2:  return (*this->functor_)(param[0], param[1]);
83            case 3:  return (*this->functor_)(param[0], param[1], param[2]);
84            case 4:  return (*this->functor_)(param[0], param[1], param[2], param[3]);
85            case 5:
86            default: return (*this->functor_)(param[0], param[1], param[2], param[3], param[4]);
87        }
88    }
89
90    int Executor::evaluateParams(const SubString& arguments, MultiType param[MAX_FUNCTOR_ARGUMENTS], int* error, const std::string& delimiter) const
91    {
92        unsigned int paramCount = this->functor_->getParamCount();
93        unsigned int argumentCount = arguments.size();
94
95        // if there are not enough params given, check if there are default values
96        for (unsigned int i = argumentCount; i < paramCount; i++)
97        {
98            if (this->defaultValue_[i].null())
99            {
100                if (error)
101                    *error = CommandExecutor::Incomplete;
102                return 0;
103            }
104        }
105
106        // assign all given arguments to the multitypes
107        for (unsigned int i = 0; i < std::min(std::min(argumentCount, paramCount), MAX_FUNCTOR_ARGUMENTS); i++)
108            param[i] = arguments[i];
109
110        // fill the remaining multitypes with default values
111        for (unsigned int i = argumentCount; i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++)
112            param[i] = this->defaultValue_[i];
113
114        // assign the remaining arguments all to the last parameter if it is a string
115        if ((paramCount <= MAX_FUNCTOR_ARGUMENTS) &&(argumentCount > paramCount) && (paramCount == 1 || this->functor_->getTypenameParam(paramCount - 1) == "string"))
116            param[paramCount - 1] = arguments.subSet(paramCount - 1).join(delimiter);
117
118        // evaluate the param types through the functor
119        for (unsigned int i = 0; i < std::min(paramCount, MAX_FUNCTOR_ARGUMENTS); i++)
120            this->functor_->evaluateParam(i, param[i]);
121
122        if (error)
123            *error = CommandExecutor::Success;
124        return paramCount;
125    }
126
127    void Executor::setDefaultValues(const MultiType& param1)
128    {
129        this->defaultValue_[0] = param1;
130    }
131
132    void Executor::setDefaultValues(const MultiType& param1, const MultiType& param2)
133    {
134        this->defaultValue_[0] = param1;
135        this->defaultValue_[1] = param2;
136    }
137
138    void Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3)
139    {
140        this->defaultValue_[0] = param1;
141        this->defaultValue_[1] = param2;
142        this->defaultValue_[2] = param3;
143    }
144
145    void Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4)
146    {
147        this->defaultValue_[0] = param1;
148        this->defaultValue_[1] = param2;
149        this->defaultValue_[2] = param3;
150        this->defaultValue_[3] = param4;
151    }
152
153    void Executor::setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5)
154    {
155        this->defaultValue_[0] = param1;
156        this->defaultValue_[1] = param2;
157        this->defaultValue_[2] = param3;
158        this->defaultValue_[3] = param4;
159        this->defaultValue_[4] = param5;
160    }
161
162    void Executor::setDefaultValue(unsigned int index, const MultiType& param)
163    {
164        if (index < MAX_FUNCTOR_ARGUMENTS)
165            this->defaultValue_[index] = param;
166    }
167
168    bool Executor::allDefaultValuesSet() const
169    {
170        for (unsigned int i = 0; i < this->functor_->getParamCount(); i++)
171            if (this->defaultValue_[i].null())
172                return false;
173
174        return true;
175    }
176}
Note: See TracBrowser for help on using the repository browser.