Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 4813 was 4746, checked in by bensch, 20 years ago

orxonox/trunk: changed (void) → ()

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