Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: valgrind mem-leak-recovered

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