Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/branches/core3/src/core/Executor.h @ 1725

Last change on this file since 1725 was 1716, checked in by landauf, 16 years ago

Added new 'MultiType', replacing MultiTypePrimitive, MultiTypeString and MultiTypeMath. MultiType can hold all types MultiTypeMath was able to hold, namely all primitives, pointers, string and several math objects (vector2, 3 and 4, quaternion, colourvalue, radian, degree).

The new MultiType has a completely changed behaviour, I'll explain this on a wiki page somewhen.
But to say the most important things in a few words:
The MultiType has a fixed type. This type is determined by the first assigned value (by using setValue(value), operator=(value) or MultiType(value)). Every other value getting assigned later, will be converted to the first type. But you can change the type (setType<T>()), convert the value (convert<T>()) or force the type of a newly assigned value manually (setValue<T>(value)) by using template functions.

In contrast, the old MultiTypeMath changed it's internal type whenever a new type was assigned. So be aware of this important change.

At the moment I can't see any issues, but there might very well be several problems yet to discover, so further tests will be done.

  • Property svn:eol-style set to native
File size: 14.8 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#ifndef _Executor_H__
31#define _Executor_H__
32
33#include "CorePrereqs.h"
34
35#include "util/SubString.h"
36#include "util/String.h"
37#include "util/Math.h"
38#include "Functor.h"
39#include "util/Debug.h"
40
41
42#define EXECUTOR_PARSE_FUNCTORCALL(mode) EXECUTOR_PARSE_FUNCTORCALL##mode
43#define EXECUTOR_PARSE_FUNCTORCALLnormal (*this->functor_)
44#define EXECUTOR_PARSE_FUNCTORCALLobject (*((FunctorMember<T>*)this->functor_))
45
46#define EXECUTOR_PARSE_OBJECT(mode, comma) EXECUTOR_PARSE_OBJECT##mode##comma
47#define EXECUTOR_PARSE_OBJECTnormal0
48#define EXECUTOR_PARSE_OBJECTnormal1
49#define EXECUTOR_PARSE_OBJECTobject0 object
50#define EXECUTOR_PARSE_OBJECTobject1 object,
51
52#define EXECUTOR_PARSE(mode) \
53    unsigned int paramCount = this->functor_->getParamCount(); \
54    \
55    if (paramCount == 0) \
56    { \
57        COUT(5) << "Calling Executor " << this->name_ << " through parser without parameters." << std::endl; \
58        EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 0)); \
59    } \
60    else if (paramCount == 1) \
61    { \
62        std::string temp = getStripped(params); \
63        if ((temp != "") && (temp.size() != 0)) \
64        { \
65            COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using whole string: " << params << std::endl; \
66            EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) MultiType(params)); \
67        } \
68        else if (this->bAddedDefaultValue_[0]) \
69        { \
70            COUT(5) << "Calling Executor " << this->name_ << " through parser with one parameter, using default value: " << this->defaultValue_[0] << std::endl; \
71            EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) this->defaultValue_[0]); \
72        } \
73        else \
74        { \
75            COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input: " << temp << ")." << std::endl; \
76            return false; \
77        } \
78    } \
79    else \
80    { \
81        SubString tokens(params, delimiter, SubString::WhiteSpaces, false, '\\', true, '"', true, '(', ')', true, '\0'); \
82        \
83        for (unsigned int i = tokens.size(); i < this->functor_->getParamCount(); i++) \
84        { \
85            if (!this->bAddedDefaultValue_[i]) \
86            { \
87                COUT(2) << "Warning: Can't call executor " << this->name_ << " through parser: Not enough parameters or default values given (input:" << params << ")." << std::endl; \
88                return false; \
89            } \
90        } \
91        \
92        MultiType param[MAX_FUNCTOR_ARGUMENTS]; \
93        COUT(5) << "Calling Executor " << this->name_ << " through parser with " << paramCount << " parameters, using " << tokens.size() << " tokens ("; \
94        for (unsigned int i = 0; i < tokens.size() && i < MAX_FUNCTOR_ARGUMENTS; i++) \
95        { \
96            param[i] = tokens[i]; \
97            if (i != 0) \
98            { \
99                COUT(5) << ", "; \
100            } \
101            COUT(5) << tokens[i]; \
102        } \
103        COUT(5) << ") and " << max((int)paramCount - (int)tokens.size(), 0) << " default values ("; \
104        for (unsigned int i = tokens.size(); i < paramCount; i++) \
105        { \
106            param[i] = this->defaultValue_[i]; \
107            if (i != 0) \
108            { \
109                COUT(5) << ", "; \
110            } \
111            COUT(5) << this->defaultValue_[i]; \
112        } \
113        COUT(5) << ")." << std::endl; \
114        \
115        if ((tokens.size() > paramCount) && (this->functor_->getTypenameParam(paramCount - 1) == "string")) \
116            param[paramCount - 1] = tokens.subSet(paramCount - 1).join(); \
117        \
118        switch(paramCount) \
119        { \
120            case 2: \
121                EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1]); \
122                break; \
123            case 3: \
124                EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2]); \
125                break; \
126            case 4: \
127                EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2], param[3]); \
128                break; \
129            case 5: \
130                EXECUTOR_PARSE_FUNCTORCALL(mode)(EXECUTOR_PARSE_OBJECT(mode, 1) param[0], param[1], param[2], param[3], param[4]); \
131                break; \
132        } \
133    } \
134    \
135    return true
136
137namespace orxonox
138{
139    class _CoreExport Executor
140    {
141        public:
142            Executor(Functor* functor, const std::string& name = "");
143            virtual ~Executor();
144
145            inline void operator()() const
146                { (*this->functor_)(this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
147            inline void operator()(const MultiType& param1) const
148                { (*this->functor_)(param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
149            inline void operator()(const MultiType& param1, const MultiType& param2) const
150                { (*this->functor_)(param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
151            inline void operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3) const
152                { (*this->functor_)(param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
153            inline void operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
154                { (*this->functor_)(param1, param2, param3, param4, this->defaultValue_[4]); }
155            inline void operator()(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
156                { (*this->functor_)(param1, param2, param3, param4, param5); }
157
158            bool parse(const std::string& params, const std::string& delimiter = " ") const;
159
160            bool evaluate(const std::string& params, MultiType param[5], const std::string& delimiter = " ") const;
161
162            Executor& setDescription(const std::string& description);
163            const std::string& getDescription() const;
164
165            Executor& setDescriptionParam(int param, const std::string& description);
166            const std::string& getDescriptionParam(int param) const;
167
168            Executor& setDescriptionReturnvalue(const std::string& description);
169            const std::string& getDescriptionReturnvalue(int param) const;
170
171            inline Functor* getFunctor() const
172                { return this->functor_; }
173            inline unsigned int getParamCount() const
174                { return this->functor_->getParamCount(); }
175            inline bool hasReturnvalue() const
176                { return this->functor_->hasReturnvalue(); }
177            inline FunctionType getType() const
178                { return this->functor_->getType(); }
179            inline MultiType getReturnvalue() const
180                { return this->functor_->getReturnvalue(); }
181            inline std::string getTypenameParam(unsigned int param) const
182                { return this->functor_->getTypenameParam(param); }
183            inline std::string getTypenameReturnvalue() const
184                { return this->functor_->getTypenameReturnvalue(); }
185
186            inline void setName(const std::string name)
187                { this->name_ = name; }
188            inline const std::string& getName() const
189                { return this->name_; }
190
191            Executor& setDefaultValues(const MultiType& param1);
192            Executor& setDefaultValues(const MultiType& param1, const MultiType& param2);
193            Executor& setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3);
194            Executor& setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4);
195            Executor& setDefaultValues(const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5);
196            Executor& setDefaultValue(unsigned int index, const MultiType& param);
197
198            inline MultiType getDefaultValue(unsigned int index) const
199            {
200                if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS)
201                    return this->defaultValue_[index];
202
203                return MT_null;
204            }
205
206            bool allDefaultValuesSet() const;
207            inline bool defaultValueSet(unsigned int index) const
208            {
209                if (index >= 0 && index < MAX_FUNCTOR_ARGUMENTS)
210                    return this->bAddedDefaultValue_[index];
211
212                return false;
213            }
214
215        protected:
216            Functor* functor_;
217            std::string name_;
218            MultiType defaultValue_[MAX_FUNCTOR_ARGUMENTS];
219            bool bAddedDefaultValue_[MAX_FUNCTOR_ARGUMENTS];
220
221        private:
222            LanguageEntryLabel description_;
223            LanguageEntryLabel descriptionReturnvalue_;
224            LanguageEntryLabel descriptionParam_[MAX_FUNCTOR_ARGUMENTS];
225
226            bool bAddedDescription_;
227            bool bAddedDescriptionReturnvalue_;
228            bool bAddedDescriptionParam_[MAX_FUNCTOR_ARGUMENTS];
229    };
230
231    class _CoreExport ExecutorStatic : public Executor
232    {
233        public:
234            ExecutorStatic(FunctorStatic* functor, const std::string& name = "") : Executor(functor, name) {}
235            virtual ~ExecutorStatic() {}
236    };
237
238    template <class T>
239    class ExecutorMember : public Executor
240    {
241        public:
242            ExecutorMember(FunctorMember<T>* functor, const std::string& name = "") : Executor(functor, name) {}
243            virtual ~ExecutorMember() {}
244
245            inline void operator()(T* object) const
246                { (*((FunctorMember<T>*)this->functor_))(object, this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
247            inline void operator()(T* object, const MultiType& param1) const
248                { (*((FunctorMember<T>*)this->functor_))(object, param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
249            inline void operator()(T* object, const MultiType& param1, const MultiType& param2) const
250                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
251            inline void operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3) const
252                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
253            inline void operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
254                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, param4, this->defaultValue_[4]); }
255            inline void operator()(T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
256                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, param4, param5); }
257
258
259            inline void operator()(const T* object) const
260                { (*((FunctorMember<T>*)this->functor_))(object, this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
261            inline void operator()(const T* object, const MultiType& param1) const
262                { (*((FunctorMember<T>*)this->functor_))(object, param1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
263            inline void operator()(const T* object, const MultiType& param1, const MultiType& param2) const
264                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
265            inline void operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3) const
266                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, this->defaultValue_[3], this->defaultValue_[4]); }
267            inline void operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4) const
268                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, param4, this->defaultValue_[4]); }
269            inline void operator()(const T* object, const MultiType& param1, const MultiType& param2, const MultiType& param3, const MultiType& param4, const MultiType& param5) const
270                { (*((FunctorMember<T>*)this->functor_))(object, param1, param2, param3, param4, param5); }
271
272            inline void setObject(T* object) const
273                { ((FunctorMember<T>*)this->functor_)->setObject(object); }
274            inline void setObject(const T* object) const
275                { ((FunctorMember<T>*)this->functor_)->setObject(object); }
276
277            bool parse(T* object, const std::string& params, const std::string& delimiter = " ") const
278            {
279                EXECUTOR_PARSE(object);
280            }
281
282            bool parse(const T* object, const std::string& params, const std::string& delimiter = " ") const
283            {
284                EXECUTOR_PARSE(object);
285            }
286    };
287
288    inline Executor* createExecutor(Functor* functor, const std::string& name = "")
289    {
290        return new Executor(functor, name);
291    }
292
293    template <class T>
294    inline ExecutorMember<T>* createExecutor(FunctorMember<T>* functor, const std::string& name = "")
295    {
296        return new ExecutorMember<T>(functor, name);
297    }
298
299    inline ExecutorStatic* createExecutor(FunctorStatic* functor, const std::string& name = "")
300    {
301        return new ExecutorStatic(functor, name);
302    }
303}
304
305#endif /* _Executor_H__ */
Note: See TracBrowser for help on using the repository browser.