Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: particles_fun compiles again

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