Changeset 2111 for code/branches/objecthierarchy/src/util
- Timestamp:
- Nov 2, 2008, 12:38:26 PM (16 years ago)
- Location:
- code/branches/objecthierarchy/src/util
- Files:
-
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
code/branches/objecthierarchy/src/util/CRC32.cc
r1791 r2111 29 29 #include "CRC32.h" 30 30 31 namespace orxonox 32 { 33 void calcCRCBit(uint32_t &crc32, int bit) 34 { 35 int hbit = (crc32 & 0x80000000) ? 1 : 0; 36 if (hbit != bit) 37 crc32 = (crc32 << 1) ^ UTIL_CRC32POLY; 38 else 39 crc32 = crc32 << 1; 40 } 31 41 32 void calcCRCBit(uint32_t &crc32, int bit){ 33 int hbit; 42 uint32_t calcCRC(unsigned char *data, unsigned int dataLength) 43 { 44 uint32_t crc32 = 0; 45 for(unsigned int i = 0; i < dataLength; i++) 46 { 47 calcCRCBit(crc32, (data[i] & 0x1) >> 0); // 1st bit 48 calcCRCBit(crc32, (data[i] & 0x2) >> 1); // 2nd bit 49 calcCRCBit(crc32, (data[i] & 0x3) >> 2); // 3rd bit 50 calcCRCBit(crc32, (data[i] & 0x4) >> 3); // 4th bit 51 calcCRCBit(crc32, (data[i] & 0x5) >> 4); // 5th bit 52 calcCRCBit(crc32, (data[i] & 0x6) >> 5); // 6th bit 53 calcCRCBit(crc32, (data[i] & 0x7) >> 6); // 7th bit 54 calcCRCBit(crc32, (data[i] & 0x8) >> 7); // 8th bit 55 } 56 return crc32; 57 } 58 } 34 59 35 hbit=(crc32 & 0x80000000) ? 1 : 0;36 if (hbit != bit)37 crc32=(crc32<<1) ^ UTIL_CRC32POLY;38 else39 crc32=crc32<<1;40 }41 42 uint32_t calcCRC(unsigned char *data, unsigned int dataLength){43 uint32_t crc32=0;44 for(unsigned int i=0; i<dataLength; i++){45 calcCRCBit(crc32, (data[i]&0x1)>>0); // 1st bit46 calcCRCBit(crc32, (data[i]&0x2)>>1); // 2nd bit47 calcCRCBit(crc32, (data[i]&0x3)>>2); // 3rd bit48 calcCRCBit(crc32, (data[i]&0x4)>>3); // 4th bit49 calcCRCBit(crc32, (data[i]&0x5)>>4); // 5th bit50 calcCRCBit(crc32, (data[i]&0x6)>>5); // 6th bit51 calcCRCBit(crc32, (data[i]&0x7)>>6); // 7th bit52 calcCRCBit(crc32, (data[i]&0x8)>>7); // 8th bit53 }54 return crc32;55 }56 -
code/branches/objecthierarchy/src/util/CRC32.h
r1791 r2111 34 34 #include "Integers.h" 35 35 36 const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */ 36 namespace orxonox 37 { 38 const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */ 37 39 38 _UtilExport void calcCRCBit(uint32_t &crc32, int bit);40 _UtilExport void calcCRCBit(uint32_t &crc32, int bit); 39 41 40 _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength);41 42 _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength); 43 } 42 44 43 45 #endif /* _Util_CRC_H__ */ -
code/branches/objecthierarchy/src/util/Clipboard.cc
r1791 r2111 37 37 38 38 #if ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 39 ///////////// 40 // Windows // 41 ///////////// 42 #include <windows.h> 43 #include "Debug.h" 39 40 ///////////// 41 // Windows // 42 ///////////// 43 44 #include <windows.h> 45 #include "Debug.h" 46 47 namespace orxonox 48 { 44 49 45 50 /** … … 97 102 return ""; 98 103 } 99 #else 100 ///////////// 101 // Default // 102 ///////////// 104 } 103 105 106 #else /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ 107 108 ///////////// 109 // Default // 110 ///////////// 111 112 namespace orxonox 113 { 104 114 std::string clipboard = ""; //!< Keeps the text of our internal clipboard 105 115 … … 123 133 return clipboard; 124 134 } 125 #endif 135 } 136 137 #endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ -
code/branches/objecthierarchy/src/util/Clipboard.h
r1791 r2111 46 46 #include <string> 47 47 48 49 _UtilExport bool toClipboard(const std::string& text); 50 _UtilExport std::string fromClipboard(); 51 48 namespace orxonox 49 { 50 _UtilExport bool toClipboard(const std::string& text); 51 _UtilExport std::string fromClipboard(); 52 } 52 53 53 54 #endif /* _Clipboard_H__ */ -
code/branches/objecthierarchy/src/util/Convert.h
r2017 r2111 68 68 #endif 69 69 70 template <class FromType, class ToType> 71 class ImplicitConversion 72 { 73 private: 74 ImplicitConversion(); ImplicitConversion(const ImplicitConversion&); ~ImplicitConversion(); 75 // Gets chosen only if there is an implicit conversion from FromType to ToType. 76 static char test(ToType); 77 // Accepts any argument. Why do we not use a template? The reason is that with templates, 78 // the function above is only taken iff it is an exact type match. But since we want to 79 // check for implicit conversion, we have to use the ellipsis. 80 static long long test(...); 81 static FromType object; // helper object to handle private c'tor and d'tor 82 public: 83 // test(object) only has 'long long' return type iff the compiler doesn't choose test(...) 84 enum { exists = (sizeof(test(object)) == sizeof(char)) }; 85 }; 70 namespace orxonox 71 { 72 template <class FromType, class ToType> 73 class ImplicitConversion 74 { 75 private: 76 ImplicitConversion(); ImplicitConversion(const ImplicitConversion&); ~ImplicitConversion(); 77 // Gets chosen only if there is an implicit conversion from FromType to ToType. 78 static char test(ToType); 79 // Accepts any argument. Why do we not use a template? The reason is that with templates, 80 // the function above is only taken iff it is an exact type match. But since we want to 81 // check for implicit conversion, we have to use the ellipsis. 82 static long long test(...); 83 static FromType object; // helper object to handle private c'tor and d'tor 84 public: 85 // test(object) only has 'long long' return type iff the compiler doesn't choose test(...) 86 enum { exists = (sizeof(test(object)) == sizeof(char)) }; 87 }; 88 } 86 89 87 90 #if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC … … 118 121 */ 119 122 120 namespace 121 { 122 //! Little template that maps integers to entire types (Alexandrescu 2001) 123 template <int I> 124 struct Int2Type { }; 123 namespace orxonox 124 { 125 namespace 126 { 127 //! Little template that maps integers to entire types (Alexandrescu 2001) 128 template <int I> 129 struct Int2Type { }; 130 } 131 132 133 /////////////////// 134 // No Conversion // 135 /////////////////// 136 137 // Default template. No conversion available at all. 138 template <class FromType, class ToType> 139 struct ConverterFallback 140 { 141 static bool convert(ToType* output, const FromType& input) 142 { 143 COUT(2) << "Could not convert value of type " << typeid(FromType).name() 144 << " to type " << typeid(ToType).name() << std::endl; 145 return false; 146 } 147 }; 148 149 // If all else fails, try a dynamic_cast for pointer types. 150 template <class FromType, class ToType> 151 struct ConverterFallback<FromType*, ToType*> 152 { 153 static bool convert(ToType** output, FromType* const input) 154 { 155 ToType* temp = dynamic_cast<ToType*>(input); 156 if (temp) 157 { 158 *output = temp; 159 return true; 160 } 161 else 162 return false; 163 } 164 }; 125 165 } 126 127 128 ///////////////////129 // No Conversion //130 ///////////////////131 132 // Default template. No conversion available at all.133 template <class FromType, class ToType>134 struct ConverterFallback135 {136 static bool convert(ToType* output, const FromType& input)137 {138 COUT(2) << "Could not convert value of type " << typeid(FromType).name()139 << " to type " << typeid(ToType).name() << std::endl;140 return false;141 }142 };143 144 // If all else fails, try a dynamic_cast for pointer types.145 template <class FromType, class ToType>146 struct ConverterFallback<FromType*, ToType*>147 {148 static bool convert(ToType** output, FromType* const input)149 {150 ToType* temp = dynamic_cast<ToType*>(input);151 if (temp)152 {153 *output = temp;154 return true;155 }156 else157 return false;158 }159 };160 166 161 167 … … 170 176 static bool convert(ToType* output, const FromType& input) 171 177 { 172 return ConverterFallback<FromType, ToType>::convert(output, input);178 return orxonox::ConverterFallback<FromType, ToType>::convert(output, input); 173 179 } 174 180 }; … … 185 191 { 186 192 std::string temp; 187 if ( ConverterFallback<FromType, std::string>::convert(&temp, input))193 if (orxonox::ConverterFallback<FromType, std::string>::convert(&temp, input)) 188 194 { 189 195 std::operator <<(outstream, temp); … … 224 230 inline bool operator >>(std::istream& instream, ToType& output) 225 231 { 226 return ConverterFallback<std::string, ToType>232 return orxonox::ConverterFallback<std::string, ToType> 227 233 ::convert(&output, static_cast<std::istringstream&>(instream).str()); 228 234 } … … 247 253 }; 248 254 249 250 /////////////////// 251 // Implicit Cast // 252 /////////////////// 253 254 // implicit cast not possible, try stringstream conversion next 255 template <class FromType, class ToType> 256 inline bool convertImplicitely(ToType* output, const FromType& input, ::Int2Type<false>) 257 { 258 return ConverterStringStream<FromType, ToType>::convert(output, input); 255 namespace orxonox 256 { 257 258 /////////////////// 259 // Implicit Cast // 260 /////////////////// 261 262 // implicit cast not possible, try stringstream conversion next 263 template <class FromType, class ToType> 264 inline bool convertImplicitely(ToType* output, const FromType& input, orxonox::Int2Type<false>) 265 { 266 return ConverterStringStream<FromType, ToType>::convert(output, input); 267 } 268 269 // We can cast implicitely 270 template <class FromType, class ToType> 271 inline bool convertImplicitely(ToType* output, const FromType& input, orxonox::Int2Type<true>) 272 { 273 (*output) = static_cast<ToType>(input); 274 return true; 275 } 276 277 278 //////////////////////////////// 279 // ConverterExplicit Fallback // 280 //////////////////////////////// 281 282 // Default template if no specialisation is available 283 template <class FromType, class ToType> 284 struct ConverterExplicit 285 { 286 static bool convert(ToType* output, const FromType& input) 287 { 288 // Try implict cast and probe first. If a simple cast is not possible, it will not compile 289 // We therefore have to out source it into another template function 290 const bool probe = ImplicitConversion<FromType, ToType>::exists; 291 return convertImplicitely(output, input, orxonox::Int2Type<probe>()); 292 } 293 }; 294 295 296 ////////////////////// 297 // Public Functions // 298 ////////////////////// 299 300 /** 301 @brief 302 Converts any value to any other as long as there exists a conversion. 303 Otherwise, the conversion will generate a runtime warning and return false. 304 For information about the different conversion methods (user defined too), see the section 305 'Actual conversion sequence' in this file above. 306 */ 307 template <class FromType, class ToType> 308 inline bool convertValue(ToType* output, const FromType& input) 309 { 310 return ConverterExplicit<FromType, ToType>::convert(output, input); 311 } 312 313 // For compatibility reasons. The same, but with capital ConvertValue 314 template<class FromType, class ToType> 315 inline bool ConvertValue(ToType* output, const FromType& input) 316 { 317 return convertValue(output, input); 318 } 319 320 // Calls convertValue and returns true if the conversion was successful. 321 // Otherwise the fallback is used. 322 /** 323 @brief 324 Converts any value to any other as long as there exists a conversion. 325 Otherwise, the conversion will generate a runtime warning and return false. 326 For information about the different conversion methods (user defined too), see the section 327 'Actual conversion sequence' in this file above. 328 If the conversion doesn't succeed, 'fallback' is written to '*output'. 329 @param fallback 330 A default value that gets written to '*output' if there is no conversion. 331 */ 332 template<class FromType, class ToType> 333 inline bool convertValue(ToType* output, const FromType& input, const ToType& fallback) 334 { 335 if (convertValue(output, input)) 336 return true; 337 else 338 { 339 (*output) = fallback; 340 return false; 341 } 342 } 343 344 // for compatibility reason. (capital 'c' in ConvertValue) 345 template<class FromType, class ToType> 346 inline bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback) 347 { 348 return convertValue(output, input, fallback); 349 } 350 351 // Directly returns the converted value, even if the conversion was not successful. 352 template<class FromType, class ToType> 353 inline ToType getConvertedValue(const FromType& input) 354 { 355 ToType output; 356 convertValue(&output, input); 357 return output; 358 } 359 360 // Directly returns the converted value, but uses the fallback on failure. 361 template<class FromType, class ToType> 362 inline ToType getConvertedValue(const FromType& input, const ToType& fallback) 363 { 364 ToType output; 365 convertValue(&output, input, fallback); 366 return output; 367 } 368 369 // Like getConvertedValue, but the template argument order is in reverse. 370 // That means you can call it exactly like static_cast<ToType>(fromTypeValue). 371 template<class ToType, class FromType> 372 inline ToType omni_cast(const FromType& input) 373 { 374 ToType output; 375 convertValue(&output, input); 376 return output; 377 } 378 379 // convert to string Shortcut 380 template <class FromType> 381 inline std::string convertToString(FromType value) 382 { 383 return getConvertedValue<FromType, std::string>(value); 384 } 385 386 // convert from string Shortcut 387 template <class ToType> 388 inline ToType convertFromString(std::string str) 389 { 390 return getConvertedValue<std::string, ToType>(str); 391 } 392 393 //////////////////////////////// 394 // Special string conversions // 395 //////////////////////////////// 396 397 // Delegate conversion from const char* to std::string 398 template <class ToType> 399 struct ConverterExplicit<const char*, ToType> 400 { 401 static bool convert(ToType* output, const char* input) 402 { 403 return convertValue<std::string, ToType>(output, input); 404 } 405 }; 406 407 // These conversions would exhibit ambiguous << or >> operators when using stringstream 408 template <> 409 struct ConverterExplicit<char, std::string> 410 { 411 static bool convert(std::string* output, const char input) 412 { 413 *output = std::string(1, input); 414 return true; 415 } 416 }; 417 template <> 418 struct ConverterExplicit<unsigned char, std::string> 419 { 420 static bool convert(std::string* output, const unsigned char input) 421 { 422 *output = std::string(1, input); 423 return true; 424 } 425 }; 426 template <> 427 struct ConverterExplicit<std::string, char> 428 { 429 static bool convert(char* output, const std::string input) 430 { 431 if (input != "") 432 *output = input[0]; 433 else 434 *output = '\0'; 435 return true; 436 } 437 }; 438 template <> 439 struct ConverterExplicit<std::string, unsigned char> 440 { 441 static bool convert(unsigned char* output, const std::string input) 442 { 443 if (input != "") 444 *output = input[0]; 445 else 446 *output = '\0'; 447 return true; 448 } 449 }; 450 451 452 // bool to std::string 453 template <> 454 struct ConverterExplicit<bool, std::string> 455 { 456 static bool convert(std::string* output, const bool& input) 457 { 458 if (input) 459 *output = "true"; 460 else 461 *output = "false"; 462 return false; 463 } 464 }; 465 466 // std::string to bool 467 template <> 468 struct ConverterExplicit<std::string, bool> 469 { 470 static bool convert(bool* output, const std::string& input) 471 { 472 std::string stripped = getLowercase(removeTrailingWhitespaces(input)); 473 if (stripped == "true" || stripped == "on" || stripped == "yes") 474 { 475 *output = true; 476 return true; 477 } 478 else if (stripped == "false" || stripped == "off" || stripped == "no") 479 { 480 *output = false; 481 return true; 482 } 483 484 std::istringstream iss(input); 485 if (iss >> (*output)) 486 return true; 487 else 488 return false; 489 } 490 }; 259 491 } 260 492 261 // We can cast implicitely262 template <class FromType, class ToType>263 inline bool convertImplicitely(ToType* output, const FromType& input, ::Int2Type<true>)264 {265 (*output) = static_cast<ToType>(input);266 return true;267 }268 269 270 ////////////////////////////////271 // ConverterExplicit Fallback //272 ////////////////////////////////273 274 // Default template if no specialisation is available275 template <class FromType, class ToType>276 struct ConverterExplicit277 {278 static bool convert(ToType* output, const FromType& input)279 {280 // Try implict cast and probe first. If a simple cast is not possible, it will not compile281 // We therefore have to out source it into another template function282 const bool probe = ImplicitConversion<FromType, ToType>::exists;283 return convertImplicitely(output, input, ::Int2Type<probe>());284 }285 };286 287 288 //////////////////////289 // Public Functions //290 //////////////////////291 292 /**293 @brief294 Converts any value to any other as long as there exists a conversion.295 Otherwise, the conversion will generate a runtime warning and return false.296 For information about the different conversion methods (user defined too), see the section297 'Actual conversion sequence' in this file above.298 */299 template <class FromType, class ToType>300 inline bool convertValue(ToType* output, const FromType& input)301 {302 return ConverterExplicit<FromType, ToType>::convert(output, input);303 }304 305 // For compatibility reasons. The same, but with capital ConvertValue306 template<class FromType, class ToType>307 inline bool ConvertValue(ToType* output, const FromType& input)308 {309 return convertValue(output, input);310 }311 312 // Calls convertValue and returns true if the conversion was successful.313 // Otherwise the fallback is used.314 /**315 @brief316 Converts any value to any other as long as there exists a conversion.317 Otherwise, the conversion will generate a runtime warning and return false.318 For information about the different conversion methods (user defined too), see the section319 'Actual conversion sequence' in this file above.320 If the conversion doesn't succeed, 'fallback' is written to '*output'.321 @param fallback322 A default value that gets written to '*output' if there is no conversion.323 */324 template<class FromType, class ToType>325 inline bool convertValue(ToType* output, const FromType& input, const ToType& fallback)326 {327 if (convertValue(output, input))328 return true;329 else330 {331 (*output) = fallback;332 return false;333 }334 }335 336 // for compatibility reason. (capital 'c' in ConvertValue)337 template<class FromType, class ToType>338 inline bool ConvertValue(ToType* output, const FromType& input, const ToType& fallback)339 {340 return convertValue(output, input, fallback);341 }342 343 // Directly returns the converted value, even if the conversion was not successful.344 template<class FromType, class ToType>345 inline ToType getConvertedValue(const FromType& input)346 {347 ToType output;348 convertValue(&output, input);349 return output;350 }351 352 // Directly returns the converted value, but uses the fallback on failure.353 template<class FromType, class ToType>354 inline ToType getConvertedValue(const FromType& input, const ToType& fallback)355 {356 ToType output;357 convertValue(&output, input, fallback);358 return output;359 }360 361 // Like getConvertedValue, but the template argument order is in reverse.362 // That means you can call it exactly like static_cast<ToType>(fromTypeValue).363 template<class ToType, class FromType>364 inline ToType omni_cast(const FromType& input)365 {366 ToType output;367 convertValue(&output, input);368 return output;369 }370 371 // convert to string Shortcut372 template <class FromType>373 inline std::string convertToString(FromType value)374 {375 return getConvertedValue<FromType, std::string>(value);376 }377 378 // convert from string Shortcut379 template <class ToType>380 inline ToType convertFromString(std::string str)381 {382 return getConvertedValue<std::string, ToType>(str);383 }384 385 ////////////////////////////////386 // Special string conversions //387 ////////////////////////////////388 389 // Delegate conversion from const char* to std::string390 template <class ToType>391 struct ConverterExplicit<const char*, ToType>392 {393 static bool convert(ToType* output, const char* input)394 {395 return convertValue<std::string, ToType>(output, input);396 }397 };398 399 // These conversions would exhibit ambiguous << or >> operators when using stringstream400 template <>401 struct ConverterExplicit<char, std::string>402 {403 static bool convert(std::string* output, const char input)404 {405 *output = std::string(1, input);406 return true;407 }408 };409 template <>410 struct ConverterExplicit<unsigned char, std::string>411 {412 static bool convert(std::string* output, const unsigned char input)413 {414 *output = std::string(1, input);415 return true;416 }417 };418 template <>419 struct ConverterExplicit<std::string, char>420 {421 static bool convert(char* output, const std::string input)422 {423 if (input != "")424 *output = input[0];425 else426 *output = '\0';427 return true;428 }429 };430 template <>431 struct ConverterExplicit<std::string, unsigned char>432 {433 static bool convert(unsigned char* output, const std::string input)434 {435 if (input != "")436 *output = input[0];437 else438 *output = '\0';439 return true;440 }441 };442 443 444 // bool to std::string445 template <>446 struct ConverterExplicit<bool, std::string>447 {448 static bool convert(std::string* output, const bool& input)449 {450 if (input)451 *output = "true";452 else453 *output = "false";454 return false;455 }456 };457 458 // std::string to bool459 template <>460 struct ConverterExplicit<std::string, bool>461 {462 static bool convert(bool* output, const std::string& input)463 {464 std::string stripped = getLowercase(removeTrailingWhitespaces(input));465 if (stripped == "true" || stripped == "on" || stripped == "yes")466 {467 *output = true;468 return true;469 }470 else if (stripped == "false" || stripped == "off" || stripped == "no")471 {472 *output = false;473 return true;474 }475 476 std::istringstream iss(input);477 if (iss >> (*output))478 return true;479 else480 return false;481 }482 };483 484 493 #endif /* _Convert_H__ */ -
code/branches/objecthierarchy/src/util/Debug.h
r2034 r2111 67 67 #include "OutputHandler.h" 68 68 69 70 /**71 @brief Returns the soft debug level, stored in the only existing instance of the OutputHandler class, configured in the config-file.72 @return The soft debug level73 */74 static inline int getSoftDebugLevel()75 {76 return orxonox::OutputHandler::getSoftDebugLevel();77 }78 79 69 namespace orxonox 80 70 { 71 /** 72 @brief Returns the soft debug level, stored in the only existing instance of the OutputHandler class, configured in the config-file. 73 @return The soft debug level 74 */ 75 static inline int getSoftDebugLevel() 76 { 77 return OutputHandler::getSoftDebugLevel(); 78 } 79 81 80 using std::endl; 82 81 } … … 115 114 #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE 116 115 #define COUT0 \ 117 (getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0)116 (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0) 118 117 #else 119 118 #define COUT0 \ … … 123 122 #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR 124 123 #define COUT1 \ 125 ( getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1)124 (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1) 126 125 #else 127 126 #define COUT1 \ … … 131 130 #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING 132 131 #define COUT2 \ 133 ( getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2)132 (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2) 134 133 #else 135 134 #define COUT2 \ … … 139 138 #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO 140 139 #define COUT3 \ 141 ( getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3)140 (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3) 142 141 #else 143 142 #define COUT3 \ … … 147 146 #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG 148 147 #define COUT4 \ 149 ( getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4)148 (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4) 150 149 #else 151 150 #define COUT4 \ … … 155 154 #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE 156 155 #define COUT5 \ 157 ( getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5)156 (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5) 158 157 #else 159 158 #define COUT5 \ … … 163 162 #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA 164 163 #define COUT6 \ 165 ( getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6)164 (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6) 166 165 #else 167 166 #define COUT6 \ … … 199 198 #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE 200 199 #define CCOUT0 \ 201 ( getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0)200 (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0) 202 201 #else 203 202 #define CCOUT0 \ … … 207 206 #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR 208 207 #define CCOUT1 \ 209 ( getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1)208 (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1) 210 209 #else 211 210 #define CCOUT1 \ … … 215 214 #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING 216 215 #define CCOUT2 \ 217 ( getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2)216 (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2) 218 217 #else 219 218 #define CCOUT2 \ … … 223 222 #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO 224 223 #define CCOUT3 \ 225 ( getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3)224 (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3) 226 225 #else 227 226 #define CCOUT3 \ … … 231 230 #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG 232 231 #define CCOUT4 \ 233 ( getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4)232 (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4) 234 233 #else 235 234 #define CCOUT4 \ … … 239 238 #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE 240 239 #define CCOUT5 \ 241 ( getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5)240 (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5) 242 241 #else 243 242 #define CCOUT5 \ … … 247 246 #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA 248 247 #define CCOUT6 \ 249 ( getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6)248 (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6) 250 249 #else 251 250 #define CCOUT6 \ -
code/branches/objecthierarchy/src/util/Exception.cc
r2101 r2111 81 81 return fullDescription_; 82 82 } 83 84 85 83 } -
code/branches/objecthierarchy/src/util/Exception.h
r2101 r2111 141 141 CREATE_ORXONOX_EXCEPTION(NotImplemented); 142 142 CREATE_ORXONOX_EXCEPTION(GameState); 143 } 143 144 144 145 #define ThrowException(type, description) \ … … 154 155 #endif 155 156 156 }157 158 157 #endif /* _Exception_H__ */ -
code/branches/objecthierarchy/src/util/ExprParser.cc
r1894 r2111 45 45 #define PARSE_BLANKS while (*reading_stream == ' ') ++reading_stream 46 46 47 ExprParser::ExprParser(const std::string& str) 47 namespace orxonox 48 48 { 49 this->failed_ = false; 50 this->reading_stream = str.c_str(); 51 if (str.size() == 0 || *reading_stream == '\0') 52 { 53 this->failed_ = true; 54 this->result_ = 0.0; 55 } 56 else 57 { 58 this->result_ = parse_expr_8(); 59 this->remains_ = reading_stream; 49 ExprParser::ExprParser(const std::string& str) 50 { 51 this->failed_ = false; 52 this->reading_stream = str.c_str(); 53 if (str.size() == 0 || *reading_stream == '\0') 54 { 55 this->failed_ = true; 56 this->result_ = 0.0; 57 } 58 else 59 { 60 this->result_ = parse_expr_8(); 61 this->remains_ = reading_stream; 62 } 63 } 64 65 //Private functions: 66 /******************/ 67 double ExprParser::parse_argument() 68 { 69 double value = parse_expr_8(); 70 if (*reading_stream == ',') 71 { 72 ++reading_stream; 73 return value; 74 } 75 else 76 { 77 this->failed_ = true; 78 return 0; 79 } 80 } 81 82 double ExprParser::parse_last_argument() 83 { 84 double value = parse_expr_8(); 85 if (*reading_stream == ')') 86 { 87 ++reading_stream; 88 return value; 89 } 90 else 91 { 92 this->failed_ = true; 93 return 0; 94 } 95 } 96 97 double ExprParser::parse_expr_8() 98 { 99 double value = parse_expr_7(); 100 for(;;) 101 { 102 switch (op) 103 { 104 case oder: 105 value = parse_expr_7() || value; 106 break; 107 default: return value; 108 } 109 }; 110 } 111 112 113 double ExprParser::parse_expr_7() 114 { 115 double value = parse_expr_6(); 116 for(;;) 117 { 118 switch (op) 119 { 120 case und: 121 value = value && parse_expr_6(); 122 break; 123 default: return value; 124 } 125 }; 126 } 127 128 double ExprParser::parse_expr_6() 129 { 130 double value = parse_expr_5(); 131 for(;;) 132 { 133 switch (op) 134 { 135 case gleich: 136 value = (value == parse_expr_5()); 137 break; 138 case ungleich: 139 value = (value != parse_expr_5()); 140 break; 141 default: 142 return value; 143 } 144 }; 145 } 146 147 double ExprParser::parse_expr_5() 148 { 149 double value = parse_expr_4(); 150 for(;;) 151 { 152 switch (op) 153 { 154 case kleiner: 155 value = (value < parse_expr_4()); 156 break; 157 case kleinergleich: 158 value = (value <= parse_expr_4()); 159 break; 160 case groesser: 161 value = (value > parse_expr_4()); 162 break; 163 case groessergleich: 164 value = (value >= parse_expr_4()); 165 break; 166 default: 167 return value; 168 } 169 }; 170 } 171 172 double ExprParser::parse_expr_4() 173 { 174 double value = parse_expr_3(); 175 for(;;) 176 { 177 switch (op) 178 { 179 case b_plus: 180 value += parse_expr_3(); 181 break; 182 case b_minus: 183 value -= parse_expr_3(); 184 break; 185 default: 186 return value; 187 } 188 }; 189 } 190 191 double ExprParser::parse_expr_3() 192 { 193 double value = parse_expr_2(); 194 for(;;) 195 { 196 switch (op) 197 { 198 case mal: 199 value *= parse_expr_2(); 200 break; 201 case durch: 202 value /= parse_expr_2(); 203 break; 204 case modulo: 205 { 206 double temp = parse_expr_2(); 207 value = value - floor(value/temp)*temp; 208 break; 209 } 210 default: 211 return value; 212 } 213 }; 214 } 215 216 double ExprParser::parse_expr_2() 217 { 218 double value = parse_expr_1(); 219 while (*reading_stream != '\0') 220 { 221 op = parse_binary_operator(); 222 switch (op) 223 { 224 case hoch: 225 value = pow(value,parse_expr_1()); 226 break; 227 default: 228 return value; 229 } 230 }; 231 op = undef; 232 return value; 233 } 234 235 double ExprParser::parse_expr_1() 236 { 237 PARSE_BLANKS; 238 double value; 239 240 unary_operator op = parse_unary_operator(); 241 PARSE_BLANKS; 242 243 if (*reading_stream == '\0') 244 { 245 // end of string 246 this->failed_ = true; 247 return 0; 248 } 249 else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46) 250 { // number 251 value = strtod(reading_stream, const_cast<char**>(&reading_stream)); 252 } 253 else if (*reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46) 254 { // variable or function 255 char* word = new char[256]; 256 parse_word(word); 257 PARSE_BLANKS; 258 if (*reading_stream == '(') 259 { 260 ++reading_stream; 261 #define SWITCH word 262 CASE_1("sin") 263 value = sin(parse_last_argument()); 264 CASE("asin") 265 value = asin(parse_last_argument()); 266 CASE("sinh") 267 value = sinh(parse_last_argument()); 268 CASE("asinh") 269 { 270 value = parse_last_argument(); 271 value = log(sqrt(pow(value, 2) + 1) + value); 272 } 273 CASE("cos") 274 value = cos(parse_last_argument()); 275 CASE("acos") 276 value = acos(parse_last_argument()); 277 CASE("cosh") 278 value = cosh(parse_last_argument()); 279 CASE("acosh") 280 { 281 value = parse_last_argument(); 282 value = log(sqrt(pow(value, 2) - 1) + value); 283 } 284 CASE("tan") 285 value = tan(parse_last_argument()); 286 CASE("atan") 287 value = atan(parse_last_argument()); 288 CASE("atan2") 289 value = atan2(parse_argument(),parse_last_argument()); 290 CASE("tanh") 291 value = tanh(parse_last_argument()); 292 CASE("atanh") 293 { 294 value = parse_last_argument(); 295 value = 0.5*log((value + 1)/(value - 1)); 296 } 297 CASE("int") 298 value = floor(parse_last_argument()); 299 CASE("floor") 300 value = floor(parse_last_argument()); 301 CASE("ceil") 302 value = ceil(parse_last_argument()); 303 CASE("abs") 304 value = fabs(parse_last_argument()); 305 CASE("exp") 306 value = exp(parse_last_argument()); 307 CASE("log") 308 value = log10(parse_last_argument()); 309 CASE("ln") 310 value = log(parse_last_argument()); 311 CASE("sign") 312 { 313 value = parse_last_argument(); 314 value = (value>0 ? 1 : (value<0 ? -1 : 0)); 315 } 316 CASE("sqrt") 317 value = sqrt(parse_last_argument()); 318 CASE("degrees") 319 value = parse_last_argument()*180/3.1415926535897932; 320 CASE("radians") 321 value = parse_last_argument()*3.1415926535897932/180; 322 CASE("mod") 323 { 324 value = parse_argument(); 325 double value2 = parse_last_argument(); 326 value = value - floor(value/value2)*value2; 327 } 328 CASE("pow") 329 value = pow(parse_argument(),parse_last_argument()); 330 CASE("div") 331 value = floor(parse_argument()/parse_last_argument()); 332 CASE("max") 333 value = std::max(parse_argument(),parse_last_argument()); 334 CASE("min") 335 value = std::min(parse_argument(),parse_last_argument()); 336 CASE_ELSE 337 { 338 this->failed_ = true; 339 delete[] word; 340 return 0; 341 } 342 } 343 else 344 { 345 #define SWITCH word 346 CASE_1("pi") 347 value = 3.1415926535897932; 348 CASE("e") 349 value = 2.7182818284590452; 350 CASE_ELSE 351 { 352 this->failed_ = true; 353 delete[] word; 354 return 0; 355 } 356 } 357 delete[] word; 358 } 359 else if (*reading_stream == 40) 360 { // expresion in paranthesis 361 ++reading_stream; 362 value = parse_last_argument(); 363 } 364 else 365 { 366 this->failed_ = true; 367 return 0; 368 } 369 370 PARSE_BLANKS; 371 switch (op) 372 { 373 case u_nicht: return !value; 374 case u_plus: return value; 375 case u_minus: return -value; 376 default: 377 this->failed_ = true; 378 return 0; 379 } 380 } 381 382 char* ExprParser::parse_word(char* str) 383 { 384 char* word = str; 385 int counter = 0; 386 while (*reading_stream > 47 && *reading_stream < 58 || *reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46) 387 { 388 *word++ = *reading_stream++; 389 counter++; 390 if (counter > 255) 391 { 392 this->failed_ = true; 393 return '\0'; 394 } 395 }; 396 *word = '\0'; 397 return str; 398 } 399 400 ExprParser::binary_operator ExprParser::parse_binary_operator() 401 { 402 binary_operator op; 403 switch (*reading_stream) 404 { 405 case '+': op = b_plus; break; 406 case '-': op = b_minus; break; 407 case '*': op = mal; break; 408 case '/': op = durch; break; 409 case '^': op = hoch; break; 410 case '%': op = modulo; break; 411 case '&': op = und; break; 412 case '|': op = oder; break; 413 case '=': op = gleich; break; 414 case '!': op = b_nicht; break; 415 case '<': op = kleiner; break; 416 case '>': op = groesser; break; 417 default: return undef; 418 } 419 if (*++reading_stream == '=') 420 { 421 if (op > 9) 422 { 423 ++reading_stream; 424 return (binary_operator)(op + 3); 425 } 426 else 427 { 428 --reading_stream; 429 return undef; 430 } 431 } 432 else 433 return op; 434 } 435 436 ExprParser::unary_operator ExprParser::parse_unary_operator() 437 { 438 switch (*reading_stream) 439 { 440 case '!': 441 ++reading_stream; 442 return u_nicht; 443 case '+': 444 ++reading_stream; 445 return u_plus; 446 case '-': 447 ++reading_stream; 448 return u_minus; 449 default : 450 return u_plus; 451 } 60 452 } 61 453 } 62 63 //Private functions:64 /******************/65 double ExprParser::parse_argument()66 {67 double value = parse_expr_8();68 if (*reading_stream == ',')69 {70 ++reading_stream;71 return value;72 }73 else74 {75 this->failed_ = true;76 return 0;77 }78 }79 80 double ExprParser::parse_last_argument()81 {82 double value = parse_expr_8();83 if (*reading_stream == ')')84 {85 ++reading_stream;86 return value;87 }88 else89 {90 this->failed_ = true;91 return 0;92 }93 }94 95 double ExprParser::parse_expr_8()96 {97 double value = parse_expr_7();98 for(;;)99 {100 switch (op)101 {102 case oder:103 value = parse_expr_7() || value;104 break;105 default: return value;106 }107 };108 }109 110 111 double ExprParser::parse_expr_7()112 {113 double value = parse_expr_6();114 for(;;)115 {116 switch (op)117 {118 case und:119 value = value && parse_expr_6();120 break;121 default: return value;122 }123 };124 }125 126 double ExprParser::parse_expr_6()127 {128 double value = parse_expr_5();129 for(;;)130 {131 switch (op)132 {133 case gleich:134 value = (value == parse_expr_5());135 break;136 case ungleich:137 value = (value != parse_expr_5());138 break;139 default:140 return value;141 }142 };143 }144 145 double ExprParser::parse_expr_5()146 {147 double value = parse_expr_4();148 for(;;)149 {150 switch (op)151 {152 case kleiner:153 value = (value < parse_expr_4());154 break;155 case kleinergleich:156 value = (value <= parse_expr_4());157 break;158 case groesser:159 value = (value > parse_expr_4());160 break;161 case groessergleich:162 value = (value >= parse_expr_4());163 break;164 default:165 return value;166 }167 };168 }169 170 double ExprParser::parse_expr_4()171 {172 double value = parse_expr_3();173 for(;;)174 {175 switch (op)176 {177 case b_plus:178 value += parse_expr_3();179 break;180 case b_minus:181 value -= parse_expr_3();182 break;183 default:184 return value;185 }186 };187 }188 189 double ExprParser::parse_expr_3()190 {191 double value = parse_expr_2();192 for(;;)193 {194 switch (op)195 {196 case mal:197 value *= parse_expr_2();198 break;199 case durch:200 value /= parse_expr_2();201 break;202 case modulo:203 {204 double temp = parse_expr_2();205 value = value - floor(value/temp)*temp;206 break;207 }208 default:209 return value;210 }211 };212 }213 214 double ExprParser::parse_expr_2()215 {216 double value = parse_expr_1();217 while (*reading_stream != '\0')218 {219 op = parse_binary_operator();220 switch (op)221 {222 case hoch:223 value = pow(value,parse_expr_1());224 break;225 default:226 return value;227 }228 };229 op = undef;230 return value;231 }232 233 double ExprParser::parse_expr_1()234 {235 PARSE_BLANKS;236 double value;237 238 unary_operator op = parse_unary_operator();239 PARSE_BLANKS;240 241 if (*reading_stream == '\0')242 {243 // end of string244 this->failed_ = true;245 return 0;246 }247 else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46)248 { // number249 value = strtod(reading_stream, const_cast<char**>(&reading_stream));250 }251 else if (*reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46)252 { // variable or function253 char* word = new char[256];254 parse_word(word);255 PARSE_BLANKS;256 if (*reading_stream == '(')257 {258 ++reading_stream;259 #define SWITCH word260 CASE_1("sin")261 value = sin(parse_last_argument());262 CASE("asin")263 value = asin(parse_last_argument());264 CASE("sinh")265 value = sinh(parse_last_argument());266 CASE("asinh")267 {268 value = parse_last_argument();269 value = log(sqrt(pow(value, 2) + 1) + value);270 }271 CASE("cos")272 value = cos(parse_last_argument());273 CASE("acos")274 value = acos(parse_last_argument());275 CASE("cosh")276 value = cosh(parse_last_argument());277 CASE("acosh")278 {279 value = parse_last_argument();280 value = log(sqrt(pow(value, 2) - 1) + value);281 }282 CASE("tan")283 value = tan(parse_last_argument());284 CASE("atan")285 value = atan(parse_last_argument());286 CASE("atan2")287 value = atan2(parse_argument(),parse_last_argument());288 CASE("tanh")289 value = tanh(parse_last_argument());290 CASE("atanh")291 {292 value = parse_last_argument();293 value = 0.5*log((value + 1)/(value - 1));294 }295 CASE("int")296 value = floor(parse_last_argument());297 CASE("floor")298 value = floor(parse_last_argument());299 CASE("ceil")300 value = ceil(parse_last_argument());301 CASE("abs")302 value = fabs(parse_last_argument());303 CASE("exp")304 value = exp(parse_last_argument());305 CASE("log")306 value = log10(parse_last_argument());307 CASE("ln")308 value = log(parse_last_argument());309 CASE("sign")310 {311 value = parse_last_argument();312 value = (value>0 ? 1 : (value<0 ? -1 : 0));313 }314 CASE("sqrt")315 value = sqrt(parse_last_argument());316 CASE("degrees")317 value = parse_last_argument()*180/3.1415926535897932;318 CASE("radians")319 value = parse_last_argument()*3.1415926535897932/180;320 CASE("mod")321 {322 value = parse_argument();323 double value2 = parse_last_argument();324 value = value - floor(value/value2)*value2;325 }326 CASE("pow")327 value = pow(parse_argument(),parse_last_argument());328 CASE("div")329 value = floor(parse_argument()/parse_last_argument());330 CASE("max")331 value = std::max(parse_argument(),parse_last_argument());332 CASE("min")333 value = std::min(parse_argument(),parse_last_argument());334 CASE_ELSE335 {336 this->failed_ = true;337 delete[] word;338 return 0;339 }340 }341 else342 {343 #define SWITCH word344 CASE_1("pi")345 value = 3.1415926535897932;346 CASE("e")347 value = 2.7182818284590452;348 CASE_ELSE349 {350 this->failed_ = true;351 delete[] word;352 return 0;353 }354 }355 delete[] word;356 }357 else if (*reading_stream == 40)358 { // expresion in paranthesis359 ++reading_stream;360 value = parse_last_argument();361 }362 else363 {364 this->failed_ = true;365 return 0;366 }367 368 PARSE_BLANKS;369 switch (op)370 {371 case u_nicht: return !value;372 case u_plus: return value;373 case u_minus: return -value;374 default:375 this->failed_ = true;376 return 0;377 }378 }379 380 char* ExprParser::parse_word(char* str)381 {382 char* word = str;383 int counter = 0;384 while (*reading_stream > 47 && *reading_stream < 58 || *reading_stream > 64 && *reading_stream < 91 || *reading_stream > 96 && *reading_stream < 123 || *reading_stream == 46)385 {386 *word++ = *reading_stream++;387 counter++;388 if (counter > 255)389 {390 this->failed_ = true;391 return '\0';392 }393 };394 *word = '\0';395 return str;396 }397 398 ExprParser::binary_operator ExprParser::parse_binary_operator()399 {400 binary_operator op;401 switch (*reading_stream)402 {403 case '+': op = b_plus; break;404 case '-': op = b_minus; break;405 case '*': op = mal; break;406 case '/': op = durch; break;407 case '^': op = hoch; break;408 case '%': op = modulo; break;409 case '&': op = und; break;410 case '|': op = oder; break;411 case '=': op = gleich; break;412 case '!': op = b_nicht; break;413 case '<': op = kleiner; break;414 case '>': op = groesser; break;415 default: return undef;416 }417 if (*++reading_stream == '=')418 {419 if (op > 9)420 {421 ++reading_stream;422 return (binary_operator)(op + 3);423 }424 else425 {426 --reading_stream;427 return undef;428 }429 }430 else431 return op;432 }433 434 ExprParser::unary_operator ExprParser::parse_unary_operator()435 {436 switch (*reading_stream)437 {438 case '!':439 ++reading_stream;440 return u_nicht;441 case '+':442 ++reading_stream;443 return u_plus;444 case '-':445 ++reading_stream;446 return u_minus;447 default :448 return u_plus;449 }450 } -
code/branches/objecthierarchy/src/util/ExprParser.h
r1894 r2111 38 38 #include <string> 39 39 40 class _UtilExport ExprParser 40 namespace orxonox 41 41 { 42 public: 43 enum binary_operator 42 class _UtilExport ExprParser 44 43 { 45 b_plus, 46 b_minus, 47 mal, 48 durch, 49 modulo, 50 hoch, 51 undef, 52 oder, 53 und, 54 gleich, 55 b_nicht, 56 kleiner, 57 groesser, 58 ungleich, 59 kleinergleich, 60 groessergleich 44 public: 45 enum binary_operator 46 { 47 b_plus, 48 b_minus, 49 mal, 50 durch, 51 modulo, 52 hoch, 53 undef, 54 oder, 55 und, 56 gleich, 57 b_nicht, 58 kleiner, 59 groesser, 60 ungleich, 61 kleinergleich, 62 groessergleich 63 }; 64 65 enum unary_operator 66 { 67 u_plus, 68 u_minus, 69 u_nicht 70 }; 71 72 73 ExprParser(const std::string& str); 74 std::string& getRemains() { return this->remains_; } 75 double getResult() { return this->result_; } 76 bool getSuccess() { return !this->failed_; } 77 78 private: 79 double parse_expr_1(); 80 double parse_expr_2(); 81 double parse_expr_3(); 82 double parse_expr_4(); 83 double parse_expr_5(); 84 double parse_expr_6(); 85 double parse_expr_7(); 86 double parse_expr_8(); 87 char* parse_word(char* str); 88 binary_operator parse_binary_operator(); 89 unary_operator parse_unary_operator(); 90 91 double parse_argument(); 92 double parse_last_argument(); 93 94 binary_operator op; 95 const char* reading_stream; 96 bool failed_; 97 double result_; 98 std::string remains_; 99 61 100 }; 62 101 63 enum unary_operator 64 { 65 u_plus, 66 u_minus, 67 u_nicht 68 }; 69 70 71 ExprParser(const std::string& str); 72 std::string& getRemains() { return this->remains_; } 73 double getResult() { return this->result_; } 74 bool getSuccess() { return !this->failed_; } 75 76 private: 77 double parse_expr_1(); 78 double parse_expr_2(); 79 double parse_expr_3(); 80 double parse_expr_4(); 81 double parse_expr_5(); 82 double parse_expr_6(); 83 double parse_expr_7(); 84 double parse_expr_8(); 85 char* parse_word(char* str); 86 binary_operator parse_binary_operator(); 87 unary_operator parse_unary_operator(); 88 89 double parse_argument(); 90 double parse_last_argument(); 91 92 binary_operator op; 93 const char* reading_stream; 94 bool failed_; 95 double result_; 96 std::string remains_; 97 98 }; 99 100 //Endzeichen für float expression: ')', '}', ']', ',', ';' 101 _UtilExport bool parse_float(char* const, char**, double*); 102 //Endzeichen angegeben 103 _UtilExport bool parse_float(char* const, char**, char, double*); 104 //Letzter Teil-float eines Vektors parsen (keine Vergleichs- und Logikoperationen) 105 _UtilExport bool parse_vector_float(char* const, char**, bool, double*); 102 //Endzeichen für float expression: ')', '}', ']', ',', ';' 103 _UtilExport bool parse_float(char* const, char**, double*); 104 //Endzeichen angegeben 105 _UtilExport bool parse_float(char* const, char**, char, double*); 106 //Letzter Teil-float eines Vektors parsen (keine Vergleichs- und Logikoperationen) 107 _UtilExport bool parse_vector_float(char* const, char**, bool, double*); 108 } 106 109 107 110 #endif /* _FloatParser_H__ */ -
code/branches/objecthierarchy/src/util/Math.cc
r2019 r2111 38 38 #include "SubString.h" 39 39 40 /** 41 @brief Function for writing a Radian to a stream. 42 */ 43 std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian) 40 namespace orxonox 44 41 { 45 out << radian.valueRadians(); 46 return out; 42 /** 43 @brief Function for writing a Radian to a stream. 44 */ 45 std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian) 46 { 47 out << radian.valueRadians(); 48 return out; 49 } 50 51 /** 52 @brief Function for reading a Radian from a stream. 53 */ 54 std::istream& operator>>(std::istream& in, orxonox::Radian& radian) 55 { 56 float temp; 57 in >> temp; 58 radian = temp; 59 return in; 60 } 61 62 /** 63 @brief Function for writing a Degree to a stream. 64 */ 65 std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree) 66 { 67 out << degree.valueDegrees(); 68 return out; 69 } 70 71 /** 72 @brief Function for reading a Degree from a stream. 73 */ 74 std::istream& operator>>(std::istream& in, orxonox::Degree& degree) 75 { 76 float temp; 77 in >> temp; 78 degree = temp; 79 return in; 80 } 81 82 83 /** 84 @brief Gets the angle between my viewing direction and the direction to the position of the other object. 85 @param myposition My position 86 @param mydirection My viewing direction 87 @param otherposition The position of the other object 88 @return The angle 89 90 @example 91 If the other object is exactly in front of me, the function returns 0. 92 If the other object is exactly behind me, the function returns pi. 93 If the other object is exactly right/left to me (or above/below), the function returns pi/2. 94 */ 95 float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition) 96 { 97 orxonox::Vector3 distance = otherposition - myposition; 98 float distancelength = distance.length(); 99 if (distancelength == 0) 100 return 0; 101 else 102 return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)); 103 } 104 105 /** 106 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object. 107 @param myposition My position 108 @param mydirection My viewing direction 109 @param myorthonormal My orthonormalvector (pointing upwards through my head) 110 @param otherposition The position of the other object 111 @return The viewing direction 112 113 @example 114 If the other object is exactly in front of me, the function returns Vector2(0, 0). 115 If the other object is exactly at my left, the function returns Vector2(-1, 0). 116 If the other object is exactly at my right, the function returns Vector2(1, 0). 117 If the other object is only a bit at my right, the function still returns Vector2(1, 0). 118 If the other object is exactly above me, the function returns Vector2(0, 1). 119 */ 120 orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition) 121 { 122 orxonox::Vector3 distance = otherposition - myposition; 123 124 // project difference vector on our plane 125 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance); 126 127 float projectionlength = projection.length(); 128 if (projectionlength == 0) return orxonox::Vector2(0, 0); 129 float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1)); 130 131 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0) 132 return orxonox::Vector2(sin(angle), cos(angle)); 133 else 134 return orxonox::Vector2(-sin(angle), cos(angle)); 135 } 136 137 /** 138 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object, multiplied with the viewing distance to the object (0° = 0, 180° = 1). 139 @param myposition My position 140 @param mydirection My viewing direction 141 @param myorthonormal My orthonormalvector (pointing upwards through my head) 142 @param otherposition The position of the other object 143 @return The viewing direction 144 145 @example 146 If the other object is exactly in front of me, the function returns Vector2(0, 0). 147 If the other object is exactly at my left, the function returns Vector2(-0.5, 0). 148 If the other object is exactly at my right, the function returns Vector2(0.5, 0). 149 If the other object is only a bit at my right, the function still returns Vector2(0.01, 0). 150 If the other object is exactly above me, the function returns Vector2(0, 0.5). 151 */ 152 orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition) 153 { 154 orxonox::Vector3 distance = otherposition - myposition; 155 156 // project difference vector on our plane 157 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance); 158 159 float projectionlength = projection.length(); 160 if (projectionlength == 0) return orxonox::Vector2(0, 0); 161 float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1)); 162 163 float distancelength = distance.length(); 164 if (distancelength == 0) return orxonox::Vector2(0, 0); 165 float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / Ogre::Math::PI; 166 167 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0) 168 return orxonox::Vector2(sin(angle) * radius, cos(angle) * radius); 169 else 170 return orxonox::Vector2(-sin(angle) * radius, cos(angle) * radius); 171 } 172 173 /** 174 @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile. 175 @param myposition My position 176 @param projectilespeed The speed of my projectile 177 @param targetposition The position of my target 178 @param targetvelocity The velocity of my target 179 @return The predicted position 180 181 The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss. 182 */ 183 orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity) 184 { 185 float squaredProjectilespeed = projectilespeed * projectilespeed; 186 orxonox::Vector3 distance = targetposition - myposition; 187 float a = distance.squaredLength(); 188 float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z); 189 float c = targetvelocity.squaredLength(); 190 191 float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c; 192 if (temp < 0) 193 return orxonox::Vector3::ZERO; 194 195 temp = sqrt(temp); 196 float time = (temp + a) / (2 * (squaredProjectilespeed - b)); 197 return (targetposition + targetvelocity * time); 198 } 199 200 unsigned long getUniqueNumber() 201 { 202 static unsigned long aNumber = 135; 203 return aNumber++; 204 } 205 206 207 ////////////////////////// 208 // Conversion functions // 209 ////////////////////////// 210 211 // std::string to Vector2 212 bool ConverterFallback<std::string, orxonox::Vector2>::convert(orxonox::Vector2* output, const std::string& input) 213 { 214 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 215 if ((opening_parenthesis = input.find('(')) == std::string::npos) 216 opening_parenthesis = 0; 217 else 218 opening_parenthesis++; 219 220 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), 221 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 222 if (tokens.size() >= 2) 223 { 224 if (!ConvertValue(&(output->x), tokens[0])) 225 return false; 226 if (!ConvertValue(&(output->y), tokens[1])) 227 return false; 228 229 return true; 230 } 231 return false; 232 } 233 234 // std::string to Vector3 235 bool ConverterFallback<std::string, orxonox::Vector3>::convert(orxonox::Vector3* output, const std::string& input) 236 { 237 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 238 if ((opening_parenthesis = input.find('(')) == std::string::npos) 239 opening_parenthesis = 0; 240 else 241 opening_parenthesis++; 242 243 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), 244 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 245 if (tokens.size() >= 3) 246 { 247 if (!ConvertValue(&(output->x), tokens[0])) 248 return false; 249 if (!ConvertValue(&(output->y), tokens[1])) 250 return false; 251 if (!ConvertValue(&(output->z), tokens[2])) 252 return false; 253 254 return true; 255 } 256 return false; 257 } 258 259 // std::string to Vector4 260 bool ConverterFallback<std::string, orxonox::Vector4>::convert(orxonox::Vector4* output, const std::string& input) 261 { 262 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 263 if ((opening_parenthesis = input.find('(')) == std::string::npos) 264 opening_parenthesis = 0; 265 else 266 opening_parenthesis++; 267 268 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), 269 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 270 if (tokens.size() >= 4) 271 { 272 if (!ConvertValue(&(output->x), tokens[0])) 273 return false; 274 if (!ConvertValue(&(output->y), tokens[1])) 275 return false; 276 if (!ConvertValue(&(output->z), tokens[2])) 277 return false; 278 if (!ConvertValue(&(output->w), tokens[3])) 279 return false; 280 281 return true; 282 } 283 return false; 284 } 285 286 // std::string to Quaternion 287 bool ConverterFallback<std::string, orxonox::Quaternion>::convert(orxonox::Quaternion* output, const std::string& input) 288 { 289 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 290 if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; } 291 292 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 293 if (tokens.size() >= 4) 294 { 295 if (!ConvertValue(&(output->w), tokens[0])) 296 return false; 297 if (!ConvertValue(&(output->x), tokens[1])) 298 return false; 299 if (!ConvertValue(&(output->y), tokens[2])) 300 return false; 301 if (!ConvertValue(&(output->z), tokens[3])) 302 return false; 303 304 return true; 305 } 306 return false; 307 } 308 309 // std::string to ColourValue 310 bool ConverterFallback<std::string, orxonox::ColourValue>::convert(orxonox::ColourValue* output, const std::string& input) 311 { 312 size_t opening_parenthesis, closing_parenthesis = input.find(')'); 313 if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; } 314 315 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0'); 316 if (tokens.size() >= 3) 317 { 318 if (!ConvertValue(&(output->r), tokens[0])) 319 return false; 320 if (!ConvertValue(&(output->g), tokens[1])) 321 return false; 322 if (!ConvertValue(&(output->b), tokens[2])) 323 return false; 324 if (tokens.size() >= 4) 325 { 326 if (!ConvertValue(&(output->a), tokens[3])) 327 return false; 328 } 329 else 330 output->a = 1.0; 331 332 return true; 333 } 334 return false; 335 } 47 336 } 48 49 /**50 @brief Function for reading a Radian from a stream.51 */52 std::istream& operator>>(std::istream& in, orxonox::Radian& radian)53 {54 float temp;55 in >> temp;56 radian = temp;57 return in;58 }59 60 /**61 @brief Function for writing a Degree to a stream.62 */63 std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree)64 {65 out << degree.valueDegrees();66 return out;67 }68 69 /**70 @brief Function for reading a Degree from a stream.71 */72 std::istream& operator>>(std::istream& in, orxonox::Degree& degree)73 {74 float temp;75 in >> temp;76 degree = temp;77 return in;78 }79 80 81 /**82 @brief Gets the angle between my viewing direction and the direction to the position of the other object.83 @param myposition My position84 @param mydirection My viewing direction85 @param otherposition The position of the other object86 @return The angle87 88 @example89 If the other object is exactly in front of me, the function returns 0.90 If the other object is exactly behind me, the function returns pi.91 If the other object is exactly right/left to me (or above/below), the function returns pi/2.92 */93 float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition)94 {95 orxonox::Vector3 distance = otherposition - myposition;96 float distancelength = distance.length();97 if (distancelength == 0)98 return 0;99 else100 return acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1));101 }102 103 /**104 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object.105 @param myposition My position106 @param mydirection My viewing direction107 @param myorthonormal My orthonormalvector (pointing upwards through my head)108 @param otherposition The position of the other object109 @return The viewing direction110 111 @example112 If the other object is exactly in front of me, the function returns Vector2(0, 0).113 If the other object is exactly at my left, the function returns Vector2(-1, 0).114 If the other object is exactly at my right, the function returns Vector2(1, 0).115 If the other object is only a bit at my right, the function still returns Vector2(1, 0).116 If the other object is exactly above me, the function returns Vector2(0, 1).117 */118 orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)119 {120 orxonox::Vector3 distance = otherposition - myposition;121 122 // project difference vector on our plane123 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);124 125 float projectionlength = projection.length();126 if (projectionlength == 0) return orxonox::Vector2(0, 0);127 float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));128 129 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)130 return orxonox::Vector2(sin(angle), cos(angle));131 else132 return orxonox::Vector2(-sin(angle), cos(angle));133 }134 135 /**136 @brief Gets the 2D viewing direction (up/down, left/right) to the position of the other object, multiplied with the viewing distance to the object (0° = 0, 180° = 1).137 @param myposition My position138 @param mydirection My viewing direction139 @param myorthonormal My orthonormalvector (pointing upwards through my head)140 @param otherposition The position of the other object141 @return The viewing direction142 143 @example144 If the other object is exactly in front of me, the function returns Vector2(0, 0).145 If the other object is exactly at my left, the function returns Vector2(-0.5, 0).146 If the other object is exactly at my right, the function returns Vector2(0.5, 0).147 If the other object is only a bit at my right, the function still returns Vector2(0.01, 0).148 If the other object is exactly above me, the function returns Vector2(0, 0.5).149 */150 orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition)151 {152 orxonox::Vector3 distance = otherposition - myposition;153 154 // project difference vector on our plane155 orxonox::Vector3 projection = Ogre::Plane(mydirection, myposition).projectVector(distance);156 157 float projectionlength = projection.length();158 if (projectionlength == 0) return orxonox::Vector2(0, 0);159 float angle = acos(clamp<float>(myorthonormal.dotProduct(projection) / projectionlength, -1, 1));160 161 float distancelength = distance.length();162 if (distancelength == 0) return orxonox::Vector2(0, 0);163 float radius = acos(clamp<float>(mydirection.dotProduct(distance) / distancelength, -1, 1)) / Ogre::Math::PI;164 165 if ((mydirection.crossProduct(myorthonormal)).dotProduct(distance) > 0)166 return orxonox::Vector2(sin(angle) * radius, cos(angle) * radius);167 else168 return orxonox::Vector2(-sin(angle) * radius, cos(angle) * radius);169 }170 171 /**172 @brief Returns the predicted position I have to aim at, if I want to hit a moving target with a moving projectile.173 @param myposition My position174 @param projectilespeed The speed of my projectile175 @param targetposition The position of my target176 @param targetvelocity The velocity of my target177 @return The predicted position178 179 The function predicts the position based on a linear velocity of the target. If the target changes speed or direction, the projectile will miss.180 */181 orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity)182 {183 float squaredProjectilespeed = projectilespeed * projectilespeed;184 orxonox::Vector3 distance = targetposition - myposition;185 float a = distance.squaredLength();186 float b = 2 * (distance.x + distance.y + distance.z) * (targetvelocity.x + targetvelocity.y + targetvelocity.z);187 float c = targetvelocity.squaredLength();188 189 float temp = 4*squaredProjectilespeed*c + a*a - 4*b*c;190 if (temp < 0)191 return orxonox::Vector3::ZERO;192 193 temp = sqrt(temp);194 float time = (temp + a) / (2 * (squaredProjectilespeed - b));195 return (targetposition + targetvelocity * time);196 }197 198 unsigned long getUniqueNumber()199 {200 static unsigned long aNumber = 135;201 return aNumber++;202 }203 204 205 //////////////////////////206 // Conversion functions //207 //////////////////////////208 209 // std::string to Vector2210 bool ConverterFallback<std::string, orxonox::Vector2>::convert(orxonox::Vector2* output, const std::string& input)211 {212 size_t opening_parenthesis, closing_parenthesis = input.find(')');213 if ((opening_parenthesis = input.find('(')) == std::string::npos)214 opening_parenthesis = 0;215 else216 opening_parenthesis++;217 218 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),219 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');220 if (tokens.size() >= 2)221 {222 if (!ConvertValue(&(output->x), tokens[0]))223 return false;224 if (!ConvertValue(&(output->y), tokens[1]))225 return false;226 227 return true;228 }229 return false;230 }231 232 // std::string to Vector3233 bool ConverterFallback<std::string, orxonox::Vector3>::convert(orxonox::Vector3* output, const std::string& input)234 {235 size_t opening_parenthesis, closing_parenthesis = input.find(')');236 if ((opening_parenthesis = input.find('(')) == std::string::npos)237 opening_parenthesis = 0;238 else239 opening_parenthesis++;240 241 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),242 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');243 if (tokens.size() >= 3)244 {245 if (!ConvertValue(&(output->x), tokens[0]))246 return false;247 if (!ConvertValue(&(output->y), tokens[1]))248 return false;249 if (!ConvertValue(&(output->z), tokens[2]))250 return false;251 252 return true;253 }254 return false;255 }256 257 // std::string to Vector4258 bool ConverterFallback<std::string, orxonox::Vector4>::convert(orxonox::Vector4* output, const std::string& input)259 {260 size_t opening_parenthesis, closing_parenthesis = input.find(')');261 if ((opening_parenthesis = input.find('(')) == std::string::npos)262 opening_parenthesis = 0;263 else264 opening_parenthesis++;265 266 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis),267 ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');268 if (tokens.size() >= 4)269 {270 if (!ConvertValue(&(output->x), tokens[0]))271 return false;272 if (!ConvertValue(&(output->y), tokens[1]))273 return false;274 if (!ConvertValue(&(output->z), tokens[2]))275 return false;276 if (!ConvertValue(&(output->w), tokens[3]))277 return false;278 279 return true;280 }281 return false;282 }283 284 // std::string to Quaternion285 bool ConverterFallback<std::string, orxonox::Quaternion>::convert(orxonox::Quaternion* output, const std::string& input)286 {287 size_t opening_parenthesis, closing_parenthesis = input.find(')');288 if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }289 290 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');291 if (tokens.size() >= 4)292 {293 if (!ConvertValue(&(output->w), tokens[0]))294 return false;295 if (!ConvertValue(&(output->x), tokens[1]))296 return false;297 if (!ConvertValue(&(output->y), tokens[2]))298 return false;299 if (!ConvertValue(&(output->z), tokens[3]))300 return false;301 302 return true;303 }304 return false;305 }306 307 // std::string to ColourValue308 bool ConverterFallback<std::string, orxonox::ColourValue>::convert(orxonox::ColourValue* output, const std::string& input)309 {310 size_t opening_parenthesis, closing_parenthesis = input.find(')');311 if ((opening_parenthesis = input.find('(')) == std::string::npos) { opening_parenthesis = 0; } else { opening_parenthesis++; }312 313 SubString tokens(input.substr(opening_parenthesis, closing_parenthesis - opening_parenthesis), ",", SubString::WhiteSpaces, false, '\\', true, '"', true, '\0', '\0', true, '\0');314 if (tokens.size() >= 3)315 {316 if (!ConvertValue(&(output->r), tokens[0]))317 return false;318 if (!ConvertValue(&(output->g), tokens[1]))319 return false;320 if (!ConvertValue(&(output->b), tokens[2]))321 return false;322 if (tokens.size() >= 4)323 {324 if (!ConvertValue(&(output->a), tokens[3]))325 return false;326 }327 else328 output->a = 1.0;329 330 return true;331 }332 return false;333 } -
code/branches/objecthierarchy/src/util/Math.h
r2019 r2111 49 49 #include <OgreQuaternion.h> 50 50 #include <OgreColourValue.h> 51 52 namespace orxonox53 {54 typedef Ogre::Radian Radian;55 typedef Ogre::Degree Degree;56 typedef Ogre::Vector2 Vector2;57 typedef Ogre::Vector3 Vector3;58 typedef Ogre::Vector4 Vector4;59 typedef Ogre::Matrix3 Matrix3;60 typedef Ogre::Matrix4 Matrix4;61 typedef Ogre::Quaternion Quaternion;62 typedef Ogre::ColourValue ColourValue;63 }64 65 _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian);66 _UtilExport std::istream& operator>>(std::istream& in, orxonox::Radian& radian);67 _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree);68 _UtilExport std::istream& operator>>(std::istream& in, orxonox::Degree& degree);69 70 _UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition);71 _UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);72 _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition);73 _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity);74 51 75 52 //Get around Windows hackery … … 83 60 #endif 84 61 85 /** 86 @brief Returns the sign of the given value. 87 @param x The value 88 @return 1 if the value is positive or zero, -1 if the value is negative 89 */ 90 template <typename T> 91 inline T sgn(T x) 62 namespace orxonox 92 63 { 93 return (x >= 0) ? 1 : -1; 64 typedef Ogre::Radian Radian; 65 typedef Ogre::Degree Degree; 66 typedef Ogre::Vector2 Vector2; 67 typedef Ogre::Vector3 Vector3; 68 typedef Ogre::Vector4 Vector4; 69 typedef Ogre::Matrix3 Matrix3; 70 typedef Ogre::Matrix4 Matrix4; 71 typedef Ogre::Quaternion Quaternion; 72 typedef Ogre::ColourValue ColourValue; 73 74 _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian); 75 _UtilExport std::istream& operator>>(std::istream& in, orxonox::Radian& radian); 76 _UtilExport std::ostream& operator<<(std::ostream& out, const orxonox::Degree& degree); 77 _UtilExport std::istream& operator>>(std::istream& in, orxonox::Degree& degree); 78 79 _UtilExport float getAngle(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& otherposition); 80 _UtilExport orxonox::Vector2 get2DViewdirection(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition); 81 _UtilExport orxonox::Vector2 get2DViewcoordinates(const orxonox::Vector3& myposition, const orxonox::Vector3& mydirection, const orxonox::Vector3& myorthonormal, const orxonox::Vector3& otherposition); 82 _UtilExport orxonox::Vector3 getPredictedPosition(const orxonox::Vector3& myposition, float projectilespeed, const orxonox::Vector3& targetposition, const orxonox::Vector3& targetvelocity); 83 84 /** 85 @brief Returns the sign of the given value. 86 @param x The value 87 @return 1 if the value is positive or zero, -1 if the value is negative 88 */ 89 template <typename T> 90 inline T sgn(T x) 91 { 92 return (x >= 0) ? 1 : -1; 93 } 94 95 /** 96 @brief Returns the smaller of two values. 97 */ 98 template <typename T> 99 inline T min(T a, T b) 100 { 101 return (a <= b) ? a : b; 102 } 103 104 /** 105 @brief Returns the greater of two values. 106 */ 107 template <typename T> 108 inline T max(T a, T b) 109 { 110 return (a >= b) ? a : b; 111 } 112 113 /** 114 @brief Keeps a value between a lower and an upper limit. 115 @param x The value 116 @param min The lower limit 117 @param max The upper limit 118 */ 119 template <typename T> 120 inline T clamp(T x, T min, T max) 121 { 122 if (x < min) 123 return min; 124 125 if (x > max) 126 return max; 127 128 return x; 129 } 130 131 /** 132 @brief Returns the square value (x^2). 133 */ 134 template <typename T> 135 inline T square(T x) 136 { 137 return x*x; 138 } 139 140 /** 141 @brief Returns the cube value (x^3). 142 */ 143 template <typename T> 144 inline T cube(T x) 145 { 146 return x*x*x; 147 } 148 149 /** 150 @brief Rounds the value down. 151 */ 152 template <typename T> 153 inline int floor(T x) 154 { 155 return (int)(x); 156 } 157 158 /** 159 @brief Rounds the value up. 160 */ 161 template <typename T> 162 inline int ceil(T x) 163 { 164 int temp = floor(x); 165 return (temp != x) ? (temp + 1) : temp; 166 } 167 168 /** 169 @brief Rounds the value. 170 */ 171 template <typename T> 172 inline int round(T x) 173 { 174 return (int)(x + 0.5); 175 } 176 177 /** 178 @brief The modulo operation, enhanced to work properly with negative values. 179 @param x The value 180 @param max The operand 181 */ 182 template <typename T> 183 inline int mod(T x, int max) 184 { 185 if (x >= 0) 186 return (x % max); 187 else 188 return ((x % max) + max); 189 } 190 191 template <typename T> 192 inline T zeroise() 193 { 194 BOOST_STATIC_ASSERT(sizeof(T) == 0); 195 return T(); 196 } 197 198 template <> inline char zeroise<char>() { return 0; } 199 template <> inline unsigned char zeroise<unsigned char>() { return 0; } 200 template <> inline short zeroise<short>() { return 0; } 201 template <> inline unsigned short zeroise<unsigned short>() { return 0; } 202 template <> inline int zeroise<int>() { return 0; } 203 template <> inline unsigned int zeroise<unsigned int>() { return 0; } 204 template <> inline long zeroise<long>() { return 0; } 205 template <> inline unsigned long zeroise<unsigned long>() { return 0; } 206 template <> inline long long zeroise<long long>() { return 0; } 207 template <> inline unsigned long long zeroise<unsigned long long>() { return 0; } 208 template <> inline float zeroise<float>() { return 0; } 209 template <> inline double zeroise<double>() { return 0; } 210 template <> inline long double zeroise<long double>() { return 0; } 211 template <> inline bool zeroise<bool>() { return 0; } 212 template <> inline void* zeroise<void*>() { return 0; } 213 template <> inline std::string zeroise<std::string>() { return ""; } 214 template <> inline orxonox::Radian zeroise<orxonox::Radian>() { return orxonox::Radian(0.0f); } 215 template <> inline orxonox::Degree zeroise<orxonox::Degree>() { return orxonox::Degree(0.0f); } 216 template <> inline orxonox::Vector2 zeroise<orxonox::Vector2>() { return orxonox::Vector2 (0, 0) ; } 217 template <> inline orxonox::Vector3 zeroise<orxonox::Vector3>() { return orxonox::Vector3 (0, 0, 0) ; } 218 template <> inline orxonox::Vector4 zeroise<orxonox::Vector4>() { return orxonox::Vector4 (0, 0, 0, 0); } 219 template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); } 220 template <> inline orxonox::Quaternion zeroise<orxonox::Quaternion>() { return orxonox::Quaternion (0, 0, 0, 0); } 221 222 /** 223 @brief Interpolates between two values for a time between 0 and 1. 224 @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1. 225 @param start The value at time = 0 226 @param end The value at time = 1 227 @return The interpolation at a given time 228 */ 229 template <typename T> 230 T interpolate(float time, const T& start, const T& end) 231 { 232 return time * (end - start) + start; 233 } 234 235 /** 236 @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again. 237 @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1. 238 @param start The value at time = 0 239 @param end The value at time = 1 240 @return The smoothed interpolation at a given time 241 */ 242 template <typename T> 243 T interpolateSmooth(float time, const T& start, const T& end) 244 { 245 return (-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start; 246 } 247 248 /** 249 @brief Returns a random number between 0 and almost 1: 0 <= rnd < 1. 250 */ 251 inline float rnd() 252 { 253 return rand() / (RAND_MAX + 1.0); 254 } 255 256 /** 257 @brief Returns a random number between 0 and almost max: 0 <= rnd < max. 258 @param max The maximum 259 */ 260 inline float rnd(float max) 261 { 262 return rnd() * max; 263 } 264 265 /** 266 @brief Returns a random number between min and almost max: min <= rnd < max. 267 @param min The minimum 268 @param max The maximum 269 */ 270 inline float rnd(float min, float max) 271 { 272 return rnd(max - min) + min; 273 } 274 275 _UtilExport unsigned long getUniqueNumber(); 276 277 class IntVector2 278 { 279 public: 280 IntVector2() : x(0), y(0) { } 281 IntVector2(int _x, int _y) : x(_x), y(_y) { } 282 int x; 283 int y; 284 }; 285 286 class IntVector3 287 { 288 public: 289 IntVector3() : x(0), y(0), z(0) { } 290 IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { } 291 int x; 292 int y; 293 int z; 294 }; 94 295 } 95 296 96 /**97 @brief Returns the smaller of two values.98 */99 template <typename T>100 inline T min(T a, T b)101 {102 return (a <= b) ? a : b;103 }104 105 /**106 @brief Returns the greater of two values.107 */108 template <typename T>109 inline T max(T a, T b)110 {111 return (a >= b) ? a : b;112 }113 114 /**115 @brief Keeps a value between a lower and an upper limit.116 @param x The value117 @param min The lower limit118 @param max The upper limit119 */120 template <typename T>121 inline T clamp(T x, T min, T max)122 {123 if (x < min)124 return min;125 126 if (x > max)127 return max;128 129 return x;130 }131 132 /**133 @brief Returns the square value (x^2).134 */135 template <typename T>136 inline T square(T x)137 {138 return x*x;139 }140 141 /**142 @brief Returns the cube value (x^3).143 */144 template <typename T>145 inline T cube(T x)146 {147 return x*x*x;148 }149 150 /**151 @brief Rounds the value down.152 */153 template <typename T>154 inline int floor(T x)155 {156 return (int)(x);157 }158 159 /**160 @brief Rounds the value up.161 */162 template <typename T>163 inline int ceil(T x)164 {165 int temp = floor(x);166 return (temp != x) ? (temp + 1) : temp;167 }168 169 /**170 @brief Rounds the value.171 */172 template <typename T>173 inline int round(T x)174 {175 return (int)(x + 0.5);176 }177 178 /**179 @brief The modulo operation, enhanced to work properly with negative values.180 @param x The value181 @param max The operand182 */183 template <typename T>184 inline int mod(T x, int max)185 {186 if (x >= 0)187 return (x % max);188 else189 return ((x % max) + max);190 }191 192 template <typename T>193 inline T zeroise()194 {195 BOOST_STATIC_ASSERT(sizeof(T) == 0);196 return T();197 }198 199 template <> inline char zeroise<char>() { return 0; }200 template <> inline unsigned char zeroise<unsigned char>() { return 0; }201 template <> inline short zeroise<short>() { return 0; }202 template <> inline unsigned short zeroise<unsigned short>() { return 0; }203 template <> inline int zeroise<int>() { return 0; }204 template <> inline unsigned int zeroise<unsigned int>() { return 0; }205 template <> inline long zeroise<long>() { return 0; }206 template <> inline unsigned long zeroise<unsigned long>() { return 0; }207 template <> inline long long zeroise<long long>() { return 0; }208 template <> inline unsigned long long zeroise<unsigned long long>() { return 0; }209 template <> inline float zeroise<float>() { return 0; }210 template <> inline double zeroise<double>() { return 0; }211 template <> inline long double zeroise<long double>() { return 0; }212 template <> inline bool zeroise<bool>() { return 0; }213 template <> inline void* zeroise<void*>() { return 0; }214 template <> inline std::string zeroise<std::string>() { return ""; }215 template <> inline orxonox::Radian zeroise<orxonox::Radian>() { return orxonox::Radian(0.0f); }216 template <> inline orxonox::Degree zeroise<orxonox::Degree>() { return orxonox::Degree(0.0f); }217 template <> inline orxonox::Vector2 zeroise<orxonox::Vector2>() { return orxonox::Vector2 (0, 0) ; }218 template <> inline orxonox::Vector3 zeroise<orxonox::Vector3>() { return orxonox::Vector3 (0, 0, 0) ; }219 template <> inline orxonox::Vector4 zeroise<orxonox::Vector4>() { return orxonox::Vector4 (0, 0, 0, 0); }220 template <> inline orxonox::ColourValue zeroise<orxonox::ColourValue>() { return orxonox::ColourValue(0, 0, 0, 0); }221 template <> inline orxonox::Quaternion zeroise<orxonox::Quaternion>() { return orxonox::Quaternion (0, 0, 0, 0); }222 223 /**224 @brief Interpolates between two values for a time between 0 and 1.225 @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1.226 @param start The value at time = 0227 @param end The value at time = 1228 @return The interpolation at a given time229 */230 template <typename T>231 T interpolate(float time, const T& start, const T& end)232 {233 return time * (end - start) + start;234 }235 236 /**237 @brief Interpolates smoothly between two values for a time between 0 and 1. The function starts slowly, increases faster and stops slowly again.238 @param time The time is a value between 0 and 1 - the function returns start if time is 0 and end if time is 1 and interpolates if time is between 0 and 1.239 @param start The value at time = 0240 @param end The value at time = 1241 @return The smoothed interpolation at a given time242 */243 template <typename T>244 T interpolateSmooth(float time, const T& start, const T& end)245 {246 return (-2 * (end - start) * cube(time)) + (3 * (end - start) * square(time)) + start;247 }248 249 /**250 @brief Returns a random number between 0 and almost 1: 0 <= rnd < 1.251 */252 inline _UtilExport float rnd()253 {254 return rand() / (RAND_MAX + 1.0);255 }256 257 /**258 @brief Returns a random number between 0 and almost max: 0 <= rnd < max.259 @param max The maximum260 */261 inline _UtilExport float rnd(float max)262 {263 return rnd() * max;264 }265 266 /**267 @brief Returns a random number between min and almost max: min <= rnd < max.268 @param min The minimum269 @param max The maximum270 */271 inline _UtilExport float rnd(float min, float max)272 {273 return rnd(max - min) + min;274 }275 276 _UtilExport unsigned long getUniqueNumber();277 278 class _UtilExport IntVector2279 {280 public:281 IntVector2() : x(0), y(0) { }282 IntVector2(int _x, int _y) : x(_x), y(_y) { }283 int x;284 int y;285 };286 287 class _UtilExport IntVector3288 {289 public:290 IntVector3() : x(0), y(0), z(0) { }291 IntVector3(int _x, int _y, int _z) : x(_x), y(_y), z(_z) { }292 int x;293 int y;294 int z;295 };296 297 297 #endif /* _Util_Math_H__ */ -
code/branches/objecthierarchy/src/util/MathConvert.h
r2016 r2111 40 40 #include "Convert.h" 41 41 42 43 //////////////////// 44 // Math to string // 45 //////////////////// 46 47 // Vector2 to std::string 48 template <> 49 struct ConverterExplicit<orxonox::Vector2, std::string> 42 namespace orxonox 50 43 { 51 static bool convert(std::string* output, const orxonox::Vector2& input) 52 { 53 std::ostringstream ostream; 54 if (ostream << input.x << "," << input.y) 55 { 56 (*output) = ostream.str(); 57 return true; 58 } 59 return false; 60 } 61 }; 62 63 // Vector3 to std::string 64 template <> 65 struct ConverterExplicit<orxonox::Vector3, std::string> 66 { 67 static bool convert(std::string* output, const orxonox::Vector3& input) 68 { 69 std::ostringstream ostream; 70 if (ostream << input.x << "," << input.y << "," << input.z) 71 { 72 (*output) = ostream.str(); 73 return true; 74 } 75 return false; 76 } 77 }; 78 79 // Vector4 to std::string 80 template <> 81 struct ConverterExplicit<orxonox::Vector4, std::string> 82 { 83 static bool convert(std::string* output, const orxonox::Vector4& input) 84 { 85 std::ostringstream ostream; 86 if (ostream << input.x << "," << input.y << "," << input.z << "," << input.w) 87 { 88 (*output) = ostream.str(); 89 return true; 90 } 91 return false; 92 } 93 }; 94 95 // Quaternion to std::string 96 template <> 97 struct ConverterExplicit<orxonox::Quaternion, std::string> 98 { 99 static bool convert(std::string* output, const orxonox::Quaternion& input) 100 { 101 std::ostringstream ostream; 102 if (ostream << input.w << "," << input.x << "," << input.y << "," << input.z) 103 { 104 (*output) = ostream.str(); 105 return true; 106 } 107 return false; 108 } 109 }; 110 111 // ColourValue to std::string 112 template <> 113 struct ConverterExplicit<orxonox::ColourValue, std::string> 114 { 115 static bool convert(std::string* output, const orxonox::ColourValue& input) 116 { 117 std::ostringstream ostream; 118 if (ostream << input.r << "," << input.g << "," << input.b << "," << input.a) 119 { 120 (*output) = ostream.str(); 121 return true; 122 } 123 return false; 124 } 125 }; 126 127 128 //////////////////// 129 // string to Math // 130 //////////////////// 131 132 // std::string to Vector2 133 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector2> 134 { static bool convert(orxonox::Vector2* output, const std::string& input); }; 135 // std::string to Vector3 136 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector3> 137 { static bool convert(orxonox::Vector3* output, const std::string& input); }; 138 // std::string to Vector4 139 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector4> 140 { static bool convert(orxonox::Vector4* output, const std::string& input); }; 141 // std::string to Quaternion 142 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Quaternion> 143 { static bool convert(orxonox::Quaternion* output, const std::string& input); }; 144 // std::string to ColourValue 145 template <> struct _UtilExport ConverterFallback<std::string, orxonox::ColourValue> 146 { static bool convert(orxonox::ColourValue* output, const std::string& input); }; 147 148 149 /////////////////////////////// 150 // From and to Radian/Degree // 151 /////////////////////////////// 152 153 // From Radian 154 template <class ToType> 155 struct ConverterFallback<orxonox::Radian, ToType> 156 { 157 static bool convert(ToType* output, const orxonox::Radian& input) 158 { 159 return convertValue<Ogre::Real, ToType>(output, input.valueRadians()); 160 } 161 }; 162 163 // From Degree 164 template <class ToType> 165 struct ConverterFallback<orxonox::Degree, ToType> 166 { 167 static bool convert(ToType* output, const orxonox::Degree& input) 168 { 169 return convertValue<Ogre::Real, ToType>(output, input.valueDegrees()); 170 } 171 }; 172 173 // To Radian 174 template <class FromType> 175 struct ConverterFallback<FromType, orxonox::Radian> 176 { 177 static bool convert(orxonox::Radian* output, const FromType& input) 178 { 179 float temp; 180 if (convertValue(&temp, input)) 181 { 182 *output = temp; 183 return true; 184 } 185 else 186 return false; 187 } 188 }; 189 190 // To Degree 191 template <class FromType> 192 struct ConverterFallback<FromType, orxonox::Degree> 193 { 194 static bool convert(orxonox::Degree* output, const FromType& input) 195 { 196 float temp; 197 if (convertValue(&temp, input)) 198 { 199 *output = temp; 200 return true; 201 } 202 else 203 return false; 204 } 205 }; 44 //////////////////// 45 // Math to string // 46 //////////////////// 47 48 // Vector2 to std::string 49 template <> 50 struct ConverterExplicit<orxonox::Vector2, std::string> 51 { 52 static bool convert(std::string* output, const orxonox::Vector2& input) 53 { 54 std::ostringstream ostream; 55 if (ostream << input.x << "," << input.y) 56 { 57 (*output) = ostream.str(); 58 return true; 59 } 60 return false; 61 } 62 }; 63 64 // Vector3 to std::string 65 template <> 66 struct ConverterExplicit<orxonox::Vector3, std::string> 67 { 68 static bool convert(std::string* output, const orxonox::Vector3& input) 69 { 70 std::ostringstream ostream; 71 if (ostream << input.x << "," << input.y << "," << input.z) 72 { 73 (*output) = ostream.str(); 74 return true; 75 } 76 return false; 77 } 78 }; 79 80 // Vector4 to std::string 81 template <> 82 struct ConverterExplicit<orxonox::Vector4, std::string> 83 { 84 static bool convert(std::string* output, const orxonox::Vector4& input) 85 { 86 std::ostringstream ostream; 87 if (ostream << input.x << "," << input.y << "," << input.z << "," << input.w) 88 { 89 (*output) = ostream.str(); 90 return true; 91 } 92 return false; 93 } 94 }; 95 96 // Quaternion to std::string 97 template <> 98 struct ConverterExplicit<orxonox::Quaternion, std::string> 99 { 100 static bool convert(std::string* output, const orxonox::Quaternion& input) 101 { 102 std::ostringstream ostream; 103 if (ostream << input.w << "," << input.x << "," << input.y << "," << input.z) 104 { 105 (*output) = ostream.str(); 106 return true; 107 } 108 return false; 109 } 110 }; 111 112 // ColourValue to std::string 113 template <> 114 struct ConverterExplicit<orxonox::ColourValue, std::string> 115 { 116 static bool convert(std::string* output, const orxonox::ColourValue& input) 117 { 118 std::ostringstream ostream; 119 if (ostream << input.r << "," << input.g << "," << input.b << "," << input.a) 120 { 121 (*output) = ostream.str(); 122 return true; 123 } 124 return false; 125 } 126 }; 127 128 129 //////////////////// 130 // string to Math // 131 //////////////////// 132 133 // std::string to Vector2 134 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector2> 135 { static bool convert(orxonox::Vector2* output, const std::string& input); }; 136 // std::string to Vector3 137 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector3> 138 { static bool convert(orxonox::Vector3* output, const std::string& input); }; 139 // std::string to Vector4 140 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Vector4> 141 { static bool convert(orxonox::Vector4* output, const std::string& input); }; 142 // std::string to Quaternion 143 template <> struct _UtilExport ConverterFallback<std::string, orxonox::Quaternion> 144 { static bool convert(orxonox::Quaternion* output, const std::string& input); }; 145 // std::string to ColourValue 146 template <> struct _UtilExport ConverterFallback<std::string, orxonox::ColourValue> 147 { static bool convert(orxonox::ColourValue* output, const std::string& input); }; 148 149 150 /////////////////////////////// 151 // From and to Radian/Degree // 152 /////////////////////////////// 153 154 // From Radian 155 template <class ToType> 156 struct ConverterFallback<orxonox::Radian, ToType> 157 { 158 static bool convert(ToType* output, const orxonox::Radian& input) 159 { 160 return convertValue<Ogre::Real, ToType>(output, input.valueRadians()); 161 } 162 }; 163 164 // From Degree 165 template <class ToType> 166 struct ConverterFallback<orxonox::Degree, ToType> 167 { 168 static bool convert(ToType* output, const orxonox::Degree& input) 169 { 170 return convertValue<Ogre::Real, ToType>(output, input.valueDegrees()); 171 } 172 }; 173 174 // To Radian 175 template <class FromType> 176 struct ConverterFallback<FromType, orxonox::Radian> 177 { 178 static bool convert(orxonox::Radian* output, const FromType& input) 179 { 180 float temp; 181 if (convertValue(&temp, input)) 182 { 183 *output = temp; 184 return true; 185 } 186 else 187 return false; 188 } 189 }; 190 191 // To Degree 192 template <class FromType> 193 struct ConverterFallback<FromType, orxonox::Degree> 194 { 195 static bool convert(orxonox::Degree* output, const FromType& input) 196 { 197 float temp; 198 if (convertValue(&temp, input)) 199 { 200 *output = temp; 201 return true; 202 } 203 else 204 return false; 205 } 206 }; 207 } 206 208 207 209 #endif /* _MathConvert_H__ */ -
code/branches/objecthierarchy/src/util/MultiType.cc
r2002 r2111 35 35 #include "MultiTypeValue.h" 36 36 37 /** 38 @brief Converts the current value of the MultiType to a new type. 39 @param type The type 40 */ 41 bool MultiType::convert(MT_Type type) 37 namespace orxonox 42 38 { 43 switch (type) 39 /** 40 @brief Converts the current value of the MultiType to a new type. 41 @param type The type 42 */ 43 bool MultiType::convert(MT_Type type) 44 44 { 45 case MT_char: 46 return this->convert<char>(); break; 47 case MT_uchar: 48 return this->convert<unsigned char>(); break; 49 case MT_short: 50 return this->convert<short>(); break; 51 case MT_ushort: 52 return this->convert<unsigned short>(); break; 53 case MT_int: 54 return this->convert<int>(); break; 55 case MT_uint: 56 return this->convert<unsigned int>(); break; 57 case MT_long: 58 return this->convert<long>(); break; 59 case MT_ulong: 60 return this->convert<unsigned long>(); break; 61 case MT_longlong: 62 return this->convert<long long>(); break; 63 case MT_ulonglong: 64 return this->convert<unsigned long long>(); break; 65 case MT_float: 66 return this->convert<float>(); break; 67 case MT_double: 68 return this->convert<double>(); break; 69 case MT_longdouble: 70 return this->convert<long double>(); break; 71 case MT_bool: 72 return this->convert<bool>(); break; 73 case MT_void: 74 return this->convert<void*>(); break; 75 case MT_string: 76 return this->convert<std::string>(); break; 77 case MT_vector2: 78 return this->convert<orxonox::Vector2>(); break; 79 case MT_vector3: 80 return this->convert<orxonox::Vector3>(); break; 81 case MT_vector4: 82 return this->convert<orxonox::Vector4>(); break; 83 case MT_colourvalue: 84 return this->convert<orxonox::ColourValue>(); break; 85 case MT_quaternion: 86 return this->convert<orxonox::Quaternion>(); break; 87 case MT_radian: 88 return this->convert<orxonox::Radian>(); break; 89 case MT_degree: 90 return this->convert<orxonox::Degree>(); break; 91 default: 92 this->reset(); return false; break; 93 }; 45 switch (type) 46 { 47 case MT_char: 48 return this->convert<char>(); break; 49 case MT_uchar: 50 return this->convert<unsigned char>(); break; 51 case MT_short: 52 return this->convert<short>(); break; 53 case MT_ushort: 54 return this->convert<unsigned short>(); break; 55 case MT_int: 56 return this->convert<int>(); break; 57 case MT_uint: 58 return this->convert<unsigned int>(); break; 59 case MT_long: 60 return this->convert<long>(); break; 61 case MT_ulong: 62 return this->convert<unsigned long>(); break; 63 case MT_longlong: 64 return this->convert<long long>(); break; 65 case MT_ulonglong: 66 return this->convert<unsigned long long>(); break; 67 case MT_float: 68 return this->convert<float>(); break; 69 case MT_double: 70 return this->convert<double>(); break; 71 case MT_longdouble: 72 return this->convert<long double>(); break; 73 case MT_bool: 74 return this->convert<bool>(); break; 75 case MT_void: 76 return this->convert<void*>(); break; 77 case MT_string: 78 return this->convert<std::string>(); break; 79 case MT_vector2: 80 return this->convert<orxonox::Vector2>(); break; 81 case MT_vector3: 82 return this->convert<orxonox::Vector3>(); break; 83 case MT_vector4: 84 return this->convert<orxonox::Vector4>(); break; 85 case MT_colourvalue: 86 return this->convert<orxonox::ColourValue>(); break; 87 case MT_quaternion: 88 return this->convert<orxonox::Quaternion>(); break; 89 case MT_radian: 90 return this->convert<orxonox::Radian>(); break; 91 case MT_degree: 92 return this->convert<orxonox::Degree>(); break; 93 default: 94 this->reset(); return false; break; 95 }; 96 } 97 98 /** 99 @brief Returns the name of the current type. 100 @return The name 101 */ 102 std::string MultiType::getTypename() const 103 { 104 MT_Type type = (this->value_) ? this->value_->type_ : MT_null; 105 106 switch (type) 107 { 108 case MT_char: 109 return "char"; break; 110 case MT_uchar: 111 return "unsigned char"; break; 112 case MT_short: 113 return "short"; break; 114 case MT_ushort: 115 return "unsigned short"; break; 116 case MT_int: 117 return "int"; break; 118 case MT_uint: 119 return "unsigned int"; break; 120 case MT_long: 121 return "long"; break; 122 case MT_ulong: 123 return "unsigned long"; break; 124 case MT_longlong: 125 return "long long"; break; 126 case MT_ulonglong: 127 return "unsigned long long"; break; 128 case MT_float: 129 return "float"; break; 130 case MT_double: 131 return "double"; break; 132 case MT_longdouble: 133 return "long double"; break; 134 case MT_bool: 135 return "bool"; break; 136 case MT_void: 137 return "void*"; break; 138 case MT_string: 139 return "std::string"; break; 140 case MT_vector2: 141 return "orxonox::Vector2"; break; 142 case MT_vector3: 143 return "orxonox::Vector3"; break; 144 case MT_vector4: 145 return "orxonox::Vector4"; break; 146 case MT_colourvalue: 147 return "orxonox::ColourValue"; break; 148 case MT_quaternion: 149 return "orxonox::Quaternion"; break; 150 case MT_radian: 151 return "orxonox::Radian"; break; 152 case MT_degree: 153 return "orxonox::Degree"; break; 154 default: 155 return "unknown"; break; 156 }; 157 } 158 159 MultiType::operator char() const { return (this->value_) ? ((this->value_->type_ == MT_char ) ? ((MT_Value<char> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 160 MultiType::operator unsigned char() const { return (this->value_) ? ((this->value_->type_ == MT_uchar ) ? ((MT_Value<unsigned char> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 161 MultiType::operator short() const { return (this->value_) ? ((this->value_->type_ == MT_short ) ? ((MT_Value<short> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 162 MultiType::operator unsigned short() const { return (this->value_) ? ((this->value_->type_ == MT_ushort ) ? ((MT_Value<unsigned short> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 163 MultiType::operator int() const { return (this->value_) ? ((this->value_->type_ == MT_int ) ? ((MT_Value<int> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 164 MultiType::operator unsigned int() const { return (this->value_) ? ((this->value_->type_ == MT_uint ) ? ((MT_Value<unsigned int> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 165 MultiType::operator long() const { return (this->value_) ? ((this->value_->type_ == MT_long ) ? ((MT_Value<long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 166 MultiType::operator unsigned long() const { return (this->value_) ? ((this->value_->type_ == MT_ulong ) ? ((MT_Value<unsigned long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 167 MultiType::operator long long() const { return (this->value_) ? ((this->value_->type_ == MT_longlong ) ? ((MT_Value<long long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 168 MultiType::operator unsigned long long() const { return (this->value_) ? ((this->value_->type_ == MT_ulonglong ) ? ((MT_Value<unsigned long long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 169 MultiType::operator float() const { return (this->value_) ? ((this->value_->type_ == MT_float ) ? ((MT_Value<float> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 170 MultiType::operator double() const { return (this->value_) ? ((this->value_->type_ == MT_double ) ? ((MT_Value<double> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 171 MultiType::operator long double() const { return (this->value_) ? ((this->value_->type_ == MT_longdouble ) ? ((MT_Value<long double> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 172 MultiType::operator bool() const { return (this->value_) ? ((this->value_->type_ == MT_bool ) ? ((MT_Value<bool> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 173 MultiType::operator void*() const { return (this->value_) ? ((this->value_->type_ == MT_void ) ? ((MT_Value<void*> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */ 174 MultiType::operator std::string() const { return (this->value_) ? ((this->value_->type_ == MT_string ) ? ((MT_Value<std::string> *)this->value_)->value_ : (*this->value_)) : zeroise<std::string>(); } /** @brief Returns the current value, converted to the requested type. */ 175 MultiType::operator orxonox::Vector2() const { return (this->value_) ? ((this->value_->type_ == MT_vector2 ) ? ((MT_Value<orxonox::Vector2> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector2>(); } /** @brief Returns the current value, converted to the requested type. */ 176 MultiType::operator orxonox::Vector3() const { return (this->value_) ? ((this->value_->type_ == MT_vector3 ) ? ((MT_Value<orxonox::Vector3> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector3>(); } /** @brief Returns the current value, converted to the requested type. */ 177 MultiType::operator orxonox::Vector4() const { return (this->value_) ? ((this->value_->type_ == MT_vector4 ) ? ((MT_Value<orxonox::Vector4> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector4>(); } /** @brief Returns the current value, converted to the requested type. */ 178 MultiType::operator orxonox::ColourValue() const { return (this->value_) ? ((this->value_->type_ == MT_colourvalue) ? ((MT_Value<orxonox::ColourValue>*)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::ColourValue>(); } /** @brief Returns the current value, converted to the requested type. */ 179 MultiType::operator orxonox::Quaternion() const { return (this->value_) ? ((this->value_->type_ == MT_quaternion ) ? ((MT_Value<orxonox::Quaternion> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Quaternion>(); } /** @brief Returns the current value, converted to the requested type. */ 180 MultiType::operator orxonox::Radian() const { return (this->value_) ? ((this->value_->type_ == MT_radian ) ? ((MT_Value<orxonox::Radian> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Radian>(); } /** @brief Returns the current value, converted to the requested type. */ 181 MultiType::operator orxonox::Degree() const { return (this->value_) ? ((this->value_->type_ == MT_degree ) ? ((MT_Value<orxonox::Degree> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Degree>(); } /** @brief Returns the current value, converted to the requested type. */ 182 183 template <> void MultiType::createNewValueContainer(const char& value) { this->value_ = new MT_Value<char> (value, MT_char ); } /** @brief Creates a new value container for the given type. */ 184 template <> void MultiType::createNewValueContainer(const unsigned char& value) { this->value_ = new MT_Value<unsigned char> (value, MT_uchar ); } /** @brief Creates a new value container for the given type. */ 185 template <> void MultiType::createNewValueContainer(const short& value) { this->value_ = new MT_Value<short> (value, MT_short ); } /** @brief Creates a new value container for the given type. */ 186 template <> void MultiType::createNewValueContainer(const unsigned short& value) { this->value_ = new MT_Value<unsigned short> (value, MT_ushort ); } /** @brief Creates a new value container for the given type. */ 187 template <> void MultiType::createNewValueContainer(const int& value) { this->value_ = new MT_Value<int> (value, MT_int ); } /** @brief Creates a new value container for the given type. */ 188 template <> void MultiType::createNewValueContainer(const unsigned int& value) { this->value_ = new MT_Value<unsigned int> (value, MT_uint ); } /** @brief Creates a new value container for the given type. */ 189 template <> void MultiType::createNewValueContainer(const long& value) { this->value_ = new MT_Value<long> (value, MT_long ); } /** @brief Creates a new value container for the given type. */ 190 template <> void MultiType::createNewValueContainer(const unsigned long& value) { this->value_ = new MT_Value<unsigned long> (value, MT_ulong ); } /** @brief Creates a new value container for the given type. */ 191 template <> void MultiType::createNewValueContainer(const long long& value) { this->value_ = new MT_Value<long long> (value, MT_longlong ); } /** @brief Creates a new value container for the given type. */ 192 template <> void MultiType::createNewValueContainer(const unsigned long long& value) { this->value_ = new MT_Value<unsigned long long> (value, MT_ulonglong ); } /** @brief Creates a new value container for the given type. */ 193 template <> void MultiType::createNewValueContainer(const float& value) { this->value_ = new MT_Value<float> (value, MT_float ); } /** @brief Creates a new value container for the given type. */ 194 template <> void MultiType::createNewValueContainer(const double& value) { this->value_ = new MT_Value<double> (value, MT_double ); } /** @brief Creates a new value container for the given type. */ 195 template <> void MultiType::createNewValueContainer(const long double& value) { this->value_ = new MT_Value<long double> (value, MT_longdouble ); } /** @brief Creates a new value container for the given type. */ 196 template <> void MultiType::createNewValueContainer(const bool& value) { this->value_ = new MT_Value<bool> (value, MT_bool ); } /** @brief Creates a new value container for the given type. */ 197 template <> void MultiType::createNewValueContainer( void* const& value) { this->value_ = new MT_Value<void*> (value, MT_void ); } /** @brief Creates a new value container for the given type. */ 198 template <> void MultiType::createNewValueContainer(const std::string& value) { this->value_ = new MT_Value<std::string> (value, MT_string ); } /** @brief Creates a new value container for the given type. */ 199 template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value) { this->value_ = new MT_Value<orxonox::Vector2> (value, MT_vector2 ); } /** @brief Creates a new value container for the given type. */ 200 template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value) { this->value_ = new MT_Value<orxonox::Vector3> (value, MT_vector3 ); } /** @brief Creates a new value container for the given type. */ 201 template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value) { this->value_ = new MT_Value<orxonox::Vector4> (value, MT_vector4 ); } /** @brief Creates a new value container for the given type. */ 202 template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value) { this->value_ = new MT_Value<orxonox::ColourValue>(value, MT_colourvalue); } /** @brief Creates a new value container for the given type. */ 203 template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value) { this->value_ = new MT_Value<orxonox::Quaternion> (value, MT_quaternion ); } /** @brief Creates a new value container for the given type. */ 204 template <> void MultiType::createNewValueContainer(const orxonox::Radian& value) { this->value_ = new MT_Value<orxonox::Radian> (value, MT_radian ); } /** @brief Creates a new value container for the given type. */ 205 template <> void MultiType::createNewValueContainer(const orxonox::Degree& value) { this->value_ = new MT_Value<orxonox::Degree> (value, MT_degree ); } /** @brief Creates a new value container for the given type. */ 94 206 } 95 96 /**97 @brief Returns the name of the current type.98 @return The name99 */100 std::string MultiType::getTypename() const101 {102 MT_Type type = (this->value_) ? this->value_->type_ : MT_null;103 104 switch (type)105 {106 case MT_char:107 return "char"; break;108 case MT_uchar:109 return "unsigned char"; break;110 case MT_short:111 return "short"; break;112 case MT_ushort:113 return "unsigned short"; break;114 case MT_int:115 return "int"; break;116 case MT_uint:117 return "unsigned int"; break;118 case MT_long:119 return "long"; break;120 case MT_ulong:121 return "unsigned long"; break;122 case MT_longlong:123 return "long long"; break;124 case MT_ulonglong:125 return "unsigned long long"; break;126 case MT_float:127 return "float"; break;128 case MT_double:129 return "double"; break;130 case MT_longdouble:131 return "long double"; break;132 case MT_bool:133 return "bool"; break;134 case MT_void:135 return "void*"; break;136 case MT_string:137 return "std::string"; break;138 case MT_vector2:139 return "orxonox::Vector2"; break;140 case MT_vector3:141 return "orxonox::Vector3"; break;142 case MT_vector4:143 return "orxonox::Vector4"; break;144 case MT_colourvalue:145 return "orxonox::ColourValue"; break;146 case MT_quaternion:147 return "orxonox::Quaternion"; break;148 case MT_radian:149 return "orxonox::Radian"; break;150 case MT_degree:151 return "orxonox::Degree"; break;152 default:153 return "unknown"; break;154 };155 }156 157 MultiType::operator char() const { return (this->value_) ? ((this->value_->type_ == MT_char ) ? ((MT_Value<char> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */158 MultiType::operator unsigned char() const { return (this->value_) ? ((this->value_->type_ == MT_uchar ) ? ((MT_Value<unsigned char> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */159 MultiType::operator short() const { return (this->value_) ? ((this->value_->type_ == MT_short ) ? ((MT_Value<short> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */160 MultiType::operator unsigned short() const { return (this->value_) ? ((this->value_->type_ == MT_ushort ) ? ((MT_Value<unsigned short> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */161 MultiType::operator int() const { return (this->value_) ? ((this->value_->type_ == MT_int ) ? ((MT_Value<int> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */162 MultiType::operator unsigned int() const { return (this->value_) ? ((this->value_->type_ == MT_uint ) ? ((MT_Value<unsigned int> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */163 MultiType::operator long() const { return (this->value_) ? ((this->value_->type_ == MT_long ) ? ((MT_Value<long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */164 MultiType::operator unsigned long() const { return (this->value_) ? ((this->value_->type_ == MT_ulong ) ? ((MT_Value<unsigned long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */165 MultiType::operator long long() const { return (this->value_) ? ((this->value_->type_ == MT_longlong ) ? ((MT_Value<long long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */166 MultiType::operator unsigned long long() const { return (this->value_) ? ((this->value_->type_ == MT_ulonglong ) ? ((MT_Value<unsigned long long> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */167 MultiType::operator float() const { return (this->value_) ? ((this->value_->type_ == MT_float ) ? ((MT_Value<float> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */168 MultiType::operator double() const { return (this->value_) ? ((this->value_->type_ == MT_double ) ? ((MT_Value<double> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */169 MultiType::operator long double() const { return (this->value_) ? ((this->value_->type_ == MT_longdouble ) ? ((MT_Value<long double> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */170 MultiType::operator bool() const { return (this->value_) ? ((this->value_->type_ == MT_bool ) ? ((MT_Value<bool> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */171 MultiType::operator void*() const { return (this->value_) ? ((this->value_->type_ == MT_void ) ? ((MT_Value<void*> *)this->value_)->value_ : (*this->value_)) : 0; } /** @brief Returns the current value, converted to the requested type. */172 MultiType::operator std::string() const { return (this->value_) ? ((this->value_->type_ == MT_string ) ? ((MT_Value<std::string> *)this->value_)->value_ : (*this->value_)) : zeroise<std::string>(); } /** @brief Returns the current value, converted to the requested type. */173 MultiType::operator orxonox::Vector2() const { return (this->value_) ? ((this->value_->type_ == MT_vector2 ) ? ((MT_Value<orxonox::Vector2> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector2>(); } /** @brief Returns the current value, converted to the requested type. */174 MultiType::operator orxonox::Vector3() const { return (this->value_) ? ((this->value_->type_ == MT_vector3 ) ? ((MT_Value<orxonox::Vector3> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector3>(); } /** @brief Returns the current value, converted to the requested type. */175 MultiType::operator orxonox::Vector4() const { return (this->value_) ? ((this->value_->type_ == MT_vector4 ) ? ((MT_Value<orxonox::Vector4> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Vector4>(); } /** @brief Returns the current value, converted to the requested type. */176 MultiType::operator orxonox::ColourValue() const { return (this->value_) ? ((this->value_->type_ == MT_colourvalue) ? ((MT_Value<orxonox::ColourValue>*)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::ColourValue>(); } /** @brief Returns the current value, converted to the requested type. */177 MultiType::operator orxonox::Quaternion() const { return (this->value_) ? ((this->value_->type_ == MT_quaternion ) ? ((MT_Value<orxonox::Quaternion> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Quaternion>(); } /** @brief Returns the current value, converted to the requested type. */178 MultiType::operator orxonox::Radian() const { return (this->value_) ? ((this->value_->type_ == MT_radian ) ? ((MT_Value<orxonox::Radian> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Radian>(); } /** @brief Returns the current value, converted to the requested type. */179 MultiType::operator orxonox::Degree() const { return (this->value_) ? ((this->value_->type_ == MT_degree ) ? ((MT_Value<orxonox::Degree> *)this->value_)->value_ : (*this->value_)) : zeroise<orxonox::Degree>(); } /** @brief Returns the current value, converted to the requested type. */180 181 template <> void MultiType::createNewValueContainer(const char& value) { this->value_ = new MT_Value<char> (value, MT_char ); } /** @brief Creates a new value container for the given type. */182 template <> void MultiType::createNewValueContainer(const unsigned char& value) { this->value_ = new MT_Value<unsigned char> (value, MT_uchar ); } /** @brief Creates a new value container for the given type. */183 template <> void MultiType::createNewValueContainer(const short& value) { this->value_ = new MT_Value<short> (value, MT_short ); } /** @brief Creates a new value container for the given type. */184 template <> void MultiType::createNewValueContainer(const unsigned short& value) { this->value_ = new MT_Value<unsigned short> (value, MT_ushort ); } /** @brief Creates a new value container for the given type. */185 template <> void MultiType::createNewValueContainer(const int& value) { this->value_ = new MT_Value<int> (value, MT_int ); } /** @brief Creates a new value container for the given type. */186 template <> void MultiType::createNewValueContainer(const unsigned int& value) { this->value_ = new MT_Value<unsigned int> (value, MT_uint ); } /** @brief Creates a new value container for the given type. */187 template <> void MultiType::createNewValueContainer(const long& value) { this->value_ = new MT_Value<long> (value, MT_long ); } /** @brief Creates a new value container for the given type. */188 template <> void MultiType::createNewValueContainer(const unsigned long& value) { this->value_ = new MT_Value<unsigned long> (value, MT_ulong ); } /** @brief Creates a new value container for the given type. */189 template <> void MultiType::createNewValueContainer(const long long& value) { this->value_ = new MT_Value<long long> (value, MT_longlong ); } /** @brief Creates a new value container for the given type. */190 template <> void MultiType::createNewValueContainer(const unsigned long long& value) { this->value_ = new MT_Value<unsigned long long> (value, MT_ulonglong ); } /** @brief Creates a new value container for the given type. */191 template <> void MultiType::createNewValueContainer(const float& value) { this->value_ = new MT_Value<float> (value, MT_float ); } /** @brief Creates a new value container for the given type. */192 template <> void MultiType::createNewValueContainer(const double& value) { this->value_ = new MT_Value<double> (value, MT_double ); } /** @brief Creates a new value container for the given type. */193 template <> void MultiType::createNewValueContainer(const long double& value) { this->value_ = new MT_Value<long double> (value, MT_longdouble ); } /** @brief Creates a new value container for the given type. */194 template <> void MultiType::createNewValueContainer(const bool& value) { this->value_ = new MT_Value<bool> (value, MT_bool ); } /** @brief Creates a new value container for the given type. */195 template <> void MultiType::createNewValueContainer( void* const& value) { this->value_ = new MT_Value<void*> (value, MT_void ); } /** @brief Creates a new value container for the given type. */196 template <> void MultiType::createNewValueContainer(const std::string& value) { this->value_ = new MT_Value<std::string> (value, MT_string ); } /** @brief Creates a new value container for the given type. */197 template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value) { this->value_ = new MT_Value<orxonox::Vector2> (value, MT_vector2 ); } /** @brief Creates a new value container for the given type. */198 template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value) { this->value_ = new MT_Value<orxonox::Vector3> (value, MT_vector3 ); } /** @brief Creates a new value container for the given type. */199 template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value) { this->value_ = new MT_Value<orxonox::Vector4> (value, MT_vector4 ); } /** @brief Creates a new value container for the given type. */200 template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value) { this->value_ = new MT_Value<orxonox::ColourValue>(value, MT_colourvalue); } /** @brief Creates a new value container for the given type. */201 template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value) { this->value_ = new MT_Value<orxonox::Quaternion> (value, MT_quaternion ); } /** @brief Creates a new value container for the given type. */202 template <> void MultiType::createNewValueContainer(const orxonox::Radian& value) { this->value_ = new MT_Value<orxonox::Radian> (value, MT_radian ); } /** @brief Creates a new value container for the given type. */203 template <> void MultiType::createNewValueContainer(const orxonox::Degree& value) { this->value_ = new MT_Value<orxonox::Degree> (value, MT_degree ); } /** @brief Creates a new value container for the given type. */ -
code/branches/objecthierarchy/src/util/MultiType.h
r2002 r2111 73 73 #include "Math.h" 74 74 75 /** 76 @brief Enum of all possible types of a MultiType. 77 */ 78 enum MT_Type 75 namespace orxonox 79 76 { 80 MT_null,81 MT_char,82 MT_uchar,83 MT_short,84 MT_ushort,85 MT_int,86 MT_uint,87 MT_long,88 MT_ulong,89 MT_longlong,90 MT_ulonglong,91 MT_float,92 MT_double,93 MT_longdouble,94 MT_bool,95 MT_void,96 MT_string,97 MT_vector2,98 MT_vector3,99 MT_vector4,100 MT_colourvalue,101 MT_quaternion,102 MT_radian,103 MT_degree104 };105 106 /**107 @brief The MultiType can hold a value of many possible types and convert them to other types.108 109 The following types are supported by the MultiType:110 - all primitves111 - all pointers112 - string113 - Vector2, Vector3, Vector4114 - Quaternion115 - ColourValue116 - Radian, Degree117 118 The internal type of a MultiType is determined by the first assigned value, but can be119 changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned120 the normal way (operator=, setValue(value)), the value gets converted to the current internal121 type of the MultiType.122 */123 class _UtilExport MultiType124 {125 _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);126 template <typename T> friend struct MT_Value;127 128 77 /** 129 @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType. 130 This class is only used within the MultiType. 78 @brief Enum of all possible types of a MultiType. 131 79 */ 132 struct _UtilExport MT_ValueBase80 enum MT_Type 133 81 { 134 MT_ValueBase(MT_Type type) : type_(type), bHasDefaultValue_(false) {} 135 virtual ~MT_ValueBase() {} 136 137 virtual MT_ValueBase* clone() const = 0; 138 139 virtual void reset() = 0; 140 virtual bool assimilate(const MultiType& other) = 0; 141 142 /** @brief Returns the type of the current value. */ 143 const MT_Type& getType() const { return this->type_; } 144 145 /** @brief Checks whether the value is a default one. */ 146 bool hasDefaultValue() const { return this->bHasDefaultValue_; } 147 148 virtual bool setValue(const char& value) = 0; 149 virtual bool setValue(const unsigned char& value) = 0; 150 virtual bool setValue(const short& value) = 0; 151 virtual bool setValue(const unsigned short& value) = 0; 152 virtual bool setValue(const int& value) = 0; 153 virtual bool setValue(const unsigned int& value) = 0; 154 virtual bool setValue(const long& value) = 0; 155 virtual bool setValue(const unsigned long& value) = 0; 156 virtual bool setValue(const long long& value) = 0; 157 virtual bool setValue(const unsigned long long& value) = 0; 158 virtual bool setValue(const float& value) = 0; 159 virtual bool setValue(const double& value) = 0; 160 virtual bool setValue(const long double& value) = 0; 161 virtual bool setValue(const bool& value) = 0; 162 virtual bool setValue( void* const& value) = 0; 163 virtual bool setValue(const std::string& value) = 0; 164 virtual bool setValue(const orxonox::Vector2& value) = 0; 165 virtual bool setValue(const orxonox::Vector3& value) = 0; 166 virtual bool setValue(const orxonox::Vector4& value) = 0; 167 virtual bool setValue(const orxonox::ColourValue& value) = 0; 168 virtual bool setValue(const orxonox::Quaternion& value) = 0; 169 virtual bool setValue(const orxonox::Radian& value) = 0; 170 virtual bool setValue(const orxonox::Degree& value) = 0; 171 172 virtual bool getValue(char* value) const = 0; 173 virtual bool getValue(unsigned char* value) const = 0; 174 virtual bool getValue(short* value) const = 0; 175 virtual bool getValue(unsigned short* value) const = 0; 176 virtual bool getValue(int* value) const = 0; 177 virtual bool getValue(unsigned int* value) const = 0; 178 virtual bool getValue(long* value) const = 0; 179 virtual bool getValue(unsigned long* value) const = 0; 180 virtual bool getValue(long long* value) const = 0; 181 virtual bool getValue(unsigned long long* value) const = 0; 182 virtual bool getValue(float* value) const = 0; 183 virtual bool getValue(double* value) const = 0; 184 virtual bool getValue(long double* value) const = 0; 185 virtual bool getValue(bool* value) const = 0; 186 virtual bool getValue(void** value) const = 0; 187 virtual bool getValue(std::string* value) const = 0; 188 virtual bool getValue(orxonox::Vector2* value) const = 0; 189 virtual bool getValue(orxonox::Vector3* value) const = 0; 190 virtual bool getValue(orxonox::Vector4* value) const = 0; 191 virtual bool getValue(orxonox::ColourValue* value) const = 0; 192 virtual bool getValue(orxonox::Quaternion* value) const = 0; 193 virtual bool getValue(orxonox::Radian* value) const = 0; 194 virtual bool getValue(orxonox::Degree* value) const = 0; 195 196 virtual operator char() const = 0; 197 virtual operator unsigned char() const = 0; 198 virtual operator short() const = 0; 199 virtual operator unsigned short() const = 0; 200 virtual operator int() const = 0; 201 virtual operator unsigned int() const = 0; 202 virtual operator long() const = 0; 203 virtual operator unsigned long() const = 0; 204 virtual operator long long() const = 0; 205 virtual operator unsigned long long() const = 0; 206 virtual operator float() const = 0; 207 virtual operator double() const = 0; 208 virtual operator long double() const = 0; 209 virtual operator bool() const = 0; 210 virtual operator void*() const = 0; 211 virtual operator std::string() const = 0; 212 virtual operator orxonox::Vector2() const = 0; 213 virtual operator orxonox::Vector3() const = 0; 214 virtual operator orxonox::Vector4() const = 0; 215 virtual operator orxonox::ColourValue() const = 0; 216 virtual operator orxonox::Quaternion() const = 0; 217 virtual operator orxonox::Radian() const = 0; 218 virtual operator orxonox::Degree() const = 0; 219 220 virtual void toString(std::ostream& outstream) const = 0; 221 222 MT_Type type_; //!< The type of the current value 223 bool bHasDefaultValue_; //!< True if the last conversion wasn't successful 82 MT_null, 83 MT_char, 84 MT_uchar, 85 MT_short, 86 MT_ushort, 87 MT_int, 88 MT_uint, 89 MT_long, 90 MT_ulong, 91 MT_longlong, 92 MT_ulonglong, 93 MT_float, 94 MT_double, 95 MT_longdouble, 96 MT_bool, 97 MT_void, 98 MT_string, 99 MT_vector2, 100 MT_vector3, 101 MT_vector4, 102 MT_colourvalue, 103 MT_quaternion, 104 MT_radian, 105 MT_degree 224 106 }; 225 107 108 /** 109 @brief The MultiType can hold a value of many possible types and convert them to other types. 110 111 The following types are supported by the MultiType: 112 - all primitves 113 - all pointers 114 - string 115 - Vector2, Vector3, Vector4 116 - Quaternion 117 - ColourValue 118 - Radian, Degree 119 120 The internal type of a MultiType is determined by the first assigned value, but can be 121 changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned 122 the normal way (operator=, setValue(value)), the value gets converted to the current internal 123 type of the MultiType. 124 */ 125 class _UtilExport MultiType 126 { 127 _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt); 128 template <typename T> friend class MT_Value; 129 226 130 public: 227 inline MultiType() : value_(0) {} /** @brief Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value. */ 228 inline MultiType(const char& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 229 inline MultiType(const unsigned char& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 230 inline MultiType(const short& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 231 inline MultiType(const unsigned short& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 232 inline MultiType(const int& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 233 inline MultiType(const unsigned int& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 234 inline MultiType(const long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 235 inline MultiType(const unsigned long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 236 inline MultiType(const long long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 237 inline MultiType(const unsigned long long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 238 inline MultiType(const float& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 239 inline MultiType(const double& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 240 inline MultiType(const long double& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 241 inline MultiType(const bool& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 242 inline MultiType( void* const& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 243 inline MultiType(const std::string& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 244 inline MultiType(const orxonox::Vector2& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 245 inline MultiType(const orxonox::Vector3& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 246 inline MultiType(const orxonox::Vector4& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 247 inline MultiType(const orxonox::ColourValue& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 248 inline MultiType(const orxonox::Quaternion& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 249 inline MultiType(const orxonox::Radian& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 250 inline MultiType(const orxonox::Degree& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 251 inline MultiType(const char* value) : value_(0) { this->setValue(std::string(value)); } /** @brief Constructor: Converts the char array to a std::string, assigns the value and sets the type. */ 252 inline MultiType(const MultiType& other) : value_(0) { this->setValue(other); } /** @brief Copyconstructor: Assigns value and type of the other MultiType. */ 253 inline MultiType(MT_Type type) : value_(0) { this->setType(type); } /** @brief Constructor: Sets the type, the next assignment will determine the value. */ 254 255 /** @brief Destructor: Deletes the MT_Value. */ 256 inline ~MultiType() { if (this->value_) { delete this->value_; } } 257 258 template <typename V> inline const MultiType& operator=(const V& value) { this->setValue(value); return (*this); } /** @brief Assigns a new value. The value will be converted to the current type of the MultiType. */ 259 template <typename V> inline const MultiType& operator=(V* value) { this->setValue(value); return (*this); } /** @brief Assigns a pointer. */ 260 inline const MultiType& operator=(const MultiType& other) { this->setValue(other); return (*this); } /** @brief Assigns the value of the other MultiType and converts it to the current type of the MultiType. */ 261 inline const MultiType& operator=(MT_Type type) { this->setType(type); return (*this); } /** @brief Resets the value and changes the type. */ 262 263 inline bool setValue(const char& value); 264 inline bool setValue(const unsigned char& value); 265 inline bool setValue(const short& value); 266 inline bool setValue(const unsigned short& value); 267 inline bool setValue(const int& value); 268 inline bool setValue(const unsigned int& value); 269 inline bool setValue(const long& value); 270 inline bool setValue(const unsigned long& value); 271 inline bool setValue(const long long& value); 272 inline bool setValue(const unsigned long long& value); 273 inline bool setValue(const float& value); 274 inline bool setValue(const double& value); 275 inline bool setValue(const long double& value); 276 inline bool setValue(const bool& value); 277 inline bool setValue( void* const& value); 278 inline bool setValue(const std::string& value); 279 inline bool setValue(const orxonox::Vector2& value); 280 inline bool setValue(const orxonox::Vector3& value); 281 inline bool setValue(const orxonox::Vector4& value); 282 inline bool setValue(const orxonox::ColourValue& value); 283 inline bool setValue(const orxonox::Quaternion& value); 284 inline bool setValue(const orxonox::Radian& value); 285 inline bool setValue(const orxonox::Degree& value); 286 inline bool setValue(const char* value); 287 /** @brief Assigns a pointer. */ 288 template <typename V> inline bool setValue(V* value) { if (this->value_) { return this->value_->setValue((void*)value); } else { return this->assignValue((void*)value); } } 289 /** @brief Assigns the value of the other MultiType and converts it to the current type. */ 290 bool setValue(const MultiType& other) { if (this->value_) { return this->value_->assimilate(other); } else { if (other.value_) { this->value_ = other.value_->clone(); } return true; } } 291 /** @brief Changes the type to T and assigns the new value (which might be of another type than T - it gets converted). */ 292 template <typename T, typename V> inline bool setValue(const V& value) { this->setType<T>(); return this->setValue(value); } 293 294 295 /** @brief Copies the other MultiType by assigning value and type. */ 296 inline void copy(const MultiType& other) { if (this == &other) { return; } if (this->value_) { delete this->value_; } this->value_ = (other.value_) ? other.value_->clone() : 0; } 297 298 template <typename T> inline bool convert() { return this->setValue<T>((T)(*this)); } /** @brief Converts the current value to type T. */ 299 inline bool convert(const MultiType& other) { return this->convert(other.getType()); } /** @brief Converts the current value to the type of the other MultiType. */ 300 bool convert(MT_Type type); 301 302 /** @brief Current content gets deleted. New type is MT_null */ 303 inline void reset() { if (this->value_) this->value_->reset(); } 304 305 template <typename T> inline void setType() { this->assignValue(T()); } /** @brief Resets the value and changes the internal type to T. */ 306 inline void setType(const MultiType& other) { this->setType(other.getType()); } /** @brief Resets the value and changes the internal type to the type of the other MultiType. */ 307 inline void setType(MT_Type type) { this->reset(); this->convert(type); this->reset(); } /** @brief Resets the value and changes the internal type to the given type. */ 308 309 /** @brief Returns the current type. */ 310 inline MT_Type getType() const { return (this->value_) ? this->value_->type_ : MT_null; } 311 /** @brief Returns true if the current type equals the given type. */ 312 inline bool isType(MT_Type type) const { return (this->value_) ? (this->value_->type_ == type) : (type == MT_null); } 313 /** @brief Returns true if the current type is T. */ 314 template <typename T> inline bool isType() const { return false; } // Only works for specialized values - see below 315 std::string getTypename() const; 316 317 /** @brief Checks whether the value is a default one. */ 318 bool hasDefaultValue() const { return this->value_->hasDefaultValue(); } 319 320 operator char() const; 321 operator unsigned char() const; 322 operator short() const; 323 operator unsigned short() const; 324 operator int() const; 325 operator unsigned int() const; 326 operator long() const; 327 operator unsigned long() const; 328 operator long long() const; 329 operator unsigned long long() const; 330 operator float() const; 331 operator double() const; 332 operator long double() const; 333 operator bool() const; 334 operator void*() const; 335 operator std::string() const; 336 operator orxonox::Vector2() const; 337 operator orxonox::Vector3() const; 338 operator orxonox::Vector4() const; 339 operator orxonox::ColourValue() const; 340 operator orxonox::Quaternion() const; 341 operator orxonox::Radian() const; 342 operator orxonox::Degree() const; 343 /** @brief Returns the current value, converted to a T* pointer. */ 344 template <class T> operator T*() const { return ((T*)this->operator void*()); } 345 346 inline bool getValue(char* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 347 inline bool getValue(unsigned char* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 348 inline bool getValue(short* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 349 inline bool getValue(unsigned short* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 350 inline bool getValue(int* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 351 inline bool getValue(unsigned int* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 352 inline bool getValue(long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 353 inline bool getValue(unsigned long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 354 inline bool getValue(long long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 355 inline bool getValue(unsigned long long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 356 inline bool getValue(float* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 357 inline bool getValue(double* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 358 inline bool getValue(long double* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 359 inline bool getValue(bool* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 360 inline bool getValue(void** value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 361 inline bool getValue(std::string* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 362 inline bool getValue(orxonox::Vector2* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 363 inline bool getValue(orxonox::Vector3* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 364 inline bool getValue(orxonox::Vector4* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 365 inline bool getValue(orxonox::ColourValue* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 366 inline bool getValue(orxonox::Quaternion* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 367 inline bool getValue(orxonox::Radian* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 368 inline bool getValue(orxonox::Degree* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 369 370 inline char getChar() const { return this->operator char(); } /** @brief Returns the current value, converted to the requested type. */ 371 inline unsigned char getUnsignedChar() const { return this->operator unsigned char(); } /** @brief Returns the current value, converted to the requested type. */ 372 inline short getShort() const { return this->operator short(); } /** @brief Returns the current value, converted to the requested type. */ 373 inline unsigned short getUnsignedShort() const { return this->operator unsigned short(); } /** @brief Returns the current value, converted to the requested type. */ 374 inline int getInt() const { return this->operator int(); } /** @brief Returns the current value, converted to the requested type. */ 375 inline unsigned int getUnsignedInt() const { return this->operator unsigned int(); } /** @brief Returns the current value, converted to the requested type. */ 376 inline long getLong() const { return this->operator long(); } /** @brief Returns the current value, converted to the requested type. */ 377 inline unsigned long getUnsignedLong() const { return this->operator unsigned long(); } /** @brief Returns the current value, converted to the requested type. */ 378 inline long long getLongLong() const { return this->operator long long(); } /** @brief Returns the current value, converted to the requested type. */ 379 inline unsigned long long getUnsignedLongLong() const { return this->operator unsigned long long(); } /** @brief Returns the current value, converted to the requested type. */ 380 inline float getFloat() const { return this->operator float(); } /** @brief Returns the current value, converted to the requested type. */ 381 inline double getDouble() const { return this->operator double(); } /** @brief Returns the current value, converted to the requested type. */ 382 inline long double getLongDouble() const { return this->operator long double(); } /** @brief Returns the current value, converted to the requested type. */ 383 inline bool getBool() const { return this->operator bool(); } /** @brief Returns the current value, converted to the requested type. */ 384 inline void* getVoid() const { return this->operator void*(); } /** @brief Returns the current value, converted to the requested type. */ 385 inline std::string getString() const { return this->operator std::string(); } /** @brief Returns the current value, converted to the requested type. */ 386 inline orxonox::Vector2 getVector2() const { return this->operator orxonox::Vector2(); } /** @brief Returns the current value, converted to the requested type. */ 387 inline orxonox::Vector3 getVector3() const { return this->operator orxonox::Vector3(); } /** @brief Returns the current value, converted to the requested type. */ 388 inline orxonox::Vector4 getVector4() const { return this->operator orxonox::Vector4(); } /** @brief Returns the current value, converted to the requested type. */ 389 inline orxonox::ColourValue getColourValue() const { return this->operator orxonox::ColourValue(); } /** @brief Returns the current value, converted to the requested type. */ 390 inline orxonox::Quaternion getQuaternion() const { return this->operator orxonox::Quaternion(); } /** @brief Returns the current value, converted to the requested type. */ 391 inline orxonox::Radian getRadian() const { return this->operator orxonox::Radian(); } /** @brief Returns the current value, converted to the requested type. */ 392 inline orxonox::Degree getDegree() const { return this->operator orxonox::Degree(); } /** @brief Returns the current value, converted to the requested type. */ 393 template <typename T> inline T* getPointer() const { return ((T*)this->getVoid()); } /** @brief Returns the current value, converted to a T* pointer. */ 394 395 private: 396 inline bool assignValue(const char& value) { if (this->value_ && this->value_->type_ == MT_char) { return this->value_->setValue(value); } else { this->changeValueContainer<char>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 397 inline bool assignValue(const unsigned char& value) { if (this->value_ && this->value_->type_ == MT_uchar) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned char>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 398 inline bool assignValue(const short& value) { if (this->value_ && this->value_->type_ == MT_short) { return this->value_->setValue(value); } else { this->changeValueContainer<short>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 399 inline bool assignValue(const unsigned short& value) { if (this->value_ && this->value_->type_ == MT_ushort) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned short>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 400 inline bool assignValue(const int& value) { if (this->value_ && this->value_->type_ == MT_int) { return this->value_->setValue(value); } else { this->changeValueContainer<int>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 401 inline bool assignValue(const unsigned int& value) { if (this->value_ && this->value_->type_ == MT_uint) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned int>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 402 inline bool assignValue(const long& value) { if (this->value_ && this->value_->type_ == MT_long) { return this->value_->setValue(value); } else { this->changeValueContainer<long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 403 inline bool assignValue(const unsigned long& value) { if (this->value_ && this->value_->type_ == MT_ulong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 404 inline bool assignValue(const long long& value) { if (this->value_ && this->value_->type_ == MT_longlong) { return this->value_->setValue(value); } else { this->changeValueContainer<long long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 405 inline bool assignValue(const unsigned long long& value) { if (this->value_ && this->value_->type_ == MT_ulonglong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 406 inline bool assignValue(const float& value) { if (this->value_ && this->value_->type_ == MT_float) { return this->value_->setValue(value); } else { this->changeValueContainer<float>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 407 inline bool assignValue(const double& value) { if (this->value_ && this->value_->type_ == MT_double) { return this->value_->setValue(value); } else { this->changeValueContainer<double>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 408 inline bool assignValue(const long double& value) { if (this->value_ && this->value_->type_ == MT_longdouble) { return this->value_->setValue(value); } else { this->changeValueContainer<long double>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 409 inline bool assignValue(const bool& value) { if (this->value_ && this->value_->type_ == MT_bool) { return this->value_->setValue(value); } else { this->changeValueContainer<bool>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 410 inline bool assignValue( void* const& value) { if (this->value_ && this->value_->type_ == MT_void) { return this->value_->setValue(value); } else { this->changeValueContainer<void*>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 411 inline bool assignValue(const std::string& value) { if (this->value_ && this->value_->type_ == MT_string) { return this->value_->setValue(value); } else { this->changeValueContainer<std::string>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 412 inline bool assignValue(const orxonox::Vector2& value) { if (this->value_ && this->value_->type_ == MT_vector2) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector2>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 413 inline bool assignValue(const orxonox::Vector3& value) { if (this->value_ && this->value_->type_ == MT_vector3) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector3>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 414 inline bool assignValue(const orxonox::Vector4& value) { if (this->value_ && this->value_->type_ == MT_vector4) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector4>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 415 inline bool assignValue(const orxonox::ColourValue& value) { if (this->value_ && this->value_->type_ == MT_colourvalue) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::ColourValue>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 416 inline bool assignValue(const orxonox::Quaternion& value) { if (this->value_ && this->value_->type_ == MT_quaternion) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Quaternion>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 417 inline bool assignValue(const orxonox::Radian& value) { if (this->value_ && this->value_->type_ == MT_radian) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Radian>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 418 inline bool assignValue(const orxonox::Degree& value) { if (this->value_ && this->value_->type_ == MT_degree) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Degree>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 419 420 /** @brief Changes the value container. */ 421 template <typename T> inline void changeValueContainer(const T& value) { if (this->value_) { delete this->value_; } this->createNewValueContainer<T>(value); } 422 /** @brief Creates a new value container (works only with specialized types). */ 423 template <typename T> void createNewValueContainer(const T& value) { BOOST_STATIC_ASSERT(sizeof(T) == 0); return false; } 424 425 MT_ValueBase* value_; //!< A pointer to the value container 426 }; 427 428 /** @brief Puts the MultiType on a stream by using the native << operator of the current type. */ 429 _UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt) { if (mt.value_) { mt.value_->toString(outstream); } return outstream; } 430 431 template <> inline bool MultiType::isType<char>() const { return (this->value_ && this->value_->type_ == MT_char); } /** @brief Returns true if the current type equals the given type. */ 432 template <> inline bool MultiType::isType<unsigned char>() const { return (this->value_ && this->value_->type_ == MT_uchar); } /** @brief Returns true if the current type equals the given type. */ 433 template <> inline bool MultiType::isType<short>() const { return (this->value_ && this->value_->type_ == MT_short); } /** @brief Returns true if the current type equals the given type. */ 434 template <> inline bool MultiType::isType<unsigned short>() const { return (this->value_ && this->value_->type_ == MT_ushort); } /** @brief Returns true if the current type equals the given type. */ 435 template <> inline bool MultiType::isType<int>() const { return (this->value_ && this->value_->type_ == MT_int); } /** @brief Returns true if the current type equals the given type. */ 436 template <> inline bool MultiType::isType<unsigned int>() const { return (this->value_ && this->value_->type_ == MT_uint); } /** @brief Returns true if the current type equals the given type. */ 437 template <> inline bool MultiType::isType<long>() const { return (this->value_ && this->value_->type_ == MT_long); } /** @brief Returns true if the current type equals the given type. */ 438 template <> inline bool MultiType::isType<unsigned long>() const { return (this->value_ && this->value_->type_ == MT_ulong); } /** @brief Returns true if the current type equals the given type. */ 439 template <> inline bool MultiType::isType<long long>() const { return (this->value_ && this->value_->type_ == MT_longlong); } /** @brief Returns true if the current type equals the given type. */ 440 template <> inline bool MultiType::isType<unsigned long long>() const { return (this->value_ && this->value_->type_ == MT_ulonglong); } /** @brief Returns true if the current type equals the given type. */ 441 template <> inline bool MultiType::isType<float>() const { return (this->value_ && this->value_->type_ == MT_float); } /** @brief Returns true if the current type equals the given type. */ 442 template <> inline bool MultiType::isType<double>() const { return (this->value_ && this->value_->type_ == MT_double); } /** @brief Returns true if the current type equals the given type. */ 443 template <> inline bool MultiType::isType<long double>() const { return (this->value_ && this->value_->type_ == MT_longdouble); } /** @brief Returns true if the current type equals the given type. */ 444 template <> inline bool MultiType::isType<bool>() const { return (this->value_ && this->value_->type_ == MT_bool); } /** @brief Returns true if the current type equals the given type. */ 445 template <> inline bool MultiType::isType<void*>() const { return (this->value_ && this->value_->type_ == MT_void); } /** @brief Returns true if the current type equals the given type. */ 446 template <> inline bool MultiType::isType<std::string>() const { return (this->value_ && this->value_->type_ == MT_string); } /** @brief Returns true if the current type equals the given type. */ 447 template <> inline bool MultiType::isType<orxonox::Vector2>() const { return (this->value_ && this->value_->type_ == MT_vector2); } /** @brief Returns true if the current type equals the given type. */ 448 template <> inline bool MultiType::isType<orxonox::Vector3>() const { return (this->value_ && this->value_->type_ == MT_vector3); } /** @brief Returns true if the current type equals the given type. */ 449 template <> inline bool MultiType::isType<orxonox::Vector4>() const { return (this->value_ && this->value_->type_ == MT_vector4); } /** @brief Returns true if the current type equals the given type. */ 450 template <> inline bool MultiType::isType<orxonox::ColourValue>() const { return (this->value_ && this->value_->type_ == MT_colourvalue); } /** @brief Returns true if the current type equals the given type. */ 451 template <> inline bool MultiType::isType<orxonox::Quaternion>() const { return (this->value_ && this->value_->type_ == MT_quaternion); } /** @brief Returns true if the current type equals the given type. */ 452 template <> inline bool MultiType::isType<orxonox::Radian>() const { return (this->value_ && this->value_->type_ == MT_radian); } /** @brief Returns true if the current type equals the given type. */ 453 template <> inline bool MultiType::isType<orxonox::Degree>() const { return (this->value_ && this->value_->type_ == MT_degree); } /** @brief Returns true if the current type equals the given type. */ 454 455 // Specialization to avoid ambiguities with the conversion operator 456 template <> inline bool MultiType::convert<std::string>() { return this->setValue<std::string> (this->operator std::string()); } /** @brief Converts the current value to the given type. */ 457 template <> inline bool MultiType::convert<orxonox::Vector2>() { return this->setValue<orxonox::Vector2> (this->operator orxonox::Vector2()); } /** @brief Converts the current value to the given type. */ 458 template <> inline bool MultiType::convert<orxonox::Vector3>() { return this->setValue<orxonox::Vector3> (this->operator orxonox::Vector3()); } /** @brief Converts the current value to the given type. */ 459 template <> inline bool MultiType::convert<orxonox::Vector4>() { return this->setValue<orxonox::Vector4> (this->operator orxonox::Vector4()); } /** @brief Converts the current value to the given type. */ 460 template <> inline bool MultiType::convert<orxonox::ColourValue>() { return this->setValue<orxonox::ColourValue>(this->operator orxonox::ColourValue()); } /** @brief Converts the current value to the given type. */ 461 template <> inline bool MultiType::convert<orxonox::Quaternion>() { return this->setValue<orxonox::Quaternion> (this->operator orxonox::Quaternion()); } /** @brief Converts the current value to the given type. */ 462 template <> inline bool MultiType::convert<orxonox::Radian>() { return this->setValue<orxonox::Radian> (this->operator orxonox::Radian()); } /** @brief Converts the current value to the given type. */ 463 template <> inline bool MultiType::convert<orxonox::Degree>() { return this->setValue<orxonox::Degree> (this->operator orxonox::Degree()); } /** @brief Converts the current value to the given type. */ 464 465 // Specialization to avoid ambiguities with the conversion operator 466 template <> inline bool MultiType::convert<const std::string&>() { return this->convert<std::string>(); } /** @brief Converts the current value to the given type. */ 467 template <> inline bool MultiType::convert<const orxonox::Vector2&>() { return this->convert<orxonox::Vector2>(); } /** @brief Converts the current value to the given type. */ 468 template <> inline bool MultiType::convert<const orxonox::Vector3&>() { return this->convert<orxonox::Vector3>(); } /** @brief Converts the current value to the given type. */ 469 template <> inline bool MultiType::convert<const orxonox::Vector4&>() { return this->convert<orxonox::Vector4>(); } /** @brief Converts the current value to the given type. */ 470 template <> inline bool MultiType::convert<const orxonox::ColourValue&>() { return this->convert<orxonox::ColourValue>(); } /** @brief Converts the current value to the given type. */ 471 template <> inline bool MultiType::convert<const orxonox::Quaternion&>() { return this->convert<orxonox::Quaternion>(); } /** @brief Converts the current value to the given type. */ 472 template <> inline bool MultiType::convert<const orxonox::Radian&>() { return this->convert<orxonox::Radian>(); } /** @brief Converts the current value to the given type. */ 473 template <> inline bool MultiType::convert<const orxonox::Degree&>() { return this->convert<orxonox::Degree>(); } /** @brief Converts the current value to the given type. */ 474 475 template <> void MultiType::createNewValueContainer(const char& value); 476 template <> void MultiType::createNewValueContainer(const unsigned char& value); 477 template <> void MultiType::createNewValueContainer(const short& value); 478 template <> void MultiType::createNewValueContainer(const unsigned short& value); 479 template <> void MultiType::createNewValueContainer(const int& value); 480 template <> void MultiType::createNewValueContainer(const unsigned int& value); 481 template <> void MultiType::createNewValueContainer(const long& value); 482 template <> void MultiType::createNewValueContainer(const unsigned long& value); 483 template <> void MultiType::createNewValueContainer(const long long& value); 484 template <> void MultiType::createNewValueContainer(const unsigned long long& value); 485 template <> void MultiType::createNewValueContainer(const float& value); 486 template <> void MultiType::createNewValueContainer(const double& value); 487 template <> void MultiType::createNewValueContainer(const bool& value); 488 template <> void MultiType::createNewValueContainer(const long double& value); 489 template <> void MultiType::createNewValueContainer( void* const& value); 490 template <> void MultiType::createNewValueContainer(const std::string& value); 491 template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value); 492 template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value); 493 template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value); 494 template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value); 495 template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value); 496 template <> void MultiType::createNewValueContainer(const orxonox::Radian& value); 497 template <> void MultiType::createNewValueContainer(const orxonox::Degree& value); 498 499 inline bool MultiType::setValue(const char& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 500 inline bool MultiType::setValue(const unsigned char& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 501 inline bool MultiType::setValue(const short& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 502 inline bool MultiType::setValue(const unsigned short& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 503 inline bool MultiType::setValue(const int& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 504 inline bool MultiType::setValue(const unsigned int& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 505 inline bool MultiType::setValue(const long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 506 inline bool MultiType::setValue(const unsigned long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 507 inline bool MultiType::setValue(const long long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 508 inline bool MultiType::setValue(const unsigned long long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 509 inline bool MultiType::setValue(const float& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 510 inline bool MultiType::setValue(const double& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 511 inline bool MultiType::setValue(const long double& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 512 inline bool MultiType::setValue(const bool& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 513 inline bool MultiType::setValue( void* const& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 514 inline bool MultiType::setValue(const std::string& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 515 inline bool MultiType::setValue(const orxonox::Vector2& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 516 inline bool MultiType::setValue(const orxonox::Vector3& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 517 inline bool MultiType::setValue(const orxonox::Vector4& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 518 inline bool MultiType::setValue(const orxonox::ColourValue& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 519 inline bool MultiType::setValue(const orxonox::Quaternion& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 520 inline bool MultiType::setValue(const orxonox::Radian& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 521 inline bool MultiType::setValue(const orxonox::Degree& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 522 523 inline bool MultiType::setValue(const char* value) { if (this->value_) { return this->value_->setValue(std::string(value)); } else { return this->assignValue(std::string(value)); } } /** @brief Assigns the given value and converts it to the current type. */ 131 /** 132 @brief MT_ValueBase is an almost pure virtual baseclass of MT_Value<T>, which holds the value of the MultiType. 133 This class is only used within the MultiType. 134 */ 135 class _UtilExport MT_ValueBase 136 { 137 public: 138 MT_ValueBase(MT_Type type) : type_(type), bHasDefaultValue_(false) {} 139 virtual ~MT_ValueBase() {} 140 141 virtual MT_ValueBase* clone() const = 0; 142 143 virtual void reset() = 0; 144 virtual bool assimilate(const MultiType& other) = 0; 145 146 /** @brief Returns the type of the current value. */ 147 const MT_Type& getType() const { return this->type_; } 148 149 /** @brief Checks whether the value is a default one. */ 150 bool hasDefaultValue() const { return this->bHasDefaultValue_; } 151 152 virtual bool setValue(const char& value) = 0; 153 virtual bool setValue(const unsigned char& value) = 0; 154 virtual bool setValue(const short& value) = 0; 155 virtual bool setValue(const unsigned short& value) = 0; 156 virtual bool setValue(const int& value) = 0; 157 virtual bool setValue(const unsigned int& value) = 0; 158 virtual bool setValue(const long& value) = 0; 159 virtual bool setValue(const unsigned long& value) = 0; 160 virtual bool setValue(const long long& value) = 0; 161 virtual bool setValue(const unsigned long long& value) = 0; 162 virtual bool setValue(const float& value) = 0; 163 virtual bool setValue(const double& value) = 0; 164 virtual bool setValue(const long double& value) = 0; 165 virtual bool setValue(const bool& value) = 0; 166 virtual bool setValue( void* const& value) = 0; 167 virtual bool setValue(const std::string& value) = 0; 168 virtual bool setValue(const orxonox::Vector2& value) = 0; 169 virtual bool setValue(const orxonox::Vector3& value) = 0; 170 virtual bool setValue(const orxonox::Vector4& value) = 0; 171 virtual bool setValue(const orxonox::ColourValue& value) = 0; 172 virtual bool setValue(const orxonox::Quaternion& value) = 0; 173 virtual bool setValue(const orxonox::Radian& value) = 0; 174 virtual bool setValue(const orxonox::Degree& value) = 0; 175 176 virtual bool getValue(char* value) const = 0; 177 virtual bool getValue(unsigned char* value) const = 0; 178 virtual bool getValue(short* value) const = 0; 179 virtual bool getValue(unsigned short* value) const = 0; 180 virtual bool getValue(int* value) const = 0; 181 virtual bool getValue(unsigned int* value) const = 0; 182 virtual bool getValue(long* value) const = 0; 183 virtual bool getValue(unsigned long* value) const = 0; 184 virtual bool getValue(long long* value) const = 0; 185 virtual bool getValue(unsigned long long* value) const = 0; 186 virtual bool getValue(float* value) const = 0; 187 virtual bool getValue(double* value) const = 0; 188 virtual bool getValue(long double* value) const = 0; 189 virtual bool getValue(bool* value) const = 0; 190 virtual bool getValue(void** value) const = 0; 191 virtual bool getValue(std::string* value) const = 0; 192 virtual bool getValue(orxonox::Vector2* value) const = 0; 193 virtual bool getValue(orxonox::Vector3* value) const = 0; 194 virtual bool getValue(orxonox::Vector4* value) const = 0; 195 virtual bool getValue(orxonox::ColourValue* value) const = 0; 196 virtual bool getValue(orxonox::Quaternion* value) const = 0; 197 virtual bool getValue(orxonox::Radian* value) const = 0; 198 virtual bool getValue(orxonox::Degree* value) const = 0; 199 200 virtual operator char() const = 0; 201 virtual operator unsigned char() const = 0; 202 virtual operator short() const = 0; 203 virtual operator unsigned short() const = 0; 204 virtual operator int() const = 0; 205 virtual operator unsigned int() const = 0; 206 virtual operator long() const = 0; 207 virtual operator unsigned long() const = 0; 208 virtual operator long long() const = 0; 209 virtual operator unsigned long long() const = 0; 210 virtual operator float() const = 0; 211 virtual operator double() const = 0; 212 virtual operator long double() const = 0; 213 virtual operator bool() const = 0; 214 virtual operator void*() const = 0; 215 virtual operator std::string() const = 0; 216 virtual operator orxonox::Vector2() const = 0; 217 virtual operator orxonox::Vector3() const = 0; 218 virtual operator orxonox::Vector4() const = 0; 219 virtual operator orxonox::ColourValue() const = 0; 220 virtual operator orxonox::Quaternion() const = 0; 221 virtual operator orxonox::Radian() const = 0; 222 virtual operator orxonox::Degree() const = 0; 223 224 virtual void toString(std::ostream& outstream) const = 0; 225 226 MT_Type type_; //!< The type of the current value 227 bool bHasDefaultValue_; //!< True if the last conversion wasn't successful 228 }; 229 230 public: 231 inline MultiType() : value_(0) {} /** @brief Default constructor: Assigns no value and no type. The type will be determined by the first assignment of a value. */ 232 inline MultiType(const char& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 233 inline MultiType(const unsigned char& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 234 inline MultiType(const short& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 235 inline MultiType(const unsigned short& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 236 inline MultiType(const int& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 237 inline MultiType(const unsigned int& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 238 inline MultiType(const long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 239 inline MultiType(const unsigned long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 240 inline MultiType(const long long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 241 inline MultiType(const unsigned long long& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 242 inline MultiType(const float& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 243 inline MultiType(const double& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 244 inline MultiType(const long double& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 245 inline MultiType(const bool& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 246 inline MultiType( void* const& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 247 inline MultiType(const std::string& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 248 inline MultiType(const orxonox::Vector2& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 249 inline MultiType(const orxonox::Vector3& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 250 inline MultiType(const orxonox::Vector4& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 251 inline MultiType(const orxonox::ColourValue& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 252 inline MultiType(const orxonox::Quaternion& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 253 inline MultiType(const orxonox::Radian& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 254 inline MultiType(const orxonox::Degree& value) : value_(0) { this->assignValue(value); } /** @brief Constructor: Assigns the given value and sets the type. */ 255 inline MultiType(const char* value) : value_(0) { this->setValue(std::string(value)); } /** @brief Constructor: Converts the char array to a std::string, assigns the value and sets the type. */ 256 inline MultiType(const MultiType& other) : value_(0) { this->setValue(other); } /** @brief Copyconstructor: Assigns value and type of the other MultiType. */ 257 inline MultiType(MT_Type type) : value_(0) { this->setType(type); } /** @brief Constructor: Sets the type, the next assignment will determine the value. */ 258 259 /** @brief Destructor: Deletes the MT_Value. */ 260 inline ~MultiType() { if (this->value_) { delete this->value_; } } 261 262 template <typename V> inline const MultiType& operator=(const V& value) { this->setValue(value); return (*this); } /** @brief Assigns a new value. The value will be converted to the current type of the MultiType. */ 263 template <typename V> inline const MultiType& operator=(V* value) { this->setValue(value); return (*this); } /** @brief Assigns a pointer. */ 264 inline const MultiType& operator=(const MultiType& other) { this->setValue(other); return (*this); } /** @brief Assigns the value of the other MultiType and converts it to the current type of the MultiType. */ 265 inline const MultiType& operator=(MT_Type type) { this->setType(type); return (*this); } /** @brief Resets the value and changes the type. */ 266 267 inline bool setValue(const char& value); 268 inline bool setValue(const unsigned char& value); 269 inline bool setValue(const short& value); 270 inline bool setValue(const unsigned short& value); 271 inline bool setValue(const int& value); 272 inline bool setValue(const unsigned int& value); 273 inline bool setValue(const long& value); 274 inline bool setValue(const unsigned long& value); 275 inline bool setValue(const long long& value); 276 inline bool setValue(const unsigned long long& value); 277 inline bool setValue(const float& value); 278 inline bool setValue(const double& value); 279 inline bool setValue(const long double& value); 280 inline bool setValue(const bool& value); 281 inline bool setValue( void* const& value); 282 inline bool setValue(const std::string& value); 283 inline bool setValue(const orxonox::Vector2& value); 284 inline bool setValue(const orxonox::Vector3& value); 285 inline bool setValue(const orxonox::Vector4& value); 286 inline bool setValue(const orxonox::ColourValue& value); 287 inline bool setValue(const orxonox::Quaternion& value); 288 inline bool setValue(const orxonox::Radian& value); 289 inline bool setValue(const orxonox::Degree& value); 290 inline bool setValue(const char* value); 291 /** @brief Assigns a pointer. */ 292 template <typename V> inline bool setValue(V* value) { if (this->value_) { return this->value_->setValue((void*)value); } else { return this->assignValue((void*)value); } } 293 /** @brief Assigns the value of the other MultiType and converts it to the current type. */ 294 bool setValue(const MultiType& other) { if (this->value_) { return this->value_->assimilate(other); } else { if (other.value_) { this->value_ = other.value_->clone(); } return true; } } 295 /** @brief Changes the type to T and assigns the new value (which might be of another type than T - it gets converted). */ 296 template <typename T, typename V> inline bool setValue(const V& value) { this->setType<T>(); return this->setValue(value); } 297 298 299 /** @brief Copies the other MultiType by assigning value and type. */ 300 inline void copy(const MultiType& other) { if (this == &other) { return; } if (this->value_) { delete this->value_; } this->value_ = (other.value_) ? other.value_->clone() : 0; } 301 302 template <typename T> inline bool convert() { return this->setValue<T>((T)(*this)); } /** @brief Converts the current value to type T. */ 303 inline bool convert(const MultiType& other) { return this->convert(other.getType()); } /** @brief Converts the current value to the type of the other MultiType. */ 304 bool convert(MT_Type type); 305 306 /** @brief Current content gets deleted. New type is MT_null */ 307 inline void reset() { if (this->value_) this->value_->reset(); } 308 309 template <typename T> inline void setType() { this->assignValue(T()); } /** @brief Resets the value and changes the internal type to T. */ 310 inline void setType(const MultiType& other) { this->setType(other.getType()); } /** @brief Resets the value and changes the internal type to the type of the other MultiType. */ 311 inline void setType(MT_Type type) { this->reset(); this->convert(type); this->reset(); } /** @brief Resets the value and changes the internal type to the given type. */ 312 313 /** @brief Returns the current type. */ 314 inline MT_Type getType() const { return (this->value_) ? this->value_->type_ : MT_null; } 315 /** @brief Returns true if the current type equals the given type. */ 316 inline bool isType(MT_Type type) const { return (this->value_) ? (this->value_->type_ == type) : (type == MT_null); } 317 /** @brief Returns true if the current type is T. */ 318 template <typename T> inline bool isType() const { return false; } // Only works for specialized values - see below 319 std::string getTypename() const; 320 321 /** @brief Checks whether the value is a default one. */ 322 bool hasDefaultValue() const { return this->value_->hasDefaultValue(); } 323 324 operator char() const; 325 operator unsigned char() const; 326 operator short() const; 327 operator unsigned short() const; 328 operator int() const; 329 operator unsigned int() const; 330 operator long() const; 331 operator unsigned long() const; 332 operator long long() const; 333 operator unsigned long long() const; 334 operator float() const; 335 operator double() const; 336 operator long double() const; 337 operator bool() const; 338 operator void*() const; 339 operator std::string() const; 340 operator orxonox::Vector2() const; 341 operator orxonox::Vector3() const; 342 operator orxonox::Vector4() const; 343 operator orxonox::ColourValue() const; 344 operator orxonox::Quaternion() const; 345 operator orxonox::Radian() const; 346 operator orxonox::Degree() const; 347 /** @brief Returns the current value, converted to a T* pointer. */ 348 template <class T> operator T*() const { return ((T*)this->operator void*()); } 349 350 inline bool getValue(char* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 351 inline bool getValue(unsigned char* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 352 inline bool getValue(short* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 353 inline bool getValue(unsigned short* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 354 inline bool getValue(int* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 355 inline bool getValue(unsigned int* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 356 inline bool getValue(long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 357 inline bool getValue(unsigned long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 358 inline bool getValue(long long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 359 inline bool getValue(unsigned long long* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 360 inline bool getValue(float* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 361 inline bool getValue(double* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 362 inline bool getValue(long double* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 363 inline bool getValue(bool* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 364 inline bool getValue(void** value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 365 inline bool getValue(std::string* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 366 inline bool getValue(orxonox::Vector2* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 367 inline bool getValue(orxonox::Vector3* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 368 inline bool getValue(orxonox::Vector4* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 369 inline bool getValue(orxonox::ColourValue* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 370 inline bool getValue(orxonox::Quaternion* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 371 inline bool getValue(orxonox::Radian* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 372 inline bool getValue(orxonox::Degree* value) const { if (this->value_) { return this->value_->getValue(value); } return false; } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 373 374 inline char getChar() const { return this->operator char(); } /** @brief Returns the current value, converted to the requested type. */ 375 inline unsigned char getUnsignedChar() const { return this->operator unsigned char(); } /** @brief Returns the current value, converted to the requested type. */ 376 inline short getShort() const { return this->operator short(); } /** @brief Returns the current value, converted to the requested type. */ 377 inline unsigned short getUnsignedShort() const { return this->operator unsigned short(); } /** @brief Returns the current value, converted to the requested type. */ 378 inline int getInt() const { return this->operator int(); } /** @brief Returns the current value, converted to the requested type. */ 379 inline unsigned int getUnsignedInt() const { return this->operator unsigned int(); } /** @brief Returns the current value, converted to the requested type. */ 380 inline long getLong() const { return this->operator long(); } /** @brief Returns the current value, converted to the requested type. */ 381 inline unsigned long getUnsignedLong() const { return this->operator unsigned long(); } /** @brief Returns the current value, converted to the requested type. */ 382 inline long long getLongLong() const { return this->operator long long(); } /** @brief Returns the current value, converted to the requested type. */ 383 inline unsigned long long getUnsignedLongLong() const { return this->operator unsigned long long(); } /** @brief Returns the current value, converted to the requested type. */ 384 inline float getFloat() const { return this->operator float(); } /** @brief Returns the current value, converted to the requested type. */ 385 inline double getDouble() const { return this->operator double(); } /** @brief Returns the current value, converted to the requested type. */ 386 inline long double getLongDouble() const { return this->operator long double(); } /** @brief Returns the current value, converted to the requested type. */ 387 inline bool getBool() const { return this->operator bool(); } /** @brief Returns the current value, converted to the requested type. */ 388 inline void* getVoid() const { return this->operator void*(); } /** @brief Returns the current value, converted to the requested type. */ 389 inline std::string getString() const { return this->operator std::string(); } /** @brief Returns the current value, converted to the requested type. */ 390 inline orxonox::Vector2 getVector2() const { return this->operator orxonox::Vector2(); } /** @brief Returns the current value, converted to the requested type. */ 391 inline orxonox::Vector3 getVector3() const { return this->operator orxonox::Vector3(); } /** @brief Returns the current value, converted to the requested type. */ 392 inline orxonox::Vector4 getVector4() const { return this->operator orxonox::Vector4(); } /** @brief Returns the current value, converted to the requested type. */ 393 inline orxonox::ColourValue getColourValue() const { return this->operator orxonox::ColourValue(); } /** @brief Returns the current value, converted to the requested type. */ 394 inline orxonox::Quaternion getQuaternion() const { return this->operator orxonox::Quaternion(); } /** @brief Returns the current value, converted to the requested type. */ 395 inline orxonox::Radian getRadian() const { return this->operator orxonox::Radian(); } /** @brief Returns the current value, converted to the requested type. */ 396 inline orxonox::Degree getDegree() const { return this->operator orxonox::Degree(); } /** @brief Returns the current value, converted to the requested type. */ 397 template <typename T> inline T* getPointer() const { return ((T*)this->getVoid()); } /** @brief Returns the current value, converted to a T* pointer. */ 398 399 private: 400 inline bool assignValue(const char& value) { if (this->value_ && this->value_->type_ == MT_char) { return this->value_->setValue(value); } else { this->changeValueContainer<char>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 401 inline bool assignValue(const unsigned char& value) { if (this->value_ && this->value_->type_ == MT_uchar) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned char>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 402 inline bool assignValue(const short& value) { if (this->value_ && this->value_->type_ == MT_short) { return this->value_->setValue(value); } else { this->changeValueContainer<short>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 403 inline bool assignValue(const unsigned short& value) { if (this->value_ && this->value_->type_ == MT_ushort) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned short>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 404 inline bool assignValue(const int& value) { if (this->value_ && this->value_->type_ == MT_int) { return this->value_->setValue(value); } else { this->changeValueContainer<int>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 405 inline bool assignValue(const unsigned int& value) { if (this->value_ && this->value_->type_ == MT_uint) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned int>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 406 inline bool assignValue(const long& value) { if (this->value_ && this->value_->type_ == MT_long) { return this->value_->setValue(value); } else { this->changeValueContainer<long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 407 inline bool assignValue(const unsigned long& value) { if (this->value_ && this->value_->type_ == MT_ulong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 408 inline bool assignValue(const long long& value) { if (this->value_ && this->value_->type_ == MT_longlong) { return this->value_->setValue(value); } else { this->changeValueContainer<long long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 409 inline bool assignValue(const unsigned long long& value) { if (this->value_ && this->value_->type_ == MT_ulonglong) { return this->value_->setValue(value); } else { this->changeValueContainer<unsigned long long>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 410 inline bool assignValue(const float& value) { if (this->value_ && this->value_->type_ == MT_float) { return this->value_->setValue(value); } else { this->changeValueContainer<float>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 411 inline bool assignValue(const double& value) { if (this->value_ && this->value_->type_ == MT_double) { return this->value_->setValue(value); } else { this->changeValueContainer<double>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 412 inline bool assignValue(const long double& value) { if (this->value_ && this->value_->type_ == MT_longdouble) { return this->value_->setValue(value); } else { this->changeValueContainer<long double>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 413 inline bool assignValue(const bool& value) { if (this->value_ && this->value_->type_ == MT_bool) { return this->value_->setValue(value); } else { this->changeValueContainer<bool>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 414 inline bool assignValue( void* const& value) { if (this->value_ && this->value_->type_ == MT_void) { return this->value_->setValue(value); } else { this->changeValueContainer<void*>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 415 inline bool assignValue(const std::string& value) { if (this->value_ && this->value_->type_ == MT_string) { return this->value_->setValue(value); } else { this->changeValueContainer<std::string>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 416 inline bool assignValue(const orxonox::Vector2& value) { if (this->value_ && this->value_->type_ == MT_vector2) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector2>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 417 inline bool assignValue(const orxonox::Vector3& value) { if (this->value_ && this->value_->type_ == MT_vector3) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector3>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 418 inline bool assignValue(const orxonox::Vector4& value) { if (this->value_ && this->value_->type_ == MT_vector4) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Vector4>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 419 inline bool assignValue(const orxonox::ColourValue& value) { if (this->value_ && this->value_->type_ == MT_colourvalue) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::ColourValue>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 420 inline bool assignValue(const orxonox::Quaternion& value) { if (this->value_ && this->value_->type_ == MT_quaternion) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Quaternion>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 421 inline bool assignValue(const orxonox::Radian& value) { if (this->value_ && this->value_->type_ == MT_radian) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Radian>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 422 inline bool assignValue(const orxonox::Degree& value) { if (this->value_ && this->value_->type_ == MT_degree) { return this->value_->setValue(value); } else { this->changeValueContainer<orxonox::Degree>(value); return true; } } /** @brief Assigns a new value by changing type and creating a new container. */ 423 424 /** @brief Changes the value container. */ 425 template <typename T> inline void changeValueContainer(const T& value) { if (this->value_) { delete this->value_; } this->createNewValueContainer<T>(value); } 426 /** @brief Creates a new value container (works only with specialized types). */ 427 template <typename T> void createNewValueContainer(const T& value) { BOOST_STATIC_ASSERT(sizeof(T) == 0); return false; } 428 429 MT_ValueBase* value_; //!< A pointer to the value container 430 }; 431 432 /** @brief Puts the MultiType on a stream by using the native << operator of the current type. */ 433 _UtilExport inline std::ostream& operator<<(std::ostream& outstream, const MultiType& mt) { if (mt.value_) { mt.value_->toString(outstream); } return outstream; } 434 435 template <> inline bool MultiType::isType<char>() const { return (this->value_ && this->value_->type_ == MT_char); } /** @brief Returns true if the current type equals the given type. */ 436 template <> inline bool MultiType::isType<unsigned char>() const { return (this->value_ && this->value_->type_ == MT_uchar); } /** @brief Returns true if the current type equals the given type. */ 437 template <> inline bool MultiType::isType<short>() const { return (this->value_ && this->value_->type_ == MT_short); } /** @brief Returns true if the current type equals the given type. */ 438 template <> inline bool MultiType::isType<unsigned short>() const { return (this->value_ && this->value_->type_ == MT_ushort); } /** @brief Returns true if the current type equals the given type. */ 439 template <> inline bool MultiType::isType<int>() const { return (this->value_ && this->value_->type_ == MT_int); } /** @brief Returns true if the current type equals the given type. */ 440 template <> inline bool MultiType::isType<unsigned int>() const { return (this->value_ && this->value_->type_ == MT_uint); } /** @brief Returns true if the current type equals the given type. */ 441 template <> inline bool MultiType::isType<long>() const { return (this->value_ && this->value_->type_ == MT_long); } /** @brief Returns true if the current type equals the given type. */ 442 template <> inline bool MultiType::isType<unsigned long>() const { return (this->value_ && this->value_->type_ == MT_ulong); } /** @brief Returns true if the current type equals the given type. */ 443 template <> inline bool MultiType::isType<long long>() const { return (this->value_ && this->value_->type_ == MT_longlong); } /** @brief Returns true if the current type equals the given type. */ 444 template <> inline bool MultiType::isType<unsigned long long>() const { return (this->value_ && this->value_->type_ == MT_ulonglong); } /** @brief Returns true if the current type equals the given type. */ 445 template <> inline bool MultiType::isType<float>() const { return (this->value_ && this->value_->type_ == MT_float); } /** @brief Returns true if the current type equals the given type. */ 446 template <> inline bool MultiType::isType<double>() const { return (this->value_ && this->value_->type_ == MT_double); } /** @brief Returns true if the current type equals the given type. */ 447 template <> inline bool MultiType::isType<long double>() const { return (this->value_ && this->value_->type_ == MT_longdouble); } /** @brief Returns true if the current type equals the given type. */ 448 template <> inline bool MultiType::isType<bool>() const { return (this->value_ && this->value_->type_ == MT_bool); } /** @brief Returns true if the current type equals the given type. */ 449 template <> inline bool MultiType::isType<void*>() const { return (this->value_ && this->value_->type_ == MT_void); } /** @brief Returns true if the current type equals the given type. */ 450 template <> inline bool MultiType::isType<std::string>() const { return (this->value_ && this->value_->type_ == MT_string); } /** @brief Returns true if the current type equals the given type. */ 451 template <> inline bool MultiType::isType<orxonox::Vector2>() const { return (this->value_ && this->value_->type_ == MT_vector2); } /** @brief Returns true if the current type equals the given type. */ 452 template <> inline bool MultiType::isType<orxonox::Vector3>() const { return (this->value_ && this->value_->type_ == MT_vector3); } /** @brief Returns true if the current type equals the given type. */ 453 template <> inline bool MultiType::isType<orxonox::Vector4>() const { return (this->value_ && this->value_->type_ == MT_vector4); } /** @brief Returns true if the current type equals the given type. */ 454 template <> inline bool MultiType::isType<orxonox::ColourValue>() const { return (this->value_ && this->value_->type_ == MT_colourvalue); } /** @brief Returns true if the current type equals the given type. */ 455 template <> inline bool MultiType::isType<orxonox::Quaternion>() const { return (this->value_ && this->value_->type_ == MT_quaternion); } /** @brief Returns true if the current type equals the given type. */ 456 template <> inline bool MultiType::isType<orxonox::Radian>() const { return (this->value_ && this->value_->type_ == MT_radian); } /** @brief Returns true if the current type equals the given type. */ 457 template <> inline bool MultiType::isType<orxonox::Degree>() const { return (this->value_ && this->value_->type_ == MT_degree); } /** @brief Returns true if the current type equals the given type. */ 458 459 // Specialization to avoid ambiguities with the conversion operator 460 template <> inline bool MultiType::convert<std::string>() { return this->setValue<std::string> (this->operator std::string()); } /** @brief Converts the current value to the given type. */ 461 template <> inline bool MultiType::convert<orxonox::Vector2>() { return this->setValue<orxonox::Vector2> (this->operator orxonox::Vector2()); } /** @brief Converts the current value to the given type. */ 462 template <> inline bool MultiType::convert<orxonox::Vector3>() { return this->setValue<orxonox::Vector3> (this->operator orxonox::Vector3()); } /** @brief Converts the current value to the given type. */ 463 template <> inline bool MultiType::convert<orxonox::Vector4>() { return this->setValue<orxonox::Vector4> (this->operator orxonox::Vector4()); } /** @brief Converts the current value to the given type. */ 464 template <> inline bool MultiType::convert<orxonox::ColourValue>() { return this->setValue<orxonox::ColourValue>(this->operator orxonox::ColourValue()); } /** @brief Converts the current value to the given type. */ 465 template <> inline bool MultiType::convert<orxonox::Quaternion>() { return this->setValue<orxonox::Quaternion> (this->operator orxonox::Quaternion()); } /** @brief Converts the current value to the given type. */ 466 template <> inline bool MultiType::convert<orxonox::Radian>() { return this->setValue<orxonox::Radian> (this->operator orxonox::Radian()); } /** @brief Converts the current value to the given type. */ 467 template <> inline bool MultiType::convert<orxonox::Degree>() { return this->setValue<orxonox::Degree> (this->operator orxonox::Degree()); } /** @brief Converts the current value to the given type. */ 468 469 // Specialization to avoid ambiguities with the conversion operator 470 template <> inline bool MultiType::convert<const std::string&>() { return this->convert<std::string>(); } /** @brief Converts the current value to the given type. */ 471 template <> inline bool MultiType::convert<const orxonox::Vector2&>() { return this->convert<orxonox::Vector2>(); } /** @brief Converts the current value to the given type. */ 472 template <> inline bool MultiType::convert<const orxonox::Vector3&>() { return this->convert<orxonox::Vector3>(); } /** @brief Converts the current value to the given type. */ 473 template <> inline bool MultiType::convert<const orxonox::Vector4&>() { return this->convert<orxonox::Vector4>(); } /** @brief Converts the current value to the given type. */ 474 template <> inline bool MultiType::convert<const orxonox::ColourValue&>() { return this->convert<orxonox::ColourValue>(); } /** @brief Converts the current value to the given type. */ 475 template <> inline bool MultiType::convert<const orxonox::Quaternion&>() { return this->convert<orxonox::Quaternion>(); } /** @brief Converts the current value to the given type. */ 476 template <> inline bool MultiType::convert<const orxonox::Radian&>() { return this->convert<orxonox::Radian>(); } /** @brief Converts the current value to the given type. */ 477 template <> inline bool MultiType::convert<const orxonox::Degree&>() { return this->convert<orxonox::Degree>(); } /** @brief Converts the current value to the given type. */ 478 479 template <> void MultiType::createNewValueContainer(const char& value); 480 template <> void MultiType::createNewValueContainer(const unsigned char& value); 481 template <> void MultiType::createNewValueContainer(const short& value); 482 template <> void MultiType::createNewValueContainer(const unsigned short& value); 483 template <> void MultiType::createNewValueContainer(const int& value); 484 template <> void MultiType::createNewValueContainer(const unsigned int& value); 485 template <> void MultiType::createNewValueContainer(const long& value); 486 template <> void MultiType::createNewValueContainer(const unsigned long& value); 487 template <> void MultiType::createNewValueContainer(const long long& value); 488 template <> void MultiType::createNewValueContainer(const unsigned long long& value); 489 template <> void MultiType::createNewValueContainer(const float& value); 490 template <> void MultiType::createNewValueContainer(const double& value); 491 template <> void MultiType::createNewValueContainer(const bool& value); 492 template <> void MultiType::createNewValueContainer(const long double& value); 493 template <> void MultiType::createNewValueContainer( void* const& value); 494 template <> void MultiType::createNewValueContainer(const std::string& value); 495 template <> void MultiType::createNewValueContainer(const orxonox::Vector2& value); 496 template <> void MultiType::createNewValueContainer(const orxonox::Vector3& value); 497 template <> void MultiType::createNewValueContainer(const orxonox::Vector4& value); 498 template <> void MultiType::createNewValueContainer(const orxonox::ColourValue& value); 499 template <> void MultiType::createNewValueContainer(const orxonox::Quaternion& value); 500 template <> void MultiType::createNewValueContainer(const orxonox::Radian& value); 501 template <> void MultiType::createNewValueContainer(const orxonox::Degree& value); 502 503 inline bool MultiType::setValue(const char& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 504 inline bool MultiType::setValue(const unsigned char& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 505 inline bool MultiType::setValue(const short& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 506 inline bool MultiType::setValue(const unsigned short& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 507 inline bool MultiType::setValue(const int& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 508 inline bool MultiType::setValue(const unsigned int& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 509 inline bool MultiType::setValue(const long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 510 inline bool MultiType::setValue(const unsigned long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 511 inline bool MultiType::setValue(const long long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 512 inline bool MultiType::setValue(const unsigned long long& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 513 inline bool MultiType::setValue(const float& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 514 inline bool MultiType::setValue(const double& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 515 inline bool MultiType::setValue(const long double& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 516 inline bool MultiType::setValue(const bool& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 517 inline bool MultiType::setValue( void* const& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 518 inline bool MultiType::setValue(const std::string& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 519 inline bool MultiType::setValue(const orxonox::Vector2& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 520 inline bool MultiType::setValue(const orxonox::Vector3& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 521 inline bool MultiType::setValue(const orxonox::Vector4& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 522 inline bool MultiType::setValue(const orxonox::ColourValue& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 523 inline bool MultiType::setValue(const orxonox::Quaternion& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 524 inline bool MultiType::setValue(const orxonox::Radian& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 525 inline bool MultiType::setValue(const orxonox::Degree& value) { if (this->value_) { return this->value_->setValue(value); } else { return this->assignValue(value); } } /** @brief Assigns the given value and converts it to the current type. */ 526 527 inline bool MultiType::setValue(const char* value) { if (this->value_) { return this->value_->setValue(std::string(value)); } else { return this->assignValue(std::string(value)); } } /** @brief Assigns the given value and converts it to the current type. */ 528 } 524 529 525 530 #endif /* _MultiType_H__ */ -
code/branches/objecthierarchy/src/util/MultiTypeValue.h
r2016 r2111 41 41 #include "MultiType.h" 42 42 43 /** 44 @brief The MT_Value<T> class is used to hold a value of type T within a MultiType. 45 */ 46 template <typename T> 47 struct MT_Value : public MultiType::MT_ValueBase 43 namespace orxonox 48 44 { 49 /** @brief Constructor: Assigns the value and the type identifier. */ 50 MT_Value(const T& value, MT_Type type) : MT_ValueBase(type), value_(value) {} 45 /** 46 @brief The MT_Value<T> class is used to hold a value of type T within a MultiType. 47 */ 48 template <typename T> 49 class MT_Value : public MultiType::MT_ValueBase 50 { 51 public: 52 /** @brief Constructor: Assigns the value and the type identifier. */ 53 MT_Value(const T& value, MT_Type type) : MT_ValueBase(type), value_(value) {} 51 54 52 /** @brief Creates a copy of itself. */53 inline MT_ValueBase* clone() const { return new MT_Value<T>(this->value_, this->type_); }55 /** @brief Creates a copy of itself. */ 56 inline MT_ValueBase* clone() const { return new MT_Value<T>(this->value_, this->type_); } 54 57 55 /** @brief Resets the current value to the default. */56 inline void reset() { this->value_ = zeroise<T>(); bHasDefaultValue_ = true; }58 /** @brief Resets the current value to the default. */ 59 inline void reset() { this->value_ = zeroise<T>(); bHasDefaultValue_ = true; } 57 60 58 /** @brief Assigns the value of the other MultiType, converted to T. @param other The other MultiType */ 59 inline bool assimilate(const MultiType& other) 60 { 61 if (other.value_) 61 /** @brief Assigns the value of the other MultiType, converted to T. @param other The other MultiType */ 62 inline bool assimilate(const MultiType& other) 62 63 { 63 return !(bHasDefaultValue_ = !other.value_->getValue(&value_)); 64 if (other.value_) 65 { 66 return !(bHasDefaultValue_ = !other.value_->getValue(&value_)); 67 } 68 else 69 { 70 this->value_ = zeroise<T>(); 71 return !(bHasDefaultValue_ = true); 72 } 64 73 } 65 else66 {67 this->value_ = zeroise<T>();68 return !(bHasDefaultValue_ = true);69 }70 }71 74 72 inline bool getValue(char* value) const { return ConvertValue<T, char >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */73 inline bool getValue(unsigned char* value) const { return ConvertValue<T, unsigned char >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */74 inline bool getValue(short* value) const { return ConvertValue<T, short >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */75 inline bool getValue(unsigned short* value) const { return ConvertValue<T, unsigned short >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */76 inline bool getValue(int* value) const { return ConvertValue<T, int >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */77 inline bool getValue(unsigned int* value) const { return ConvertValue<T, unsigned int >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */78 inline bool getValue(long* value) const { return ConvertValue<T, long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */79 inline bool getValue(unsigned long* value) const { return ConvertValue<T, unsigned long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */80 inline bool getValue(long long* value) const { return ConvertValue<T, long long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */81 inline bool getValue(unsigned long long* value) const { return ConvertValue<T, unsigned long long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */82 inline bool getValue(float* value) const { return ConvertValue<T, float >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */83 inline bool getValue(double* value) const { return ConvertValue<T, double >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */84 inline bool getValue(long double* value) const { return ConvertValue<T, long double >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */85 inline bool getValue(bool* value) const { return ConvertValue<T, bool >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */86 inline bool getValue(void** value) const { return ConvertValue<T, void* >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */87 inline bool getValue(std::string* value) const { return ConvertValue<T, std::string >(value, value_, zeroise<std::string> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */88 inline bool getValue(orxonox::Vector2* value) const { return ConvertValue<T, orxonox::Vector2 >(value, value_, zeroise<orxonox::Vector2> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */89 inline bool getValue(orxonox::Vector3* value) const { return ConvertValue<T, orxonox::Vector3 >(value, value_, zeroise<orxonox::Vector3> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */90 inline bool getValue(orxonox::Vector4* value) const { return ConvertValue<T, orxonox::Vector4 >(value, value_, zeroise<orxonox::Vector4> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */91 inline bool getValue(orxonox::ColourValue* value) const { return ConvertValue<T, orxonox::ColourValue>(value, value_, zeroise<orxonox::ColourValue>()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */92 inline bool getValue(orxonox::Quaternion* value) const { return ConvertValue<T, orxonox::Quaternion >(value, value_, zeroise<orxonox::Quaternion> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */93 inline bool getValue(orxonox::Radian* value) const { return ConvertValue<T, orxonox::Radian >(value, value_, zeroise<orxonox::Radian> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */94 inline bool getValue(orxonox::Degree* value) const { return ConvertValue<T, orxonox::Degree >(value, value_, zeroise<orxonox::Degree> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */75 inline bool getValue(char* value) const { return ConvertValue<T, char >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 76 inline bool getValue(unsigned char* value) const { return ConvertValue<T, unsigned char >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 77 inline bool getValue(short* value) const { return ConvertValue<T, short >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 78 inline bool getValue(unsigned short* value) const { return ConvertValue<T, unsigned short >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 79 inline bool getValue(int* value) const { return ConvertValue<T, int >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 80 inline bool getValue(unsigned int* value) const { return ConvertValue<T, unsigned int >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 81 inline bool getValue(long* value) const { return ConvertValue<T, long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 82 inline bool getValue(unsigned long* value) const { return ConvertValue<T, unsigned long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 83 inline bool getValue(long long* value) const { return ConvertValue<T, long long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 84 inline bool getValue(unsigned long long* value) const { return ConvertValue<T, unsigned long long >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 85 inline bool getValue(float* value) const { return ConvertValue<T, float >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 86 inline bool getValue(double* value) const { return ConvertValue<T, double >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 87 inline bool getValue(long double* value) const { return ConvertValue<T, long double >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 88 inline bool getValue(bool* value) const { return ConvertValue<T, bool >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 89 inline bool getValue(void** value) const { return ConvertValue<T, void* >(value, value_, 0); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 90 inline bool getValue(std::string* value) const { return ConvertValue<T, std::string >(value, value_, zeroise<std::string> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 91 inline bool getValue(orxonox::Vector2* value) const { return ConvertValue<T, orxonox::Vector2 >(value, value_, zeroise<orxonox::Vector2> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 92 inline bool getValue(orxonox::Vector3* value) const { return ConvertValue<T, orxonox::Vector3 >(value, value_, zeroise<orxonox::Vector3> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 93 inline bool getValue(orxonox::Vector4* value) const { return ConvertValue<T, orxonox::Vector4 >(value, value_, zeroise<orxonox::Vector4> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 94 inline bool getValue(orxonox::ColourValue* value) const { return ConvertValue<T, orxonox::ColourValue>(value, value_, zeroise<orxonox::ColourValue>()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 95 inline bool getValue(orxonox::Quaternion* value) const { return ConvertValue<T, orxonox::Quaternion >(value, value_, zeroise<orxonox::Quaternion> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 96 inline bool getValue(orxonox::Radian* value) const { return ConvertValue<T, orxonox::Radian >(value, value_, zeroise<orxonox::Radian> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 97 inline bool getValue(orxonox::Degree* value) const { return ConvertValue<T, orxonox::Degree >(value, value_, zeroise<orxonox::Degree> ()); } /** @brief Assigns the value to the given pointer. The value gets converted if the types don't match. */ 95 98 96 inline bool setValue(const char& value) { return !(bHasDefaultValue_ = !ConvertValue<char , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */97 inline bool setValue(const unsigned char& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned char , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */98 inline bool setValue(const short& value) { return !(bHasDefaultValue_ = !ConvertValue<short , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */99 inline bool setValue(const unsigned short& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned short , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */100 inline bool setValue(const int& value) { return !(bHasDefaultValue_ = !ConvertValue<int , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */101 inline bool setValue(const unsigned int& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned int , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */102 inline bool setValue(const long& value) { return !(bHasDefaultValue_ = !ConvertValue<long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */103 inline bool setValue(const unsigned long& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */104 inline bool setValue(const long long& value) { return !(bHasDefaultValue_ = !ConvertValue<long long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */105 inline bool setValue(const unsigned long long& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned long long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */106 inline bool setValue(const float& value) { return !(bHasDefaultValue_ = !ConvertValue<float , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */107 inline bool setValue(const double& value) { return !(bHasDefaultValue_ = !ConvertValue<double , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */108 inline bool setValue(const long double& value) { return !(bHasDefaultValue_ = !ConvertValue<long double , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */109 inline bool setValue(const bool& value) { return !(bHasDefaultValue_ = !ConvertValue<bool , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */110 inline bool setValue( void* const& value) { return !(bHasDefaultValue_ = !ConvertValue<void* , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */111 inline bool setValue(const std::string& value) { return !(bHasDefaultValue_ = !ConvertValue<std::string , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */112 inline bool setValue(const orxonox::Vector2& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector2 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */113 inline bool setValue(const orxonox::Vector3& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector3 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */114 inline bool setValue(const orxonox::Vector4& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector4 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */115 inline bool setValue(const orxonox::ColourValue& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::ColourValue, T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */116 inline bool setValue(const orxonox::Quaternion& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Quaternion , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */117 inline bool setValue(const orxonox::Radian& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Radian , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */118 inline bool setValue(const orxonox::Degree& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Degree , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */99 inline bool setValue(const char& value) { return !(bHasDefaultValue_ = !ConvertValue<char , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 100 inline bool setValue(const unsigned char& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned char , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 101 inline bool setValue(const short& value) { return !(bHasDefaultValue_ = !ConvertValue<short , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 102 inline bool setValue(const unsigned short& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned short , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 103 inline bool setValue(const int& value) { return !(bHasDefaultValue_ = !ConvertValue<int , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 104 inline bool setValue(const unsigned int& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned int , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 105 inline bool setValue(const long& value) { return !(bHasDefaultValue_ = !ConvertValue<long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 106 inline bool setValue(const unsigned long& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 107 inline bool setValue(const long long& value) { return !(bHasDefaultValue_ = !ConvertValue<long long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 108 inline bool setValue(const unsigned long long& value) { return !(bHasDefaultValue_ = !ConvertValue<unsigned long long , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 109 inline bool setValue(const float& value) { return !(bHasDefaultValue_ = !ConvertValue<float , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 110 inline bool setValue(const double& value) { return !(bHasDefaultValue_ = !ConvertValue<double , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 111 inline bool setValue(const long double& value) { return !(bHasDefaultValue_ = !ConvertValue<long double , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 112 inline bool setValue(const bool& value) { return !(bHasDefaultValue_ = !ConvertValue<bool , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 113 inline bool setValue( void* const& value) { return !(bHasDefaultValue_ = !ConvertValue<void* , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 114 inline bool setValue(const std::string& value) { return !(bHasDefaultValue_ = !ConvertValue<std::string , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 115 inline bool setValue(const orxonox::Vector2& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector2 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 116 inline bool setValue(const orxonox::Vector3& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector3 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 117 inline bool setValue(const orxonox::Vector4& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Vector4 , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 118 inline bool setValue(const orxonox::ColourValue& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::ColourValue, T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 119 inline bool setValue(const orxonox::Quaternion& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Quaternion , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 120 inline bool setValue(const orxonox::Radian& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Radian , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 121 inline bool setValue(const orxonox::Degree& value) { return !(bHasDefaultValue_ = !ConvertValue<orxonox::Degree , T>(&value_, value, zeroise<T>())); } /** @brief Assigns the value by converting it to T. */ 119 122 120 inline operator char() const { return getConvertedValue<T, char> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */121 inline operator unsigned char() const { return getConvertedValue<T, unsigned char> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */122 inline operator short() const { return getConvertedValue<T, short> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */123 inline operator unsigned short() const { return getConvertedValue<T, unsigned short> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */124 inline operator int() const { return getConvertedValue<T, int> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */125 inline operator unsigned int() const { return getConvertedValue<T, unsigned int> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */126 inline operator long() const { return getConvertedValue<T, long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */127 inline operator unsigned long() const { return getConvertedValue<T, unsigned long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */128 inline operator long long() const { return getConvertedValue<T, long long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */129 inline operator unsigned long long() const { return getConvertedValue<T, unsigned long long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */130 inline operator float() const { return getConvertedValue<T, float> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */131 inline operator double() const { return getConvertedValue<T, double> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */132 inline operator long double() const { return getConvertedValue<T, long double> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */133 inline operator bool() const { return getConvertedValue<T, bool> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */134 inline operator void*() const { return getConvertedValue<T, void*> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */135 inline operator std::string() const { return getConvertedValue<T, std::string> (this->value_, zeroise<std::string >()); } /** @brief Returns the current value, converted to the requested type. */136 inline operator orxonox::Vector2() const { return getConvertedValue<T, orxonox::Vector2> (this->value_, zeroise<orxonox::Vector2 >()); } /** @brief Returns the current value, converted to the requested type. */137 inline operator orxonox::Vector3() const { return getConvertedValue<T, orxonox::Vector3> (this->value_, zeroise<orxonox::Vector3 >()); } /** @brief Returns the current value, converted to the requested type. */138 inline operator orxonox::Vector4() const { return getConvertedValue<T, orxonox::Vector4> (this->value_, zeroise<orxonox::Vector4 >()); } /** @brief Returns the current value, converted to the requested type. */139 inline operator orxonox::ColourValue() const { return getConvertedValue<T, orxonox::ColourValue>(this->value_, zeroise<orxonox::ColourValue>()); } /** @brief Returns the current value, converted to the requested type. */140 inline operator orxonox::Quaternion() const { return getConvertedValue<T, orxonox::Quaternion> (this->value_, zeroise<orxonox::Quaternion >()); } /** @brief Returns the current value, converted to the requested type. */141 inline operator orxonox::Radian() const { return getConvertedValue<T, orxonox::Radian> (this->value_, zeroise<orxonox::Radian >()); } /** @brief Returns the current value, converted to the requested type. */142 inline operator orxonox::Degree() const { return getConvertedValue<T, orxonox::Degree> (this->value_, zeroise<orxonox::Degree >()); } /** @brief Returns the current value, converted to the requested type. */123 inline operator char() const { return getConvertedValue<T, char> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 124 inline operator unsigned char() const { return getConvertedValue<T, unsigned char> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 125 inline operator short() const { return getConvertedValue<T, short> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 126 inline operator unsigned short() const { return getConvertedValue<T, unsigned short> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 127 inline operator int() const { return getConvertedValue<T, int> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 128 inline operator unsigned int() const { return getConvertedValue<T, unsigned int> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 129 inline operator long() const { return getConvertedValue<T, long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 130 inline operator unsigned long() const { return getConvertedValue<T, unsigned long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 131 inline operator long long() const { return getConvertedValue<T, long long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 132 inline operator unsigned long long() const { return getConvertedValue<T, unsigned long long> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 133 inline operator float() const { return getConvertedValue<T, float> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 134 inline operator double() const { return getConvertedValue<T, double> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 135 inline operator long double() const { return getConvertedValue<T, long double> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 136 inline operator bool() const { return getConvertedValue<T, bool> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 137 inline operator void*() const { return getConvertedValue<T, void*> (this->value_, 0); } /** @brief Returns the current value, converted to the requested type. */ 138 inline operator std::string() const { return getConvertedValue<T, std::string> (this->value_, zeroise<std::string >()); } /** @brief Returns the current value, converted to the requested type. */ 139 inline operator orxonox::Vector2() const { return getConvertedValue<T, orxonox::Vector2> (this->value_, zeroise<orxonox::Vector2 >()); } /** @brief Returns the current value, converted to the requested type. */ 140 inline operator orxonox::Vector3() const { return getConvertedValue<T, orxonox::Vector3> (this->value_, zeroise<orxonox::Vector3 >()); } /** @brief Returns the current value, converted to the requested type. */ 141 inline operator orxonox::Vector4() const { return getConvertedValue<T, orxonox::Vector4> (this->value_, zeroise<orxonox::Vector4 >()); } /** @brief Returns the current value, converted to the requested type. */ 142 inline operator orxonox::ColourValue() const { return getConvertedValue<T, orxonox::ColourValue>(this->value_, zeroise<orxonox::ColourValue>()); } /** @brief Returns the current value, converted to the requested type. */ 143 inline operator orxonox::Quaternion() const { return getConvertedValue<T, orxonox::Quaternion> (this->value_, zeroise<orxonox::Quaternion >()); } /** @brief Returns the current value, converted to the requested type. */ 144 inline operator orxonox::Radian() const { return getConvertedValue<T, orxonox::Radian> (this->value_, zeroise<orxonox::Radian >()); } /** @brief Returns the current value, converted to the requested type. */ 145 inline operator orxonox::Degree() const { return getConvertedValue<T, orxonox::Degree> (this->value_, zeroise<orxonox::Degree >()); } /** @brief Returns the current value, converted to the requested type. */ 143 146 144 /** @brief Puts the current value on the stream */145 inline void toString(std::ostream& outstream) const { outstream << this->value_; }147 /** @brief Puts the current value on the stream */ 148 inline void toString(std::ostream& outstream) const { outstream << this->value_; } 146 149 147 T value_; //!< The stored value 148 }; 150 T value_; //!< The stored value 151 }; 152 } 149 153 150 154 #endif /* _MultiTypeValue_H__ */ -
code/branches/objecthierarchy/src/util/OutputBuffer.h
r1854 r2111 58 58 an OutputBuffer and this buffer changes. 59 59 */ 60 class _UtilExportOutputBufferListener60 class OutputBufferListener 61 61 { 62 62 friend class OutputBuffer; -
code/branches/objecthierarchy/src/util/SignalHandler.cc
r2101 r2111 40 40 #include <cstring> 41 41 42 SignalHandler * SignalHandler::singletonRef = NULL; 42 namespace orxonox 43 { 44 SignalHandler * SignalHandler::singletonRef = NULL; 45 } 43 46 44 47 #if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32 … … 49 52 #include <X11/keysym.h> 50 53 51 bool SignalHandler::bXAutoKeyRepeatOn_ = false; 52 53 SignalHandler::SignalHandler() 54 namespace orxonox 54 55 { 56 bool SignalHandler::bXAutoKeyRepeatOn_ = false; 57 58 SignalHandler::SignalHandler() 59 { 60 } 61 62 /** 63 * register signal handlers for SIGSEGV and SIGABRT 64 * @param appName path to executable eg argv[0] 65 * @param filename filename to append backtrace to 66 */ 67 void SignalHandler::doCatch( const std::string & appName, const std::string & filename ) 68 { 69 this->appName = appName; 70 this->filename = filename; 71 72 // prepare for restoring XAutoKeyRepeat 73 Display* display; 74 if ((display = XOpenDisplay(0))) 75 { 76 XKeyboardState oldState; 77 XGetKeyboardControl(display, &oldState); 78 if (oldState.global_auto_repeat == AutoRepeatModeOn) 79 bXAutoKeyRepeatOn_ = true; 80 else 81 bXAutoKeyRepeatOn_ = false; 82 XCloseDisplay(display); 83 } 84 else 85 { 86 std::cout << "Warning: couldn't open X display to restore XAutoKeyRepeat." << std::endl; 87 bXAutoKeyRepeatOn_ = false; 88 } 89 90 91 // make sure doCatch is only called once without calling dontCatch 92 assert( sigRecList.size() == 0 ); 93 94 catchSignal( SIGSEGV ); 95 catchSignal( SIGABRT ); 96 catchSignal( SIGILL ); 97 } 98 99 /** 100 * restore previous signal handlers 101 */ 102 void SignalHandler::dontCatch() 103 { 104 for ( SignalRecList::iterator it = sigRecList.begin(); it != sigRecList.end(); it++ ) 105 { 106 signal( it->signal, it->handler ); 107 } 108 109 sigRecList.clear(); 110 } 111 112 /** 113 * catch signal sig 114 * @param sig signal to catch 115 */ 116 void SignalHandler::catchSignal( int sig ) 117 { 118 sig_t handler = signal( sig, SignalHandler::sigHandler ); 119 120 assert( handler != SIG_ERR ); 121 122 SignalRec rec; 123 rec.signal = sig; 124 rec.handler = handler; 125 126 sigRecList.push_front( rec ); 127 } 128 129 /** 130 * sigHandler is called when receiving signals 131 * @param sig 132 */ 133 void SignalHandler::sigHandler( int sig ) 134 { 135 for ( SignalCallbackList::iterator it = SignalHandler::getInstance()->callbackList.begin(); it != SignalHandler::getInstance()->callbackList.end(); it++ ) 136 { 137 (*(it->cb))( it->someData ); 138 } 139 140 std::string sigName = "UNKNOWN"; 141 142 switch ( sig ) 143 { 144 case SIGSEGV: 145 sigName = "SIGSEGV"; 146 break; 147 case SIGABRT: 148 sigName = "SIGABRT"; 149 break; 150 case SIGILL: 151 sigName = "SIGILL"; 152 break; 153 } 154 155 if (bXAutoKeyRepeatOn_) 156 { 157 std::cout << "Trying to restore XAutoKeyRepeat" << std::endl; 158 Display* display; 159 if ((display = XOpenDisplay(0))) 160 { 161 XAutoRepeatOn(display); 162 XCloseDisplay(display); 163 } 164 } 165 166 COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox.log" << std::endl; 167 168 int sigPipe[2]; 169 if ( pipe(sigPipe) == -1 ) 170 { 171 perror("pipe failed!\n"); 172 exit(EXIT_FAILURE); 173 } 174 175 int sigPid = fork(); 176 177 if ( sigPid == -1 ) 178 { 179 perror("fork failed!\n"); 180 exit(EXIT_FAILURE); 181 } 182 183 // gdb will be attached to this process 184 if ( sigPid == 0 ) 185 { 186 getInstance()->dontCatch(); 187 // wait for message from parent when it has attached gdb 188 int someData; 189 190 read( sigPipe[0], &someData, sizeof(someData) ); 191 192 if ( someData != 0x12345678 ) 193 { 194 COUT(0) << "something went wrong :(" << std::endl; 195 } 196 197 return; 198 } 199 200 int gdbIn[2]; 201 int gdbOut[2]; 202 int gdbErr[2]; 203 204 if ( pipe(gdbIn) == -1 || pipe(gdbOut) == -1 || pipe(gdbErr) == -1 ) 205 { 206 perror("pipe failed!\n"); 207 kill( sigPid, SIGTERM ); 208 waitpid( sigPid, NULL, 0 ); 209 exit(EXIT_FAILURE); 210 } 211 212 int gdbPid = fork(); 213 // this process will run gdb 214 215 if ( gdbPid == -1 ) 216 { 217 perror("fork failed\n"); 218 kill( sigPid, SIGTERM ); 219 waitpid( sigPid, NULL, 0 ); 220 exit(EXIT_FAILURE); 221 } 222 223 if ( gdbPid == 0 ) 224 { 225 // start gdb 226 227 close(gdbIn[1]); 228 close(gdbOut[0]); 229 close(gdbErr[0]); 230 231 dup2( gdbIn[0], STDIN_FILENO ); 232 dup2( gdbOut[1], STDOUT_FILENO ); 233 dup2( gdbErr[1], STDERR_FILENO ); 234 235 execlp( "sh", "sh", "-c", "gdb", (void*)NULL); 236 } 237 238 char cmd[256]; 239 snprintf( cmd, 256, "file %s\nattach %d\nc\n", getInstance()->appName.c_str(), sigPid ); 240 write( gdbIn[1], cmd, strlen(cmd) ); 241 242 int charsFound = 0; 243 int promptFound = 0; 244 char byte; 245 while ( read( gdbOut[0], &byte, 1 ) == 1 ) 246 { 247 if ( 248 charsFound == 0 && byte == '(' || 249 charsFound == 1 && byte == 'g' || 250 charsFound == 2 && byte == 'd' || 251 charsFound == 3 && byte == 'b' || 252 charsFound == 4 && byte == ')' || 253 charsFound == 5 && byte == ' ' 254 ) 255 charsFound++; 256 else 257 charsFound = 0; 258 259 if ( charsFound == 6 ) 260 { 261 promptFound++; 262 charsFound = 0; 263 } 264 265 if ( promptFound == 3 ) 266 { 267 break; 268 } 269 } 270 271 int someData = 0x12345678; 272 write( sigPipe[1], &someData, sizeof(someData) ); 273 274 write( gdbIn[1], "bt\nk\nq\n", 7 ); 275 276 277 charsFound = 0; 278 promptFound = 0; 279 std::string bt; 280 while ( read( gdbOut[0], &byte, 1 ) == 1 ) 281 { 282 bt += std::string( &byte, 1 ); 283 284 if ( 285 charsFound == 0 && byte == '(' || 286 charsFound == 1 && byte == 'g' || 287 charsFound == 2 && byte == 'd' || 288 charsFound == 3 && byte == 'b' || 289 charsFound == 4 && byte == ')' || 290 charsFound == 5 && byte == ' ' 291 ) 292 charsFound++; 293 else 294 charsFound = 0; 295 296 if ( charsFound == 6 ) 297 { 298 promptFound++; 299 charsFound = 0; 300 bt += "\n"; 301 } 302 303 if ( promptFound == 3 ) 304 { 305 break; 306 } 307 } 308 309 310 waitpid( sigPid, NULL, 0 ); 311 waitpid( gdbPid, NULL, 0 ); 312 313 int wsRemoved = 0; 314 315 while ( wsRemoved < 2 && bt.length() > 0 ) 316 { 317 if ( bt[1] == '\n' ) 318 wsRemoved++; 319 bt.erase(0, 1); 320 } 321 322 if ( bt.length() > 0 ) 323 bt.erase(0, 1); 324 325 time_t now = time(NULL); 326 327 std::string timeString = "\n\n\n\n" 328 "=======================================================\n" 329 "= time: " + std::string(ctime(&now)) + 330 "=======================================================\n"; 331 bt.insert(0, timeString); 332 333 FILE * f = fopen( getInstance()->filename.c_str(), "a" ); 334 335 if ( !f ) 336 { 337 perror( ( std::string( "could not append to " ) + getInstance()->filename ).c_str() ); 338 exit(EXIT_FAILURE); 339 } 340 341 if ( fwrite( bt.c_str(), 1, bt.length(), f ) != bt.length() ) 342 { 343 COUT(0) << "could not write " << bt.length() << " byte to " << getInstance()->filename << std::endl; 344 exit(EXIT_FAILURE); 345 } 346 347 exit(EXIT_FAILURE); 348 } 349 350 void SignalHandler::registerCallback( SignalCallback cb, void * someData ) 351 { 352 SignalCallbackRec rec; 353 rec.cb = cb; 354 rec.someData = someData; 355 356 callbackList.push_back(rec); 357 } 55 358 } 56 359 57 /**58 * register signal handlers for SIGSEGV and SIGABRT59 * @param appName path to executable eg argv[0]60 * @param filename filename to append backtrace to61 */62 void SignalHandler::doCatch( const std::string & appName, const std::string & filename )63 {64 this->appName = appName;65 this->filename = filename;66 67 // prepare for restoring XAutoKeyRepeat68 Display* display;69 if ((display = XOpenDisplay(0)))70 {71 XKeyboardState oldState;72 XGetKeyboardControl(display, &oldState);73 if (oldState.global_auto_repeat == AutoRepeatModeOn)74 bXAutoKeyRepeatOn_ = true;75 else76 bXAutoKeyRepeatOn_ = false;77 XCloseDisplay(display);78 }79 else80 {81 std::cout << "Warning: couldn't open X display to restore XAutoKeyRepeat." << std::endl;82 bXAutoKeyRepeatOn_ = false;83 }84 85 86 // make sure doCatch is only called once without calling dontCatch87 assert( sigRecList.size() == 0 );88 89 catchSignal( SIGSEGV );90 catchSignal( SIGABRT );91 catchSignal( SIGILL );92 }93 94 /**95 * restore previous signal handlers96 */97 void SignalHandler::dontCatch()98 {99 for ( SignalRecList::iterator it = sigRecList.begin(); it != sigRecList.end(); it++ )100 {101 signal( it->signal, it->handler );102 }103 104 sigRecList.clear();105 }106 107 /**108 * catch signal sig109 * @param sig signal to catch110 */111 void SignalHandler::catchSignal( int sig )112 {113 sig_t handler = signal( sig, SignalHandler::sigHandler );114 115 assert( handler != SIG_ERR );116 117 SignalRec rec;118 rec.signal = sig;119 rec.handler = handler;120 121 sigRecList.push_front( rec );122 }123 124 /**125 * sigHandler is called when receiving signals126 * @param sig127 */128 void SignalHandler::sigHandler( int sig )129 {130 for ( SignalCallbackList::iterator it = SignalHandler::getInstance()->callbackList.begin(); it != SignalHandler::getInstance()->callbackList.end(); it++ )131 {132 (*(it->cb))( it->someData );133 }134 135 std::string sigName = "UNKNOWN";136 137 switch ( sig )138 {139 case SIGSEGV:140 sigName = "SIGSEGV";141 break;142 case SIGABRT:143 sigName = "SIGABRT";144 break;145 case SIGILL:146 sigName = "SIGILL";147 break;148 }149 150 if (bXAutoKeyRepeatOn_)151 {152 std::cout << "Trying to restore XAutoKeyRepeat" << std::endl;153 Display* display;154 if ((display = XOpenDisplay(0)))155 {156 XAutoRepeatOn(display);157 XCloseDisplay(display);158 }159 }160 161 COUT(0) << "recieved signal " << sigName.c_str() << std::endl << "try to write backtrace to file orxonox.log" << std::endl;162 163 int sigPipe[2];164 if ( pipe(sigPipe) == -1 )165 {166 perror("pipe failed!\n");167 exit(EXIT_FAILURE);168 }169 170 int sigPid = fork();171 172 if ( sigPid == -1 )173 {174 perror("fork failed!\n");175 exit(EXIT_FAILURE);176 }177 178 // gdb will be attached to this process179 if ( sigPid == 0 )180 {181 getInstance()->dontCatch();182 // wait for message from parent when it has attached gdb183 int someData;184 185 read( sigPipe[0], &someData, sizeof(someData) );186 187 if ( someData != 0x12345678 )188 {189 COUT(0) << "something went wrong :(" << std::endl;190 }191 192 return;193 }194 195 int gdbIn[2];196 int gdbOut[2];197 int gdbErr[2];198 199 if ( pipe(gdbIn) == -1 || pipe(gdbOut) == -1 || pipe(gdbErr) == -1 )200 {201 perror("pipe failed!\n");202 kill( sigPid, SIGTERM );203 waitpid( sigPid, NULL, 0 );204 exit(EXIT_FAILURE);205 }206 207 int gdbPid = fork();208 // this process will run gdb209 210 if ( gdbPid == -1 )211 {212 perror("fork failed\n");213 kill( sigPid, SIGTERM );214 waitpid( sigPid, NULL, 0 );215 exit(EXIT_FAILURE);216 }217 218 if ( gdbPid == 0 )219 {220 // start gdb221 222 close(gdbIn[1]);223 close(gdbOut[0]);224 close(gdbErr[0]);225 226 dup2( gdbIn[0], STDIN_FILENO );227 dup2( gdbOut[1], STDOUT_FILENO );228 dup2( gdbErr[1], STDERR_FILENO );229 230 execlp( "sh", "sh", "-c", "gdb", (void*)NULL);231 }232 233 char cmd[256];234 snprintf( cmd, 256, "file %s\nattach %d\nc\n", getInstance()->appName.c_str(), sigPid );235 write( gdbIn[1], cmd, strlen(cmd) );236 237 int charsFound = 0;238 int promptFound = 0;239 char byte;240 while ( read( gdbOut[0], &byte, 1 ) == 1 )241 {242 if (243 charsFound == 0 && byte == '(' ||244 charsFound == 1 && byte == 'g' ||245 charsFound == 2 && byte == 'd' ||246 charsFound == 3 && byte == 'b' ||247 charsFound == 4 && byte == ')' ||248 charsFound == 5 && byte == ' '249 )250 charsFound++;251 else252 charsFound = 0;253 254 if ( charsFound == 6 )255 {256 promptFound++;257 charsFound = 0;258 }259 260 if ( promptFound == 3 )261 {262 break;263 }264 }265 266 int someData = 0x12345678;267 write( sigPipe[1], &someData, sizeof(someData) );268 269 write( gdbIn[1], "bt\nk\nq\n", 7 );270 271 272 charsFound = 0;273 promptFound = 0;274 std::string bt;275 while ( read( gdbOut[0], &byte, 1 ) == 1 )276 {277 bt += std::string( &byte, 1 );278 279 if (280 charsFound == 0 && byte == '(' ||281 charsFound == 1 && byte == 'g' ||282 charsFound == 2 && byte == 'd' ||283 charsFound == 3 && byte == 'b' ||284 charsFound == 4 && byte == ')' ||285 charsFound == 5 && byte == ' '286 )287 charsFound++;288 else289 charsFound = 0;290 291 if ( charsFound == 6 )292 {293 promptFound++;294 charsFound = 0;295 bt += "\n";296 }297 298 if ( promptFound == 3 )299 {300 break;301 }302 }303 304 305 waitpid( sigPid, NULL, 0 );306 waitpid( gdbPid, NULL, 0 );307 308 int wsRemoved = 0;309 310 while ( wsRemoved < 2 && bt.length() > 0 )311 {312 if ( bt[1] == '\n' )313 wsRemoved++;314 bt.erase(0, 1);315 }316 317 if ( bt.length() > 0 )318 bt.erase(0, 1);319 320 time_t now = time(NULL);321 322 std::string timeString = "\n\n\n\n"323 "=======================================================\n"324 "= time: " + std::string(ctime(&now)) +325 "=======================================================\n";326 bt.insert(0, timeString);327 328 FILE * f = fopen( getInstance()->filename.c_str(), "a" );329 330 if ( !f )331 {332 perror( ( std::string( "could not append to " ) + getInstance()->filename ).c_str() );333 exit(EXIT_FAILURE);334 }335 336 if ( fwrite( bt.c_str(), 1, bt.length(), f ) != bt.length() )337 {338 COUT(0) << "could not write " << bt.length() << " byte to " << getInstance()->filename << std::endl;339 exit(EXIT_FAILURE);340 }341 342 exit(EXIT_FAILURE);343 }344 345 void SignalHandler::registerCallback( SignalCallback cb, void * someData )346 {347 SignalCallbackRec rec;348 rec.cb = cb;349 rec.someData = someData;350 351 callbackList.push_back(rec);352 }353 354 360 #endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ -
code/branches/objecthierarchy/src/util/SignalHandler.h
r2101 r2111 40 40 #include <string> 41 41 42 typedef int (*SignalCallback)( void * someData ); 42 namespace orxonox 43 { 44 typedef int (*SignalCallback)( void * someData ); 45 } 43 46 44 47 #if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32 45 48 #include <signal.h> 46 49 47 struct SignalRec 50 namespace orxonox 48 51 { 49 int signal; 50 sig_t handler; 51 }; 52 struct SignalRec 53 { 54 int signal; 55 sig_t handler; 56 }; 52 57 53 struct SignalCallbackRec54 {55 SignalCallback cb;56 void * someData;57 };58 struct SignalCallbackRec 59 { 60 SignalCallback cb; 61 void * someData; 62 }; 58 63 59 64 60 typedef std::list<SignalRec> SignalRecList;61 typedef std::list<SignalCallbackRec> SignalCallbackList;65 typedef std::list<SignalRec> SignalRecList; 66 typedef std::list<SignalCallbackRec> SignalCallbackList; 62 67 63 class SignalHandler64 {65 private:66 SignalHandler();67 public:68 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }69 ~SignalHandler(){ SignalHandler::singletonRef = NULL; }68 class SignalHandler 69 { 70 private: 71 SignalHandler(); 72 public: 73 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; } 74 ~SignalHandler(){ SignalHandler::singletonRef = NULL; } 70 75 71 void registerCallback( SignalCallback cb, void * someData );76 void registerCallback( SignalCallback cb, void * someData ); 72 77 73 void doCatch( const std::string & appName, const std::string & filename );74 void dontCatch();78 void doCatch( const std::string & appName, const std::string & filename ); 79 void dontCatch(); 75 80 76 private:77 static void sigHandler( int sig );81 private: 82 static void sigHandler( int sig ); 78 83 79 void catchSignal( int sig );80 SignalRecList sigRecList;84 void catchSignal( int sig ); 85 SignalRecList sigRecList; 81 86 82 SignalCallbackList callbackList;87 SignalCallbackList callbackList; 83 88 84 static SignalHandler * singletonRef;89 static SignalHandler * singletonRef; 85 90 86 std::string appName;87 std::string filename;91 std::string appName; 92 std::string filename; 88 93 89 // used to turn on KeyAutoRepeat if OIS crashes 90 static bool bXAutoKeyRepeatOn_; 91 }; 94 // used to turn on KeyAutoRepeat if OIS crashes 95 static bool bXAutoKeyRepeatOn_; 96 }; 97 } 92 98 93 99 #else /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ 94 100 95 class _UtilExport SignalHandler 101 namespace orxonox 96 102 { 97 public: 98 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }; 99 void doCatch( const std::string & appName, const std::string & filename ) {}; 100 void dontCatch() {}; 101 void registerCallback( SignalCallback cb, void * someData ) {}; 103 class _UtilExport SignalHandler 104 { 105 public: 106 inline static SignalHandler* getInstance() { if (!SignalHandler::singletonRef) SignalHandler::singletonRef = new SignalHandler(); return SignalHandler::singletonRef; }; 107 void doCatch( const std::string & appName, const std::string & filename ) {}; 108 void dontCatch() {}; 109 void registerCallback( SignalCallback cb, void * someData ) {}; 102 110 103 private: 104 static SignalHandler * singletonRef; 105 }; 111 private: 112 static SignalHandler * singletonRef; 113 }; 114 } 106 115 107 116 #endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */ -
code/branches/objecthierarchy/src/util/Sleep.h
r1841 r2111 41 41 #include <winbase.h> 42 42 43 inline void usleep(DWORD dwMicroseconds) 43 namespace orxonox 44 44 { 45 Sleep(dwMicroseconds / 1000); 46 } 45 inline void usleep(DWORD dwMicroseconds) 46 { 47 Sleep(dwMicroseconds / 1000); 48 } 47 49 48 inline void msleep(DWORD dwMilliseconds)49 {50 Sleep(dwMilliseconds);51 }50 inline void msleep(DWORD dwMilliseconds) 51 { 52 Sleep(dwMilliseconds); 53 } 52 54 53 inline void sleep(DWORD dwSeconds) 54 { 55 Sleep(dwSeconds * 1000); 55 inline void sleep(DWORD dwSeconds) 56 { 57 Sleep(dwSeconds * 1000); 58 } 56 59 } 57 60 … … 60 63 #include <unistd.h> 61 64 62 inline void msleep(unsigned long msec) 65 namespace orxonox 63 66 { 64 usleep(msec * 1000); 67 inline void usleep(unsigned long usec) 68 { 69 usleep(usec); 70 } 71 inline void msleep(unsigned long msec) 72 { 73 usleep(msec * 1000); 74 } 75 inline void sleep(unsigned long sec) 76 { 77 usleep(sec * 1000000); 78 } 65 79 } 66 80 -
code/branches/objecthierarchy/src/util/String.cc
r2020 r2111 40 40 #include "Math.h" 41 41 42 std::string BLANKSTRING(""); 43 44 std::string getUniqueNumberString() 42 namespace orxonox 45 43 { 46 return convertToString(getUniqueNumber()); 44 std::string BLANKSTRING(""); 45 46 std::string getUniqueNumberString() 47 { 48 return convertToString(getUniqueNumber()); 49 } 50 51 /** 52 @brief Removes all whitespaces from a string. 53 @param str The string to strip 54 */ 55 void strip(std::string* str) 56 { 57 size_t pos; 58 while ((pos = (*str).find(" ")) < (*str).length()) 59 (*str).erase(pos, 1); 60 while ((pos = (*str).find("\t")) < (*str).length()) 61 (*str).erase(pos, 1); 62 while ((pos = (*str).find("\n")) < (*str).length()) 63 (*str).erase(pos, 1); 64 } 65 66 /** 67 @brief Returns a copy of a string without whitespaces. 68 @param str The string to strip 69 @return The stripped line 70 */ 71 std::string getStripped(const std::string& str) 72 { 73 std::string output = std::string(str); 74 strip(&output); 75 return output; 76 } 77 78 /** 79 @brief Returns a copy of a string without trailing whitespaces. 80 @param str The string 81 @return The modified copy 82 */ 83 std::string removeTrailingWhitespaces(const std::string& str) 84 { 85 size_t pos1 = 0; 86 int pos2 = str.size() - 1; 87 for (; pos1 < str.size() && (str[pos1] == ' ' || str[pos1] == '\t' || str[pos1] == '\n'); pos1++); 88 for (; pos2 > 0 && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--); 89 return str.substr(pos1, pos2 - pos1 + 1); 90 } 91 92 /** 93 @brief Returns the position of the next quote in the string, starting with start. 94 @param str The string 95 @param start The startposition 96 @return The position of the next quote (std::string::npos if there is no next quote) 97 */ 98 size_t getNextQuote(const std::string& str, size_t start) 99 { 100 size_t quote = start - 1; 101 102 while ((quote = str.find('\"', quote + 1)) != std::string::npos) 103 { 104 size_t backslash = quote; 105 size_t numbackslashes = 0; 106 for (; backslash > 0; backslash--, numbackslashes++) 107 if (str[backslash - 1] != '\\') 108 break; 109 110 if (numbackslashes % 2 == 0) 111 break; 112 } 113 114 return quote; 115 } 116 117 /** 118 @brief Returns true if pos is between two quotes. 119 @param str The string 120 @param pos The position to check 121 @return True if pos is between two quotes 122 */ 123 bool isBetweenQuotes(const std::string& str, size_t pos) 124 { 125 if (pos == std::string::npos) 126 return false; 127 128 size_t quotecount = 0; 129 size_t quote = (size_t)-1; 130 while ((quote = getNextQuote(str, quote + 1)) < pos) 131 { 132 if (quote == pos) 133 return false; 134 quotecount++; 135 } 136 137 if (quote == std::string::npos) 138 return false; 139 140 return ((quotecount % 2) == 1); 141 } 142 143 /** 144 @brief Returns true if the string contains something like '..."between quotes"...'. 145 @param The string 146 @return True if there is something between quotes 147 */ 148 bool hasStringBetweenQuotes(const std::string& str) 149 { 150 size_t pos1 = getNextQuote(str, 0); 151 size_t pos2 = getNextQuote(str, pos1 + 1); 152 return (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1); 153 } 154 155 /** 156 @brief If the string contains something like '..."between quotes"...' then 'between quotes' gets returned (without quotes). 157 @param The string 158 @param The string between the quotes 159 */ 160 std::string getStringBetweenQuotes(const std::string& str) 161 { 162 size_t pos1 = getNextQuote(str, 0); 163 size_t pos2 = getNextQuote(str, pos1 + 1); 164 if (pos1 != std::string::npos && pos2 != std::string::npos) 165 return str.substr(pos1, pos2 - pos1 + 1); 166 else 167 return ""; 168 } 169 170 /** 171 @brief Removes enclosing quotes if available (including whitespaces at the outside of the quotes). 172 @brief str The string to strip 173 @return The string with removed quotes 174 */ 175 std::string stripEnclosingQuotes(const std::string& str) 176 { 177 size_t start = std::string::npos; 178 size_t end = 0; 179 180 for (size_t pos = 0; (pos < str.size()) && (pos < std::string::npos); pos++) 181 { 182 if (str[pos] == '"') 183 { 184 start = pos; 185 break; 186 } 187 188 if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n')) 189 return str; 190 } 191 192 for (size_t pos = str.size() - 1; pos < std::string::npos; pos--) 193 { 194 if (str[pos] == '"') 195 { 196 end = pos; 197 break; 198 } 199 200 if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n')) 201 return str; 202 } 203 204 if ((start != std::string::npos) && (end != 0)) 205 return str.substr(start + 1, end - start - 1); 206 else 207 return str; 208 } 209 210 /** 211 @brief Removes enclosing {braces} (braces must be exactly on the beginning and the end of the string). 212 @param str The string to strip 213 @return The striped string 214 */ 215 std::string stripEnclosingBraces(const std::string& str) 216 { 217 std::string output = str; 218 219 while (output.size() >= 2 && output[0] == '{' && output[output.size() - 1] == '}') 220 output = output.substr(1, output.size() - 2); 221 222 return output; 223 } 224 225 /** 226 @brief Determines if a string is a comment (starts with a comment-symbol). 227 @param str The string to check 228 @return True = it's a comment 229 230 A comment is defined by a leading '#', '%', ';' or '//'. 231 */ 232 bool isComment(const std::string& str) 233 { 234 // Strip the line, whitespaces are disturbing 235 std::string teststring = getStripped(str); 236 237 // There are four possible comment-symbols: 238 // 1) #comment in script-language style 239 // 2) %comment in matlab style 240 // 3) ;comment in unreal tournament config-file style 241 // 4) //comment in code style 242 if (teststring.size() >= 2) 243 { 244 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[1] == '/')) 245 return true; 246 } 247 else if (teststring.size() == 1) 248 { 249 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';') 250 return true; 251 } 252 253 return false; 254 } 255 256 /** 257 @brief Determines if a string is empty (contains only whitespaces). 258 @param str The string to check 259 @return True = it's empty 260 */ 261 bool isEmpty(const std::string& str) 262 { 263 std::string temp = getStripped(str); 264 return ((temp == "") || (temp.size() == 0)); 265 } 266 267 /** 268 @brief Determines if a string contains only numbers and maximal one '.'. 269 @param str The string to check 270 @return True = it's a number 271 */ 272 bool isNumeric(const std::string& str) 273 { 274 bool foundPoint = false; 275 276 for (std::string::const_iterator it = str.begin(); it != str.end(); ++it) 277 { 278 if (((*it) < '0' || (*it) > '9')) 279 { 280 if ((*it) != '.' && !foundPoint) 281 foundPoint = true; 282 else 283 return false; 284 } 285 } 286 287 return true; 288 } 289 290 /** 291 @brief Adds backslashes to the given string which makes special chars visible. Existing slashes will be doubled. 292 @param str The string to manipulate 293 @return The string with added slashes 294 */ 295 std::string addSlashes(const std::string& str) 296 { 297 std::string output = str; 298 299 for (size_t pos = 0; (pos = output.find('\\', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\\"); } 300 for (size_t pos = 0; (pos = output.find('\n', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\n"); } 301 for (size_t pos = 0; (pos = output.find('\t', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\t"); } 302 for (size_t pos = 0; (pos = output.find('\v', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\v"); } 303 for (size_t pos = 0; (pos = output.find('\b', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\b"); } 304 for (size_t pos = 0; (pos = output.find('\r', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\r"); } 305 for (size_t pos = 0; (pos = output.find('\f', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\f"); } 306 for (size_t pos = 0; (pos = output.find('\a', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\a"); } 307 for (size_t pos = 0; (pos = output.find('"', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\""); } 308 for (size_t pos = 0; (pos = output.find('\0', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\0"); } 309 310 return output; 311 } 312 313 /** 314 @brief Removes backslashes from the given string. Double backslashes are interpreted as one backslash. 315 @param str The string to manipulate 316 @return The string with removed slashes 317 */ 318 std::string removeSlashes(const std::string& str) 319 { 320 if (str.size() <= 1) 321 return str; 322 323 std::string output = ""; 324 for (size_t pos = 0; pos < str.size() - 1; ) 325 { 326 if (str[pos] == '\\') 327 { 328 if (str[pos + 1] == '\\') { output += '\\'; pos += 2; continue; } 329 else if (str[pos + 1] == 'n') { output += '\n'; pos += 2; continue; } 330 else if (str[pos + 1] == 't') { output += '\t'; pos += 2; continue; } 331 else if (str[pos + 1] == 'v') { output += '\v'; pos += 2; continue; } 332 else if (str[pos + 1] == 'b') { output += '\b'; pos += 2; continue; } 333 else if (str[pos + 1] == 'r') { output += '\r'; pos += 2; continue; } 334 else if (str[pos + 1] == 'f') { output += '\f'; pos += 2; continue; } 335 else if (str[pos + 1] == 'a') { output += '\a'; pos += 2; continue; } 336 else if (str[pos + 1] == '"') { output += '"'; pos += 2; continue; } 337 else if (str[pos + 1] == '0') { output += '\0'; pos += 2; continue; } 338 } 339 output += str[pos]; 340 pos++; 341 if (pos == str.size() - 1) 342 output += str[pos]; 343 } 344 345 return output; 346 } 347 348 /** 349 @brief Replaces each char between A and Z with its lowercase equivalent. 350 @param str The string to convert 351 */ 352 void lowercase(std::string* str) 353 { 354 for (size_t i = 0; i < str->size(); ++i) 355 { 356 (*str)[i] = (char)tolower((*str)[i]); 357 } 358 } 359 360 /** 361 @brief Returns a copy of the given string without uppercase chars. 362 @param str The string 363 @return The copy 364 */ 365 std::string getLowercase(const std::string& str) 366 { 367 std::string output = std::string(str); 368 lowercase(&output); 369 return output; 370 } 371 372 /** 373 @brief Replaces each char between a and z with its uppercase equivalent. 374 @param str The string to convert 375 */ 376 void uppercase(std::string* str) 377 { 378 for (size_t i = 0; i < str->size(); ++i) 379 { 380 (*str)[i] = (char)toupper((*str)[i]); 381 } 382 } 383 384 /** 385 @brief Returns a copy of the given string without lowercase chars. 386 @param str The string 387 @return The copy 388 */ 389 std::string getUppercase(const std::string& str) 390 { 391 std::string output = std::string(str); 392 uppercase(&output); 393 return output; 394 } 395 396 /** 397 @brief Compares two strings ignoring different casing. 398 @param s1 First string 399 @param s2 Second string 400 */ 401 int nocaseCmp(const std::string& s1, const std::string& s2) 402 { 403 std::string::const_iterator it1=s1.begin(); 404 std::string::const_iterator it2=s2.begin(); 405 406 //stop when either string's end has been reached 407 while ( (it1!=s1.end()) && (it2!=s2.end()) ) 408 { 409 if(::toupper(*it1) != ::toupper(*it2)) //letters differ? 410 // return -1 to indicate smaller than, 1 otherwise 411 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1; 412 //proceed to the next character in each string 413 ++it1; 414 ++it2; 415 } 416 size_t size1=s1.size(), size2=s2.size();// cache lengths 417 //return -1,0 or 1 according to strings' lengths 418 if (size1==size2) 419 return 0; 420 return (size1<size2) ? -1 : 1; 421 } 422 423 424 /** 425 @brief Compares the first 'len' chars of two strings ignoring different casing. 426 @param s1 First string 427 @param s2 Second string 428 @param len Maximal number of chars to compare 429 */ 430 int nocaseCmp(const std::string& s1, const std::string& s2, size_t len) 431 { 432 if (len == 0) 433 return 0; 434 std::string::const_iterator it1=s1.begin(); 435 std::string::const_iterator it2=s2.begin(); 436 437 //stop when either string's end has been reached 438 while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0) 439 { 440 if(::toupper(*it1) != ::toupper(*it2)) //letters differ? 441 // return -1 to indicate smaller than, 1 otherwise 442 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1; 443 //proceed to the next character in each string 444 ++it1; 445 ++it2; 446 } 447 return 0; 448 } 449 450 /** 451 @brief Returns true if the string contains a comment, introduced by #, %, ; or //. 452 @param str The string 453 @return True if the string contains a comment 454 */ 455 bool hasComment(const std::string& str) 456 { 457 return (getCommentPosition(str) != std::string::npos); 458 } 459 460 /** 461 @brief If the string contains a comment, the comment gets returned (including the comment symbol), an empty string otherwise. 462 @param str The string 463 @return The comment 464 */ 465 std::string getComment(const std::string& str) 466 { 467 return str.substr(getCommentPosition(str)); 468 } 469 470 /** 471 @brief If the string contains a comment, the position of the comment-symbol gets returned, std::string::npos otherwise. 472 @param str The string 473 @return The position 474 */ 475 size_t getCommentPosition(const std::string& str) 476 { 477 return getNextCommentPosition(str, 0); 478 } 479 480 /** 481 @brief Returns the position of the next comment-symbol, starting with start. 482 @param str The string 483 @param start The startposition 484 @return The position 485 */ 486 size_t getNextCommentPosition(const std::string& str, size_t start) 487 { 488 for (size_t i = start; i < str.size(); i++) 489 if (isComment(str.substr(i))) 490 return i; 491 492 return std::string::npos; 493 } 47 494 } 48 49 /**50 @brief Removes all whitespaces from a string.51 @param str The string to strip52 */53 void strip(std::string* str)54 {55 size_t pos;56 while ((pos = (*str).find(" ")) < (*str).length())57 (*str).erase(pos, 1);58 while ((pos = (*str).find("\t")) < (*str).length())59 (*str).erase(pos, 1);60 while ((pos = (*str).find("\n")) < (*str).length())61 (*str).erase(pos, 1);62 }63 64 /**65 @brief Returns a copy of a string without whitespaces.66 @param str The string to strip67 @return The stripped line68 */69 std::string getStripped(const std::string& str)70 {71 std::string output = std::string(str);72 strip(&output);73 return output;74 }75 76 /**77 @brief Returns a copy of a string without trailing whitespaces.78 @param str The string79 @return The modified copy80 */81 std::string removeTrailingWhitespaces(const std::string& str)82 {83 size_t pos1 = 0;84 int pos2 = str.size() - 1;85 for (; pos1 < str.size() && (str[pos1] == ' ' || str[pos1] == '\t' || str[pos1] == '\n'); pos1++);86 for (; pos2 > 0 && (str[pos2] == ' ' || str[pos2] == '\t' || str[pos2] == '\n'); pos2--);87 return str.substr(pos1, pos2 - pos1 + 1);88 }89 90 /**91 @brief Returns the position of the next quote in the string, starting with start.92 @param str The string93 @param start The startposition94 @return The position of the next quote (std::string::npos if there is no next quote)95 */96 size_t getNextQuote(const std::string& str, size_t start)97 {98 size_t quote = start - 1;99 100 while ((quote = str.find('\"', quote + 1)) != std::string::npos)101 {102 size_t backslash = quote;103 size_t numbackslashes = 0;104 for (; backslash > 0; backslash--, numbackslashes++)105 if (str[backslash - 1] != '\\')106 break;107 108 if (numbackslashes % 2 == 0)109 break;110 }111 112 return quote;113 }114 115 /**116 @brief Returns true if pos is between two quotes.117 @param str The string118 @param pos The position to check119 @return True if pos is between two quotes120 */121 bool isBetweenQuotes(const std::string& str, size_t pos)122 {123 if (pos == std::string::npos)124 return false;125 126 size_t quotecount = 0;127 size_t quote = (size_t)-1;128 while ((quote = getNextQuote(str, quote + 1)) < pos)129 {130 if (quote == pos)131 return false;132 quotecount++;133 }134 135 if (quote == std::string::npos)136 return false;137 138 return ((quotecount % 2) == 1);139 }140 141 /**142 @brief Returns true if the string contains something like '..."between quotes"...'.143 @param The string144 @return True if there is something between quotes145 */146 bool hasStringBetweenQuotes(const std::string& str)147 {148 size_t pos1 = getNextQuote(str, 0);149 size_t pos2 = getNextQuote(str, pos1 + 1);150 return (pos1 != std::string::npos && pos2 != std::string::npos && pos2 > pos1 + 1);151 }152 153 /**154 @brief If the string contains something like '..."between quotes"...' then 'between quotes' gets returned (without quotes).155 @param The string156 @param The string between the quotes157 */158 std::string getStringBetweenQuotes(const std::string& str)159 {160 size_t pos1 = getNextQuote(str, 0);161 size_t pos2 = getNextQuote(str, pos1 + 1);162 if (pos1 != std::string::npos && pos2 != std::string::npos)163 return str.substr(pos1, pos2 - pos1 + 1);164 else165 return "";166 }167 168 /**169 @brief Removes enclosing quotes if available (including whitespaces at the outside of the quotes).170 @brief str The string to strip171 @return The string with removed quotes172 */173 std::string stripEnclosingQuotes(const std::string& str)174 {175 size_t start = std::string::npos;176 size_t end = 0;177 178 for (size_t pos = 0; (pos < str.size()) && (pos < std::string::npos); pos++)179 {180 if (str[pos] == '"')181 {182 start = pos;183 break;184 }185 186 if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))187 return str;188 }189 190 for (size_t pos = str.size() - 1; pos < std::string::npos; pos--)191 {192 if (str[pos] == '"')193 {194 end = pos;195 break;196 }197 198 if ((str[pos] != ' ') && (str[pos] != '\t') && (str[pos] != '\n'))199 return str;200 }201 202 if ((start != std::string::npos) && (end != 0))203 return str.substr(start + 1, end - start - 1);204 else205 return str;206 }207 208 /**209 @brief Removes enclosing {braces} (braces must be exactly on the beginning and the end of the string).210 @param str The string to strip211 @return The striped string212 */213 std::string stripEnclosingBraces(const std::string& str)214 {215 std::string output = str;216 217 while (output.size() >= 2 && output[0] == '{' && output[output.size() - 1] == '}')218 output = output.substr(1, output.size() - 2);219 220 return output;221 }222 223 /**224 @brief Determines if a string is a comment (starts with a comment-symbol).225 @param str The string to check226 @return True = it's a comment227 228 A comment is defined by a leading '#', '%', ';' or '//'.229 */230 bool isComment(const std::string& str)231 {232 // Strip the line, whitespaces are disturbing233 std::string teststring = getStripped(str);234 235 // There are four possible comment-symbols:236 // 1) #comment in script-language style237 // 2) %comment in matlab style238 // 3) ;comment in unreal tournament config-file style239 // 4) //comment in code style240 if (teststring.size() >= 2)241 {242 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';' || (teststring[0] == '/' && teststring[1] == '/'))243 return true;244 }245 else if (teststring.size() == 1)246 {247 if (teststring[0] == '#' || teststring[0] == '%' || teststring[0] == ';')248 return true;249 }250 251 return false;252 }253 254 /**255 @brief Determines if a string is empty (contains only whitespaces).256 @param str The string to check257 @return True = it's empty258 */259 bool isEmpty(const std::string& str)260 {261 std::string temp = getStripped(str);262 return ((temp == "") || (temp.size() == 0));263 }264 265 /**266 @brief Determines if a string contains only numbers and maximal one '.'.267 @param str The string to check268 @return True = it's a number269 */270 bool isNumeric(const std::string& str)271 {272 bool foundPoint = false;273 274 for (std::string::const_iterator it = str.begin(); it != str.end(); ++it)275 {276 if (((*it) < '0' || (*it) > '9'))277 {278 if ((*it) != '.' && !foundPoint)279 foundPoint = true;280 else281 return false;282 }283 }284 285 return true;286 }287 288 /**289 @brief Adds backslashes to the given string which makes special chars visible. Existing slashes will be doubled.290 @param str The string to manipulate291 @return The string with added slashes292 */293 std::string addSlashes(const std::string& str)294 {295 std::string output = str;296 297 for (size_t pos = 0; (pos = output.find('\\', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\\"); }298 for (size_t pos = 0; (pos = output.find('\n', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\n"); }299 for (size_t pos = 0; (pos = output.find('\t', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\t"); }300 for (size_t pos = 0; (pos = output.find('\v', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\v"); }301 for (size_t pos = 0; (pos = output.find('\b', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\b"); }302 for (size_t pos = 0; (pos = output.find('\r', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\r"); }303 for (size_t pos = 0; (pos = output.find('\f', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\f"); }304 for (size_t pos = 0; (pos = output.find('\a', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\a"); }305 for (size_t pos = 0; (pos = output.find('"', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\\""); }306 for (size_t pos = 0; (pos = output.find('\0', pos)) < std::string::npos; pos += 2) { output.replace(pos, 1, "\\0"); }307 308 return output;309 }310 311 /**312 @brief Removes backslashes from the given string. Double backslashes are interpreted as one backslash.313 @param str The string to manipulate314 @return The string with removed slashes315 */316 std::string removeSlashes(const std::string& str)317 {318 if (str.size() <= 1)319 return str;320 321 std::string output = "";322 for (size_t pos = 0; pos < str.size() - 1; )323 {324 if (str[pos] == '\\')325 {326 if (str[pos + 1] == '\\') { output += '\\'; pos += 2; continue; }327 else if (str[pos + 1] == 'n') { output += '\n'; pos += 2; continue; }328 else if (str[pos + 1] == 't') { output += '\t'; pos += 2; continue; }329 else if (str[pos + 1] == 'v') { output += '\v'; pos += 2; continue; }330 else if (str[pos + 1] == 'b') { output += '\b'; pos += 2; continue; }331 else if (str[pos + 1] == 'r') { output += '\r'; pos += 2; continue; }332 else if (str[pos + 1] == 'f') { output += '\f'; pos += 2; continue; }333 else if (str[pos + 1] == 'a') { output += '\a'; pos += 2; continue; }334 else if (str[pos + 1] == '"') { output += '"'; pos += 2; continue; }335 else if (str[pos + 1] == '0') { output += '\0'; pos += 2; continue; }336 }337 output += str[pos];338 pos++;339 if (pos == str.size() - 1)340 output += str[pos];341 }342 343 return output;344 }345 346 /**347 @brief Replaces each char between A and Z with its lowercase equivalent.348 @param str The string to convert349 */350 void lowercase(std::string* str)351 {352 for (size_t i = 0; i < str->size(); ++i)353 {354 (*str)[i] = (char)tolower((*str)[i]);355 }356 }357 358 /**359 @brief Returns a copy of the given string without uppercase chars.360 @param str The string361 @return The copy362 */363 std::string getLowercase(const std::string& str)364 {365 std::string output = std::string(str);366 lowercase(&output);367 return output;368 }369 370 /**371 @brief Replaces each char between a and z with its uppercase equivalent.372 @param str The string to convert373 */374 void uppercase(std::string* str)375 {376 for (size_t i = 0; i < str->size(); ++i)377 {378 (*str)[i] = (char)toupper((*str)[i]);379 }380 }381 382 /**383 @brief Returns a copy of the given string without lowercase chars.384 @param str The string385 @return The copy386 */387 std::string getUppercase(const std::string& str)388 {389 std::string output = std::string(str);390 uppercase(&output);391 return output;392 }393 394 /**395 @brief Compares two strings ignoring different casing.396 @param s1 First string397 @param s2 Second string398 */399 int nocaseCmp(const std::string& s1, const std::string& s2)400 {401 std::string::const_iterator it1=s1.begin();402 std::string::const_iterator it2=s2.begin();403 404 //stop when either string's end has been reached405 while ( (it1!=s1.end()) && (it2!=s2.end()) )406 {407 if(::toupper(*it1) != ::toupper(*it2)) //letters differ?408 // return -1 to indicate smaller than, 1 otherwise409 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;410 //proceed to the next character in each string411 ++it1;412 ++it2;413 }414 size_t size1=s1.size(), size2=s2.size();// cache lengths415 //return -1,0 or 1 according to strings' lengths416 if (size1==size2)417 return 0;418 return (size1<size2) ? -1 : 1;419 }420 421 422 /**423 @brief Compares the first 'len' chars of two strings ignoring different casing.424 @param s1 First string425 @param s2 Second string426 @param len Maximal number of chars to compare427 */428 int nocaseCmp(const std::string& s1, const std::string& s2, size_t len)429 {430 if (len == 0)431 return 0;432 std::string::const_iterator it1=s1.begin();433 std::string::const_iterator it2=s2.begin();434 435 //stop when either string's end has been reached436 while ( (it1!=s1.end()) && (it2!=s2.end()) && len-- > 0)437 {438 if(::toupper(*it1) != ::toupper(*it2)) //letters differ?439 // return -1 to indicate smaller than, 1 otherwise440 return (::toupper(*it1) < ::toupper(*it2)) ? -1 : 1;441 //proceed to the next character in each string442 ++it1;443 ++it2;444 }445 return 0;446 }447 448 /**449 @brief Returns true if the string contains a comment, introduced by #, %, ; or //.450 @param str The string451 @return True if the string contains a comment452 */453 bool hasComment(const std::string& str)454 {455 return (getCommentPosition(str) != std::string::npos);456 }457 458 /**459 @brief If the string contains a comment, the comment gets returned (including the comment symbol), an empty string otherwise.460 @param str The string461 @return The comment462 */463 std::string getComment(const std::string& str)464 {465 return str.substr(getCommentPosition(str));466 }467 468 /**469 @brief If the string contains a comment, the position of the comment-symbol gets returned, std::string::npos otherwise.470 @param str The string471 @return The position472 */473 size_t getCommentPosition(const std::string& str)474 {475 return getNextCommentPosition(str, 0);476 }477 478 /**479 @brief Returns the position of the next comment-symbol, starting with start.480 @param str The string481 @param start The startposition482 @return The position483 */484 size_t getNextCommentPosition(const std::string& str, size_t start)485 {486 for (size_t i = start; i < str.size(); i++)487 if (isComment(str.substr(i)))488 return i;489 490 return std::string::npos;491 } -
code/branches/objecthierarchy/src/util/String.h
r2020 r2111 40 40 #include <sstream> 41 41 42 extern _UtilExport std::string BLANKSTRING; 43 _UtilExport std::string getUniqueNumberString(); 42 namespace orxonox 43 { 44 extern _UtilExport std::string BLANKSTRING; 45 _UtilExport std::string getUniqueNumberString(); 44 46 45 _UtilExport void strip(std::string* str);46 _UtilExport std::string getStripped(const std::string& str);47 _UtilExport void strip(std::string* str); 48 _UtilExport std::string getStripped(const std::string& str); 47 49 48 _UtilExport std::string removeTrailingWhitespaces(const std::string& str);50 _UtilExport std::string removeTrailingWhitespaces(const std::string& str); 49 51 50 _UtilExport size_t getNextQuote(const std::string& str, size_t start);51 _UtilExport bool isBetweenQuotes(const std::string& str, size_t pos);52 _UtilExport size_t getNextQuote(const std::string& str, size_t start); 53 _UtilExport bool isBetweenQuotes(const std::string& str, size_t pos); 52 54 53 _UtilExport bool hasStringBetweenQuotes(const std::string& str);54 _UtilExport std::string getStringBetweenQuotes(const std::string& str);55 _UtilExport bool hasStringBetweenQuotes(const std::string& str); 56 _UtilExport std::string getStringBetweenQuotes(const std::string& str); 55 57 56 _UtilExport std::string stripEnclosingQuotes(const std::string& str);57 _UtilExport std::string stripEnclosingBraces(const std::string& str);58 _UtilExport std::string stripEnclosingQuotes(const std::string& str); 59 _UtilExport std::string stripEnclosingBraces(const std::string& str); 58 60 59 _UtilExport bool isEmpty(const std::string& str);60 _UtilExport bool isComment(const std::string& str);61 _UtilExport bool isNumeric(const std::string& str);61 _UtilExport bool isEmpty(const std::string& str); 62 _UtilExport bool isComment(const std::string& str); 63 _UtilExport bool isNumeric(const std::string& str); 62 64 63 _UtilExport std::string addSlashes(const std::string& str);64 _UtilExport std::string removeSlashes(const std::string& str);65 _UtilExport std::string addSlashes(const std::string& str); 66 _UtilExport std::string removeSlashes(const std::string& str); 65 67 66 _UtilExport void lowercase(std::string* str);67 _UtilExport std::string getLowercase(const std::string& str);68 _UtilExport void lowercase(std::string* str); 69 _UtilExport std::string getLowercase(const std::string& str); 68 70 69 _UtilExport void uppercase(std::string* str);70 _UtilExport std::string getUppercase(const std::string& str);71 _UtilExport void uppercase(std::string* str); 72 _UtilExport std::string getUppercase(const std::string& str); 71 73 72 _UtilExport int nocaseCmp(const std::string& s1, const std::string& s2);73 _UtilExport int nocaseCmp(const std::string& s1, const std::string& s2, size_t len);74 _UtilExport int nocaseCmp(const std::string& s1, const std::string& s2); 75 _UtilExport int nocaseCmp(const std::string& s1, const std::string& s2, size_t len); 74 76 75 _UtilExport bool hasComment(const std::string& str); 76 _UtilExport std::string getComment(const std::string& str); 77 _UtilExport size_t getCommentPosition(const std::string& str); 78 _UtilExport size_t getNextCommentPosition(const std::string& str, size_t start = 0); 77 _UtilExport bool hasComment(const std::string& str); 78 _UtilExport std::string getComment(const std::string& str); 79 _UtilExport size_t getCommentPosition(const std::string& str); 80 _UtilExport size_t getNextCommentPosition(const std::string& str, size_t start = 0); 81 } 79 82 80 83 #endif /* _Util_String_H__ */ -
code/branches/objecthierarchy/src/util/SubString.cc
r1791 r2111 40 40 #include "SubString.h" 41 41 42 /** 43 * @brief default constructor 44 */ 45 SubString::SubString() 46 {} 47 48 49 /** 50 * @brief create a SubString from 51 * @param string the String to Split 52 * @param delimiter the Character at which to split string (delimiter) 53 */ 54 SubString::SubString(const std::string& string, char delimiter) 42 namespace orxonox 55 43 { 56 this->split(string, delimiter); 57 } 58 59 60 /** 61 * @brief Splits a String into multiple splitters. 62 * @param string the String to split 63 * @param delimiters multiple set of characters at what to split. (delimiters) 64 * @param delimiterNeighbours neighbours of the delimiters, that will be erased only when near a delimiter. 65 * @param emptyEntries If empty entries should be allewed or removed. 66 * @param escapeChar The Escape Character that overrides splitters commends and so on... 67 * @param safemode_char within these characters splitting won't happen 68 * @param comment_char the Comment character. 69 */ 70 SubString::SubString(const std::string& string, 71 const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries, 72 char escapeChar, bool removeEscapeChar, char safemode_char, bool removeSafemodeChar, 73 char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char) 74 { 75 SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeEscapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char); 76 } 77 78 /** 79 * @brief creates a SubSet of a SubString. 80 * @param subString the SubString to take a set from. 81 * @param subSetBegin the beginning to the end 82 */ 83 SubString::SubString(const SubString& subString, unsigned int subSetBegin) 84 { 85 for (unsigned int i = subSetBegin; i < subString.size(); i++) 86 { 87 this->strings.push_back(subString[i]); 88 this->bInSafemode.push_back(subString.isInSafemode(i)); 89 } 90 } 91 92 93 /** 94 * @brief creates a SubSet of a SubString. 95 * @param subString the SubString to take a Set from 96 * @param subSetBegin the beginning to the end 97 * @param subSetEnd the end of the SubSet (max subString.size() will be checked internaly) 98 */ 99 SubString::SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd) 100 { 101 for (unsigned int i = subSetBegin; i < subString.size() && i < subSetEnd; i++) 102 { 103 this->strings.push_back(subString[i]); 104 this->bInSafemode.push_back(subString.isInSafemode(i)); 105 } 106 } 107 108 /** 109 * @brief creates a Substring from a count and values set. 110 * @param argc: the Arguments Count. 111 * @param argv: Argument Values. 112 */ 113 SubString::SubString(unsigned int argc, const char** argv) 114 { 115 for(unsigned int i = 0; i < argc; ++i) 116 { 117 this->strings.push_back(std::string(argv[i])); 118 this->bInSafemode.push_back(false); 119 } 120 } 121 122 /** 123 * @brief removes the object from memory 124 */ 125 SubString::~SubString() 126 { } 127 128 /** @brief An empty String */ 129 // const std::string SubString::emptyString = ""; 130 /** @brief Helper that gets you a String consisting of all White Spaces */ 131 const std::string SubString::WhiteSpaces = " \n\t"; 132 /** @brief Helper that gets you a String consisting of all WhiteSpaces and the Comma */ 133 const std::string SubString::WhiteSpacesWithComma = " \n\t,"; 134 /** An Empty SubString */ 135 const SubString SubString::NullSubString = SubString(); 136 137 /** 138 * @brief stores the Value of subString in this SubString 139 * @param subString will be copied into this String. 140 * @returns this SubString. 141 */ 142 SubString& SubString::operator=(const SubString& subString) 143 { 144 this->strings = subString.strings; 145 this->bInSafemode = subString.bInSafemode; 146 return *this; 147 } 148 149 150 /** 151 * @brief comparator. 152 * @param subString the SubString to compare against this one. 153 * @returns true if the Stored Strings match 154 */ 155 bool SubString::operator==(const SubString& subString) const 156 { 157 return ((this->strings == subString.strings) && (this->bInSafemode == subString.bInSafemode)); 158 } 159 160 /** 161 * @brief comparator. 162 * @param subString the SubString to compare against this one. 163 * @returns true if the Stored Strings match 164 */ 165 bool SubString::compare(const SubString& subString) const 166 { 167 return (*this == subString); 168 } 169 170 /** 171 * @brief comparator. 172 * @param subString the SubString to compare against this one. 173 * @param length how many entries to compare. (from 0 to length) 174 * @returns true if the Stored Strings match 175 */ 176 bool SubString::compare(const SubString& subString, unsigned int length) const 177 { 178 if (length > this->size() || length > subString.size()) 179 return false; 180 181 for (unsigned int i = 0; i < length; i++) 182 if ((this->strings[i] != subString.strings[i]) || (this->bInSafemode[i] != subString.bInSafemode[i])) 183 return false; 184 return true; 185 } 186 187 188 /** 189 * @brief append operator 190 * @param subString the String to append. 191 * @returns a SubString where this and subString are appended. 192 */ 193 SubString SubString::operator+(const SubString& subString) const 194 { 195 return SubString(*this) += subString; 196 } 197 198 199 /** 200 * @brief append operator. 201 * @param subString append subString to this SubString. 202 * @returns this substring appended with subString 203 */ 204 SubString& SubString::operator+=(const SubString& subString) 205 { 206 for (unsigned int i = 0; i < subString.size(); i++) 207 { 208 this->strings.push_back(subString[i]); 209 this->bInSafemode.push_back(subString.isInSafemode(i)); 210 } 211 return *this; 212 } 213 214 215 /** 216 * @brief Split the String at 217 * @param string where to split 218 * @param splitter delimiter. 219 */ 220 unsigned int SubString::split(const std::string& string, char splitter) 221 { 222 this->strings.clear(); 223 this->bInSafemode.clear(); 224 char split[2]; 225 split[0] = splitter; 226 split[1] = '\0'; 227 SubString::splitLine(this->strings, this->bInSafemode, string, split); 228 return strings.size(); 229 } 230 231 232 /** 233 * @brief Splits a String into multiple splitters. 234 * @param string the String to split 235 * @param delimiters multiple set of characters at what to split. (delimiters) 236 * @param delimiterNeighbours: Neighbours to the Delimiters that will be erased too. 237 * @param emptyEntries: If empty entries are added to the List of SubStrings 238 * @param escapeChar The Escape Character that overrides splitters commends and so on... 239 * @param safemode_char within these characters splitting won't happen 240 * @param comment_char the Comment character. 241 */ 242 unsigned int SubString::split(const std::string& string, 243 const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries, 244 char escapeChar, bool removeExcapeChar, char safemode_char, bool removeSafemodeChar, 245 char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char) 246 { 247 this->strings.clear(); 248 this->bInSafemode.clear(); 249 SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeExcapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char); 250 return this->strings.size(); 251 } 252 253 254 /** 255 * @brief joins together all Strings of this Substring. 256 * @param delimiter the String between the subStrings. 257 * @returns the joined String. 258 */ 259 std::string SubString::join(const std::string& delimiter) const 260 { 261 if (!this->strings.empty()) 262 { 263 std::string retVal = this->strings[0]; 264 for (unsigned int i = 1; i < this->strings.size(); i++) 265 retVal += delimiter + this->strings[i]; 266 return retVal; 267 } 268 else 269 { 270 static std::string empty; 271 return empty; 272 } 273 } 274 275 276 /** 277 * @brief creates a SubSet of a SubString. 278 * @param subSetBegin the beginning to the end 279 * @returns the SubSet 280 * 281 * This function is added for your convenience, and does the same as 282 * SubString::SubString(const SubString& subString, unsigned int subSetBegin) 283 */ 284 SubString SubString::subSet(unsigned int subSetBegin) const 285 { 286 return SubString(*this, subSetBegin); 287 } 288 289 290 /** 291 * @brief creates a SubSet of a SubString. 292 * @param subSetBegin the beginning to 293 * @param subSetEnd the end of the SubSet to select (if bigger than subString.size() it will be downset.) 294 * @returns the SubSet 295 * 296 * This function is added for your convenience, and does the same as 297 * SubString::SubString(const SubString& subString, unsigned int subSetBegin) 298 */ 299 SubString SubString::subSet(unsigned int subSetBegin, unsigned int subSetEnd) const 300 { 301 return SubString(*this, subSetBegin, subSetEnd); 302 } 303 304 305 /** 306 * @brief splits line into tokens and stores them in ret. 307 * @param ret the Array, where the Splitted strings will be stored in 308 * to the beginning of the current token is stored 309 * @param line the inputLine to split 310 * @param delimiters a String of Delimiters (here the input will be splitted) 311 * @param delimiterNeighbours Naighbours to the Delimitter, that will be removed if they are to the left or the right of a Delimiter. 312 * @param emptyEntries: if empty Strings are added to the List of Strings. 313 * @param escape_char: Escape carater (escapes splitters) 314 * @param safemode_char: the beginning of the safemode is marked with this 315 * @param removeSafemodeChar removes the safemode_char from the beginning and the ending of a token 316 * @param openparenthesis_char the beginning of a safemode is marked with this 317 * @param closeparenthesis_char the ending of a safemode is marked with this 318 * @param removeParenthesisChars removes the parenthesis from the beginning and the ending of a token 319 * @param comment_char: the beginning of a comment is marked with this: (until the end of a Line) 320 * @param start_state: the Initial state on how to parse the String. 321 * @return SPLIT_LINE_STATE the parser was in when returning 322 * 323 * This is the Actual Splitting Algorithm from Clemens Wacha 324 * Supports delimiters, escape characters, 325 * ignores special characters between safemode_char and between comment_char and linend '\n'. 326 */ 327 SubString::SPLIT_LINE_STATE 328 SubString::splitLine(std::vector<std::string>& ret, 329 std::vector<bool>& bInSafemode, 330 const std::string& line, 331 const std::string& delimiters, 332 const std::string& delimiterNeighbours, 333 bool emptyEntries, 334 char escape_char, 335 bool removeExcapeChar, 336 char safemode_char, 337 bool removeSafemodeChar, 338 char openparenthesis_char, 339 char closeparenthesis_char, 340 bool removeParenthesisChars, 341 char comment_char, 342 SPLIT_LINE_STATE start_state) 343 { 344 SPLIT_LINE_STATE state = start_state; 345 unsigned int i = 0; 346 unsigned int fallBackNeighbours = 0; 347 348 std::string token; 349 bool inSafemode = false; 350 351 if(start_state != SL_NORMAL && ret.size() > 0) 352 { 353 token = ret[ret.size()-1]; 354 ret.pop_back(); 355 } 356 if(start_state != SL_NORMAL && bInSafemode.size() > 0) 357 { 358 inSafemode = bInSafemode[bInSafemode.size()-1]; 359 bInSafemode.pop_back(); 360 } 361 362 while(i < line.size()) 363 { 364 switch(state) 365 { 366 case SL_NORMAL: 367 if(line[i] == escape_char) 368 { 369 state = SL_ESCAPE; 370 if (!removeExcapeChar) 371 token += line[i]; 372 } 373 else if(line[i] == safemode_char) 374 { 375 state = SL_SAFEMODE; 376 inSafemode = true; 377 if (!removeSafemodeChar) 378 token += line[i]; 379 } 380 else if(line[i] == openparenthesis_char) 381 { 382 state = SL_PARENTHESES; 383 inSafemode = true; 384 if (!removeParenthesisChars) 385 token += line[i]; 386 } 387 else if(line[i] == comment_char) 388 { 389 if (fallBackNeighbours > 0) 44 /** 45 * @brief default constructor 46 */ 47 SubString::SubString() 48 {} 49 50 51 /** 52 * @brief create a SubString from 53 * @param string the String to Split 54 * @param delimiter the Character at which to split string (delimiter) 55 */ 56 SubString::SubString(const std::string& string, char delimiter) 57 { 58 this->split(string, delimiter); 59 } 60 61 62 /** 63 * @brief Splits a String into multiple splitters. 64 * @param string the String to split 65 * @param delimiters multiple set of characters at what to split. (delimiters) 66 * @param delimiterNeighbours neighbours of the delimiters, that will be erased only when near a delimiter. 67 * @param emptyEntries If empty entries should be allewed or removed. 68 * @param escapeChar The Escape Character that overrides splitters commends and so on... 69 * @param safemode_char within these characters splitting won't happen 70 * @param comment_char the Comment character. 71 */ 72 SubString::SubString(const std::string& string, 73 const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries, 74 char escapeChar, bool removeEscapeChar, char safemode_char, bool removeSafemodeChar, 75 char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char) 76 { 77 SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeEscapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char); 78 } 79 80 /** 81 * @brief creates a SubSet of a SubString. 82 * @param subString the SubString to take a set from. 83 * @param subSetBegin the beginning to the end 84 */ 85 SubString::SubString(const SubString& subString, unsigned int subSetBegin) 86 { 87 for (unsigned int i = subSetBegin; i < subString.size(); i++) 88 { 89 this->strings.push_back(subString[i]); 90 this->bInSafemode.push_back(subString.isInSafemode(i)); 91 } 92 } 93 94 95 /** 96 * @brief creates a SubSet of a SubString. 97 * @param subString the SubString to take a Set from 98 * @param subSetBegin the beginning to the end 99 * @param subSetEnd the end of the SubSet (max subString.size() will be checked internaly) 100 */ 101 SubString::SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd) 102 { 103 for (unsigned int i = subSetBegin; i < subString.size() && i < subSetEnd; i++) 104 { 105 this->strings.push_back(subString[i]); 106 this->bInSafemode.push_back(subString.isInSafemode(i)); 107 } 108 } 109 110 /** 111 * @brief creates a Substring from a count and values set. 112 * @param argc: the Arguments Count. 113 * @param argv: Argument Values. 114 */ 115 SubString::SubString(unsigned int argc, const char** argv) 116 { 117 for(unsigned int i = 0; i < argc; ++i) 118 { 119 this->strings.push_back(std::string(argv[i])); 120 this->bInSafemode.push_back(false); 121 } 122 } 123 124 /** 125 * @brief removes the object from memory 126 */ 127 SubString::~SubString() 128 { } 129 130 /** @brief An empty String */ 131 // const std::string SubString::emptyString = ""; 132 /** @brief Helper that gets you a String consisting of all White Spaces */ 133 const std::string SubString::WhiteSpaces = " \n\t"; 134 /** @brief Helper that gets you a String consisting of all WhiteSpaces and the Comma */ 135 const std::string SubString::WhiteSpacesWithComma = " \n\t,"; 136 /** An Empty SubString */ 137 const SubString SubString::NullSubString = SubString(); 138 139 /** 140 * @brief stores the Value of subString in this SubString 141 * @param subString will be copied into this String. 142 * @returns this SubString. 143 */ 144 SubString& SubString::operator=(const SubString& subString) 145 { 146 this->strings = subString.strings; 147 this->bInSafemode = subString.bInSafemode; 148 return *this; 149 } 150 151 152 /** 153 * @brief comparator. 154 * @param subString the SubString to compare against this one. 155 * @returns true if the Stored Strings match 156 */ 157 bool SubString::operator==(const SubString& subString) const 158 { 159 return ((this->strings == subString.strings) && (this->bInSafemode == subString.bInSafemode)); 160 } 161 162 /** 163 * @brief comparator. 164 * @param subString the SubString to compare against this one. 165 * @returns true if the Stored Strings match 166 */ 167 bool SubString::compare(const SubString& subString) const 168 { 169 return (*this == subString); 170 } 171 172 /** 173 * @brief comparator. 174 * @param subString the SubString to compare against this one. 175 * @param length how many entries to compare. (from 0 to length) 176 * @returns true if the Stored Strings match 177 */ 178 bool SubString::compare(const SubString& subString, unsigned int length) const 179 { 180 if (length > this->size() || length > subString.size()) 181 return false; 182 183 for (unsigned int i = 0; i < length; i++) 184 if ((this->strings[i] != subString.strings[i]) || (this->bInSafemode[i] != subString.bInSafemode[i])) 185 return false; 186 return true; 187 } 188 189 190 /** 191 * @brief append operator 192 * @param subString the String to append. 193 * @returns a SubString where this and subString are appended. 194 */ 195 SubString SubString::operator+(const SubString& subString) const 196 { 197 return SubString(*this) += subString; 198 } 199 200 201 /** 202 * @brief append operator. 203 * @param subString append subString to this SubString. 204 * @returns this substring appended with subString 205 */ 206 SubString& SubString::operator+=(const SubString& subString) 207 { 208 for (unsigned int i = 0; i < subString.size(); i++) 209 { 210 this->strings.push_back(subString[i]); 211 this->bInSafemode.push_back(subString.isInSafemode(i)); 212 } 213 return *this; 214 } 215 216 217 /** 218 * @brief Split the String at 219 * @param string where to split 220 * @param splitter delimiter. 221 */ 222 unsigned int SubString::split(const std::string& string, char splitter) 223 { 224 this->strings.clear(); 225 this->bInSafemode.clear(); 226 char split[2]; 227 split[0] = splitter; 228 split[1] = '\0'; 229 SubString::splitLine(this->strings, this->bInSafemode, string, split); 230 return strings.size(); 231 } 232 233 234 /** 235 * @brief Splits a String into multiple splitters. 236 * @param string the String to split 237 * @param delimiters multiple set of characters at what to split. (delimiters) 238 * @param delimiterNeighbours: Neighbours to the Delimiters that will be erased too. 239 * @param emptyEntries: If empty entries are added to the List of SubStrings 240 * @param escapeChar The Escape Character that overrides splitters commends and so on... 241 * @param safemode_char within these characters splitting won't happen 242 * @param comment_char the Comment character. 243 */ 244 unsigned int SubString::split(const std::string& string, 245 const std::string& delimiters, const std::string& delimiterNeighbours, bool emptyEntries, 246 char escapeChar, bool removeExcapeChar, char safemode_char, bool removeSafemodeChar, 247 char openparenthesis_char, char closeparenthesis_char, bool removeParenthesisChars, char comment_char) 248 { 249 this->strings.clear(); 250 this->bInSafemode.clear(); 251 SubString::splitLine(this->strings, this->bInSafemode, string, delimiters, delimiterNeighbours, emptyEntries, escapeChar, removeExcapeChar, safemode_char, removeSafemodeChar, openparenthesis_char, closeparenthesis_char, removeParenthesisChars, comment_char); 252 return this->strings.size(); 253 } 254 255 256 /** 257 * @brief joins together all Strings of this Substring. 258 * @param delimiter the String between the subStrings. 259 * @returns the joined String. 260 */ 261 std::string SubString::join(const std::string& delimiter) const 262 { 263 if (!this->strings.empty()) 264 { 265 std::string retVal = this->strings[0]; 266 for (unsigned int i = 1; i < this->strings.size(); i++) 267 retVal += delimiter + this->strings[i]; 268 return retVal; 269 } 270 else 271 { 272 static std::string empty; 273 return empty; 274 } 275 } 276 277 278 /** 279 * @brief creates a SubSet of a SubString. 280 * @param subSetBegin the beginning to the end 281 * @returns the SubSet 282 * 283 * This function is added for your convenience, and does the same as 284 * SubString::SubString(const SubString& subString, unsigned int subSetBegin) 285 */ 286 SubString SubString::subSet(unsigned int subSetBegin) const 287 { 288 return SubString(*this, subSetBegin); 289 } 290 291 292 /** 293 * @brief creates a SubSet of a SubString. 294 * @param subSetBegin the beginning to 295 * @param subSetEnd the end of the SubSet to select (if bigger than subString.size() it will be downset.) 296 * @returns the SubSet 297 * 298 * This function is added for your convenience, and does the same as 299 * SubString::SubString(const SubString& subString, unsigned int subSetBegin) 300 */ 301 SubString SubString::subSet(unsigned int subSetBegin, unsigned int subSetEnd) const 302 { 303 return SubString(*this, subSetBegin, subSetEnd); 304 } 305 306 307 /** 308 * @brief splits line into tokens and stores them in ret. 309 * @param ret the Array, where the Splitted strings will be stored in 310 * to the beginning of the current token is stored 311 * @param line the inputLine to split 312 * @param delimiters a String of Delimiters (here the input will be splitted) 313 * @param delimiterNeighbours Naighbours to the Delimitter, that will be removed if they are to the left or the right of a Delimiter. 314 * @param emptyEntries: if empty Strings are added to the List of Strings. 315 * @param escape_char: Escape carater (escapes splitters) 316 * @param safemode_char: the beginning of the safemode is marked with this 317 * @param removeSafemodeChar removes the safemode_char from the beginning and the ending of a token 318 * @param openparenthesis_char the beginning of a safemode is marked with this 319 * @param closeparenthesis_char the ending of a safemode is marked with this 320 * @param removeParenthesisChars removes the parenthesis from the beginning and the ending of a token 321 * @param comment_char: the beginning of a comment is marked with this: (until the end of a Line) 322 * @param start_state: the Initial state on how to parse the String. 323 * @return SPLIT_LINE_STATE the parser was in when returning 324 * 325 * This is the Actual Splitting Algorithm from Clemens Wacha 326 * Supports delimiters, escape characters, 327 * ignores special characters between safemode_char and between comment_char and linend '\n'. 328 */ 329 SubString::SPLIT_LINE_STATE 330 SubString::splitLine(std::vector<std::string>& ret, 331 std::vector<bool>& bInSafemode, 332 const std::string& line, 333 const std::string& delimiters, 334 const std::string& delimiterNeighbours, 335 bool emptyEntries, 336 char escape_char, 337 bool removeExcapeChar, 338 char safemode_char, 339 bool removeSafemodeChar, 340 char openparenthesis_char, 341 char closeparenthesis_char, 342 bool removeParenthesisChars, 343 char comment_char, 344 SPLIT_LINE_STATE start_state) 345 { 346 SPLIT_LINE_STATE state = start_state; 347 unsigned int i = 0; 348 unsigned int fallBackNeighbours = 0; 349 350 std::string token; 351 bool inSafemode = false; 352 353 if(start_state != SL_NORMAL && ret.size() > 0) 354 { 355 token = ret[ret.size()-1]; 356 ret.pop_back(); 357 } 358 if(start_state != SL_NORMAL && bInSafemode.size() > 0) 359 { 360 inSafemode = bInSafemode[bInSafemode.size()-1]; 361 bInSafemode.pop_back(); 362 } 363 364 while(i < line.size()) 365 { 366 switch(state) 367 { 368 case SL_NORMAL: 369 if(line[i] == escape_char) 370 { 371 state = SL_ESCAPE; 372 if (!removeExcapeChar) 373 token += line[i]; 374 } 375 else if(line[i] == safemode_char) 376 { 377 state = SL_SAFEMODE; 378 inSafemode = true; 379 if (!removeSafemodeChar) 380 token += line[i]; 381 } 382 else if(line[i] == openparenthesis_char) 383 { 384 state = SL_PARENTHESES; 385 inSafemode = true; 386 if (!removeParenthesisChars) 387 token += line[i]; 388 } 389 else if(line[i] == comment_char) 390 { 391 if (fallBackNeighbours > 0) 392 token = token.substr(0, token.size() - fallBackNeighbours); 393 /// FINISH 394 if(emptyEntries || token.size() > 0) 395 { 396 ret.push_back(token); 397 token.clear(); 398 bInSafemode.push_back(inSafemode); 399 inSafemode = false; 400 } 401 token += line[i]; // EAT 402 state = SL_COMMENT; 403 } 404 else if(delimiters.find(line[i]) != std::string::npos) 405 { 406 // line[i] is a delimiter 407 if (fallBackNeighbours > 0) 408 token = token.substr(0, token.size() - fallBackNeighbours); 409 /// FINISH 410 if(emptyEntries || token.size() > 0) 411 { 412 ret.push_back(token); 413 token.clear(); 414 bInSafemode.push_back(inSafemode); 415 inSafemode = false; 416 } 417 state = SL_NORMAL; 418 } 419 else 420 { 421 if (delimiterNeighbours.find(line[i]) != std::string::npos) 422 { 423 if (token.size() > 0) 424 ++fallBackNeighbours; 425 else 426 { 427 i++; 428 continue; 429 } 430 } 431 else 432 fallBackNeighbours = 0; 433 token += line[i]; // EAT 434 } 435 break; 436 case SL_ESCAPE: 437 if (!removeSafemodeChar) 438 token += line[i]; 439 else 440 { 441 if(line[i] == 'n') token += '\n'; 442 else if(line[i] == 't') token += '\t'; 443 else if(line[i] == 'v') token += '\v'; 444 else if(line[i] == 'b') token += '\b'; 445 else if(line[i] == 'r') token += '\r'; 446 else if(line[i] == 'f') token += '\f'; 447 else if(line[i] == 'a') token += '\a'; 448 else if(line[i] == '?') token += '\?'; 449 else token += line[i]; // EAT 450 } 451 state = SL_NORMAL; 452 break; 453 case SL_SAFEMODE: 454 if(line[i] == safemode_char) 455 { 456 state = SL_NORMAL; 457 if (!removeSafemodeChar) 458 token += line[i]; 459 } 460 else if(line[i] == escape_char) 461 { 462 state = SL_SAFEESCAPE; 463 } 464 else 465 { 466 token += line[i]; // EAT 467 } 468 break; 469 470 case SL_SAFEESCAPE: 471 if(line[i] == 'n') token += '\n'; 472 else if(line[i] == 't') token += '\t'; 473 else if(line[i] == 'v') token += '\v'; 474 else if(line[i] == 'b') token += '\b'; 475 else if(line[i] == 'r') token += '\r'; 476 else if(line[i] == 'f') token += '\f'; 477 else if(line[i] == 'a') token += '\a'; 478 else if(line[i] == '?') token += '\?'; 479 else token += line[i]; // EAT 480 state = SL_SAFEMODE; 481 break; 482 483 case SL_PARENTHESES: 484 if(line[i] == closeparenthesis_char) 485 { 486 state = SL_NORMAL; 487 if (!removeParenthesisChars) 488 token += line[i]; 489 } 490 else if(line[i] == escape_char) 491 { 492 state = SL_PARENTHESESESCAPE; 493 } 494 else 495 { 496 token += line[i]; // EAT 497 } 498 break; 499 500 case SL_PARENTHESESESCAPE: 501 if(line[i] == 'n') token += '\n'; 502 else if(line[i] == 't') token += '\t'; 503 else if(line[i] == 'v') token += '\v'; 504 else if(line[i] == 'b') token += '\b'; 505 else if(line[i] == 'r') token += '\r'; 506 else if(line[i] == 'f') token += '\f'; 507 else if(line[i] == 'a') token += '\a'; 508 else if(line[i] == '?') token += '\?'; 509 else token += line[i]; // EAT 510 state = SL_PARENTHESES; 511 break; 512 513 case SL_COMMENT: 514 if(line[i] == '\n') 515 { 516 /// FINISH 517 if(token.size() > 0) 518 { 519 ret.push_back(token); 520 token.clear(); 521 bInSafemode.push_back(inSafemode); 522 inSafemode = false; 523 } 524 state = SL_NORMAL; 525 } 526 else 527 { 528 token += line[i]; // EAT 529 } 530 break; 531 532 default: 533 // nothing 534 break; 535 } 536 i++; 537 } 538 539 /// FINISH 540 if (fallBackNeighbours > 0) 390 541 token = token.substr(0, token.size() - fallBackNeighbours); 391 /// FINISH 392 if(emptyEntries || token.size() > 0) 393 { 542 if(emptyEntries || token.size() > 0) 543 { 394 544 ret.push_back(token); 395 545 token.clear(); 396 546 bInSafemode.push_back(inSafemode); 397 547 inSafemode = false; 398 } 399 token += line[i]; // EAT 400 state = SL_COMMENT; 401 } 402 else if(delimiters.find(line[i]) != std::string::npos) 403 { 404 // line[i] is a delimiter 405 if (fallBackNeighbours > 0) 406 token = token.substr(0, token.size() - fallBackNeighbours); 407 /// FINISH 408 if(emptyEntries || token.size() > 0) 409 { 410 ret.push_back(token); 411 token.clear(); 412 bInSafemode.push_back(inSafemode); 413 inSafemode = false; 414 } 415 state = SL_NORMAL; 416 } 417 else 418 { 419 if (delimiterNeighbours.find(line[i]) != std::string::npos) 420 { 421 if (token.size() > 0) 422 ++fallBackNeighbours; 423 else 424 { 425 i++; 426 continue; 427 } 428 } 429 else 430 fallBackNeighbours = 0; 431 token += line[i]; // EAT 432 } 433 break; 434 case SL_ESCAPE: 435 if (!removeSafemodeChar) 436 token += line[i]; 437 else 438 { 439 if(line[i] == 'n') token += '\n'; 440 else if(line[i] == 't') token += '\t'; 441 else if(line[i] == 'v') token += '\v'; 442 else if(line[i] == 'b') token += '\b'; 443 else if(line[i] == 'r') token += '\r'; 444 else if(line[i] == 'f') token += '\f'; 445 else if(line[i] == 'a') token += '\a'; 446 else if(line[i] == '?') token += '\?'; 447 else token += line[i]; // EAT 448 } 449 state = SL_NORMAL; 450 break; 451 case SL_SAFEMODE: 452 if(line[i] == safemode_char) 453 { 454 state = SL_NORMAL; 455 if (!removeSafemodeChar) 456 token += line[i]; 457 } 458 else if(line[i] == escape_char) 459 { 460 state = SL_SAFEESCAPE; 461 } 462 else 463 { 464 token += line[i]; // EAT 465 } 466 break; 467 468 case SL_SAFEESCAPE: 469 if(line[i] == 'n') token += '\n'; 470 else if(line[i] == 't') token += '\t'; 471 else if(line[i] == 'v') token += '\v'; 472 else if(line[i] == 'b') token += '\b'; 473 else if(line[i] == 'r') token += '\r'; 474 else if(line[i] == 'f') token += '\f'; 475 else if(line[i] == 'a') token += '\a'; 476 else if(line[i] == '?') token += '\?'; 477 else token += line[i]; // EAT 478 state = SL_SAFEMODE; 479 break; 480 481 case SL_PARENTHESES: 482 if(line[i] == closeparenthesis_char) 483 { 484 state = SL_NORMAL; 485 if (!removeParenthesisChars) 486 token += line[i]; 487 } 488 else if(line[i] == escape_char) 489 { 490 state = SL_PARENTHESESESCAPE; 491 } 492 else 493 { 494 token += line[i]; // EAT 495 } 496 break; 497 498 case SL_PARENTHESESESCAPE: 499 if(line[i] == 'n') token += '\n'; 500 else if(line[i] == 't') token += '\t'; 501 else if(line[i] == 'v') token += '\v'; 502 else if(line[i] == 'b') token += '\b'; 503 else if(line[i] == 'r') token += '\r'; 504 else if(line[i] == 'f') token += '\f'; 505 else if(line[i] == 'a') token += '\a'; 506 else if(line[i] == '?') token += '\?'; 507 else token += line[i]; // EAT 508 state = SL_PARENTHESES; 509 break; 510 511 case SL_COMMENT: 512 if(line[i] == '\n') 513 { 514 /// FINISH 515 if(token.size() > 0) 516 { 517 ret.push_back(token); 518 token.clear(); 519 bInSafemode.push_back(inSafemode); 520 inSafemode = false; 521 } 522 state = SL_NORMAL; 523 } 524 else 525 { 526 token += line[i]; // EAT 527 } 528 break; 529 530 default: 531 // nothing 532 break; 533 } 534 i++; 535 } 536 537 /// FINISH 538 if (fallBackNeighbours > 0) 539 token = token.substr(0, token.size() - fallBackNeighbours); 540 if(emptyEntries || token.size() > 0) 541 { 542 ret.push_back(token); 543 token.clear(); 544 bInSafemode.push_back(inSafemode); 545 inSafemode = false; 546 } 547 return(state); 548 } 549 return(state); 550 } 551 552 553 /** 554 * @brief Some nice debug information about this SubString 555 */ 556 void SubString::debug() const 557 { 558 printf("Substring-information::count=%d ::", this->strings.size()); 559 for (unsigned int i = 0; i < this->strings.size(); i++) 560 printf("s%d='%s'::", i, this->strings[i].c_str()); 561 printf("\n"); 562 } 548 563 } 549 550 551 /**552 * @brief Some nice debug information about this SubString553 */554 void SubString::debug() const555 {556 printf("Substring-information::count=%d ::", this->strings.size());557 for (unsigned int i = 0; i < this->strings.size(); i++)558 printf("s%d='%s'::", i, this->strings[i].c_str());559 printf("\n");560 } -
code/branches/objecthierarchy/src/util/SubString.h
r1791 r2111 64 64 #include <string> 65 65 66 //! A class that can load one string and split it in multipe ones 67 /** 68 * SubString is a very Powerfull way to create a SubSet from a String 69 * It can be used, to Split strings append them and join them again. 70 */ 71 class _UtilExport SubString 66 namespace orxonox 72 67 { 73 public: 74 //! An enumerator for the State the Parser is in 75 typedef enum { 76 SL_NORMAL, //!< Normal state 77 SL_ESCAPE, //!< After an escape character 78 SL_SAFEMODE, //!< In safe mode (between "" mostly). 79 SL_SAFEESCAPE, //!< In safe mode with the internal escape character, that escapes even the savemode character. 80 SL_COMMENT, //!< In Comment mode. 81 SL_PARENTHESES, //!< Between parentheses (usually '(' and ')') 82 SL_PARENTHESESESCAPE, //!< Between parentheses with the internal escape character, that escapes even the closing paranthesis character. 83 } SPLIT_LINE_STATE; 68 //! A class that can load one string and split it in multipe ones 69 /** 70 * SubString is a very Powerfull way to create a SubSet from a String 71 * It can be used, to Split strings append them and join them again. 72 */ 73 class _UtilExport SubString 74 { 75 public: 76 //! An enumerator for the State the Parser is in 77 typedef enum { 78 SL_NORMAL, //!< Normal state 79 SL_ESCAPE, //!< After an escape character 80 SL_SAFEMODE, //!< In safe mode (between "" mostly). 81 SL_SAFEESCAPE, //!< In safe mode with the internal escape character, that escapes even the savemode character. 82 SL_COMMENT, //!< In Comment mode. 83 SL_PARENTHESES, //!< Between parentheses (usually '(' and ')') 84 SL_PARENTHESESESCAPE, //!< Between parentheses with the internal escape character, that escapes even the closing paranthesis character. 85 } SPLIT_LINE_STATE; 84 86 85 87 86 public:87 SubString();88 SubString(const std::string& string, char delimiter = ',');89 SubString(const std::string& string,90 const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries=false,91 char escapeChar ='\\', bool removeEscapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true,92 char openparenthesis_char = '(', char closeparenthesis_char = ')', bool removeParenthesisChars = true, char comment_char = '\0');93 SubString(unsigned int argc, const char** argv);94 /** @brief create a Substring as a copy of another one. @param subString the SubString to copy. */95 SubString(const SubString& subString) { *this = subString; };96 SubString(const SubString& subString, unsigned int subSetBegin);97 SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd);98 ~SubString();88 public: 89 SubString(); 90 SubString(const std::string& string, char delimiter = ','); 91 SubString(const std::string& string, 92 const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries=false, 93 char escapeChar ='\\', bool removeEscapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true, 94 char openparenthesis_char = '(', char closeparenthesis_char = ')', bool removeParenthesisChars = true, char comment_char = '\0'); 95 SubString(unsigned int argc, const char** argv); 96 /** @brief create a Substring as a copy of another one. @param subString the SubString to copy. */ 97 SubString(const SubString& subString) { *this = subString; }; 98 SubString(const SubString& subString, unsigned int subSetBegin); 99 SubString(const SubString& subString, unsigned int subSetBegin, unsigned int subSetEnd); 100 ~SubString(); 99 101 100 // operate on the SubString101 SubString& operator=(const SubString& subString);102 bool operator==(const SubString& subString) const;103 bool compare(const SubString& subString) const;104 bool compare(const SubString& subString, unsigned int length) const;105 SubString operator+(const SubString& subString) const;106 SubString& operator+=(const SubString& subString);107 /** @param subString the String to append @returns appended String. @brief added for convenience */108 SubString& append(const SubString subString) { return (*this += subString); };102 // operate on the SubString 103 SubString& operator=(const SubString& subString); 104 bool operator==(const SubString& subString) const; 105 bool compare(const SubString& subString) const; 106 bool compare(const SubString& subString, unsigned int length) const; 107 SubString operator+(const SubString& subString) const; 108 SubString& operator+=(const SubString& subString); 109 /** @param subString the String to append @returns appended String. @brief added for convenience */ 110 SubString& append(const SubString subString) { return (*this += subString); }; 109 111 110 /////////////////////////////////////////111 // Split and Join the any String. ///////112 unsigned int split(const std::string& string = "", char delimiter = ',');113 unsigned int split(const std::string& string,114 const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries = false,115 char escapeChar ='\\', bool removeExcapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true,116 char openparenthesis_char = '(', char closeparenthesis_char = ')', bool removeParenthesisChars = true, char comment_char = '\0');117 std::string join(const std::string& delimiter = " ") const;118 ////////////////////////////////////////112 ///////////////////////////////////////// 113 // Split and Join the any String. /////// 114 unsigned int split(const std::string& string = "", char delimiter = ','); 115 unsigned int split(const std::string& string, 116 const std::string& delimiters, const std::string& delimiterNeighbours = "", bool emptyEntries = false, 117 char escapeChar ='\\', bool removeExcapeChar = true, char safemode_char = '"', bool removeSafemodeChar = true, 118 char openparenthesis_char = '(', char closeparenthesis_char = ')', bool removeParenthesisChars = true, char comment_char = '\0'); 119 std::string join(const std::string& delimiter = " ") const; 120 //////////////////////////////////////// 119 121 120 // retrieve a SubSet from the String121 SubString subSet(unsigned int subSetBegin) const;122 SubString subSet(unsigned int subSetBegin, unsigned int subSetEnd) const;122 // retrieve a SubSet from the String 123 SubString subSet(unsigned int subSetBegin) const; 124 SubString subSet(unsigned int subSetBegin, unsigned int subSetEnd) const; 123 125 124 // retrieve Information from within125 /** @brief Returns true if the SubString is empty */126 inline bool empty() const { return this->strings.empty(); };127 /** @brief Returns the count of Strings stored in this substring */128 inline unsigned int size() const { return this->strings.size(); };129 /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */130 inline const std::string& operator[](unsigned int i) const { return this->strings[i]; };131 /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */132 inline const std::string& getString(unsigned int i) const { return (*this)[i]; };133 /** @brief Returns all Strings as std::vector */134 inline const std::vector<std::string>& getAllStrings() const { return this->strings; }135 /** @brief Returns true if the token is in safemode. @param i the i'th token */136 inline bool isInSafemode(unsigned int i) const { return this->bInSafemode[i]; }137 /** @brief Returns the front of the StringList. */138 inline const std::string& front() const { return this->strings.front(); };139 /** @brief Returns the back of the StringList. */140 inline const std::string& back() const { return this->strings.back(); };141 /** @brief removes the back of the strings list. */142 inline void pop_back() { this->strings.pop_back(); this->bInSafemode.pop_back(); };126 // retrieve Information from within 127 /** @brief Returns true if the SubString is empty */ 128 inline bool empty() const { return this->strings.empty(); }; 129 /** @brief Returns the count of Strings stored in this substring */ 130 inline unsigned int size() const { return this->strings.size(); }; 131 /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */ 132 inline const std::string& operator[](unsigned int i) const { return this->strings[i]; }; 133 /** @brief Returns the i'th string from the subset of Strings @param i the i'th String */ 134 inline const std::string& getString(unsigned int i) const { return (*this)[i]; }; 135 /** @brief Returns all Strings as std::vector */ 136 inline const std::vector<std::string>& getAllStrings() const { return this->strings; } 137 /** @brief Returns true if the token is in safemode. @param i the i'th token */ 138 inline bool isInSafemode(unsigned int i) const { return this->bInSafemode[i]; } 139 /** @brief Returns the front of the StringList. */ 140 inline const std::string& front() const { return this->strings.front(); }; 141 /** @brief Returns the back of the StringList. */ 142 inline const std::string& back() const { return this->strings.back(); }; 143 /** @brief removes the back of the strings list. */ 144 inline void pop_back() { this->strings.pop_back(); this->bInSafemode.pop_back(); }; 143 145 144 // the almighty algorithm.145 static SPLIT_LINE_STATE splitLine(std::vector<std::string>& ret,146 std::vector<bool>& bInSafemode,147 const std::string& line,148 const std::string& delimiters = SubString::WhiteSpaces,149 const std::string& delimiterNeighbours = "",150 bool emptyEntries = false,151 char escape_char = '\\',152 bool removeExcapeChar = true,153 char safemode_char = '"',154 bool removeSafemodeChar = true,155 char openparenthesis_char = '(',156 char closeparenthesis_char = ')',157 bool removeParenthesisChars = true,158 char comment_char = '\0',159 SPLIT_LINE_STATE start_state = SL_NORMAL);160 // debugging.161 void debug() const;146 // the almighty algorithm. 147 static SPLIT_LINE_STATE splitLine(std::vector<std::string>& ret, 148 std::vector<bool>& bInSafemode, 149 const std::string& line, 150 const std::string& delimiters = SubString::WhiteSpaces, 151 const std::string& delimiterNeighbours = "", 152 bool emptyEntries = false, 153 char escape_char = '\\', 154 bool removeExcapeChar = true, 155 char safemode_char = '"', 156 bool removeSafemodeChar = true, 157 char openparenthesis_char = '(', 158 char closeparenthesis_char = ')', 159 bool removeParenthesisChars = true, 160 char comment_char = '\0', 161 SPLIT_LINE_STATE start_state = SL_NORMAL); 162 // debugging. 163 void debug() const; 162 164 163 public:164 static const std::string WhiteSpaces;165 static const std::string WhiteSpacesWithComma;166 static const SubString NullSubString;165 public: 166 static const std::string WhiteSpaces; 167 static const std::string WhiteSpacesWithComma; 168 static const SubString NullSubString; 167 169 168 private: 169 std::vector<std::string> strings; //!< strings produced from a single string splitted in multiple strings 170 std::vector<bool> bInSafemode; 171 }; 170 private: 171 std::vector<std::string> strings; //!< strings produced from a single string splitted in multiple strings 172 std::vector<bool> bInSafemode; 173 }; 174 } 172 175 173 176 #endif /* __SubString_H__ */ -
code/branches/objecthierarchy/src/util/UtilPrereqs.h
r1747 r2111 60 60 // Forward declarations 61 61 //----------------------------------------------------------------------- 62 class ArgReader;63 class Convert;64 class ExprParser;65 class MultiType;66 class SubString;67 62 namespace orxonox 68 63 { 64 class Exception; 65 class ExprParser; 66 class IntVector2; 67 class IntVector3; 68 class MultiType; 69 69 class OutputBuffer; 70 70 class OutputBufferListener; 71 class Error;72 71 class OutputHandler; 72 class SignalHandler; 73 class SubString; 73 74 } 74 75
Note: See TracChangeset
for help on using the changeset viewer.