Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: changed the behaviour of the iterator.
Now it is soon possible to walk through a List from front and back, and tell the Iterator from where to seek

@patrick: i had to disable your Collision-Detection algorithms, because they had a seekElement inside, that i did not entirely grasp the meaning of….
trying to fix this now

File size: 12.5 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  if (this->types != NULL)
200  {
201    for(int i = 0; i < this->paramCount; i++)
202    {
203      delete []this->types[i];
204    }
205  }
206  if (this->defaultValues != NULL)
207  {
208    for(int i = 0; i < this->paramCount; i++)
209    {
210      delete []this->defaultValues[i];
211    }
212  }
213
214  delete []this->types;
215  delete []this->defaultValues;
216  delete []this->paramName;
217  delete []this->description;
218}
219
220/**
221 * @param descriptionText The text to set as a description for this Parameter
222*/
223void LoadParamDescription::setDescription(const char* descriptionText)
224{
225  this->description = new char[strlen(descriptionText)+1];
226  strcpy(this->description, descriptionText);
227}
228
229/**
230 *  prints out this parameter, its input method and the description (if availiable)
231*/
232void LoadParamDescription::print() const
233{
234  PRINT(3)(" <%s>", this->paramName);
235  for (int i = 0; i < this->paramCount; i++)
236    {
237      if (i > 0)
238        PRINT(3)(",");
239      PRINT(3)("%s", this->types[i]);
240    }
241  PRINT(3)("</%s>", this->paramName);
242  if (this->description)
243    PRINT(3)(" -- %s", this->description);
244  // default values
245  if (this->paramCount > 0)
246  {
247    PRINT(3)(" (Default: ");
248    for (int i = 0; i < this->paramCount; i++)
249    {
250      if (i > 0)
251        PRINT(3)(", ");
252      if (!strcmp(this->types[i], l_STRING_NAME))
253      { // leave brackets !!
254        PRINT(3)("\"%s\"", this->defaultValues[i]);
255      }
256      else
257      {
258        PRINT(3)("%s", this->defaultValues[i]);
259      }
260    }
261    PRINT(3)(")");
262  }
263  PRINT(3)("\n");
264}
265
266/**
267 *  A list, that holds all the classes that are loadable (classes not objects!!)
268*/
269tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
270
271/**
272 *  if the description of Parameters should be executed
273*/
274bool LoadClassDescription::parametersDescription = true;
275
276/**
277 * @param className the name of the class to be loadable
278*/
279LoadClassDescription::LoadClassDescription(const char* className)
280{
281  this->className = new char[strlen(className)+1];
282  strcpy(this->className, className);
283
284  classList->add(this);
285
286  this->paramList = new tList<LoadParamDescription>;
287}
288
289/**
290 *  deletes a classDescription (deletes all the parameterDescriptions as well
291*/
292LoadClassDescription::~LoadClassDescription()
293{
294  delete []this->className;
295
296  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
297  LoadParamDescription* enumParamDesc = iterator->firstElement();
298  while (enumParamDesc)
299    {
300      delete enumParamDesc;
301      enumParamDesc = iterator->nextElement();
302    }
303  delete iterator;
304}
305
306/**
307 *  adds a class to the list of loadable classes
308 * @param className The name of the class to add
309
310   this function searches for the className string, and if found just returns the appropriate Class.
311   Otherwise it returns a new classDescription
312*/
313LoadClassDescription* LoadClassDescription::addClass(const char* className)
314{
315  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
316  LoadClassDescription* enumClassDesc = iterator->firstElement();
317  while (enumClassDesc)
318    {
319      if (!strcmp(enumClassDesc->className, className))
320        {
321          delete iterator;
322          return enumClassDesc;
323        }
324      enumClassDesc = iterator->nextElement();
325    }
326  delete iterator;
327
328  return new LoadClassDescription(className);
329}
330
331/**
332 *  does the same as addClass(const char* className), but with params
333 * @param paramName the name of the parameter to add.
334*/
335LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
336{
337  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
338  LoadParamDescription* enumParamDesc = iterator->firstElement();
339  while (enumParamDesc)
340    {
341      if (!strcmp(enumParamDesc->paramName, paramName))
342        {
343          delete iterator;
344          return enumParamDesc;
345        }
346      enumParamDesc = iterator->nextElement();
347    }
348  delete iterator;
349
350  this->paramList->add(new LoadParamDescription(paramName));
351  return paramList->lastElement();
352}
353
354/**
355 *  prints out all loadable Classes, and their parameters
356 * @param fileName prints the output to a File
357 * @todo implement it
358*/
359void LoadClassDescription::printAll(const char* fileName)
360{
361  PRINT(3)("===============================================================\n");
362  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
363  tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
364  LoadClassDescription* enumClassDesc = classIT->firstElement();
365  while (enumClassDesc)
366    {
367      PRINT(3)("<%s>\n", enumClassDesc->className);
368      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
369      LoadParamDescription* enumParamDesc = paramIT->firstElement();
370      while (enumParamDesc)
371        {
372          enumParamDesc->print();
373          enumParamDesc = paramIT->nextElement();
374        }
375      delete paramIT;
376
377      PRINT(3)("</%s>\n\n", enumClassDesc->className);
378      enumClassDesc = classIT->nextElement();
379    }
380  delete classIT;
381  PRINT(3)("===============================================================\n");
382}
383
384/**
385 * searches for classes, which beginn with classNameBegin
386 * @param classNameBegin the beginning string of a Class
387 * @return a NEW char-array with ClassNames. The LIST should be deleted afterwards,
388 * !! The strings MUST NOT be deleted !!
389 */
390tList<const char>* LoadClassDescription::searchClassWithShort(const char* classNameBegin)
391{
392  unsigned int searchLength = strlen(classNameBegin);
393  tList<const char>* retVal = new tList<const char>;
394
395  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
396  LoadClassDescription* enumClassDesc = iterator->firstElement();
397  while (enumClassDesc)
398  {
399    if (strlen(enumClassDesc->className)>searchLength+1 &&
400        !strncasecmp(enumClassDesc->className, classNameBegin, searchLength))
401    {
402      retVal->add(enumClassDesc->className);
403    }
404    enumClassDesc = iterator->nextElement();
405  }
406  delete iterator;
407
408  return retVal;
409}
410
411// const LoadParamDescription* LoadParamDescription::getClass(const char* className)
412// {
413//   tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
414//   LoadClassDescription* enumClassDesc = iterator->firstElement();
415//   while (enumClassDesc)
416//   {
417//     if (!strcmp(enumClassDesc->className, classNameBegin, className))
418//     {
419//       delete iterator;
420//       return enumClassDesc;
421//     }
422//     enumClassDesc = iterator->nextElement();
423//   }
424//   delete iterator;
425//
426//   return NULL;
427// }
428
429/**
430 * @param root: The XML-element to grab a parameter from
431 * @param parameterName: the parameter to grab
432 * @returns the Value of the parameter if found, NULL otherwise
433*/
434const char* grabParameter(const TiXmlElement* root, const char* parameterName)
435{
436  const TiXmlElement* element;
437  const TiXmlNode* node;
438
439  if (root == NULL)
440    return NULL;
441  assert( parameterName != NULL);
442
443  element = root->FirstChildElement( parameterName);
444  if( element == NULL) return NULL;
445
446  node = element->FirstChild();
447  while( node != NULL)
448    {
449      if( node->ToText()) return node->Value();
450      node = node->NextSibling();
451    }
452  return NULL;
453}
Note: See TracBrowser for help on using the repository browser.