Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk:restoring the trunk…

File size: 12.5 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/**
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;
[4624]129
[4860]130}
131
[4734]132int isInt(const char* INT, int defaultValue)
[4624]133{
134  char* endPtr = NULL;
[4734]135  int result = strtol(INT, &endPtr, 10);
[4624]136
[4734]137  if ( endPtr >= INT && endPtr < INT + strlen(INT))
[4624]138    return defaultValue;
139  else
140    return result;
141}
142
[4734]143float isFloat(const char* FLOAT, float defaultValue)
[4624]144{
145  char* endPtr = NULL;
[4734]146  double result = strtod(FLOAT, &endPtr);
[4624]147
[4734]148  if ( endPtr >= FLOAT && endPtr < FLOAT + strlen(FLOAT))
[4624]149    return defaultValue;
150  else
151    return result;
152}
153
[4734]154const Vector& isVector(const char* VECTOR, const Vector& defaultValue)
[4624]155{
[4734]156
157
158}
159
160const char* isString(const char* STRING, const char* defaultValue)
161{
162  if (STRING != NULL)
163    return STRING;
[4624]164  else
165    return defaultValue;
166}
167
168
[4256]169/**
[4836]170 * @param descriptionText The text to set as a description for this Parameter
171 * @returns a pointer to itself.
[4256]172*/
[4260]173BaseLoadParam* BaseLoadParam::describe(const char* descriptionText)
[4254]174{
[4255]175  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
[4254]176    {
[4255]177      this->paramDesc->setDescription(descriptionText);
[4254]178    }
[4260]179  return this;
[4254]180}
181
[4256]182/**
[4836]183 * @param paramName the name of the parameter to load
[4256]184*/
[4254]185LoadParamDescription::LoadParamDescription(const char* paramName)
186{
187  this->types = NULL;
[4255]188  this->description = NULL;
[4254]189  this->paramName = new char[strlen(paramName)+1];
190  strcpy(this->paramName, paramName);
[4623]191  this->defaultValues = NULL;
[4254]192}
193
[4256]194/**
[4836]195 *  removes all the alocated memory
[4256]196*/
[4746]197LoadParamDescription::~LoadParamDescription()
[4254]198{
[5099]199  if (this->types != NULL)
[4623]200  {
[5099]201    for(int i = 0; i < this->paramCount; i++)
202    {
203      delete []this->types[i];
204    }
[4623]205  }
[5099]206  if (this->defaultValues != NULL)
[4623]207  {
[5099]208    for(int i = 0; i < this->paramCount; i++)
209    {
210      delete []this->defaultValues[i];
211    }
[4623]212  }
213
[4254]214  delete []this->types;
[4623]215  delete []this->defaultValues;
[4254]216  delete []this->paramName;
[4256]217  delete []this->description;
[4254]218}
219
[4256]220/**
[4836]221 * @param descriptionText The text to set as a description for this Parameter
[4256]222*/
[4255]223void LoadParamDescription::setDescription(const char* descriptionText)
224{
[4256]225  this->description = new char[strlen(descriptionText)+1];
226  strcpy(this->description, descriptionText);
[4255]227}
[4254]228
[4256]229/**
[4836]230 *  prints out this parameter, its input method and the description (if availiable)
[4256]231*/
[4746]232void LoadParamDescription::print() const
[4255]233{
234  PRINT(3)(" <%s>", this->paramName);
235  for (int i = 0; i < this->paramCount; i++)
236    {
237      if (i > 0)
[4597]238        PRINT(3)(",");
[4255]239      PRINT(3)("%s", this->types[i]);
240    }
241  PRINT(3)("</%s>", this->paramName);
242  if (this->description)
243    PRINT(3)(" -- %s", this->description);
[4623]244  // default values
245  if (this->paramCount > 0)
246  {
[4637]247    PRINT(3)(" (Default: ");
[4623]248    for (int i = 0; i < this->paramCount; i++)
249    {
250      if (i > 0)
251        PRINT(3)(", ");
[4625]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      }
[4623]260    }
261    PRINT(3)(")");
262  }
[4255]263  PRINT(3)("\n");
264}
265
[4256]266/**
[4836]267 *  A list, that holds all the classes that are loadable (classes not objects!!)
[4256]268*/
[4254]269tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
270
[4251]271/**
[4836]272 *  if the description of Parameters should be executed
[4251]273*/
[4254]274bool LoadClassDescription::parametersDescription = true;
275
[4256]276/**
[4836]277 * @param className the name of the class to be loadable
[4256]278*/
[4254]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
[4256]289/**
[4836]290 *  deletes a classDescription (deletes all the parameterDescriptions as well
[4256]291*/
[4746]292LoadClassDescription::~LoadClassDescription()
[4254]293{
294  delete []this->className;
295
296  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
[5111]297  LoadParamDescription* enumParamDesc = iterator->nextElement();
[4254]298  while (enumParamDesc)
299    {
300      delete enumParamDesc;
301      enumParamDesc = iterator->nextElement();
302    }
303  delete iterator;
304}
305
[4256]306/**
[4836]307 *  adds a class to the list of loadable classes
308 * @param className The name of the class to add
[4254]309
[4256]310   this function searches for the className string, and if found just returns the appropriate Class.
311   Otherwise it returns a new classDescription
312*/
[4254]313LoadClassDescription* LoadClassDescription::addClass(const char* className)
314{
315  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
[5111]316  LoadClassDescription* enumClassDesc = iterator->nextElement();
[4254]317  while (enumClassDesc)
318    {
319      if (!strcmp(enumClassDesc->className, className))
[4597]320        {
321          delete iterator;
322          return enumClassDesc;
323        }
[4254]324      enumClassDesc = iterator->nextElement();
325    }
326  delete iterator;
327
328  return new LoadClassDescription(className);
329}
330
[4256]331/**
[4836]332 *  does the same as addClass(const char* className), but with params
333 * @param paramName the name of the parameter to add.
[4256]334*/
[4254]335LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
336{
337  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
[5111]338  LoadParamDescription* enumParamDesc = iterator->nextElement();
[4254]339  while (enumParamDesc)
340    {
341      if (!strcmp(enumParamDesc->paramName, paramName))
[4597]342        {
343          delete iterator;
344          return enumParamDesc;
345        }
[4254]346      enumParamDesc = iterator->nextElement();
347    }
348  delete iterator;
349
350  this->paramList->add(new LoadParamDescription(paramName));
351  return paramList->lastElement();
352}
[4255]353
[4256]354/**
[4836]355 *  prints out all loadable Classes, and their parameters
[5100]356 * @param fileName prints the output to a File
357 * @todo implement it
[4256]358*/
[4260]359void LoadClassDescription::printAll(const char* fileName)
[4255]360{
[4259]361  PRINT(3)("===============================================================\n");
362  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
[4255]363  tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
[5111]364  LoadClassDescription* enumClassDesc = classIT->nextElement();
[4255]365  while (enumClassDesc)
366    {
367      PRINT(3)("<%s>\n", enumClassDesc->className);
368      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
[5111]369      LoadParamDescription* enumParamDesc = paramIT->nextElement();
[4255]370      while (enumParamDesc)
[4597]371        {
372          enumParamDesc->print();
373          enumParamDesc = paramIT->nextElement();
374        }
[4255]375      delete paramIT;
376
377      PRINT(3)("</%s>\n\n", enumClassDesc->className);
378      enumClassDesc = classIT->nextElement();
379    }
380  delete classIT;
[4259]381  PRINT(3)("===============================================================\n");
[4255]382}
[4492]383
[5100]384/**
385 * searches for classes, which beginn with classNameBegin
386 * @param classNameBegin the beginning string of a Class
[5113]387 * @return a NEW char-array with ClassNames. The LIST should be deleted afterwards,
[5100]388 * !! The strings MUST NOT be deleted !!
389 */
[5113]390tList<const char>* LoadClassDescription::searchClassWithShort(const char* classNameBegin)
[5100]391{
392  unsigned int searchLength = strlen(classNameBegin);
[5113]393  tList<const char>* retVal = new tList<const char>;
[4492]394
[5100]395  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
[5111]396  LoadClassDescription* enumClassDesc = iterator->nextElement();
[5100]397  while (enumClassDesc)
398  {
399    if (strlen(enumClassDesc->className)>searchLength+1 &&
400        !strncasecmp(enumClassDesc->className, classNameBegin, searchLength))
401    {
[5113]402      retVal->add(enumClassDesc->className);
[5100]403    }
404    enumClassDesc = iterator->nextElement();
405  }
406  delete iterator;
[4492]407
[5100]408  return retVal;
409}
410
411// const LoadParamDescription* LoadParamDescription::getClass(const char* className)
412// {
413//   tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
[5111]414//   LoadClassDescription* enumClassDesc = iterator->nextElement();
[5100]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
[4492]429/**
[4836]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
[4492]433*/
434const char* grabParameter(const TiXmlElement* root, const char* parameterName)
435{
436  const TiXmlElement* element;
437  const TiXmlNode* node;
[4597]438
[4492]439  if (root == NULL)
440    return NULL;
441  assert( parameterName != NULL);
[4597]442
[4492]443  element = root->FirstChildElement( parameterName);
444  if( element == NULL) return NULL;
[4597]445
[4492]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.