Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: testing some AutoCompletion in the Shell.

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"
[5100]19#include "array.h"
[4254]20#include "base_object.h"
[4250]21
[4254]22#include <stdarg.h>
23
[4256]24/**
[4836]25 * @param object The object this Parameter is loaded too.
26 * @param root: the XML-element to load this option from.
27 * @param paramName: The name of the parameter loaded.
28 * @param paramCount: how many parameters this loading-function takes
29 * @param multi: if false LoadParam assumes only one occurence of this parameter in root, if true it assumes multiple occurences.
30 * @param ...: the parameter information (1. Parameter, 2. Default Value for the Parameter, ...)
[4256]31*/
[4496]32BaseLoadParam::BaseLoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName,
[4598]33                             int paramCount, bool multi, const void* pointerToParam, ...)
[4251]34{
[4597]35  this->setClassID(CL_LOAD_PARAM, "LoadParam");
[4637]36
[4496]37  this->loadString = NULL;
[4598]38  this->pointerToParam = pointerToParam;
[4299]39
[4598]40  if (paramCount == 0 || this->pointerToParam)
[4501]41    this->loadString = "none";
[4496]42  else
43    {
[4501]44      if (likely(!multi))
[4597]45        this->loadString = grabParameter(root, paramName);
[4501]46      else
[4597]47        {
48          if (!strcmp(root->Value(), paramName))
49            {
50              const TiXmlNode* val = root->FirstChild();
51              if( val->ToText())
52                this->loadString = val->Value();
53            }
54        }
[4496]55    }
56
[4255]57  this->paramDesc = NULL;
[4254]58  if (LoadClassDescription::parametersDescription)
[4623]59  {
[4625]60    // locating the class
[4623]61    this->classDesc = LoadClassDescription::addClass(object->getClassName());
[4254]62
[4623]63    if ((this->paramDesc = this->classDesc->addParam(paramName)) != NULL)
64    {
65
66      this->paramDesc->paramCount = paramCount;
[4254]67      this->paramDesc->types = new char*[paramCount];
[4623]68      this->paramDesc->defaultValues = new char*[paramCount];
[4254]69
70      va_list types;
[4598]71      va_start (types, pointerToParam);
[4623]72      char defaultVal[512];
[4254]73      for(int i = 0; i < paramCount; i++)
[4623]74      {
75          // parameters parsed
76        const char* tmpTypeName = va_arg (types, const char*);
77        this->paramDesc->types[i] = new char[strlen(tmpTypeName)+1];
78        strcpy(this->paramDesc->types[i], tmpTypeName);
79
80          // default value description
81        if (!strcmp(tmpTypeName, l_INT_NAME))
[4597]82        {
[4623]83          sprintf(defaultVal, "%d", va_arg(types, l_INT_TYPE));
[4597]84        }
[4623]85        else if (!strcmp(tmpTypeName, l_LONG_NAME))
86        {
87          sprintf(defaultVal, "%0.3f", va_arg(types, l_LONG_TYPE));
88        }
89          /*          else if (!strcmp(tmpTypeName, l_SHORT_NAME))
90        {
91        sprintf(defaultVal, "%d", va_arg(types, l_SHORT_TYPE));
92      }*/
93        else if (!strcmp(tmpTypeName, l_FLOAT_NAME))
94        {
95          sprintf(defaultVal, "%0.3f", va_arg(types, double));
96        }
97        else if (!strcmp(tmpTypeName, l_STRING_NAME))
98        {
99          sprintf(defaultVal, "%s", va_arg(types, l_STRING_TYPE));
100        }
101        else if (!strcmp(tmpTypeName, l_XML_ELEM_NAME))
102        {
103          sprintf(defaultVal, "");
104        }
105
106        this->paramDesc->defaultValues[i] = new char[strlen(defaultVal)+1];
107        strcpy(this->paramDesc->defaultValues[i], defaultVal);
108      }
[4299]109      va_end(types);
[4254]110
111      int argCount = 0;
112    }
[4623]113  }
[4251]114}
[4250]115
[4860]116/**
117 * checks if the input was a Bool
118 * @param BOOL a String that holds a bool: must be one of those: 1,0,true,false,TRUE,FALSE
119 * @param defaultValue a default value that is set, if BOOL is corrupt
120 * @return returns the bool, if BOOL was correct otherwise defaultValue
121 */
122bool isBool(const char* BOOL, bool defaultValue)
123{
124  if(!strcmp(BOOL, "1") || !strcmp( BOOL,"true") || !strcmp(BOOL,"TRUE"))
125    return true;
126  else if (!strcmp(BOOL, "0") || !strcmp( BOOL,"false") || !strcmp(BOOL,"FALSE"))
127    return false;
128  else
129    return defaultValue;
[4624]130
[4860]131}
132
[4734]133int isInt(const char* INT, int defaultValue)
[4624]134{
135  char* endPtr = NULL;
[4734]136  int result = strtol(INT, &endPtr, 10);
[4624]137
[4734]138  if ( endPtr >= INT && endPtr < INT + strlen(INT))
[4624]139    return defaultValue;
140  else
141    return result;
142}
143
[4734]144float isFloat(const char* FLOAT, float defaultValue)
[4624]145{
146  char* endPtr = NULL;
[4734]147  double result = strtod(FLOAT, &endPtr);
[4624]148
[4734]149  if ( endPtr >= FLOAT && endPtr < FLOAT + strlen(FLOAT))
[4624]150    return defaultValue;
151  else
152    return result;
153}
154
[4734]155const Vector& isVector(const char* VECTOR, const Vector& defaultValue)
[4624]156{
[4734]157
158
159}
160
161const char* isString(const char* STRING, const char* defaultValue)
162{
163  if (STRING != NULL)
164    return STRING;
[4624]165  else
166    return defaultValue;
167}
168
169
[4256]170/**
[4836]171 * @param descriptionText The text to set as a description for this Parameter
172 * @returns a pointer to itself.
[4256]173*/
[4260]174BaseLoadParam* BaseLoadParam::describe(const char* descriptionText)
[4254]175{
[4255]176  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
[4254]177    {
[4255]178      this->paramDesc->setDescription(descriptionText);
[4254]179    }
[4260]180  return this;
[4254]181}
182
[4256]183/**
[4836]184 * @param paramName the name of the parameter to load
[4256]185*/
[4254]186LoadParamDescription::LoadParamDescription(const char* paramName)
187{
188  this->types = NULL;
[4255]189  this->description = NULL;
[4254]190  this->paramName = new char[strlen(paramName)+1];
191  strcpy(this->paramName, paramName);
[4623]192  this->defaultValues = NULL;
[4254]193}
194
[4256]195/**
[4836]196 *  removes all the alocated memory
[4256]197*/
[4746]198LoadParamDescription::~LoadParamDescription()
[4254]199{
[5099]200  if (this->types != NULL)
[4623]201  {
[5099]202    for(int i = 0; i < this->paramCount; i++)
203    {
204      delete []this->types[i];
205    }
[4623]206  }
[5099]207  if (this->defaultValues != NULL)
[4623]208  {
[5099]209    for(int i = 0; i < this->paramCount; i++)
210    {
211      delete []this->defaultValues[i];
212    }
[4623]213  }
214
[4254]215  delete []this->types;
[4623]216  delete []this->defaultValues;
[4254]217  delete []this->paramName;
[4256]218  delete []this->description;
[4254]219}
220
[4256]221/**
[4836]222 * @param descriptionText The text to set as a description for this Parameter
[4256]223*/
[4255]224void LoadParamDescription::setDescription(const char* descriptionText)
225{
[4256]226  this->description = new char[strlen(descriptionText)+1];
227  strcpy(this->description, descriptionText);
[4255]228}
[4254]229
[4256]230/**
[4836]231 *  prints out this parameter, its input method and the description (if availiable)
[4256]232*/
[4746]233void LoadParamDescription::print() const
[4255]234{
235  PRINT(3)(" <%s>", this->paramName);
236  for (int i = 0; i < this->paramCount; i++)
237    {
238      if (i > 0)
[4597]239        PRINT(3)(",");
[4255]240      PRINT(3)("%s", this->types[i]);
241    }
242  PRINT(3)("</%s>", this->paramName);
243  if (this->description)
244    PRINT(3)(" -- %s", this->description);
[4623]245  // default values
246  if (this->paramCount > 0)
247  {
[4637]248    PRINT(3)(" (Default: ");
[4623]249    for (int i = 0; i < this->paramCount; i++)
250    {
251      if (i > 0)
252        PRINT(3)(", ");
[4625]253      if (!strcmp(this->types[i], l_STRING_NAME))
254      { // leave brackets !!
255        PRINT(3)("\"%s\"", this->defaultValues[i]);
256      }
257      else
258      {
259        PRINT(3)("%s", this->defaultValues[i]);
260      }
[4623]261    }
262    PRINT(3)(")");
263  }
[4255]264  PRINT(3)("\n");
265}
266
[4256]267/**
[4836]268 *  A list, that holds all the classes that are loadable (classes not objects!!)
[4256]269*/
[4254]270tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
271
[4251]272/**
[4836]273 *  if the description of Parameters should be executed
[4251]274*/
[4254]275bool LoadClassDescription::parametersDescription = true;
276
[4256]277/**
[4836]278 * @param className the name of the class to be loadable
[4256]279*/
[4254]280LoadClassDescription::LoadClassDescription(const char* className)
281{
282  this->className = new char[strlen(className)+1];
283  strcpy(this->className, className);
284
285  classList->add(this);
286
287  this->paramList = new tList<LoadParamDescription>;
288}
289
[4256]290/**
[4836]291 *  deletes a classDescription (deletes all the parameterDescriptions as well
[4256]292*/
[4746]293LoadClassDescription::~LoadClassDescription()
[4254]294{
295  delete []this->className;
296
297  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
298  LoadParamDescription* enumParamDesc = iterator->nextElement();
299  while (enumParamDesc)
300    {
301      delete enumParamDesc;
302      enumParamDesc = iterator->nextElement();
303    }
304  delete iterator;
305}
306
[4256]307/**
[4836]308 *  adds a class to the list of loadable classes
309 * @param className The name of the class to add
[4254]310
[4256]311   this function searches for the className string, and if found just returns the appropriate Class.
312   Otherwise it returns a new classDescription
313*/
[4254]314LoadClassDescription* LoadClassDescription::addClass(const char* className)
315{
316  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
317  LoadClassDescription* enumClassDesc = iterator->nextElement();
318  while (enumClassDesc)
319    {
320      if (!strcmp(enumClassDesc->className, className))
[4597]321        {
322          delete iterator;
323          return enumClassDesc;
324        }
[4254]325      enumClassDesc = iterator->nextElement();
326    }
327  delete iterator;
328
329  return new LoadClassDescription(className);
330}
331
[4256]332/**
[4836]333 *  does the same as addClass(const char* className), but with params
334 * @param paramName the name of the parameter to add.
[4256]335*/
[4254]336LoadParamDescription* LoadClassDescription::addParam(const char* paramName)
337{
338  tIterator<LoadParamDescription>* iterator = this->paramList->getIterator();
339  LoadParamDescription* enumParamDesc = iterator->nextElement();
340  while (enumParamDesc)
341    {
342      if (!strcmp(enumParamDesc->paramName, paramName))
[4597]343        {
344          delete iterator;
345          return enumParamDesc;
346        }
[4254]347      enumParamDesc = iterator->nextElement();
348    }
349  delete iterator;
350
351  this->paramList->add(new LoadParamDescription(paramName));
352  return paramList->lastElement();
353}
[4255]354
[4256]355/**
[4836]356 *  prints out all loadable Classes, and their parameters
[5100]357 * @param fileName prints the output to a File
358 * @todo implement it
[4256]359*/
[4260]360void LoadClassDescription::printAll(const char* fileName)
[4255]361{
[4259]362  PRINT(3)("===============================================================\n");
363  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
[4255]364  tIterator<LoadClassDescription>* classIT = LoadClassDescription::classList->getIterator();
365  LoadClassDescription* enumClassDesc = classIT->nextElement();
366  while (enumClassDesc)
367    {
368      PRINT(3)("<%s>\n", enumClassDesc->className);
369      tIterator<LoadParamDescription>* paramIT = enumClassDesc->paramList->getIterator();
370      LoadParamDescription* enumParamDesc = paramIT->nextElement();
371      while (enumParamDesc)
[4597]372        {
373          enumParamDesc->print();
374          enumParamDesc = paramIT->nextElement();
375        }
[4255]376      delete paramIT;
377
378      PRINT(3)("</%s>\n\n", enumClassDesc->className);
379      enumClassDesc = classIT->nextElement();
380    }
381  delete classIT;
[4259]382  PRINT(3)("===============================================================\n");
[4255]383}
[4492]384
[5100]385/**
386 * searches for classes, which beginn with classNameBegin
387 * @param classNameBegin the beginning string of a Class
388 * @return a NEW char-array with ClassNames. The ARRAY should be deleted afterwards,
389 * !! The strings MUST NOT be deleted !!
390 */
391Array<char*>* LoadClassDescription::searchClassWithShort(const char* classNameBegin)
392{
393  unsigned int searchLength = strlen(classNameBegin);
394  Array<char*>* retVal = new Array<char*>;
[4492]395
[5100]396  tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
397  LoadClassDescription* enumClassDesc = iterator->nextElement();
398  while (enumClassDesc)
399  {
400    if (strlen(enumClassDesc->className)>searchLength+1 &&
401        !strncasecmp(enumClassDesc->className, classNameBegin, searchLength))
402    {
403      retVal->addEntry(enumClassDesc->className);
404    }
405    enumClassDesc = iterator->nextElement();
406  }
407  delete iterator;
[4492]408
[5100]409  retVal->finalizeArray();
410  return retVal;
411}
412
413// const LoadParamDescription* LoadParamDescription::getClass(const char* className)
414// {
415//   tIterator<LoadClassDescription>* iterator = LoadClassDescription::classList->getIterator();
416//   LoadClassDescription* enumClassDesc = iterator->nextElement();
417//   while (enumClassDesc)
418//   {
419//     if (!strcmp(enumClassDesc->className, classNameBegin, className))
420//     {
421//       delete iterator;
422//       return enumClassDesc;
423//     }
424//     enumClassDesc = iterator->nextElement();
425//   }
426//   delete iterator;
427//
428//   return NULL;
429// }
430
[4492]431/**
[4836]432 * @param root: The XML-element to grab a parameter from
433 * @param parameterName: the parameter to grab
434 * @returns the Value of the parameter if found, NULL otherwise
[4492]435*/
436const char* grabParameter(const TiXmlElement* root, const char* parameterName)
437{
438  const TiXmlElement* element;
439  const TiXmlNode* node;
[4597]440
[4492]441  if (root == NULL)
442    return NULL;
443  assert( parameterName != NULL);
[4597]444
[4492]445  element = root->FirstChildElement( parameterName);
446  if( element == NULL) return NULL;
[4597]447
[4492]448  node = element->FirstChild();
449  while( node != NULL)
450    {
451      if( node->ToText()) return node->Value();
452      node = node->NextSibling();
453    }
454  return NULL;
455}
Note: See TracBrowser for help on using the repository browser.