Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/orxonox/trunk/src/util/loading/load_param.cc @ 4625

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

orxonox/trunk: default Values should work now even better

File size: 10.3 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#include "load_param.h"
17
18#include "list.h"
19#include "base_object.h"
20
21#include <stdarg.h>
22
23/**
24   \param object The object this Parameter is loaded too.
25   \param root: the XML-element to load this option from.
26   \param paramName: The name of the parameter loaded.
27   \param paramCount: how many parameters this loading-function takes
28   \param multi: if false LoadParam assumes only one occurence of this parameter in root, if true it assumes multiple occurences.
29   \param ...: the parameter information (1. Parameter, 2. Default Value for the Parameter, ...)
30*/
31BaseLoadParam::BaseLoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName,
32                             int paramCount, bool multi, const void* pointerToParam, ...)
33{
34  this->setClassID(CL_LOAD_PARAM, "LoadParam");
35  this->loadString = NULL;
36  this->pointerToParam = pointerToParam;
37
38  if (paramCount == 0 || this->pointerToParam)
39    this->loadString = "none";
40  else
41    {
42      if (likely(!multi))
43        this->loadString = grabParameter(root, paramName);
44      else
45        {
46          if (!strcmp(root->Value(), paramName))
47            {
48              const TiXmlNode* val = root->FirstChild();
49              if( val->ToText())
50                this->loadString = val->Value();
51            }
52        }
53    }
54
55  this->paramDesc = NULL;
56  if (LoadClassDescription::parametersDescription)
57  {
58    // locating the class
59    this->classDesc = LoadClassDescription::addClass(object->getClassName());
60
61    if ((this->paramDesc = this->classDesc->addParam(paramName)) != NULL)
62    {
63
64      this->paramDesc->paramCount = paramCount;
65      this->paramDesc->types = new char*[paramCount];
66      this->paramDesc->defaultValues = new char*[paramCount];
67
68      va_list types;
69      va_start (types, pointerToParam);
70      char defaultVal[512];
71      for(int i = 0; i < paramCount; i++)
72      {
73          // parameters parsed
74        const char* tmpTypeName = va_arg (types, const char*);
75        this->paramDesc->types[i] = new char[strlen(tmpTypeName)+1];
76        strcpy(this->paramDesc->types[i], tmpTypeName);
77
78          // default value description
79        if (!strcmp(tmpTypeName, l_INT_NAME))
80        {
81          sprintf(defaultVal, "%d", va_arg(types, l_INT_TYPE));
82        }
83        else if (!strcmp(tmpTypeName, l_LONG_NAME))
84        {
85          sprintf(defaultVal, "%0.3f", va_arg(types, l_LONG_TYPE));
86        }
87          /*          else if (!strcmp(tmpTypeName, l_SHORT_NAME))
88        {
89        sprintf(defaultVal, "%d", va_arg(types, l_SHORT_TYPE));
90      }*/
91        else if (!strcmp(tmpTypeName, l_FLOAT_NAME))
92        {
93          sprintf(defaultVal, "%0.3f", va_arg(types, double));
94        }
95        else if (!strcmp(tmpTypeName, l_STRING_NAME))
96        {
97          sprintf(defaultVal, "%s", va_arg(types, l_STRING_TYPE));
98        }
99        else if (!strcmp(tmpTypeName, l_XML_ELEM_NAME))
100        {
101          sprintf(defaultVal, "");
102        }
103
104        this->paramDesc->defaultValues[i] = new char[strlen(defaultVal)+1];
105        strcpy(this->paramDesc->defaultValues[i], defaultVal);
106      }
107      va_end(types);
108
109      int argCount = 0;
110    }
111  }
112}
113
114
115int isInt(const char* Int, int defaultValue)
116{
117  char* endPtr = NULL;
118  int result = strtol(Int, &endPtr, 10);
119
120  if ( endPtr >= Int && endPtr < Int + strlen(Int))
121    return defaultValue;
122  else
123    return result;
124}
125
126float isFloat(const char* Float, float defaultValue)
127{
128  char* endPtr = NULL;
129  double result = strtod(Float, &endPtr);
130
131  if ( endPtr >= Float && endPtr < Float + strlen(Float))
132    return defaultValue;
133  else
134    return result;
135}
136
137const char* isString(const char* string, const char* defaultValue)
138{
139  if (string != NULL)
140    return string;
141  else
142    return defaultValue;
143}
144
145
146/**
147   \param descriptionText The text to set as a description for this Parameter
148   \returns a pointer to itself.
149*/
150BaseLoadParam* BaseLoadParam::describe(const char* descriptionText)
151{
152  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
153    {
154      this->paramDesc->setDescription(descriptionText);
155    }
156  return this;
157}
158
159/**
160   \param paramName the name of the parameter to load
161*/
162LoadParamDescription::LoadParamDescription(const char* paramName)
163{
164  this->types = NULL;
165  this->description = NULL;
166  this->paramName = new char[strlen(paramName)+1];
167  strcpy(this->paramName, paramName);
168  this->defaultValues = NULL;
169}
170
171/**
172   \brief removes all the alocated memory
173*/
174LoadParamDescription::~LoadParamDescription(void)
175{
176  for(int i = 0; i < this->paramCount; i++)
177  {
178    delete this->types[i];
179  }
180  for(int i = 0; i < this->paramCount; i++)
181  {
182    delete this->defaultValues[i];
183  }
184
185  delete []this->types;
186  delete []this->defaultValues;
187  delete []this->paramName;
188  delete []this->description;
189}
190
191/**
192   \param descriptionText The text to set as a description for this Parameter
193*/
194void LoadParamDescription::setDescription(const char* descriptionText)
195{
196  this->description = new char[strlen(descriptionText)+1];
197  strcpy(this->description, descriptionText);
198}
199
200/**
201   \brief prints out this parameter, its input method and the description (if availiable)
202*/
203void LoadParamDescription::print(void) const
204{
205  PRINT(3)(" <%s>", this->paramName);
206  for (int i = 0; i < this->paramCount; i++)
207    {
208      if (i > 0)
209        PRINT(3)(",");
210      PRINT(3)("%s", this->types[i]);
211    }
212  PRINT(3)("</%s>", this->paramName);
213  if (this->description)
214    PRINT(3)(" -- %s", this->description);
215  // default values
216  if (this->paramCount > 0)
217  {
218      PRINT(3)(" (Default: ");
219    for (int i = 0; i < this->paramCount; i++)
220    {
221      if (i > 0)
222        PRINT(3)(", ");
223      if (!strcmp(this->types[i], l_STRING_NAME))
224      { // leave brackets !!
225        PRINT(3)("\"%s\"", this->defaultValues[i]);
226      }
227      else
228      {
229        PRINT(3)("%s", this->defaultValues[i]);
230      }
231    }
232    PRINT(3)(")");
233  }
234  PRINT(3)("\n");
235}
236
237/**
238   \brief A list, that holds all the classes that are loadable (classes not objects!!)
239*/
240tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
241
242/**
243   \brief if the description of Parameters should be executed
244*/
245bool LoadClassDescription::parametersDescription = true;
246
247/**
248   \param className the name of the class to be loadable
249*/
250LoadClassDescription::LoadClassDescription(const char* className)
251{
252  this->className = new char[strlen(className)+1];
253  strcpy(this->className, className);
254
255  classList->add(this);
256
257  this->paramList = new tList<LoadParamDescription>;
258}
259
260/**
261   \brief deletes a classDescription (deletes all the parameterDescriptions as well
262*/
263LoadClassDescription::~LoadClassDescription(void)
264{
265  delete []this->className;
266
267  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
268  LoadParamDescription* enumParamDesc = iterator->nextElement();
269  while (enumParamDesc)
270    {
271      delete enumParamDesc;
272      enumParamDesc = iterator->nextElement();
273    }
274  delete iterator;
275}
276
277/**
278   \brief adds a class to the list of loadable classes
279   \param className The name of the class to add
280
281   this function searches for the className string, and if found just returns the appropriate Class.
282   Otherwise it returns a new classDescription
283*/
284LoadClassDescription* LoadClassDescription::addClass(const char* className)
285{
286  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
287  LoadClassDescription* enumClassDesc = iterator->nextElement();
288  while (enumClassDesc)
289    {
290      if (!strcmp(enumClassDesc->className, className))
291        {
292          delete iterator;
293          return enumClassDesc;
294        }
295      enumClassDesc = iterator->nextElement();
296    }
297  delete iterator;
298
299  return new LoadClassDescription(className);
300}
301
302/**
303   \brief does the same as addClass(const char* className), but with params
304   \param paramName the name of the parameter to add.
305*/
306LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
307{
308  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
309  LoadParamDescription* enumParamDesc = iterator->nextElement();
310  while (enumParamDesc)
311    {
312      if (!strcmp(enumParamDesc->paramName, paramName))
313        {
314          delete iterator;
315          return enumParamDesc;
316        }
317      enumParamDesc = iterator->nextElement();
318    }
319  delete iterator;
320
321  this->paramList->add(new LoadParamDescription(paramName));
322  return paramList->lastElement();
323}
324
325/**
326   \brief prints out all loadable Classes, and their parameters
327*/
328void LoadClassDescription::printAll(const char* fileName)
329{
330  PRINT(3)("===============================================================\n");
331  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
332  tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
333  LoadClassDescription* enumClassDesc = classIT->nextElement();
334  while (enumClassDesc)
335    {
336      PRINT(3)("<%s>\n", enumClassDesc->className);
337      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
338      LoadParamDescription* enumParamDesc = paramIT->nextElement();
339      while (enumParamDesc)
340        {
341          enumParamDesc->print();
342          enumParamDesc = paramIT->nextElement();
343        }
344      delete paramIT;
345
346      PRINT(3)("</%s>\n\n", enumClassDesc->className);
347      enumClassDesc = classIT->nextElement();
348    }
349  delete classIT;
350  PRINT(3)("===============================================================\n");
351}
352
353
354
355/**
356   \param root: The XML-element to grab a parameter from
357   \param parameterName: the parameter to grab
358   \returns the Value of the parameter if found, NULL otherwise
359*/
360const char* grabParameter(const TiXmlElement* root, const char* parameterName)
361{
362  const TiXmlElement* element;
363  const TiXmlNode* node;
364
365  if (root == NULL)
366    return NULL;
367  assert( parameterName != NULL);
368
369  element = root->FirstChildElement( parameterName);
370  if( element == NULL) return NULL;
371
372  node = element->FirstChild();
373  while( node != NULL)
374    {
375      if( node->ToText()) return node->Value();
376      node = node->NextSibling();
377    }
378  return NULL;
379}
Note: See TracBrowser for help on using the repository browser.