Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: made bool's loadable

File size: 10.9 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/**
116 * checks if the input was a Bool
117 * @param BOOL a String that holds a bool: must be one of those: 1,0,true,false,TRUE,FALSE
118 * @param defaultValue a default value that is set, if BOOL is corrupt
119 * @return returns the bool, if BOOL was correct otherwise defaultValue
120 */
121bool isBool(const char* BOOL, bool defaultValue)
122{
123  if(!strcmp(BOOL, "1") || !strcmp( BOOL,"true") || !strcmp(BOOL,"TRUE"))
124    return true;
125  else if (!strcmp(BOOL, "0") || !strcmp( BOOL,"false") || !strcmp(BOOL,"FALSE"))
126    return false;
127  else
128    return defaultValue;
129
130}
131
132int isInt(const char* INT, int defaultValue)
133{
134  char* endPtr = NULL;
135  int result = strtol(INT, &endPtr, 10);
136
137  if ( endPtr >= INT && endPtr < INT + strlen(INT))
138    return defaultValue;
139  else
140    return result;
141}
142
143float isFloat(const char* FLOAT, float defaultValue)
144{
145  char* endPtr = NULL;
146  double result = strtod(FLOAT, &endPtr);
147
148  if ( endPtr >= FLOAT && endPtr < FLOAT + strlen(FLOAT))
149    return defaultValue;
150  else
151    return result;
152}
153
154const Vector& isVector(const char* VECTOR, const Vector& defaultValue)
155{
156
157
158}
159
160const char* isString(const char* STRING, const char* defaultValue)
161{
162  if (STRING != NULL)
163    return STRING;
164  else
165    return defaultValue;
166}
167
168
169/**
170 * @param descriptionText The text to set as a description for this Parameter
171 * @returns a pointer to itself.
172*/
173BaseLoadParam* BaseLoadParam::describe(const char* descriptionText)
174{
175  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
176    {
177      this->paramDesc->setDescription(descriptionText);
178    }
179  return this;
180}
181
182/**
183 * @param paramName the name of the parameter to load
184*/
185LoadParamDescription::LoadParamDescription(const char* paramName)
186{
187  this->types = NULL;
188  this->description = NULL;
189  this->paramName = new char[strlen(paramName)+1];
190  strcpy(this->paramName, paramName);
191  this->defaultValues = NULL;
192}
193
194/**
195 *  removes all the alocated memory
196*/
197LoadParamDescription::~LoadParamDescription()
198{
199  for(int i = 0; i < this->paramCount; i++)
200  {
201    delete this->types[i];
202  }
203  for(int i = 0; i < this->paramCount; i++)
204  {
205    delete this->defaultValues[i];
206  }
207
208  delete []this->types;
209  delete []this->defaultValues;
210  delete []this->paramName;
211  delete []this->description;
212}
213
214/**
215 * @param descriptionText The text to set as a description for this Parameter
216*/
217void LoadParamDescription::setDescription(const char* descriptionText)
218{
219  this->description = new char[strlen(descriptionText)+1];
220  strcpy(this->description, descriptionText);
221}
222
223/**
224 *  prints out this parameter, its input method and the description (if availiable)
225*/
226void LoadParamDescription::print() const
227{
228  PRINT(3)(" <%s>", this->paramName);
229  for (int i = 0; i < this->paramCount; i++)
230    {
231      if (i > 0)
232        PRINT(3)(",");
233      PRINT(3)("%s", this->types[i]);
234    }
235  PRINT(3)("</%s>", this->paramName);
236  if (this->description)
237    PRINT(3)(" -- %s", this->description);
238  // default values
239  if (this->paramCount > 0)
240  {
241    PRINT(3)(" (Default: ");
242    for (int i = 0; i < this->paramCount; i++)
243    {
244      if (i > 0)
245        PRINT(3)(", ");
246      if (!strcmp(this->types[i], l_STRING_NAME))
247      { // leave brackets !!
248        PRINT(3)("\"%s\"", this->defaultValues[i]);
249      }
250      else
251      {
252        PRINT(3)("%s", this->defaultValues[i]);
253      }
254    }
255    PRINT(3)(")");
256  }
257  PRINT(3)("\n");
258}
259
260/**
261 *  A list, that holds all the classes that are loadable (classes not objects!!)
262*/
263tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
264
265/**
266 *  if the description of Parameters should be executed
267*/
268bool LoadClassDescription::parametersDescription = true;
269
270/**
271 * @param className the name of the class to be loadable
272*/
273LoadClassDescription::LoadClassDescription(const char* className)
274{
275  this->className = new char[strlen(className)+1];
276  strcpy(this->className, className);
277
278  classList->add(this);
279
280  this->paramList = new tList<LoadParamDescription>;
281}
282
283/**
284 *  deletes a classDescription (deletes all the parameterDescriptions as well
285*/
286LoadClassDescription::~LoadClassDescription()
287{
288  delete []this->className;
289
290  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
291  LoadParamDescription* enumParamDesc = iterator->nextElement();
292  while (enumParamDesc)
293    {
294      delete enumParamDesc;
295      enumParamDesc = iterator->nextElement();
296    }
297  delete iterator;
298}
299
300/**
301 *  adds a class to the list of loadable classes
302 * @param className The name of the class to add
303
304   this function searches for the className string, and if found just returns the appropriate Class.
305   Otherwise it returns a new classDescription
306*/
307LoadClassDescription* LoadClassDescription::addClass(const char* className)
308{
309  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
310  LoadClassDescription* enumClassDesc = iterator->nextElement();
311  while (enumClassDesc)
312    {
313      if (!strcmp(enumClassDesc->className, className))
314        {
315          delete iterator;
316          return enumClassDesc;
317        }
318      enumClassDesc = iterator->nextElement();
319    }
320  delete iterator;
321
322  return new LoadClassDescription(className);
323}
324
325/**
326 *  does the same as addClass(const char* className), but with params
327 * @param paramName the name of the parameter to add.
328*/
329LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
330{
331  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
332  LoadParamDescription* enumParamDesc = iterator->nextElement();
333  while (enumParamDesc)
334    {
335      if (!strcmp(enumParamDesc->paramName, paramName))
336        {
337          delete iterator;
338          return enumParamDesc;
339        }
340      enumParamDesc = iterator->nextElement();
341    }
342  delete iterator;
343
344  this->paramList->add(new LoadParamDescription(paramName));
345  return paramList->lastElement();
346}
347
348/**
349 *  prints out all loadable Classes, and their parameters
350*/
351void LoadClassDescription::printAll(const char* fileName)
352{
353  PRINT(3)("===============================================================\n");
354  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
355  tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
356  LoadClassDescription* enumClassDesc = classIT->nextElement();
357  while (enumClassDesc)
358    {
359      PRINT(3)("<%s>\n", enumClassDesc->className);
360      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
361      LoadParamDescription* enumParamDesc = paramIT->nextElement();
362      while (enumParamDesc)
363        {
364          enumParamDesc->print();
365          enumParamDesc = paramIT->nextElement();
366        }
367      delete paramIT;
368
369      PRINT(3)("</%s>\n\n", enumClassDesc->className);
370      enumClassDesc = classIT->nextElement();
371    }
372  delete classIT;
373  PRINT(3)("===============================================================\n");
374}
375
376
377
378/**
379 * @param root: The XML-element to grab a parameter from
380 * @param parameterName: the parameter to grab
381 * @returns the Value of the parameter if found, NULL otherwise
382*/
383const char* grabParameter(const TiXmlElement* root, const char* parameterName)
384{
385  const TiXmlElement* element;
386  const TiXmlNode* node;
387
388  if (root == NULL)
389    return NULL;
390  assert( parameterName != NULL);
391
392  element = root->FirstChildElement( parameterName);
393  if( element == NULL) return NULL;
394
395  node = element->FirstChild();
396  while( node != NULL)
397    {
398      if( node->ToText()) return node->Value();
399      node = node->NextSibling();
400    }
401  return NULL;
402}
Note: See TracBrowser for help on using the repository browser.