Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: default Values should work now

File size: 10.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#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      //! \todo this must only be done once for each class.
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      PRINT(3)("%s", this->defaultValues[i]);
225    }
226    PRINT(3)(")");
227  }
228  PRINT(3)("\n");
229}
230
231/**
232   \brief A list, that holds all the classes that are loadable (classes not objects!!)
233*/
234tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
235
236/**
237   \brief if the description of Parameters should be executed
238*/
239bool LoadClassDescription::parametersDescription = true;
240
241/**
242   \param className the name of the class to be loadable
243*/
244LoadClassDescription::LoadClassDescription(const char* className)
245{
246  this->className = new char[strlen(className)+1];
247  strcpy(this->className, className);
248
249  classList->add(this);
250
251  this->paramList = new tList<LoadParamDescription>;
252}
253
254/**
255   \brief deletes a classDescription (deletes all the parameterDescriptions as well
256*/
257LoadClassDescription::~LoadClassDescription(void)
258{
259  delete []this->className;
260
261  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
262  LoadParamDescription* enumParamDesc = iterator->nextElement();
263  while (enumParamDesc)
264    {
265      delete enumParamDesc;
266      enumParamDesc = iterator->nextElement();
267    }
268  delete iterator;
269}
270
271/**
272   \brief adds a class to the list of loadable classes
273   \param className The name of the class to add
274
275   this function searches for the className string, and if found just returns the appropriate Class.
276   Otherwise it returns a new classDescription
277*/
278LoadClassDescription* LoadClassDescription::addClass(const char* className)
279{
280  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
281  LoadClassDescription* enumClassDesc = iterator->nextElement();
282  while (enumClassDesc)
283    {
284      if (!strcmp(enumClassDesc->className, className))
285        {
286          delete iterator;
287          return enumClassDesc;
288        }
289      enumClassDesc = iterator->nextElement();
290    }
291  delete iterator;
292
293  return new LoadClassDescription(className);
294}
295
296/**
297   \brief does the same as addClass(const char* className), but with params
298   \param paramName the name of the parameter to add.
299*/
300LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
301{
302  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
303  LoadParamDescription* enumParamDesc = iterator->nextElement();
304  while (enumParamDesc)
305    {
306      if (!strcmp(enumParamDesc->paramName, paramName))
307        {
308          delete iterator;
309          return enumParamDesc;
310        }
311      enumParamDesc = iterator->nextElement();
312    }
313  delete iterator;
314
315  this->paramList->add(new LoadParamDescription(paramName));
316  return paramList->lastElement();
317}
318
319/**
320   \brief prints out all loadable Classes, and their parameters
321*/
322void LoadClassDescription::printAll(const char* fileName)
323{
324  PRINT(3)("===============================================================\n");
325  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
326  tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
327  LoadClassDescription* enumClassDesc = classIT->nextElement();
328  while (enumClassDesc)
329    {
330      PRINT(3)("<%s>\n", enumClassDesc->className);
331      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
332      LoadParamDescription* enumParamDesc = paramIT->nextElement();
333      while (enumParamDesc)
334        {
335          enumParamDesc->print();
336          enumParamDesc = paramIT->nextElement();
337        }
338      delete paramIT;
339
340      PRINT(3)("</%s>\n\n", enumClassDesc->className);
341      enumClassDesc = classIT->nextElement();
342    }
343  delete classIT;
344  PRINT(3)("===============================================================\n");
345}
346
347
348
349/**
350   \param root: The XML-element to grab a parameter from
351   \param parameterName: the parameter to grab
352   \returns the Value of the parameter if found, NULL otherwise
353*/
354const char* grabParameter(const TiXmlElement* root, const char* parameterName)
355{
356  const TiXmlElement* element;
357  const TiXmlNode* node;
358
359  if (root == NULL)
360    return NULL;
361  assert( parameterName != NULL);
362
363  element = root->FirstChildElement( parameterName);
364  if( element == NULL) return NULL;
365
366  node = element->FirstChild();
367  while( node != NULL)
368    {
369      if( node->ToText()) return node->Value();
370      node = node->NextSibling();
371    }
372  return NULL;
373}
Note: See TracBrowser for help on using the repository browser.