Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/libraries/core/command/Executor.h @ 11989

Last change on this file since 11989 was 11071, checked in by landauf, 9 years ago

merged branch cpp11_v3 back to trunk

  • Property svn:eol-style set to native
File size: 15.3 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/**
31    @defgroup FunctorExecutor Functor and Executor
32    @ingroup Command
33*/
34
35/**
36    @file
37    @ingroup Command FunctorExecutor
38    @brief Declaration of the orxonox::Executor class and the createExecutor() functions.
39
40    @anchor ExecutorExample
41
42    orxonox::Executor is used to wrap an orxonox::Functor and to store default values for
43    its parameters. Usually one uses the function createExecutor() to create a new executor.
44    This function returns an orxonox::ExecutorPtr which is a typedef of "std::shared_ptr<Executor>",
45    used to manage the pointer to the executor.
46
47    Executors are mostly used to execute callbacks. Because some callback functions need arguments,
48    Executor provides an easy interface to store these arguments as default values, so the
49    executor can also be executed without arguments because it will use these default values.
50
51    The Executor doesn't contain the function-pointer directly. Instead it wraps an instance
52    of orxonox::Functor. See @ref FunctorExample "Functor.h" for more information and some
53    examples.
54
55    Example:
56    @code
57    void myFunction(int a, int b)                           // declare a static function
58    {
59        orxout() << "The sum is " << (a + b) << endl;       // print the sum of a and b to the console
60    }
61
62    FunctorPtr functor = createFunctor(&myFunction);        // create a functor that wraps the function-pointer
63    ExecutorPtr executor = createExecutor(functor);         // create an executor that wraps the functor
64
65    (*executor)(2, 5);                                      // calls the executor with arguments 2 and 5, prints "The sum is 7" to the console
66
67    executor->setDefaultValue(1, 10);                       // sets the default-value for the second parameter (note: paramters start at index 0) to 10
68
69    (*executor)(2);                                         // calls the executor with argument 2 and default-value 10, prints "The sum is 12"
70
71    executor->setDefaultValue(0, 5);                        // sets the default-value for the first parameter to 5
72
73    (*executor)();                                          // calls the executor with default-values only, prints "The sum is 15"
74    @endcode
75
76    Executors don't need to be deleted after usage normally because they are managed by an
77    std::shared_ptr when they were created with createExecutor().
78*/
79
80#ifndef _Executor_H__
81#define _Executor_H__
82
83#include "core/CorePrereqs.h"
84
85#include <string>
86#include "util/MultiType.h"
87#include "Functor.h"
88#include "ExecutorPtr.h"
89
90namespace orxonox
91{
92    /**
93        @brief This class is used to wrap a Functor and to store default values for any of its parameters.
94
95        @see See @ref ExecutorExample "Executor.h" for an example.
96    */
97    class _CoreExport Executor
98    {
99        public:
100            Executor(const FunctorPtr& functor, const std::string& name = "");
101            Executor(const Executor& other);
102            virtual ~Executor() = default;
103
104            /// Calls the wrapped function with 0 arguments. If the function needs more arguments, the executor's default values are used.
105            inline MultiType operator()() const
106                { return (*this->functor_)(this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
107            /// Calls the wrapped function with 1 argument. If the function needs more arguments, the executor's default values are used.
108            inline MultiType operator()(const MultiType& arg1) const
109                { return (*this->functor_)(arg1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
110            /// Calls the wrapped function with 2 arguments. If the function needs more arguments, the executor's default values are used.
111            inline MultiType operator()(const MultiType& arg1, const MultiType& arg2) const
112                { return (*this->functor_)(arg1, arg2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
113            /// Calls the wrapped function with 3 arguments. If the function needs more arguments, the executor's default values are used.
114            inline MultiType operator()(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3) const
115                { return (*this->functor_)(arg1, arg2, arg3, this->defaultValue_[3], this->defaultValue_[4]); }
116            /// Calls the wrapped function with 4 arguments. If the function needs more arguments, the executor's default values are used.
117            inline MultiType operator()(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4) const
118                { return (*this->functor_)(arg1, arg2, arg3, arg4, this->defaultValue_[4]); }
119            /// Calls the wrapped function with 5 arguments. If the function needs more arguments, the executor's default values are used.
120            inline MultiType operator()(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5) const
121                { return (*this->functor_)(arg1, arg2, arg3, arg4, arg5); }
122
123            MultiType parse(const std::string& arguments, int* error = nullptr, const std::string& delimiter = " ", bool bPrintError = false) const;
124            MultiType parse(const SubString& arguments, int* error = nullptr, const std::string& delimiter = " ", bool bPrintError = false) const;
125
126            int evaluateArguments(const SubString& arguments, MultiType arg[MAX_FUNCTOR_ARGUMENTS], int* error = nullptr, const std::string& delimiter = " ") const;
127
128            /// Changes the functor.
129            inline void setFunctor(const FunctorPtr& functor)
130                { this->functor_ = functor; }
131            /// Returns the functor.
132            inline const FunctorPtr& getFunctor() const
133                { return this->functor_; }
134
135            /// Changes the name of the executor.
136            inline void setName(const std::string& name)
137                { this->name_ = name; }
138            /// Returns the name of the executor.
139            inline const std::string& getName() const
140                { return this->name_; }
141
142            /// Returns the number of parameters of the wrapped function.
143            inline unsigned int getParamCount() const
144                { return this->functor_->getParamCount(); }
145            /// Returns true if the wrapped function returns a value.
146            inline bool hasReturnvalue() const
147                { return this->functor_->hasReturnvalue(); }
148            /// Returns the type of the wrapped function (static or member).
149            inline Functor::Type getType() const
150                { return this->functor_->getType(); }
151            /// Returns the name of the type of a parameter with given index (the first parameter has index 0).
152            inline std::string getTypenameParam(unsigned int param) const
153                { return this->functor_->getTypenameParam(param); }
154            /// Returns the name of the type of the return value.
155            inline std::string getTypenameReturnvalue() const
156                { return this->functor_->getTypenameReturnvalue(); }
157
158            void setDefaultValues(const MultiType& arg1);
159            void setDefaultValues(const MultiType& arg1, const MultiType& arg2);
160            void setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3);
161            void setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4);
162            void setDefaultValues(const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5);
163            void setDefaultValue(unsigned int index, const MultiType& arg);
164
165            /// Returns the default value for a parameter with given index (the first parameter has index 0).
166            inline MultiType getDefaultValue(unsigned int index) const
167            {
168                if (index < MAX_FUNCTOR_ARGUMENTS)
169                    return this->defaultValue_[index];
170
171                return MultiType::Null;
172            }
173
174            bool allDefaultValuesSet() const;
175
176            /// Returns true if the executor contains a default value for the parameter with given index (the first parameter has index 0).
177            inline bool defaultValueSet(unsigned int index) const
178            {
179                if (index < MAX_FUNCTOR_ARGUMENTS)
180                    return !this->defaultValue_[index].null();
181
182                return false;
183            }
184
185        protected:
186            FunctorPtr functor_;                                ///< The underlying Functor that wraps a function
187            std::string name_;                                  ///< The name of the executor
188            MultiType defaultValue_[MAX_FUNCTOR_ARGUMENTS];     ///< The default values, one for each parameter
189    };
190
191    /**
192        @brief A child class of Executor, used to distinguish executors that wrap static functions from executors that wrap member-functions.
193
194        Behaves exactly like Executor, because static functions need no special treatment.
195    */
196    class _CoreExport ExecutorStatic : public Executor
197    {
198        public:
199            /// Constructor: Initializes the parent class
200            ExecutorStatic(const FunctorStaticPtr& functor, const std::string& name = "") : Executor(functor, name) {}
201            /// Destructor
202            virtual ~ExecutorStatic() {}
203    };
204
205    /**
206        @brief A child class of Executor, used for easier handling of non-static member-functions.
207
208        Overloads some functions that call the underlying FunctorMember and additionally pass
209        an object-pointer that is needed for non-static member-functions.
210    */
211    template <class T>
212    class ExecutorMember : public Executor
213    {
214        public:
215            /// Constructor: Initializes the parent class and the pointer to the member-functor.
216            ExecutorMember(const FunctorMemberPtr<T>& functor, const std::string& name = "") : Executor(functor, name), functorMember_(functor) {}
217            /// Destructor
218            virtual ~ExecutorMember() {}
219
220            using Executor::operator();
221
222            /// Calls the wrapped function with 0 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
223            inline MultiType operator()(T* object) const
224                { return (*this->functorMember_)(object, this->defaultValue_[0], this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
225            /// Calls the wrapped function with 1 argument and an object-pointer. If the function needs more arguments, the executor's default values are used.
226            inline MultiType operator()(T* object, const MultiType& arg1) const
227                { return (*this->functorMember_)(object, arg1, this->defaultValue_[1], this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
228            /// Calls the wrapped function with 2 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
229            inline MultiType operator()(T* object, const MultiType& arg1, const MultiType& arg2) const
230                { return (*this->functorMember_)(object, arg1, arg2, this->defaultValue_[2], this->defaultValue_[3], this->defaultValue_[4]); }
231            /// Calls the wrapped function with 3 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
232            inline MultiType operator()(T* object, const MultiType& arg1, const MultiType& arg2, const MultiType& arg3) const
233                { return (*this->functorMember_)(object, arg1, arg2, arg3, this->defaultValue_[3], this->defaultValue_[4]); }
234            /// Calls the wrapped function with 4 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
235            inline MultiType operator()(T* object, const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4) const
236                { return (*this->functorMember_)(object, arg1, arg2, arg3, arg4, this->defaultValue_[4]); }
237            /// Calls the wrapped function with 5 arguments and an object-pointer. If the function needs more arguments, the executor's default values are used.
238            inline MultiType operator()(T* object, const MultiType& arg1, const MultiType& arg2, const MultiType& arg3, const MultiType& arg4, const MultiType& arg5) const
239                { return (*this->functorMember_)(object, arg1, arg2, arg3, arg4, arg5); }
240
241            /// Changes the object-pointer of the underlying FunctorMember.
242            inline void setObject(T* object) const
243                { this->functorMember_->setObject(object); }
244            /// Returns the object-pointer of the underlying FunctorMember.
245            inline T* getObject() const
246                { return this->functorMember_->getObject(); }
247
248            using Executor::parse;
249
250            /// Overloads Executor::parse() with an additional object-pointer.
251            MultiType parse(T* object, const std::string& arguments, int* error = nullptr, const std::string& delimiter = " ", bool bPrintError = false) const
252            {
253                T* oldobject = this->functorMember_->getObject();
254
255                this->functorMember_->setObject(object);
256                const MultiType& result = this->Executor::parse(arguments, error, delimiter, bPrintError);
257                this->functorMember_->setObject(oldobject);
258
259                return result;
260            }
261
262        protected:
263            FunctorMemberPtr<T> functorMember_;     ///< A pointer to the FunctorMember is stored separately to avoid casting when executing the function.
264    };
265
266    /// Creates a new Executor that wraps a given Functor.
267    inline ExecutorPtr createExecutor(const FunctorPtr& functor, const std::string& name = "")
268    {
269        return std::make_shared<Executor>(functor, name);
270    }
271
272    /// Creates a new ExecutorMember that wraps a given FunctorMember.
273    template <class T>
274    inline ExecutorMemberPtr<T> createExecutor(const FunctorMemberPtr<T>& functor, const std::string& name = "")
275    {
276        return std::make_shared<ExecutorMember<T>>(functor, name);
277    }
278
279    /// Creates a new ExecutorStatic that wraps a given FunctorStatic.
280    inline ExecutorStaticPtr createExecutor(const FunctorStaticPtr& functor, const std::string& name = "")
281    {
282        return std::make_shared<ExecutorStatic>(functor, name);
283    }
284}
285
286#endif /* _Executor_H__ */
Note: See TracBrowser for help on using the repository browser.