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
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 "array.h"
20#include "base_object.h"
21
22#include <stdarg.h>
23
24/**
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, ...)
31*/
32BaseLoadParam::BaseLoadParam(const TiXmlElement* root, BaseObject* object, const char* paramName,
33                             int paramCount, bool multi, const void* pointerToParam, ...)
34{
35  this->setClassID(CL_LOAD_PARAM, "LoadParam");
36
37  this->loadString = NULL;
38  this->pointerToParam = pointerToParam;
39
40  if (paramCount == 0 || this->pointerToParam)
41    this->loadString = "none";
42  else
43    {
44      if (likely(!multi))
45        this->loadString = grabParameter(root, paramName);
46      else
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        }
55    }
56
57  this->paramDesc = NULL;
58  if (LoadClassDescription::parametersDescription)
59  {
60    // locating the class
61    this->classDesc = LoadClassDescription::addClass(object->getClassName());
62
63    if ((this->paramDesc = this->classDesc->addParam(paramName)) != NULL)
64    {
65
66      this->paramDesc->paramCount = paramCount;
67      this->paramDesc->types = new char*[paramCount];
68      this->paramDesc->defaultValues = new char*[paramCount];
69
70      va_list types;
71      va_start (types, pointerToParam);
72      char defaultVal[512];
73      for(int i = 0; i < paramCount; i++)
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))
82        {
83          sprintf(defaultVal, "%d", va_arg(types, l_INT_TYPE));
84        }
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      }
109      va_end(types);
110
111      int argCount = 0;
112    }
113  }
114}
115
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;
130
131}
132
133int isInt(const char* INT, int defaultValue)
134{
135  char* endPtr = NULL;
136  int result = strtol(INT, &endPtr, 10);
137
138  if ( endPtr >= INT && endPtr < INT + strlen(INT))
139    return defaultValue;
140  else
141    return result;
142}
143
144float isFloat(const char* FLOAT, float defaultValue)
145{
146  char* endPtr = NULL;
147  double result = strtod(FLOAT, &endPtr);
148
149  if ( endPtr >= FLOAT && endPtr < FLOAT + strlen(FLOAT))
150    return defaultValue;
151  else
152    return result;
153}
154
155const Vector& isVector(const char* VECTOR, const Vector& defaultValue)
156{
157
158
159}
160
161const char* isString(const char* STRING, const char* defaultValue)
162{
163  if (STRING != NULL)
164    return STRING;
165  else
166    return defaultValue;
167}
168
169
170/**
171 * @param descriptionText The text to set as a description for this Parameter
172 * @returns a pointer to itself.
173*/
174BaseLoadParam* BaseLoadParam::describe(const char* descriptionText)
175{
176  if (LoadClassDescription::parametersDescription && this->paramDesc && !this->paramDesc->getDescription())
177    {
178      this->paramDesc->setDescription(descriptionText);
179    }
180  return this;
181}
182
183/**
184 * @param paramName the name of the parameter to load
185*/
186LoadParamDescription::LoadParamDescription(const char* paramName)
187{
188  this->types = NULL;
189  this->description = NULL;
190  this->paramName = new char[strlen(paramName)+1];
191  strcpy(this->paramName, paramName);
192  this->defaultValues = NULL;
193}
194
195/**
196 *  removes all the alocated memory
197*/
198LoadParamDescription::~LoadParamDescription()
199{
200  if (this->types != NULL)
201  {
202    for(int i = 0; i < this->paramCount; i++)
203    {
204      delete []this->types[i];
205    }
206  }
207  if (this->defaultValues != NULL)
208  {
209    for(int i = 0; i < this->paramCount; i++)
210    {
211      delete []this->defaultValues[i];
212    }
213  }
214
215  delete []this->types;
216  delete []this->defaultValues;
217  delete []this->paramName;
218  delete []this->description;
219}
220
221/**
222 * @param descriptionText The text to set as a description for this Parameter
223*/
224void LoadParamDescription::setDescription(const char* descriptionText)
225{
226  this->description = new char[strlen(descriptionText)+1];
227  strcpy(this->description, descriptionText);
228}
229
230/**
231 *  prints out this parameter, its input method and the description (if availiable)
232*/
233void LoadParamDescription::print() const
234{
235  PRINT(3)(" <%s>", this->paramName);
236  for (int i = 0; i < this->paramCount; i++)
237    {
238      if (i > 0)
239        PRINT(3)(",");
240      PRINT(3)("%s", this->types[i]);
241    }
242  PRINT(3)("</%s>", this->paramName);
243  if (this->description)
244    PRINT(3)(" -- %s", this->description);
245  // default values
246  if (this->paramCount > 0)
247  {
248    PRINT(3)(" (Default: ");
249    for (int i = 0; i < this->paramCount; i++)
250    {
251      if (i > 0)
252        PRINT(3)(", ");
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      }
261    }
262    PRINT(3)(")");
263  }
264  PRINT(3)("\n");
265}
266
267/**
268 *  A list, that holds all the classes that are loadable (classes not objects!!)
269*/
270tList<LoadClassDescription>* LoadClassDescription::classList = new tList<LoadClassDescription>;
271
272/**
273 *  if the description of Parameters should be executed
274*/
275bool LoadClassDescription::parametersDescription = true;
276
277/**
278 * @param className the name of the class to be loadable
279*/
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
290/**
291 *  deletes a classDescription (deletes all the parameterDescriptions as well
292*/
293LoadClassDescription::~LoadClassDescription()
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
307/**
308 *  adds a class to the list of loadable classes
309 * @param className The name of the class to add
310
311   this function searches for the className string, and if found just returns the appropriate Class.
312   Otherwise it returns a new classDescription
313*/
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))
321        {
322          delete iterator;
323          return enumClassDesc;
324        }
325      enumClassDesc = iterator->nextElement();
326    }
327  delete iterator;
328
329  return new LoadClassDescription(className);
330}
331
332/**
333 *  does the same as addClass(const char* className), but with params
334 * @param paramName the name of the parameter to add.
335*/
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))
343        {
344          delete iterator;
345          return enumParamDesc;
346        }
347      enumParamDesc = iterator->nextElement();
348    }
349  delete iterator;
350
351  this->paramList->add(new LoadParamDescription(paramName));
352  return paramList->lastElement();
353}
354
355/**
356 *  prints out all loadable Classes, and their parameters
357 * @param fileName prints the output to a File
358 * @todo implement it
359*/
360void LoadClassDescription::printAll(const char* fileName)
361{
362  PRINT(3)("===============================================================\n");
363  PRINT(3)(" Listing all the Loadable Options (loaded since Game started).\n\n");
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)
372        {
373          enumParamDesc->print();
374          enumParamDesc = paramIT->nextElement();
375        }
376      delete paramIT;
377
378      PRINT(3)("</%s>\n\n", enumClassDesc->className);
379      enumClassDesc = classIT->nextElement();
380    }
381  delete classIT;
382  PRINT(3)("===============================================================\n");
383}
384
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*>;
395
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;
408
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
431/**
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
435*/
436const char* grabParameter(const TiXmlElement* root, const char* parameterName)
437{
438  const TiXmlElement* element;
439  const TiXmlNode* node;
440
441  if (root == NULL)
442    return NULL;
443  assert( parameterName != NULL);
444
445  element = root->FirstChildElement( parameterName);
446  if( element == NULL) return NULL;
447
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.