Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/trunk/src/util/loading/load_param.h @ 5137

Last change on this file since 5137 was 5137, checked in by bensch, 19 years ago

orxonox/trunk: better macro-definition

File size: 14.0 KB
Line 
1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   ### File Specific:
12   main-programmer: Benjamin Grauer
13   co-programmer: ...
14*/
15
16/*!
17 * @file load_param.h
18 * A Class and macro-functions, that makes our lives easy to load-in parameters
19 */
20
21#ifndef _LOAD_PARAM_H
22#define _LOAD_PARAM_H
23
24#include "base_object.h"
25
26#include "factory.h"
27#include "debug.h"
28#include "substring.h"
29#include "tinyxml.h"
30
31// Forward Declaration //
32template<class T> class tList;
33
34//! macro that makes it even more easy to load a Parameter
35/**
36 * @param className the name of the class to load
37 * @param parameterName the name of the parameter to load as written in the XML-file
38 * @param function the function to call
39 */
40#define LOAD_PARAM(className, parameterName, paramFunction) \
41        LoadParam<className>(root, #parameterName, this, &className::paramFunction)
42
43/**
44 * this Starts a Cycle in the Loading Process
45 * be aware, that in the cycle the first parameter of load_param should because
46 * called element, and that you must say true at the Fith parameter, or it will fail
47 * also you will have to close the Cycle again with LOAD_PARAM_END_CYCLE
48 */
49#define LOAD_PARAM_START_CYCLE   const TiXmlElement* element; \
50                                 element = root->FirstChildElement(); \
51                                 while( element != NULL) \
52                                  {
53/**
54 * closes a LoadParam Loop
55 * @see LOAD_PARAM_START_CYCLE
56 */
57#define LOAD_PARAM_END_CYCLE        element = element->NextSiblingElement(); \
58                                  }
59
60
61/*****************************************
62**** MACROS DEFINITIONS OF LOADABLES *****
63*****************************************/
64// 0. TYPES
65/**
66 *  a Macro to easily implement many different Constructors for the LoadParam-Class with no argument
67 */
68#define LoadParam0() \
69LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(), bool multi = false) \
70  : BaseLoadParam(root, pt2Object, paramName, 0, multi, NULL, "") \
71{ \
72  if (loadString != NULL && root != NULL) \
73    (*pt2Object.*function)(); \
74  else \
75    PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName());\
76}
77
78// 1. TYPE
79/**
80 *  a Macro to easily implement many different Constructors for the LoadParam-Class with 1 argument
81 * @param type1 The type of the first functionParameter
82*/
83#define LoadParam1(type1) \
84 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE), \
85           bool multi = false, type1##_TYPE default1 = type1##_DEFAULT) \
86  : BaseLoadParam(root, pt2Object, paramName, 1, multi, NULL, type1##_NAME, default1) \
87    { \
88      if (loadString != NULL && root != NULL) \
89        (*pt2Object.*function)(type1##_FUNC(loadString, default1)); \
90      else \
91        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
92    }
93
94// 2. TYPES
95/**
96 *  a Macro to easily implement many different Constructors for the LoadParam-Class with 2 arguments
97 * @param type1 The type of the first functionParameter
98 * @param type2 The type of the second functionParameter
99*/
100#define LoadParam2(type1, type2) \
101 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE), \
102           bool multi = false,  type1##_TYPE default1 = type1##_DEFAULT,  type2##_TYPE default2 = type2##_DEFAULT) \
103  : BaseLoadParam(root, pt2Object, paramName, 2, multi, NULL, type1##_NAME, default1, type2##_NAME, default2) \
104    { \
105      if (loadString != NULL && root != NULL) \
106        { \
107          SubString subLoads(loadString); \
108          if (subLoads.getCount() == 2) \
109            (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0), default1), type2##_FUNC(subLoads.getString(1), default2)); \
110          else \
111            PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
112                      paramName, pt2Object->getClassName(), 2, subLoads.getCount()); \
113        } \
114      else \
115        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
116    }
117
118
119// 3. TYPES
120/**
121 *  a Macro to easily implement many different Constructors for the LoadParam-Class with 3 arguments
122 * @param type1 The type of the first functionParameter
123 * @param type2 The type of the second functionParameter
124 * @param type3 The type of the third functionParameter
125*/
126#define LoadParam3(type1, type2, type3) \
127 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE), \
128           bool multi = false, type1##_TYPE default1 = type1##_DEFAULT, type2##_TYPE default2 = type2##_DEFAULT, type3##_TYPE default3 = type3##_DEFAULT)\
129  : BaseLoadParam(root, pt2Object, paramName, 3, multi, NULL, type1##_NAME, default1, type2##_NAME, default2, type3##_NAME, default3) \
130    { \
131      if (loadString != NULL && root != NULL) \
132        { \
133          SubString subLoads(loadString); \
134          if (subLoads.getCount() == 3) \
135            (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0), default1), type2##_FUNC(subLoads.getString(1), default2), type3##_FUNC(subLoads.getString(2), default3)); \
136          else \
137            PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
138                      paramName, pt2Object->getClassName(), 3, subLoads.getCount()); \
139        } \
140      else \
141        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
142    }
143
144
145// 4. TYPES
146/**
147 *  a Macro to easily implement many different Constructors for the LoadParam-Class with 4 arguments
148 * @param type1 The type of the first functionParameter
149 * @param type2 The type of the second functionParameter
150 * @param type3 The type of the third functionParameter
151 * @param type4 The type of the forth functionParameter
152*/
153#define LoadParam4(type1, type2, type3, type4) \
154 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE, type4##_TYPE), \
155           bool multi = false, type1##_TYPE default1 = type1##_DEFAULT, type2##_TYPE default2 = type2##_DEFAULT, type3##_TYPE default3 = type3##_DEFAULT, \
156           type4##_TYPE default4 = type4##_DEFAULT) \
157  : BaseLoadParam(root, pt2Object, paramName, 4, multi, NULL, type1##_NAME, default1, type2##_NAME, default2, type3##_NAME, default3, \
158                  type4##_NAME, default4) \
159    { \
160      if (loadString != NULL && root != NULL) \
161        { \
162          SubString subLoads(loadString); \
163          if (subLoads.getCount() == 4) \
164            (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0), default1), type2##_FUNC(subLoads.getString(1), default2), type3##_FUNC(subLoads.getString(2), default3), type4##_FUNC(subLoads.getString(3), default4)); \
165          else \
166            PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
167                      paramName, pt2Object->getClassName(), 4, subLoads.getCount()); \
168        } \
169      else \
170        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
171    }
172
173
174// 5. TYPES
175/**
176 *  a Macro to easily implement many different Constructors for the LoadParam-Class with 5 arguments
177 * @param type1 The type of the first functionParameter
178 * @param type2 The type of the second functionParameter
179 * @param type3 The type of the third functionParameter
180 * @param type4 The type of the forth functionParameter
181 * @param type5 The type of the fifth functionParameter
182*/
183#define LoadParam5(type1, type2, type3, type4, type5) \
184 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, \
185           void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE, type4##_TYPE, type5##_TYPE), \
186           bool multi = false, type1##_TYPE default1 = type1##_DEFAULT, type2##_TYPE default2 = type2##_DEFAULT, type3##_TYPE default3 = type3##_DEFAULT, \
187           type4##_TYPE default4 = type4##_DEFAULT, type5##_TYPE default5 = type5##_DEFAULT ) \
188  : BaseLoadParam(root, pt2Object, paramName, 5, multi, NULL, type1##_NAME, default1, type2##_NAME, default2, type3##_NAME, default3, \
189                  type4##_NAME, default4, type5##_NAME, default5) \
190    { \
191      if (loadString != NULL && root != NULL) \
192        { \
193          SubString subLoads(loadString); \
194          if (subLoads.getCount() == 5) \
195            (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0), default1), type2##_FUNC(subLoads.getString(1), default2), type3##_FUNC(subLoads.getString(2), default3), type4##_FUNC(subLoads.getString(3), default4), type5##_FUNC(subLoads.getString(4), default5)); \
196          else \
197            PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
198                      paramName, pt2Object->getClassName(), 5, subLoads.getCount()); \
199        } \
200      else \
201        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
202    }
203
204// Pointer TYPE
205/**
206 *  a Macro to easily implement many different Constructors for the LoadParam-Class with one Pointer argument
207 * @param type1 The type of the Pointer
208 */
209#define LoadParamPT(type1) \
210 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE), type1##_TYPE pointerToParam, bool multi = false) \
211  : BaseLoadParam(root, pt2Object, paramName, 1, multi, pointerToParam, type1##_NAME) \
212{ \
213      if (pointerToParam != NULL && root != NULL) \
214        (*pt2Object.*function)((type1##_TYPE) pointerToParam); \
215      else \
216        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
217}
218
219
220/***********************
221*** HELPER FUNCTIONS ***
222***********************/
223bool          isBool(const char* BOOL, bool defaultValue);
224int           isInt(const char* INT, int defaultValue);
225float         isFloat(const char* FLOAT, float defaultValue);
226//const Vector& isVector(const char* VECTOR, const Vector& defaultValue);
227const char*   isString(const char* STRING, const char* defaultValue);
228
229//TiXmlEmlemnt* isXmlElem(const)
230
231
232/************************
233*** DESCRIPTION STUFF ***
234************************/
235//! A class that handles the description of loadable parameters
236class LoadParamDescription
237{
238  friend class BaseLoadParam;
239  friend class LoadClassDescription;
240 public:
241  LoadParamDescription(const char* paramName);
242  ~LoadParamDescription();
243
244  void setDescription(const char* descriptionText);
245  /** @returns the descriptionString */
246  const char* getDescription() { return this->description; };
247
248  void print() const;
249 private:
250  char*         paramName;             //!< The name of the parameter.
251  int           paramCount;            //!< The count of parameters.
252  char**        types;                 //!< What kind of parameters does this function take ??
253  char*         description;           //!< A longer description about this function.
254  char**        defaultValues;         //!< The 'Default Values'.
255};
256
257//! A class for descriptions of a loadable module
258class LoadClassDescription
259{
260  friend class BaseLoadParam;
261 public:
262  LoadClassDescription(const char* className);
263  ~LoadClassDescription();
264
265  static LoadClassDescription* addClass(const char* className);
266  LoadParamDescription* addParam(const char* paramName);
267
268  static void printAll(const char* fileName = NULL);
269  static tList<const char>* searchClassWithShort(const char* classNameBegin);
270//  static const LoadParamDescription* getClass(const char* className);
271
272 private:
273  static bool                          parametersDescription;  //!< if parameter-description should be enabled.
274  static tList<LoadClassDescription>*  classList;              //!< a list, that holds all the loadable classes. (after one instance has been loaded)
275  char*                                className;              //!< name of the class
276  tList<LoadParamDescription>*         paramList;              //!< List of parameters this class knows.
277};
278
279
280/**************************
281**** REAL DECLARATIONS ****
282**************************/
283//! abstract Base class for a Loadable parameter
284class BaseLoadParam : public BaseObject
285{
286 public:
287  BaseLoadParam* describe(const char* descriptionText);
288
289 protected:
290  BaseLoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName, int paramCount, bool multi, const void* pointerToParam, ...);
291
292 protected:
293  LoadClassDescription*    classDesc;            //!< The LoadClassDescription of this LoadParameter
294  LoadParamDescription*    paramDesc;            //!< The LoadParameterDescription of this LoadParameter
295  const char*              loadString;           //!< The string loaded by this LoadParam
296  const void*              pointerToParam;       //!< A Pointer to a Parameter.
297};
298
299
300//! derived template class, so all the Classes can load something.
301template<class T> class LoadParam : public BaseLoadParam
302{
303  public:
304
305#define FUNCTOR_LIST(x)    LoadParam ## x
306#include "functor_list.h"
307#undef FUNCTOR_LIST
308
309  //! makes functions with one Vector loadable
310  //LoadParam1(l_VECTOR);
311
312  // loads a Ti-XML-element
313  LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(const TiXmlElement*), bool multi = false)
314  : BaseLoadParam(root, pt2Object, paramName, 1, multi, NULL, "XML")
315  {
316    if (root != NULL)
317    {
318      const TiXmlElement* elem = root->FirstChildElement(paramName);
319      if (likely(elem != NULL))
320        (*pt2Object.*function)(elem);
321      else
322        PRINTF(2)("%s of %s is empty", paramName, pt2Object->getClassName());
323    }
324    else
325      PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName());
326  }
327
328  //LoadParamPT(l_XML_ELEM);
329};
330
331// helper function
332
333const char* grabParameter(const TiXmlElement* root, const char* parameterName);
334
335#endif /* _LOAD_PARAM_H */
Note: See TracBrowser for help on using the repository browser.