Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/lib/util/executor/executor.h @ 7352

Last change on this file since 7352 was 7331, checked in by bensch, 18 years ago

orxonox/trunk: small improved functoid

File size: 11.0 KB
RevLine 
[4838]1/*!
[5632]2 * @file executor.h
[7197]3 * Definition of an Executor
[5391]4 */
[1853]5
[5632]6#ifndef _EXECUTOR_H
7#define _EXECUTOR_H
[1853]8
[5129]9#include "base_object.h"
[1853]10
[5141]11#include "helper_functions.h"
[5552]12#include "multi_type.h"
[5155]13#include "substring.h"
[5635]14#include "functor_list.h" //< MUST BE INCLUDED HERE AT LEAST ONCE.
[5141]15
[5328]16//! an enumerator for the definition of the Type.
17typedef enum {
[7221]18  Executor_Objective         = 1,
19  Executor_Static            = 2,
[5652]20
[7221]21  Executor_NoLoadString      = 8,
[5632]22} Executor_Type;
[5328]23
[5161]24////////////////
25// BASE CLASS //
26////////////////
[7197]27//! a BaseClass for all possible Executors
28/**
29 * An Executor is an Object, that is able to call Objects of Any type (class)
30 * and execute a function with given parameters on it.
31 *
32 * The Executor is able to handle:
33 *  Objects of any Class (Templated)
34 *  Default Values
35 *  Functions with up to 5 parameters (more seems useless)
[7331]36 *  Functions with many types (@see functor_list.h)
[7197]37 */
[5632]38class Executor: public BaseObject
[5170]39{
40  public:
[5641]41    virtual ~Executor();
42
43    virtual Executor* clone () const = 0;
44
[7331]45    // SETTING up the EXECUTOR
[7198]46    Executor* defaultValues(const MultiType& value0 = MT_NULL, const MultiType& value1 = MT_NULL,
47                            const MultiType& value2 = MT_NULL, const MultiType& value3 = MT_NULL,
48                            const MultiType& value4 = MT_NULL);
[5164]49
[7331]50    // EXECUTE
[5633]51    /** executes a Command @param object the object to apply this to @param parameters the parameters the command takes */
[7331]52    virtual void operator()(BaseObject* object, const std::string& parameters = "") = 0;
53    /** executes a Command @param object the object to apply this to @param parameters the parameters the command takes @brief here for your convenience*/
54    void execute (BaseObject* object, const std::string& parameters = "") { (*this)(object, parameters); };
[5161]55
[7331]56    // RETRIEVE INFORMATION
[5641]57    /** @returns the Type of this Function (either static or objective) */
[5652]58    inline long getType() const { return this->functorType; };
[5642]59    /** @returns the Count of Parameters this Executor takes */
60    inline unsigned int getParamCount() const { return this->paramCount; };
[5641]61
[5161]62    static void debug();
63
64  protected:
[7198]65    Executor(const MultiType& param0 = MT_NULL, const MultiType& param1 = MT_NULL,
66             const MultiType& param2 = MT_NULL, const MultiType& param3 = MT_NULL,
[7197]67             const MultiType& param4 = MT_NULL);
[5161]68
[5641]69    void cloning(Executor* executor) const;
[5328]70
[5161]71  protected:
[7331]72    short                       functorType;      //!< The type of Function we've got (either static or objective).
[5652]73    unsigned int                paramCount;       //!< the count of parameters.
[7197]74    MultiType                   defaultValue[5];  //!< Default Values.
[5161]75};
76
77///////////////////////////////////////////////////
78///////////////////////////////////////////////////
79
[5153]80//////////////////////////
81// COMMAND REGISTRATION //
82//////////////////////////
[5636]83// EXECUTOR             can be redefined as Executor or ExecutorStatic
84// EXECUTOREXECUTER     can be redefined too.
[5632]85// EXECUTORINCLASS
86// EXECUTORTYPE
[5135]87
[5636]88
[5551]89///////////////////////
90// FUNCTION POINTERS //
91///////////////////////
[5632]92#define ExecutorFunctionPoiter0() \
93  void EXECUTORINCLASS(*functionPointer_0)();
[5551]94
[5632]95#define ExecutorFunctionPoiter1(t1) \
96  void EXECUTORINCLASS(*functionPointer_1_##t1)(t1##_TYPE);
[5551]97
[5632]98#define ExecutorFunctionPoiter2(t1, t2) \
99  void EXECUTORINCLASS(*functionPointer_2_##t1##_##t2)(t1##_TYPE, t2##_TYPE);
[5551]100
101
[5632]102#define ExecutorFunctionPoiter3(t1, t2, t3) \
103  void EXECUTORINCLASS(*functionPointer_3_##t1##_##t2##_##t3)(t1##_TYPE, t2##_TYPE, t3##_TYPE);
[5551]104
[5632]105#define ExecutorFunctionPoiter4(t1, t2, t3, t4) \
106  void EXECUTORINCLASS(*functionPointer_4_##t1##_##t2##_##t3##_##t4)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE);
[5551]107
108
[5632]109#define ExecutorFunctionPoiter5(t1, t2, t3, t4, t5) \
[7300]110  void EXECUTORINCLASS(*functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE);
[5551]111
112
[5153]113//////////////////
114// CONSTRUCTORS //
115/////////////////
[5166]116//! creates a command that takes no parameters
[5632]117#define ExecutorConstructor0() \
[5636]118  EXECUTOR(void EXECUTORINCLASS(*function)()) \
119  : Executor(0) \
[5142]120  { \
[5632]121    this->functorType = EXECUTORTYPE; \
[5551]122    this->fp.functionPointer_0 = function; \
[5142]123  }
124
[5166]125//! creates a command that takes one parameter
[5632]126#define ExecutorConstructor1(t1) \
[5636]127  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE)) \
[7197]128  : Executor(t1##_PARAM) \
[5135]129  { \
[5632]130    this->functorType = EXECUTORTYPE; \
[5551]131    this->fp.functionPointer_1_##t1 = function; \
[5135]132  }
133
[5166]134//! creates a command that takes two parameters
[5632]135#define ExecutorConstructor2(t1,t2) \
[5636]136  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE, t2##_TYPE)) \
[7197]137  : Executor(t1##_PARAM, t2##_PARAM) \
[5153]138  { \
[5632]139    this->functorType = EXECUTORTYPE; \
[5551]140    this->fp.functionPointer_2_##t1##_##t2 = function; \
[5153]141  }
[5135]142
[5166]143//! creates a command that takes three parameter
[5632]144#define ExecutorConstructor3(t1,t2,t3) \
[5636]145  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE)) \
[7197]146  : Executor(t1##_PARAM, t2##_PARAM, t3##_PARAM) \
[5153]147  { \
[5632]148    this->functorType = EXECUTORTYPE; \
[5551]149    this->fp.functionPointer_3_##t1##_##t2##_##t3 = function; \
[5153]150  }
[5141]151
[5166]152//! creates a command that takes four parameter
[5632]153#define ExecutorConstructor4(t1,t2,t3,t4) \
[5636]154  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE)) \
[7197]155  : Executor(t1##_PARAM, t2##_PARAM, t3##_PARAM, t4##_PARAM) \
[5153]156  { \
[5632]157    this->functorType = EXECUTORTYPE; \
[5551]158    this->fp.functionPointer_4_##t1##_##t2##_##t3##_##t4 = function; \
[5153]159  }
160
[5166]161//! creates a command that takes five parameter
[5632]162#define ExecutorConstructor5(t1,t2,t3,t4,t5) \
[5636]163  EXECUTOR(void EXECUTORINCLASS(*function)(t1##_TYPE, t2##_TYPE, t3##_TYPE, t4##_TYPE, t5##_TYPE)) \
[7197]164  : Executor(t1##_PARAM, t2##_PARAM, t3##_PARAM, t4##_PARAM, t5##_PARAM) \
[5153]165  { \
[5632]166    this->functorType = EXECUTORTYPE; \
[5551]167    this->fp.functionPointer_5_##t1##_##t2##_##t3##_##t4##_##t5 = function; \
[5153]168  }
169
170///////////////
171// EXECUTION //
172///////////////
[5166]173//! execute-macro for functions with no parameters
[5632]174#define ExecutorExecute0() \
[5145]175  if (this->paramCount == 0) \
[5632]176    EXECUTOREXECUTER(_0)()
[5145]177
[5166]178//! execute-macro for functions with one parameter
[5632]179#define ExecutorExecute1(t1) \
[7200]180   else if (this->paramCount == 1 && this->defaultValue[0] == t1##_PARAM) \
[7221]181    EXECUTOREXECUTER(_1_##t1)(t1##_FUNC(sub[0], t1##_DEFGRAB(0)))
[5145]182
[5166]183//! execute-macro for functions with two parameters
[5632]184#define ExecutorExecute2(t1,t2) \
[7200]185   else if (this->paramCount == 2 && this->defaultValue[0] == t1##_PARAM && this->defaultValue[1] == t2##_PARAM) \
[7221]186    EXECUTOREXECUTER(_2_##t1##_##t2)(t1##_FUNC(sub[0], t1##_DEFGRAB(0)), t2##_FUNC(sub[1], t2##_DEFGRAB(1)))
[5145]187
[5166]188//! execute-macro for functions with three parameters
[5632]189#define ExecutorExecute3(t1,t2,t3) \
[7200]190   else if (this->paramCount == 3 && this->defaultValue[0] == t1##_PARAM && this->defaultValue[1] == t2##_PARAM && this->defaultValue[2] == t3##_PARAM) \
[7221]191    EXECUTOREXECUTER(_3_##t1##_##t2##_##t3)(t1##_FUNC(sub[0], t1##_DEFGRAB(0)), t2##_FUNC(sub[1], t2##_DEFGRAB(1)), t3##_FUNC(sub[2], t3##_DEFGRAB(2)))
[5153]192
[5166]193//! execute-macro for functions with four parameters
[5632]194#define ExecutorExecute4(t1,t2,t3,t4) \
[7200]195   else if (this->paramCount == 4 && this->defaultValue[0] == t1##_PARAM && this->defaultValue[1] == t2##_PARAM && this->defaultValue[2] == t3##_PARAM && this->defaultValue[3] == t4##_PARAM) \
[7221]196    EXECUTOREXECUTER(_4_##t1##_##t2##_##t3##_##t4)(t1##_FUNC(sub[0], t1##_DEFGRAB(0)), t2##_FUNC(sub[1], t2##_DEFGRAB(1)), t3##_FUNC(sub[2], t3##_DEFGRAB(2)), t4##_FUNC(sub[3], t4##_DEFGRAB(3))) \
[5153]197
[5652]198
[5166]199//! execute-macro for functions with five parameters
[5632]200#define ExecutorExecute5(t1,t2,t3,t4,t5) \
[7200]201   else if (this->paramCount == 5 && this->defaultValue[0] == t1##_PARAM && this->defaultValue[1] == t2##_PARAM && this->defaultValue[2] == t3##_PARAM && this->defaultValue[3] == t4##_PARAM && this->defaultValue[4] == t5##_PARAM) \
[7221]202    EXECUTOREXECUTER(_5_##t1##_##t2##_##t3##_##t4##_##t5)(t1##_FUNC(sub[0], t1##_DEFGRAB(0)), t2##_FUNC(sub[1], t2##_DEFGRAB(1)), t3##_FUNC(sub[2], t3##_DEFGRAB(2)), t4##_FUNC(sub[3], t4##_DEFGRAB(3)), t5##_FUNC(sub[4], t5##_DEFGRAB(4)))
[5153]203
204
[5632]205
206
[7300]207/////////////////////
[5632]208// DYNAMIC FUNCTOR //
[7300]209/////////////////////
[5153]210#ifdef FUNCTOR_LIST
211#undef FUNCTOR_LIST
212#endif
[5632]213#ifdef EXECUTOR
214#undef EXECUTOR
[5326]215#endif
[5632]216#define EXECUTOR                       ExecutorObjective
217#ifdef EXECUTOREXECUTER
218#undef EXECUTOREXECUTER
[5326]219#endif
[5632]220#define EXECUTOREXECUTER(nameExt)      (dynamic_cast<T*>(object)->*(fp.functionPointer##nameExt))
221#ifdef EXECUTORINCLASS
222#undef EXECUTORINCLASS
[5327]223#endif
[5632]224#define EXECUTORINCLASS(FUNCTION)      (T::FUNCTION)
225#ifdef EXECUTORTYPE
226#undef EXECUTORTYPE
[5328]227#endif
[5632]228#define EXECUTORTYPE                   Executor_Objective
[5633]229//! keeps information about a Executor
[7221]230template<class T> class EXECUTOR : public Executor
[5633]231{
[5641]232  public:
[7221]233    EXECUTOR() : Executor() { };
[5641]234    // COPY constuctor (virtual version)
235    virtual Executor* clone () const
236    {
[7221]237      EXECUTOR<T>* executor = new EXECUTOR<T>();
[5641]238      this->cloning(executor);
239      executor->fp = this->fp;
240      return executor;
241    }
[5633]242
243//! FUNCTOR_LIST is the List of CommandConstructors
244#define FUNCTOR_LIST(x) ExecutorConstructor ## x
[5153]245#include "functor_list.h"
[5142]246#undef FUNCTOR_LIST
[5136]247
[5068]248  private:
[5551]249//! FUNCTOR_LIST is the List of FunctionPointers
250    union FunctionPointers {
[5632]251#define FUNCTOR_LIST(x) ExecutorFunctionPoiter ## x
[5551]252#include "functor_list.h"
253#undef FUNCTOR_LIST
254    } fp;
255
[7331]256    virtual void operator()(BaseObject* object, const std::string& parameters = "")
[5135]257    {
[7221]258      SubString sub;
259      sub.split(parameters, " \n\t,", '\\');
[5166]260//! FUNCTOR_LIST is the List of Executive Functions
[5632]261#define FUNCTOR_LIST(x) ExecutorExecute ## x
[5153]262#include "functor_list.h"
[5135]263#undef FUNCTOR_LIST
[5145]264    }
[5129]265};
[5113]266
[5632]267
268////////////////////
269// STATIC FUNCTOR //
270////////////////////
[5326]271#ifdef FUNCTOR_LIST
272#undef FUNCTOR_LIST
273#endif
[5632]274#ifdef EXECUTOR
275#undef EXECUTOR
[5326]276#endif
[5632]277#define EXECUTOR                      ExecutorStatic
278#ifdef EXECUTOREXECUTER
279#undef EXECUTOREXECUTER
[5326]280#endif
[5632]281#define EXECUTOREXECUTER(nameExt)     fp.functionPointer##nameExt
282#ifdef EXECUTORINCLASS
283#undef EXECUTORINCLASS
[5327]284#endif
[5632]285#define EXECUTORINCLASS(FUNCTION)     (FUNCTION)
286#ifdef EXECUTORTYPE
287#undef EXECUTORTYPE
[5328]288#endif
[5632]289#define EXECUTORTYPE                   Executor_Static
[5326]290
[5633]291//! keeps information about a Executor, that points to a Static Function
292template<class T> class ExecutorStatic : public Executor
293{
294  public:
[7221]295    EXECUTOR() : Executor() { };
[5641]296    // COPY constuctor
297    virtual Executor* clone () const
298    {
[7221]299      EXECUTOR<T>* executor = new EXECUTOR<T>();
[5641]300      this->cloning(executor);
301      executor->fp = this->fp;
302      return executor;
303    }
304
[5633]305//! FUNCTOR_LIST is the List of CommandConstructors
306#define FUNCTOR_LIST(x) ExecutorConstructor ## x
[5326]307#include "functor_list.h"
308#undef FUNCTOR_LIST
309
310  private:
[5551]311//! FUNCTOR_LIST is the List of FunctionPointers
312    union FunctionPointers {
[5632]313#define FUNCTOR_LIST(x) ExecutorFunctionPoiter ## x
[5551]314#include "functor_list.h"
315#undef FUNCTOR_LIST
316    } fp;
317
[5326]318
[7331]319    virtual void operator()(BaseObject* object, const std::string& parameters = "")
[5326]320    {
[7221]321      SubString sub;
322      sub.split(parameters, " \n\t,", '\\');
[5326]323//! FUNCTOR_LIST is the List of Executive Functions
[5632]324#define FUNCTOR_LIST(x) ExecutorExecute ## x
[5326]325#include "functor_list.h"
326#undef FUNCTOR_LIST
327    }
328};
329
[5632]330#endif /* _EXECUTOR_H */
Note: See TracBrowser for help on using the repository browser.