Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: moved helper-functions to helper-functions.cc

File size: 11.3 KB
RevLine 
[4597]1/*
[4250]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:
[4285]12   main-programmer: Benjamin Grauer
[4250]13   co-programmer: ...
14*/
15
16#include "load_param.h"
17
[4254]18#include "list.h"
19#include "base_object.h"
[4250]20
[4254]21#include <stdarg.h>
22
[4256]23/**
[4836]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, ...)
[4256]30*/
[4496]31BaseLoadParam::BaseLoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName,
[4598]32                             int paramCount, bool multi, const void* pointerToParam, ...)
[4251]33{
[4597]34  this->setClassID(CL_LOAD_PARAM, "LoadParam");
[4637]35
[4496]36  this->loadString = NULL;
[4598]37  this->pointerToParam = pointerToParam;
[4299]38
[4598]39  if (paramCount == 0 || this->pointerToParam)
[4501]40    this->loadString = "none";
[4496]41  else
42    {
[4501]43      if (likely(!multi))
[4597]44        this->loadString = grabParameter(root, paramName);
[4501]45      else
[4597]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        }
[4496]54    }
55
[4255]56  this->paramDesc = NULL;
[4254]57  if (LoadClassDescription::parametersDescription)
[4623]58  {
[4625]59    // locating the class
[4623]60    this->classDesc = LoadClassDescription::addClass(object->getClassName());
[4254]61
[4623]62    if ((this->paramDesc = this->classDesc->addParam(paramName)) != NULL)
63    {
64
65      this->paramDesc->paramCount = paramCount;
[4254]66      this->paramDesc->types = new char*[paramCount];
[4623]67      this->paramDesc->defaultValues = new char*[paramCount];
[4254]68
69      va_list types;
[4598]70      va_start (types, pointerToParam);
[4623]71      char defaultVal[512];
[4254]72      for(int i = 0; i < paramCount; i++)
[4623]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))
[4597]81        {
[4623]82          sprintf(defaultVal, "%d", va_arg(types, l_INT_TYPE));
[4597]83        }
[4623]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      }
[4299]108      va_end(types);
[4254]109
110      int argCount = 0;
111    }
[4623]112  }
[4251]113}
[4250]114
[4860]115/**
[4836]116 * @param descriptionText The text to set as a description for this Parameter
117 * @returns a pointer to itself.
[4256]118*/
[4260]119BaseLoadParam* BaseLoadParam::describe(const char* descriptionText)
[4254]120{
[4255]121  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
[4254]122    {
[4255]123      this->paramDesc->setDescription(descriptionText);
[4254]124    }
[4260]125  return this;
[4254]126}
127
[4256]128/**
[4836]129 * @param paramName the name of the parameter to load
[4256]130*/
[4254]131LoadParamDescription::LoadParamDescription(const char* paramName)
132{
133  this->types = NULL;
[4255]134  this->description = NULL;
[4254]135  this->paramName = new char[strlen(paramName)+1];
136  strcpy(this->paramName, paramName);
[4623]137  this->defaultValues = NULL;
[4254]138}
139
[4256]140/**
[4836]141 *  removes all the alocated memory
[4256]142*/
[4746]143LoadParamDescription::~LoadParamDescription()
[4254]144{
[5099]145  if (this->types != NULL)
[4623]146  {
[5099]147    for(int i = 0; i < this->paramCount; i++)
148    {
149      delete []this->types[i];
150    }
[4623]151  }
[5099]152  if (this->defaultValues != NULL)
[4623]153  {
[5099]154    for(int i = 0; i < this->paramCount; i++)
155    {
156      delete []this->defaultValues[i];
157    }
[4623]158  }
159
[4254]160  delete []this->types;
[4623]161  delete []this->defaultValues;
[4254]162  delete []this->paramName;
[4256]163  delete []this->description;
[4254]164}
165
[4256]166/**
[4836]167 * @param descriptionText The text to set as a description for this Parameter
[4256]168*/
[4255]169void LoadParamDescription::setDescription(const char* descriptionText)
170{
[4256]171  this->description = new char[strlen(descriptionText)+1];
172  strcpy(this->description, descriptionText);
[4255]173}
[4254]174
[4256]175/**
[4836]176 *  prints out this parameter, its input method and the description (if availiable)
[4256]177*/
[4746]178void LoadParamDescription::print() const
[4255]179{
180  PRINT(3)(" <%s>", this->paramName);
181  for (int i = 0; i < this->paramCount; i++)
182    {
183      if (i > 0)
[4597]184        PRINT(3)(",");
[4255]185      PRINT(3)("%s", this->types[i]);
186    }
187  PRINT(3)("</%s>", this->paramName);
188  if (this->description)
189    PRINT(3)(" -- %s", this->description);
[4623]190  // default values
191  if (this->paramCount > 0)
192  {
[4637]193    PRINT(3)(" (Default: ");
[4623]194    for (int i = 0; i < this->paramCount; i++)
195    {
196      if (i > 0)
197        PRINT(3)(", ");
[4625]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      }
[4623]206    }
207    PRINT(3)(")");
208  }
[4255]209  PRINT(3)("\n");
210}
211
[4256]212/**
[4836]213 *  A list, that holds all the classes that are loadable (classes not objects!!)
[4256]214*/
[4254]215tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
216
[4251]217/**
[4836]218 *  if the description of Parameters should be executed
[4251]219*/
[4254]220bool LoadClassDescription::parametersDescription = true;
221
[4256]222/**
[4836]223 * @param className the name of the class to be loadable
[4256]224*/
[4254]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
[4256]235/**
[4836]236 *  deletes a classDescription (deletes all the parameterDescriptions as well
[4256]237*/
[4746]238LoadClassDescription::~LoadClassDescription()
[4254]239{
240  delete []this->className;
241
242  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
[5115]243  LoadParamDescription* enumParamDesc = iterator->firstElement();
[4254]244  while (enumParamDesc)
245    {
246      delete enumParamDesc;
247      enumParamDesc = iterator->nextElement();
248    }
249  delete iterator;
250}
251
[4256]252/**
[4836]253 *  adds a class to the list of loadable classes
254 * @param className The name of the class to add
[4254]255
[4256]256   this function searches for the className string, and if found just returns the appropriate Class.
257   Otherwise it returns a new classDescription
258*/
[4254]259LoadClassDescription* LoadClassDescription::addClass(const char* className)
260{
261  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
[5115]262  LoadClassDescription* enumClassDesc = iterator->firstElement();
[4254]263  while (enumClassDesc)
264    {
265      if (!strcmp(enumClassDesc->className, className))
[4597]266        {
267          delete iterator;
268          return enumClassDesc;
269        }
[4254]270      enumClassDesc = iterator->nextElement();
271    }
272  delete iterator;
273
274  return new LoadClassDescription(className);
275}
276
[4256]277/**
[4836]278 *  does the same as addClass(const char* className), but with params
279 * @param paramName the name of the parameter to add.
[4256]280*/
[4254]281LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
282{
283  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
[5115]284  LoadParamDescription* enumParamDesc = iterator->firstElement();
[4254]285  while (enumParamDesc)
286    {
287      if (!strcmp(enumParamDesc->paramName, paramName))
[4597]288        {
289          delete iterator;
290          return enumParamDesc;
291        }
[4254]292      enumParamDesc = iterator->nextElement();
293    }
294  delete iterator;
295
296  this->paramList->add(new LoadParamDescription(paramName));
297  return paramList->lastElement();
298}
[4255]299
[4256]300/**
[4836]301 *  prints out all loadable Classes, and their parameters
[5100]302 * @param fileName prints the output to a File
303 * @todo implement it
[4256]304*/
[4260]305void LoadClassDescription::printAll(const char* fileName)
[4255]306{
[4259]307  PRINT(3)("===============================================================\n");
308  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
[4255]309  tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
[5115]310  LoadClassDescription* enumClassDesc = classIT->firstElement();
[4255]311  while (enumClassDesc)
312    {
313      PRINT(3)("<%s>\n", enumClassDesc->className);
314      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
[5115]315      LoadParamDescription* enumParamDesc = paramIT->firstElement();
[4255]316      while (enumParamDesc)
[4597]317        {
318          enumParamDesc->print();
319          enumParamDesc = paramIT->nextElement();
320        }
[4255]321      delete paramIT;
322
323      PRINT(3)("</%s>\n\n", enumClassDesc->className);
324      enumClassDesc = classIT->nextElement();
325    }
326  delete classIT;
[4259]327  PRINT(3)("===============================================================\n");
[4255]328}
[4492]329
[5100]330/**
331 * searches for classes, which beginn with classNameBegin
332 * @param classNameBegin the beginning string of a Class
[5113]333 * @return a NEW char-array with ClassNames. The LIST should be deleted afterwards,
[5100]334 * !! The strings MUST NOT be deleted !!
335 */
[5113]336tList<const char>* LoadClassDescription::searchClassWithShort(const char* classNameBegin)
[5100]337{
338  unsigned int searchLength = strlen(classNameBegin);
[5113]339  tList<const char>* retVal = new tList<const char>;
[4492]340
[5100]341  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
[5115]342  LoadClassDescription* enumClassDesc = iterator->firstElement();
[5100]343  while (enumClassDesc)
344  {
345    if (strlen(enumClassDesc->className)>searchLength+1 &&
346        !strncasecmp(enumClassDesc->className, classNameBegin, searchLength))
347    {
[5113]348      retVal->add(enumClassDesc->className);
[5100]349    }
350    enumClassDesc = iterator->nextElement();
351  }
352  delete iterator;
[4492]353
[5100]354  return retVal;
355}
356
357// const LoadParamDescription* LoadParamDescription::getClass(const char* className)
358// {
359//   tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
[5115]360//   LoadClassDescription* enumClassDesc = iterator->firstElement();
[5100]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
[4492]375/**
[4836]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
[4492]379*/
380const char* grabParameter(const TiXmlElement* root, const char* parameterName)
381{
382  const TiXmlElement* element;
383  const TiXmlNode* node;
[4597]384
[4492]385  if (root == NULL)
386    return NULL;
387  assert( parameterName != NULL);
[4597]388
[4492]389  element = root->FirstChildElement( parameterName);
390  if( element == NULL) return NULL;
[4597]391
[4492]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.