Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: 1-st step to LoadParam→default-values (get printed and stuff)

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