Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: loading of XML-elements is real smooth now

File size: 13.6 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    \brief 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#include "factory.h"
26#include "debug.h"
27#include "substring.h"
28#include "tinyxml.h"
29
30// Forward Declaration //
31template<class T> class tList;
32
33//! macro that makes it even more easy to load a Parameter
34/**
35   \param className the name of the class to load
36   \param parameterName the name of the parameter to load as written in the XML-file
37   \param function the function to call
38*/
39#define LOAD_PARAM(className, parameterName, paramFunction) \
40        LoadParam<className>(root, #parameterName, this, &className::paramFunction)
41
42/**
43   useable FunctionParameters are:
44   l_INT:       int
45   l_LONG:      long
46   l_SHORT:     short
47   l_FLOAT:     float
48   l_STRING:    const char*
49   l_XML_ELEM:  TiXmlElement*
50*/
51
52#define l_INT_TYPE       int                  //!< The type of an INT
53#define l_INT_FUNC       atoi                 //!< the function to call to parse INT
54#define l_INT_NAME       "int"                //!< the name of an INT
55
56#define l_LONG_TYPE      long                 //!< The type of a LONG
57#define l_LONG_FUNC      atol                 //!< The function to parse a LONG
58#define l_LONG_NAME      "long"               //!< The name of a LONG
59
60#define l_SHORT_TYPE     short                //!< The type of a SHORT
61#define l_SHORT_FUNC     atoi                 //!< The function to parse a SHORT
62#define l_SHORT_NAME     "short"              //!< The name of a SHORT
63
64#define l_FLOAT_TYPE     float                //!< The type of a FLOAT
65#define l_FLOAT_FUNC     atof                 //!< The function to parse a FLOAT
66#define l_FLOAT_NAME     "float"              //!< The name of a FLOAT
67
68#define l_STRING_TYPE    const char*          //!< The type of a STRING
69#define l_STRING_FUNC                         //!< The function to parse a STRING
70#define l_STRING_NAME    "string"             //!< The name of a STRING
71
72#define l_XML_ELEM_TYPE  const TiXmlElement*  //!< The type of an XML_ELEM
73#define l_XML_ELEM_FUNC                       //!< The function to parse an XML_ELEM
74#define l_XML_ELEM_NAME  "XML"                //!< The name of an XML_ELEM
75
76// 1. TYPE
77/**
78   \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 1 argument
79   \param type1 The type of the first functionParameter
80*/
81#define LoadParam1(type1) \
82 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE), bool multi = false) \
83  : BaseLoadParam(root, pt2Object, paramName, 1, multi, NULL, type1##_NAME) \
84    { \
85      if (loadString != NULL && root != NULL) \
86        (*pt2Object.*function)(type1##_FUNC(loadString)); \
87      else \
88        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
89    }
90
91
92// 2. TYPES
93/**
94   \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 2 arguments
95   \param type1 The type of the first functionParameter
96   \param type2 The type of the second functionParameter
97*/
98#define LoadParam2(type1, type2) \
99 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE), bool multi = false) \
100  : BaseLoadParam(root, pt2Object, paramName, 2, multi, NULL, type1##_NAME, type2##_NAME) \
101    { \
102      if (loadString != NULL && root != NULL) \
103        { \
104          SubString subLoads(loadString); \
105          if (subLoads.getCount() == 2) \
106            (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1))); \
107          else \
108            PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
109                      paramName, pt2Object->getClassName(), 2, subLoads.getCount()); \
110        } \
111      else \
112        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
113    }
114
115
116// 3. TYPES
117/**
118   \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 3 arguments
119   \param type1 The type of the first functionParameter
120   \param type2 The type of the second functionParameter
121   \param type3 The type of the third functionParameter
122*/
123#define LoadParam3(type1, type2, type3) \
124 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE), bool multi = false)\
125  : BaseLoadParam(root, pt2Object, paramName, 3, multi, NULL, type1##_NAME, type2##_NAME, type3##_NAME) \
126    { \
127      if (loadString != NULL && root != NULL) \
128        { \
129          SubString subLoads(loadString); \
130          if (subLoads.getCount() == 3) \
131            (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2))); \
132          else \
133            PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
134                      paramName, pt2Object->getClassName(), 3, subLoads.getCount()); \
135        } \
136      else \
137        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
138    }
139
140
141// 4. TYPES
142/**
143   \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 4 arguments
144   \param type1 The type of the first functionParameter
145   \param type2 The type of the second functionParameter
146   \param type3 The type of the third functionParameter
147   \param type4 The type of the forth functionParameter
148*/
149#define LoadParam4(type1, type2, type3, type4) \
150 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE, type4##_TYPE), bool multi = false) \
151  : BaseLoadParam(root, pt2Object, paramName, 4, multi, NULL, type1##_NAME, type2##_NAME, type3##_NAME, type2##_NAME, type4##_NAME) \
152    { \
153      if (loadString != NULL && root != NULL) \
154        { \
155          SubString subLoads(loadString); \
156          if (subLoads.getCount() == 4) \
157            (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2)), type4##_FUNC(subLoads.getString(3))); \
158          else \
159            PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
160                      paramName, pt2Object->getClassName(), 4, subLoads.getCount()); \
161        } \
162      else \
163        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
164    }
165
166
167// 5. TYPES
168/**
169   \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 5 arguments
170   \param type1 The type of the first functionParameter
171   \param type2 The type of the second functionParameter
172   \param type3 The type of the third functionParameter
173   \param type4 The type of the forth functionParameter
174   \param type5 The type of the fifth functionParameter
175*/
176#define LoadParam5(type1, type2, type3, type4, type5) \
177 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE, type2##_TYPE, type3##_TYPE, type4##_TYPE, type5##_TYPE), bool multi = false) \
178  : BaseLoadParam(root, pt2Object, paramName, 5, multi, NULL, type1##_NAME, type2##_NAME, type3##_NAME, type2##_NAME, type4##_NAME, type5##_NAME) \
179    { \
180      if (loadString != NULL && root != NULL) \
181        { \
182          SubString subLoads(loadString); \
183          if (subLoads.getCount() == 5) \
184            (*pt2Object.*function)(type1##_FUNC(subLoads.getString(0)), type2##_FUNC(subLoads.getString(1)), type3##_FUNC(subLoads.getString(2)), type4##_FUNC(subLoads.getString(3)), type5##_FUNC(subLoads.getString(4))); \
185          else \
186            PRINTF(2)("Not loaded Parameter %s of %s, because wrong count of arguments.\n -> Should have %d but have %d\n", \
187                      paramName, pt2Object->getClassName(), 5, subLoads.getCount()); \
188        } \
189      else \
190        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
191    }
192
193// Pointer TYPE
194/**
195   \brief a Macro to easily implement many different Constructors for the LoadParam-Class with 1 argument
196   \param type1 The type of the Pointer
197 */
198#define LoadParamPT(type1) \
199 LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(type1##_TYPE), type1##_TYPE pointerToParam, bool multi = false) \
200  : BaseLoadParam(root, pt2Object, paramName, 1, multi, pointerToParam, type1##_NAME) \
201{ \
202      if (pointerToParam != NULL && root != NULL) \
203        (*pt2Object.*function)((type1##_TYPE) pointerToParam); \
204      else \
205        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName()); \
206}
207
208//! A class that handles the description of loadable parameters
209class LoadParamDescription
210{
211  friend class BaseLoadParam;
212  friend class LoadClassDescription;
213 public:
214  LoadParamDescription(const char* paramName);
215  ~LoadParamDescription(void);
216
217  void setDescription(const char* descriptionText);
218  /** \returns the descriptionString */
219  const char* getDescription(void) { return this->description; };
220
221  void print(void) const;
222 private:
223  char*         paramName;             //!< The name of the parameter
224  int           paramCount;            //!< The count of parameters
225  char**        types;                 //!< What kind of parameters does this function take ??
226  char*         description;           //!< A longer description about this function
227};
228
229//! A class for descriptions of a loadable module
230class LoadClassDescription
231{
232  friend class BaseLoadParam;
233 public:
234  LoadClassDescription(const char* className);
235  ~LoadClassDescription(void);
236
237  static LoadClassDescription* addClass(const char* className);
238  LoadParamDescription* addParam(const char* paramName);
239
240
241  static void printAll(const char* fileName = NULL);
242
243 private:
244  static bool                          parametersDescription;  //!< if parameter-description should be enabled.
245  static tList<LoadClassDescription>*  classList;              //!< a list, that holds all the loadable classes. (after one instance has been loaded)
246  char*                                className;              //!< name of the class
247  tList<LoadParamDescription>*         paramList;              //!< List of parameters this class knows.
248};
249
250//! abstract Base class for a Loadable parameter
251class BaseLoadParam : public BaseObject
252{
253 public:
254  BaseLoadParam* describe(const char* descriptionText);
255
256 protected:
257  BaseLoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName, int paramCount, bool multi, const void* pointerToParam, ...);
258
259 protected:
260  LoadClassDescription*    classDesc;            //!< The LoadClassDescription of this LoadParameter
261  LoadParamDescription*    paramDesc;            //!< The LoadParameterDescription of this LoadParameter
262  const char*              loadString;           //!< The string loaded by this LoadParam
263  const void*              pointerToParam;       //!< A Pointer to a Parameter.
264};
265
266
267//! derived template class, so all the Classes can load something.
268template<class T> class LoadParam : public BaseLoadParam
269{
270 public:
271  LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(), bool multi = false)
272    : BaseLoadParam(root, pt2Object, paramName, 0, multi, NULL, "")
273    {
274      if (loadString != NULL && root != NULL)
275        (*pt2Object.*function)();
276      else
277        PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName());
278    }
279
280
281  //! makes functions with one string loadable
282  LoadParam1(l_STRING);
283  //! makes functions with two strings loadable
284  LoadParam2(l_STRING, l_STRING);
285  //! makes functions with three strings loadable
286  LoadParam3(l_STRING, l_STRING, l_STRING);
287  //! makes functions with four strings loadable
288  LoadParam4(l_STRING, l_STRING, l_STRING, l_STRING);
289
290  //! makes functions with one int loadable
291  LoadParam1(l_INT);
292  //! makes functions with two ints loadable
293  LoadParam2(l_INT, l_INT);
294  //! makes functions with three ints loadable
295  LoadParam3(l_INT, l_INT, l_INT);
296  //! makes functions with four ints loadable
297  LoadParam4(l_INT, l_INT, l_INT, l_INT);
298
299  //! makes functions with one float loadable
300  LoadParam1(l_FLOAT);
301  //! makes functions with two floats loadable
302  LoadParam2(l_FLOAT, l_FLOAT);
303  //! makes functions with three floats loadable
304  LoadParam3(l_FLOAT, l_FLOAT, l_FLOAT);
305  //! makes functions with four floats loadable
306  LoadParam4(l_FLOAT, l_FLOAT, l_FLOAT, l_FLOAT);
307
308
309  LoadParam(const TiXmlElement* root, const char* paramName, T* pt2Object, void(T::*function)(const TiXmlElement*), bool multi = false)
310  : BaseLoadParam(root, pt2Object, paramName, 1, multi, NULL, "XML-Element")
311  {
312    if (root != NULL)
313    {
314      const TiXmlElement* elem = root->FirstChildElement(paramName);
315      if (likely(elem != NULL))
316        (*pt2Object.*function)(elem);
317      else
318        PRINTF(2)("%s of %s is empty", paramName, pt2Object->getClassName());
319    }
320    else
321      PRINTF(4)("Not loaded parameter %s of %s\n", paramName, pt2Object->getClassName());
322  }
323
324  //LoadParamPT(l_XML_ELEM);
325};
326
327// helper function
328
329const char* grabParameter(const TiXmlElement* root, const char* parameterName);
330
331#endif /* _LOAD_PARAM_H */
Note: See TracBrowser for help on using the repository browser.