Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/new_class_id/src/lib/util/multi_type.cc @ 9734

Last change on this file since 9734 was 9730, checked in by bensch, 18 years ago

cleaner executor with evaluate function, that will be made an Object Soon.

File size: 11.6 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//#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_
17
18#include "multi_type.h"
19
20#include <sstream>
21
22#ifdef DEBUG
23#include "debug.h"
24#endif
25
26/**
27 * @brief creates a multiType without any stored value at all.
28 */
29MultiType::MultiType(MT_Type type)
30{
31  this->type = type;
32  switch (this->type)
33  {
34    default:
35    this->value.Float = 0.0f;
36    break;
37    case MT_BOOL:
38    this->value.Bool = false;
39    break;
40    case MT_INT:
41    this->value.Int = 0;
42    break;
43    case MT_FLOAT:
44    this->value.Float = 0.0f;
45    break;
46    case MT_CHAR:
47    this->value.Char = '\0';
48    break;
49    case MT_STRING:
50    this->storedString = "";
51    break;
52  }
53}
54/**
55 * @brief creates a multiType out of a boolean
56 * @param value the Value of this MulitType
57 */
58MultiType::MultiType(bool value)
59{
60  this->setBool(value);
61}
62
63/**
64 * @brief creates a multiType out of an integer
65 * @param value the Value of this MulitType
66 */
67MultiType::MultiType(int value)
68{
69  this->setInt(value);
70}
71
72/**
73 * @brief creates a multiType out of a float (double)
74 * @param value the Value of this MulitType
75 */
76MultiType::MultiType(double value)
77{
78  this->setFloat(value);
79}
80
81/**
82 * @brief creates a multiType out of a char
83 * @param value the Value of this MulitType
84 */
85MultiType::MultiType(char value)
86{
87  this->setChar(value);
88}
89
90/**
91 * @brief creates a multiType out of a String
92 * @param value the Value of this MulitType
93 */
94MultiType::MultiType(const std::string& value)
95{
96  this->setString(value);
97}
98
99/**
100 * @brief constructs a new MultiType from another one (copy)
101 */
102MultiType::MultiType(const MultiType& multiType)
103{
104  *this = multiType;
105}
106
107/**
108 * @brief standard deconstructor
109*/
110MultiType::~MultiType ()
111{ }
112
113/**
114 * @brief copy operator
115 * @param mt: the entity to copy
116 * @returns A Copy of itself. (strings inside are copied as well)
117 */
118MultiType& MultiType::operator= (const MultiType& mt)
119{
120  this->type = mt.type;
121  this->value = mt.value;
122  this->storedString = mt.storedString;
123
124  return *this;
125}
126
127/**
128 * @brief checks if the two Multitypes match
129 * @param mt MultiType to check against this one
130 * @returns true on match. false otherwise
131 *
132 * Two MultiType match if and only if
133 *  1. the internal Type is the same
134 *  2. the stored values match
135 */
136bool MultiType::operator==(const MultiType& mt) const
137{
138  if (this->type != mt.type)
139    return false;
140
141  switch (this->type)
142  {
143    case MT_NULL:
144    return true;
145    case MT_BOOL:
146    return (this->value.Bool == mt.value.Bool);
147    case MT_INT:
148    return (this->value.Int == mt.value.Int);
149    case MT_CHAR:
150    return (this->value.Char == mt.value.Char);
151    case MT_FLOAT:
152    return (this->value.Float == mt.value.Float);
153    case MT_STRING:
154    return (this->storedString == mt.storedString);
155    default:
156    return false;
157  }
158}
159
160
161/**
162 * @brief sets the type of this MultiType and resets to the default value
163 * @param type the new Type
164 */
165void MultiType::setType(MT_Type type)
166{
167  if (this->type == type)
168    return;
169
170  switch (type)
171  {
172    case MT_BOOL:
173    this->setBool(this->getBool());
174    break;
175    case MT_INT:
176    this->setInt(this->getInt());
177    break;
178    case MT_FLOAT:
179    this->setFloat(this->getFloat());
180    break;
181    case MT_CHAR:
182    this->setChar(this->getChar());
183    break;
184    case MT_STRING:
185    this->setString(this->getString());
186    break;
187    default:
188    this->type = type;
189  }
190}
191
192/**
193 * @brief sets the Value of mt without changing the type of this MultiType
194 * @param mt: the MultiType to get the value from
195 *
196 * This is a pure Value copy. The current type will be preserved.
197 *
198 * @TODO speedup
199 */
200void MultiType::setValueOf(const MultiType& mt)
201{
202  MT_Type prevType = this->type;
203
204  *this = mt;
205  this->setType(prevType);
206}
207
208
209/**
210 * @brief sets a new Value to the MultiType
211 * @param value the new Value as a bool
212 */
213void MultiType::setBool(bool value)
214{
215  this->type = MT_BOOL;
216  this->value.Bool = value;
217}
218
219/**
220 * @brief sets a new Value to the MultiType
221 * @param value the new Value as an int
222 */
223void MultiType::setInt(int value)
224{
225  this->type = MT_INT;
226  this->value.Int = value;
227}
228
229/**
230 * @brief sets a new Value to the MultiType
231 * @param value the new Value as a float
232 */
233void MultiType::setFloat(float value)
234{
235  this->type = MT_FLOAT;
236  this->value.Float = value;
237}
238
239/**
240 * @brief sets a new Value to the MultiType
241 * @param value the new Value as a char
242 */
243void MultiType::setChar(char value)
244{
245  this->type = MT_CHAR;
246  this->value.Char = value;
247}
248
249/**
250 * @brief sets a new Value to the MultiType
251 * @param value the new Value as a String
252 */
253void MultiType::setString(const std::string& value)
254{
255  this->type = MT_STRING;
256  this->storedString = value;
257}
258
259/**
260 * @brief stores any value to the string.
261 * @note this Value can be grabbed by using the getStoredString function.
262 */
263void MultiType::storeString()
264{
265  if (!(this->type & MT_STRING))
266    this->storedString = this->getString();
267}
268
269/**************************
270*** RETRIEVAL FUNCTIONS ***
271**************************/
272/**
273 * @returns the Value of this MultiType as a int
274 */
275bool MultiType::getBool() const
276{
277  // default case:
278  if (this->type & MT_BOOL)
279    return this->value.Bool;
280  // Special Cases:
281  else if (this->type & MT_INT) return (this->value.Int == 0)? false : true;
282  else if (this->type & MT_FLOAT) return (this->value.Float == 0.0f)? false : true;
283  else if (this->type & MT_CHAR) return (this->value.Char == '\0')? false : true;
284  else if (this->type & MT_STRING) return (this->storedString == "true" ||
285                                            this->storedString == "TRUE" ||
286                                            this->storedString != "0"); //! @TODO make this better...
287
288  return false;
289}
290
291/**
292 * @returns the Value of this MultiType as a int
293 */
294int MultiType::getInt() const
295{
296  // default case:
297  if (this->type & MT_INT)
298    return this->value.Int;
299  if (this->type & MT_BOOL) return (this->value.Bool)? 1 : 0;
300  else if (this->type & MT_FLOAT) return (int) this->value.Float;
301  else if (this->type & MT_CHAR) return (int) this->value.Char;
302  else if (this->type & MT_STRING)
303  {
304    std::stringstream ssStream(this->storedString);
305    int iReturn;
306    ssStream >> iReturn;
307    return iReturn;
308  }
309  return 0;
310}
311
312
313/**
314 * @returns the Value of this MultiType as a float
315 */
316float MultiType::getFloat() const
317{
318  // default case:
319  if (this->type & MT_FLOAT)
320    return this->value.Float;
321  if (this->type & MT_BOOL) return (this->value.Bool == true)? 1.0f : 0.0f;
322  else if (this->type & MT_INT) return (float) this->value.Int;
323  else if (this->type & MT_CHAR) return (float) this->value.Char;
324  else if (this->type & MT_STRING)
325  {
326    char* endPtr = NULL;
327    double result = strtod(this->storedString.c_str(), &endPtr);
328    if ( endPtr >= this->storedString.c_str() && endPtr < this->storedString.c_str() + this->storedString.size())
329      return 0.0f;
330    else
331      return result;
332  }
333  return 0.0f;
334}
335
336
337/**
338 * @returns the Value of this MultiType as a char
339 */
340char MultiType::getChar() const
341{
342  // default case:
343  if (this->type & MT_INT)
344    return this->value.Int;
345  if (this->type & MT_BOOL) return (this->value.Bool)? 'y' : 'n';
346  else if (this->type & MT_INT) return (int) this->value.Int;
347  else if (this->type & MT_FLOAT) return (char) this->value.Float;
348  else if (this->type & MT_STRING) return this->storedString[0];
349
350  return '\0';
351}
352
353
354/**
355 * @returns the Value of this MultiType as a String
356 */
357std::string MultiType::getString() const
358{
359  // default case:
360  if (this->type & MT_STRING)
361    return this->storedString;
362  else
363  {
364    if (this->type & MT_BOOL) return (this->value.Bool)? "true" : "false";
365
366    else if (this->type & MT_INT)
367    {
368      char tmpString[32];
369      sprintf(tmpString, "%d", this->value.Int);
370      return tmpString;
371    }
372    else if (this->type & MT_FLOAT)
373    {
374      char tmpString[64];
375      sprintf(tmpString, "%f", this->value.Float);
376      return tmpString;
377    }
378    else if (this->type & MT_CHAR)
379    {
380      char tmpString[2];
381      tmpString[0] = this->value.Char;
382      tmpString[1] = '\0';
383      return tmpString;
384    }
385  }
386  return "";
387}
388
389/**
390 * @brief returns a Constant string (actually this is slower than getString()
391 * @returns a constant string of the stored version's one.
392 * @note this  could lead to a inconsistency of data AND IS HIGHLY NON_THREAD_SAFE!
393 * PLEASE THINK ABOUT USING THE getStoredString function in conjunction with storeString().
394 */
395const std::string& MultiType::getConstString() const
396{
397  MultiType::constString = this->getString();
398  return MultiType::constString;
399}
400
401/**
402 * @brief returns the currently stored string.
403 * @returns the Stored string.
404 * @note Storing a string works as follows: \\
405 * MultiType a(3);  // Creates a MultiType of Type int with value 3 \\
406 * a.storeString(); // Stores the String in the internal structure. \\
407 * std::string name = a.getStoredString();
408 *
409 * This would be the same as
410 * name = a.getString();
411 * but with much more const'ness.
412 */
413const std::string& MultiType::getStoredString() const
414{
415  MultiType::constString = this->getString();
416  return MultiType::constString;
417}
418
419/**
420 * @returns a formated c-string of the held value
421 */
422const char* MultiType::getCString()
423{
424  if (this->type & MT_STRING) return this->storedString.c_str();
425  else
426  {
427    this->storedString = this->getString();
428    return this->storedString.c_str();
429  }
430}
431
432/**
433 * @brief prints out some nice debug output
434 */
435void MultiType::debug() const
436{
437#ifdef DEBUG
438  PRINT(0)
439#else
440  printf
441#endif
442  ("MultiType of Type '%s' :: Values: BOOL: '%d', INT: '%d', FLOAT: '%f', CHAR: '%c', STRING '%s'\n",
443   MultiType::MultiTypeToString(this->type).c_str(),
444   this->getBool(),
445   this->getInt(),
446   this->getFloat(),
447   this->getChar(),
448   this->getString().c_str()
449  );
450}
451
452
453/**
454 * @brief Resets the MultiType to default values.
455 */
456void MultiType::reset()
457{
458  switch ( this->type )
459  {
460    case MT_BOOL:
461    this->setBool(false);
462    break;
463    case MT_INT:
464    this->setInt(0);
465    break;
466    case MT_FLOAT:
467    this->setFloat(0.0f);
468    break;
469    case MT_CHAR:
470    this->setChar('\0');
471    break;
472    case MT_STRING:
473    this->setString("");
474    break;
475    default:
476#ifdef DEBUG
477    PRINTF(2)("Unknown Type not reseting\n");
478#endif
479    break;
480  }
481}
482
483/**
484 * @brief converts a MT_Type into a String
485 * @param type: the MT_Type
486 * @returns: the Type as a constant String (do not delete)
487 */
488const std::string& MultiType::MultiTypeToString(MT_Type type)
489{
490  switch ( type )
491  {
492    case MT_BOOL:
493    return MultiType::typeNames[1];
494    case MT_INT:
495    return MultiType::typeNames[2];
496    case MT_FLOAT:
497    return MultiType::typeNames[3];
498    case MT_CHAR:
499    return MultiType::typeNames[4];
500    case MT_STRING:
501    return MultiType::typeNames[5];
502    default:
503    return MultiType::typeNames[0];
504  }
505}
506
507/**
508 * @brief converts a String into a MT_Type
509 * @param type: the Type as a String
510 * @returns: the Type as MT_Type
511 */
512MT_Type MultiType::StringToMultiType(const std::string& type)
513{
514  if (type == MultiType::typeNames[1])
515    return MT_BOOL;
516  if (type == MultiType::typeNames[2])
517    return MT_INT;
518  if (type == MultiType::typeNames[3])
519    return MT_FLOAT;
520  if (type == MultiType::typeNames[4])
521    return MT_CHAR;
522  if (type == MultiType::typeNames[5])
523    return MT_STRING;
524
525  return MT_NULL;
526}
527
528
529std::string MultiType::constString = "";
530const std::string MultiType::typeNames[] =
531  {
532    "NONE",      //0
533    "bool",      //1
534    "int",       //2
535    "float",     //3
536    "char",      //4
537    "string"     //5
538  };
Note: See TracBrowser for help on using the repository browser.