Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: 1-st step to LoadParam→default-values (get printed and stuff)

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