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
RevLine 
[4597]1/*
[4250]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:
[4285]12   main-programmer: Benjamin Grauer
[4250]13   co-programmer: ...
14*/
15
16#include "load_param.h"
17
[4254]18#include "list.h"
19#include "base_object.h"
[4250]20
[4254]21#include <stdarg.h>
22
[4256]23/**
24   \param object The object this Parameter is loaded too.
[4487]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
[4496]28   \param multi: if false LoadParam assumes only one occurence of this parameter in root, if true it assumes multiple occurences.
[4623]29   \param ...: the parameter information (1. Parameter, 2. Default Value for the Parameter, ...)
[4256]30*/
[4496]31BaseLoadParam::BaseLoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName,
[4598]32                             int paramCount, bool multi, const void* pointerToParam, ...)
[4251]33{
[4597]34  this->setClassID(CL_LOAD_PARAM, "LoadParam");
[4496]35  this->loadString = NULL;
[4598]36  this->pointerToParam = pointerToParam;
[4299]37
[4598]38  if (paramCount == 0 || this->pointerToParam)
[4501]39    this->loadString = "none";
[4496]40  else
41    {
[4501]42      if (likely(!multi))
[4597]43        this->loadString = grabParameter(root, paramName);
[4501]44      else
[4597]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        }
[4496]53    }
54
[4255]55  this->paramDesc = NULL;
[4254]56  if (LoadClassDescription::parametersDescription)
[4623]57  {
[4625]58    // locating the class
[4623]59    this->classDesc = LoadClassDescription::addClass(object->getClassName());
[4254]60
[4623]61    if ((this->paramDesc = this->classDesc->addParam(paramName)) != NULL)
62    {
63
64      this->paramDesc->paramCount = paramCount;
[4254]65      this->paramDesc->types = new char*[paramCount];
[4623]66      this->paramDesc->defaultValues = new char*[paramCount];
[4254]67
68      va_list types;
[4598]69      va_start (types, pointerToParam);
[4623]70      char defaultVal[512];
[4254]71      for(int i = 0; i < paramCount; i++)
[4623]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))
[4597]80        {
[4623]81          sprintf(defaultVal, "%d", va_arg(types, l_INT_TYPE));
[4597]82        }
[4623]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      }
[4299]107      va_end(types);
[4254]108
109      int argCount = 0;
110    }
[4623]111  }
[4251]112}
[4250]113
[4624]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
[4256]146/**
147   \param descriptionText The text to set as a description for this Parameter
[4260]148   \returns a pointer to itself.
[4256]149*/
[4260]150BaseLoadParam* BaseLoadParam::describe(const char* descriptionText)
[4254]151{
[4255]152  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
[4254]153    {
[4255]154      this->paramDesc->setDescription(descriptionText);
[4254]155    }
[4260]156  return this;
[4254]157}
158
[4256]159/**
160   \param paramName the name of the parameter to load
161*/
[4254]162LoadParamDescription::LoadParamDescription(const char* paramName)
163{
164  this->types = NULL;
[4255]165  this->description = NULL;
[4254]166  this->paramName = new char[strlen(paramName)+1];
167  strcpy(this->paramName, paramName);
[4623]168  this->defaultValues = NULL;
[4254]169}
170
[4256]171/**
172   \brief removes all the alocated memory
173*/
[4254]174LoadParamDescription::~LoadParamDescription(void)
175{
176  for(int i = 0; i < this->paramCount; i++)
[4623]177  {
178    delete this->types[i];
179  }
180  for(int i = 0; i < this->paramCount; i++)
181  {
182    delete this->defaultValues[i];
183  }
184
[4254]185  delete []this->types;
[4623]186  delete []this->defaultValues;
[4254]187  delete []this->paramName;
[4256]188  delete []this->description;
[4254]189}
190
[4256]191/**
192   \param descriptionText The text to set as a description for this Parameter
193*/
[4255]194void LoadParamDescription::setDescription(const char* descriptionText)
195{
[4256]196  this->description = new char[strlen(descriptionText)+1];
197  strcpy(this->description, descriptionText);
[4255]198}
[4254]199
[4256]200/**
201   \brief prints out this parameter, its input method and the description (if availiable)
202*/
[4255]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)
[4597]209        PRINT(3)(",");
[4255]210      PRINT(3)("%s", this->types[i]);
211    }
212  PRINT(3)("</%s>", this->paramName);
213  if (this->description)
214    PRINT(3)(" -- %s", this->description);
[4623]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)(", ");
[4625]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      }
[4623]231    }
232    PRINT(3)(")");
233  }
[4255]234  PRINT(3)("\n");
235}
236
[4256]237/**
238   \brief A list, that holds all the classes that are loadable (classes not objects!!)
239*/
[4254]240tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
241
[4251]242/**
243   \brief if the description of Parameters should be executed
244*/
[4254]245bool LoadClassDescription::parametersDescription = true;
246
[4256]247/**
248   \param className the name of the class to be loadable
249*/
[4254]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
[4256]260/**
261   \brief deletes a classDescription (deletes all the parameterDescriptions as well
262*/
[4254]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
[4256]277/**
278   \brief adds a class to the list of loadable classes
279   \param className The name of the class to add
[4254]280
[4256]281   this function searches for the className string, and if found just returns the appropriate Class.
282   Otherwise it returns a new classDescription
283*/
[4254]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))
[4597]291        {
292          delete iterator;
293          return enumClassDesc;
294        }
[4254]295      enumClassDesc = iterator->nextElement();
296    }
297  delete iterator;
298
299  return new LoadClassDescription(className);
300}
301
[4256]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*/
[4254]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))
[4597]313        {
314          delete iterator;
315          return enumParamDesc;
316        }
[4254]317      enumParamDesc = iterator->nextElement();
318    }
319  delete iterator;
320
321  this->paramList->add(new LoadParamDescription(paramName));
322  return paramList->lastElement();
323}
[4255]324
[4256]325/**
326   \brief prints out all loadable Classes, and their parameters
327*/
[4260]328void LoadClassDescription::printAll(const char* fileName)
[4255]329{
[4259]330  PRINT(3)("===============================================================\n");
331  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
[4255]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)
[4597]340        {
341          enumParamDesc->print();
342          enumParamDesc = paramIT->nextElement();
343        }
[4255]344      delete paramIT;
345
346      PRINT(3)("</%s>\n\n", enumClassDesc->className);
347      enumClassDesc = classIT->nextElement();
348    }
349  delete classIT;
[4259]350  PRINT(3)("===============================================================\n");
[4255]351}
[4492]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;
[4597]364
[4492]365  if (root == NULL)
366    return NULL;
367  assert( parameterName != NULL);
[4597]368
[4492]369  element = root->FirstChildElement( parameterName);
370  if( element == NULL) return NULL;
[4597]371
[4492]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.