Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

Ignore:
Timestamp:
Nov 2, 2008, 12:38:26 PM (16 years ago)
Author:
rgrieder
Message:

Moved all util classes and functions to orxonox namespace.
Converted all code to 4 spaces/tab in util.

Location:
code/branches/objecthierarchy/src/util
Files:
25 edited

Legend:

Unmodified
Added
Removed
  • code/branches/objecthierarchy/src/util/CRC32.cc

    r1791 r2111  
    2929#include "CRC32.h"
    3030
     31namespace 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      }
    3141
    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}
    3459
    35     hbit=(crc32 & 0x80000000) ? 1 : 0;
    36     if (hbit != bit)
    37       crc32=(crc32<<1) ^ UTIL_CRC32POLY;
    38     else
    39       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 bit
    46       calcCRCBit(crc32, (data[i]&0x2)>>1); // 2nd bit
    47       calcCRCBit(crc32, (data[i]&0x3)>>2); // 3rd bit
    48       calcCRCBit(crc32, (data[i]&0x4)>>3); // 4th bit
    49       calcCRCBit(crc32, (data[i]&0x5)>>4); // 5th bit
    50       calcCRCBit(crc32, (data[i]&0x6)>>5); // 6th bit
    51       calcCRCBit(crc32, (data[i]&0x7)>>6); // 7th bit
    52       calcCRCBit(crc32, (data[i]&0x8)>>7); // 8th bit
    53     }
    54     return crc32;
    55   }
    56 
  • code/branches/objecthierarchy/src/util/CRC32.h

    r1791 r2111  
    3434#include "Integers.h"
    3535
    36 const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */
     36namespace orxonox
     37{
     38    const unsigned int UTIL_CRC32POLY = 0x04C11DB7; /* CRC-32 Polynom */
    3739
    38 _UtilExport void calcCRCBit(uint32_t &crc32, int bit);
     40    _UtilExport void calcCRCBit(uint32_t &crc32, int bit);
    3941
    40 _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength);
    41 
     42    _UtilExport uint32_t calcCRC(unsigned char *data, unsigned int dataLength);
     43}
    4244
    4345#endif /* _Util_CRC_H__ */
  • code/branches/objecthierarchy/src/util/Clipboard.cc

    r1791 r2111  
    3737
    3838#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
     47namespace orxonox
     48{
    4449
    4550    /**
     
    97102        return "";
    98103    }
    99 #else
    100     /////////////
    101     // Default //
    102     /////////////
     104}
    103105
     106#else /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
     107
     108/////////////
     109// Default //
     110/////////////
     111
     112namespace orxonox
     113{
    104114    std::string clipboard = ""; //!< Keeps the text of our internal clipboard
    105115
     
    123133        return clipboard;
    124134    }
    125 #endif
     135}
     136
     137#endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
  • code/branches/objecthierarchy/src/util/Clipboard.h

    r1791 r2111  
    4646#include <string>
    4747
    48 
    49 _UtilExport bool toClipboard(const std::string& text);
    50 _UtilExport std::string fromClipboard();
    51 
     48namespace orxonox
     49{
     50    _UtilExport bool toClipboard(const std::string& text);
     51    _UtilExport std::string fromClipboard();
     52}
    5253
    5354#endif /* _Clipboard_H__ */
  • code/branches/objecthierarchy/src/util/Convert.h

    r2017 r2111  
    6868#endif
    6969
    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 };
     70namespace 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}
    8689
    8790#if ORXONOX_COMPILER == ORXONOX_COMPILER_MSVC
     
    118121*/
    119122
    120 namespace
    121 {
    122     //! Little template that maps integers to entire types (Alexandrescu 2001)
    123     template <int I>
    124     struct Int2Type { };
     123namespace 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    };
    125165}
    126 
    127 
    128 ///////////////////
    129 // No Conversion //
    130 ///////////////////
    131 
    132 // Default template. No conversion available at all.
    133 template <class FromType, class ToType>
    134 struct ConverterFallback
    135 {
    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         else
    157             return false;
    158     }
    159 };
    160166
    161167
     
    170176    static bool convert(ToType* output, const FromType& input)
    171177    {
    172         return ConverterFallback<FromType, ToType>::convert(output, input);
     178        return orxonox::ConverterFallback<FromType, ToType>::convert(output, input);
    173179    }
    174180};
     
    185191    {
    186192        std::string temp;
    187         if (ConverterFallback<FromType, std::string>::convert(&temp, input))
     193        if (orxonox::ConverterFallback<FromType, std::string>::convert(&temp, input))
    188194        {
    189195            std::operator <<(outstream, temp);
     
    224230    inline bool operator >>(std::istream& instream, ToType& output)
    225231    {
    226         return ConverterFallback<std::string, ToType>
     232        return orxonox::ConverterFallback<std::string, ToType>
    227233            ::convert(&output, static_cast<std::istringstream&>(instream).str());
    228234    }
     
    247253};
    248254
    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);
     255namespace 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    };
    259491}
    260492
    261 // We can cast implicitely
    262 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 available
    275 template <class FromType, class ToType>
    276 struct ConverterExplicit
    277 {
    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 compile
    281         // We therefore have to out source it into another template function
    282         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 @brief
    294     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 section
    297     '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 ConvertValue
    306 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 @brief
    316     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 section
    319     'Actual conversion sequence' in this file above.
    320     If the conversion doesn't succeed, 'fallback' is written to '*output'.
    321 @param fallback
    322     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     else
    330     {
    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 Shortcut
    372 template <class FromType>
    373 inline std::string convertToString(FromType value)
    374 {
    375   return getConvertedValue<FromType, std::string>(value);
    376 }
    377 
    378 // convert from string Shortcut
    379 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::string
    390 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 stringstream
    400 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         else
    426             *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         else
    438             *output = '\0';
    439         return true;
    440     }
    441 };
    442 
    443 
    444 // bool to std::string
    445 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         else
    453           *output = "false";
    454         return false;
    455     }
    456 };
    457 
    458 // std::string to bool
    459 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         else
    480             return false;
    481     }
    482 };
    483 
    484493#endif /* _Convert_H__ */
  • code/branches/objecthierarchy/src/util/Debug.h

    r2034 r2111  
    6767#include "OutputHandler.h"
    6868
    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 level
    73 */
    74 static inline int getSoftDebugLevel()
    75 {
    76     return orxonox::OutputHandler::getSoftDebugLevel();
    77 }
    78 
    7969namespace orxonox
    8070{
     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
    8180    using std::endl;
    8281}
     
    115114  #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE
    116115   #define COUT0 \
    117     (getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0)
     116   (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : COUT_EXEC(0)
    118117  #else
    119118   #define COUT0 \
     
    123122  #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR
    124123   #define COUT1 \
    125     (getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1)
     124    (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : COUT_EXEC(1)
    126125  #else
    127126   #define COUT1 \
     
    131130  #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING
    132131   #define COUT2 \
    133     (getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2)
     132    (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : COUT_EXEC(2)
    134133  #else
    135134   #define COUT2 \
     
    139138  #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO
    140139   #define COUT3 \
    141     (getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3)
     140    (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : COUT_EXEC(3)
    142141  #else
    143142   #define COUT3 \
     
    147146  #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG
    148147   #define COUT4 \
    149     (getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4)
     148    (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : COUT_EXEC(4)
    150149  #else
    151150   #define COUT4 \
     
    155154  #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE
    156155   #define COUT5 \
    157     (getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5)
     156    (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : COUT_EXEC(5)
    158157  #else
    159158   #define COUT5 \
     
    163162  #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA
    164163   #define COUT6 \
    165     (getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6)
     164    (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : COUT_EXEC(6)
    166165  #else
    167166   #define COUT6 \
     
    199198  #if ORX_HARD_DEBUG_LEVEL >= ORX_NONE
    200199   #define CCOUT0 \
    201     (getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0)
     200    (orxonox::getSoftDebugLevel() < ORX_NONE) ? COUT_EXEC(0) : CCOUT_EXEC(0)
    202201  #else
    203202   #define CCOUT0 \
     
    207206  #if ORX_HARD_DEBUG_LEVEL >= ORX_ERROR
    208207   #define CCOUT1 \
    209     (getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1)
     208    (orxonox::getSoftDebugLevel() < ORX_ERROR) ? COUT_EXEC(1) : CCOUT_EXEC(1)
    210209  #else
    211210   #define CCOUT1 \
     
    215214  #if ORX_HARD_DEBUG_LEVEL >= ORX_WARNING
    216215   #define CCOUT2 \
    217     (getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2)
     216    (orxonox::getSoftDebugLevel() < ORX_WARNING) ? COUT_EXEC(2) : CCOUT_EXEC(2)
    218217  #else
    219218   #define CCOUT2 \
     
    223222  #if ORX_HARD_DEBUG_LEVEL >= ORX_INFO
    224223   #define CCOUT3 \
    225     (getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3)
     224    (orxonox::getSoftDebugLevel() < ORX_INFO) ? COUT_EXEC(3) : CCOUT_EXEC(3)
    226225  #else
    227226   #define CCOUT3 \
     
    231230  #if ORX_HARD_DEBUG_LEVEL >= ORX_DEBUG
    232231   #define CCOUT4 \
    233     (getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4)
     232    (orxonox::getSoftDebugLevel() < ORX_DEBUG) ? COUT_EXEC(4) : CCOUT_EXEC(4)
    234233  #else
    235234   #define CCOUT4 \
     
    239238  #if ORX_HARD_DEBUG_LEVEL >= ORX_VERBOSE
    240239   #define CCOUT5 \
    241     (getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5)
     240    (orxonox::getSoftDebugLevel() < ORX_VERBOSE) ? COUT_EXEC(5) : CCOUT_EXEC(5)
    242241  #else
    243242   #define CCOUT5 \
     
    247246  #if ORX_HARD_DEBUG_LEVEL >= ORX_ULTRA
    248247   #define CCOUT6 \
    249     (getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6)
     248    (orxonox::getSoftDebugLevel() < ORX_ULTRA) ? COUT_EXEC(6) : CCOUT_EXEC(6)
    250249  #else
    251250   #define CCOUT6 \
  • code/branches/objecthierarchy/src/util/Exception.cc

    r2101 r2111  
    8181        return fullDescription_;
    8282    }
    83 
    84 
    8583}
  • code/branches/objecthierarchy/src/util/Exception.h

    r2101 r2111  
    141141    CREATE_ORXONOX_EXCEPTION(NotImplemented);
    142142    CREATE_ORXONOX_EXCEPTION(GameState);
     143}
    143144
    144145#define ThrowException(type, description) \
     
    154155#endif
    155156
    156 }
    157 
    158157#endif /* _Exception_H__ */
  • code/branches/objecthierarchy/src/util/ExprParser.cc

    r1894 r2111  
    4545#define PARSE_BLANKS while (*reading_stream == ' ') ++reading_stream
    4646
    47 ExprParser::ExprParser(const std::string& str)
     47namespace orxonox
    4848{
    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        }
    60452    }
    61453}
    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     else
    74     {
    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     else
    89     {
    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 string
    244         this->failed_ = true;
    245         return 0;
    246     }
    247     else if (*reading_stream > 47 && *reading_stream < 59 || *reading_stream == 46)
    248     {  // number
    249         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 function
    253         char* word = new char[256];
    254         parse_word(word);
    255         PARSE_BLANKS;
    256         if (*reading_stream == '(')
    257         {
    258             ++reading_stream;
    259 #define SWITCH word
    260             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_ELSE
    335             {
    336                 this->failed_ = true;
    337                 delete[] word;
    338                 return 0;
    339             }
    340         }
    341         else
    342         {
    343 #define SWITCH word
    344             CASE_1("pi")
    345                 value = 3.1415926535897932;
    346             CASE("e")
    347                 value = 2.7182818284590452;
    348             CASE_ELSE
    349             {
    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 paranthesis
    359         ++reading_stream;
    360         value = parse_last_argument();
    361     }
    362     else
    363     {
    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         else
    425         {
    426             --reading_stream;
    427             return undef;
    428         }
    429     }
    430     else
    431         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  
    3838#include <string>
    3939
    40 class _UtilExport ExprParser
     40namespace orxonox
    4141{
    42 public:
    43     enum binary_operator
     42    class _UtilExport ExprParser
    4443    {
    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
    61100    };
    62101
    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}
    106109
    107110#endif /* _FloatParser_H__ */
  • code/branches/objecthierarchy/src/util/Math.cc

    r2019 r2111  
    3838#include "SubString.h"
    3939
    40 /**
    41     @brief Function for writing a Radian to a stream.
    42 */
    43 std::ostream& operator<<(std::ostream& out, const orxonox::Radian& radian)
     40namespace orxonox
    4441{
    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    }
    47336}
    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 position
    84     @param mydirection My viewing direction
    85     @param otherposition The position of the other object
    86     @return The angle
    87 
    88     @example
    89     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     else
    100         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 position
    106     @param mydirection My viewing direction
    107     @param myorthonormal My orthonormalvector (pointing upwards through my head)
    108     @param otherposition The position of the other object
    109     @return The viewing direction
    110 
    111     @example
    112     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 plane
    123     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     else
    132         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 position
    138     @param mydirection My viewing direction
    139     @param myorthonormal My orthonormalvector (pointing upwards through my head)
    140     @param otherposition The position of the other object
    141     @return The viewing direction
    142 
    143     @example
    144     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 plane
    155     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     else
    168         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 position
    174     @param projectilespeed The speed of my projectile
    175     @param targetposition The position of my target
    176     @param targetvelocity The velocity of my target
    177     @return The predicted position
    178 
    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 Vector2
    210 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     else
    216         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 Vector3
    233 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     else
    239         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 Vector4
    258 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     else
    264         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 Quaternion
    285 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 ColourValue
    308 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         else
    328             output->a = 1.0;
    329 
    330         return true;
    331     }
    332     return false;
    333 }
  • code/branches/objecthierarchy/src/util/Math.h

    r2019 r2111  
    4949#include <OgreQuaternion.h>
    5050#include <OgreColourValue.h>
    51 
    52 namespace orxonox
    53 {
    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);
    7451
    7552//Get around Windows hackery
     
    8360#endif
    8461
    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)
     62namespace orxonox
    9263{
    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    };
    94295}
    95296
    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 value
    117     @param min The lower limit
    118     @param max The upper limit
    119 */
    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 value
    181     @param max The operand
    182 */
    183 template <typename T>
    184 inline int mod(T x, int max)
    185 {
    186     if (x >= 0)
    187         return (x % max);
    188     else
    189         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 = 0
    227     @param end The value at time = 1
    228     @return The interpolation at a given time
    229 */
    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 = 0
    240     @param end The value at time = 1
    241     @return The smoothed interpolation at a given time
    242 */
    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 maximum
    260 */
    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 minimum
    269     @param max The maximum
    270 */
    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 IntVector2
    279 {
    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 IntVector3
    288 {
    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 
    297297#endif /* _Util_Math_H__ */
  • code/branches/objecthierarchy/src/util/MathConvert.h

    r2016 r2111  
    4040#include "Convert.h"
    4141
    42 
    43 ////////////////////
    44 // Math to string //
    45 ////////////////////
    46 
    47 // Vector2 to std::string
    48 template <>
    49 struct ConverterExplicit<orxonox::Vector2, std::string>
     42namespace orxonox
    5043{
    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}
    206208
    207209#endif /* _MathConvert_H__ */
  • code/branches/objecthierarchy/src/util/MultiType.cc

    r2002 r2111  
    3535#include "MultiTypeValue.h"
    3636
    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)
     37namespace orxonox
    4238{
    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)
    4444    {
    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. */
    94206}
    95 
    96 /**
    97     @brief Returns the name of the current type.
    98     @return The name
    99 */
    100 std::string MultiType::getTypename() const
    101 {
    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  
    7373#include "Math.h"
    7474
    75 /**
    76     @brief Enum of all possible types of a MultiType.
    77 */
    78 enum MT_Type
     75namespace orxonox
    7976{
    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_degree
    104 };
    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 primitves
    111      - all pointers
    112      - string
    113      - Vector2, Vector3, Vector4
    114      - Quaternion
    115      - ColourValue
    116      - Radian, Degree
    117 
    118     The internal type of a MultiType is determined by the first assigned value, but can be
    119     changed by using setType<T>(), convert<T>() or setValue<T>(value). If a value gets assigned
    120     the normal way (operator=, setValue(value)), the value gets converted to the current internal
    121     type of the MultiType.
    122 */
    123 class _UtilExport MultiType
    124 {
    125     _UtilExport friend std::ostream& operator<<(std::ostream& outstream, const MultiType& mt);
    126     template <typename T> friend struct MT_Value;
    127 
    12877    /**
    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.
    13179    */
    132     struct _UtilExport MT_ValueBase
     80    enum MT_Type
    13381    {
    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
    224106    };
    225107
     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
    226130    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}
    524529
    525530#endif /* _MultiType_H__ */
  • code/branches/objecthierarchy/src/util/MultiTypeValue.h

    r2016 r2111  
    4141#include "MultiType.h"
    4242
    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
     43namespace orxonox
    4844{
    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) {}
    5154
    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_); }
    5457
    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; }
    5760
    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)
    6263        {
    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            }
    6473        }
    65         else
    66         {
    67             this->value_ = zeroise<T>();
    68             return !(bHasDefaultValue_ = true);
    69         }
    70     }
    7174
    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. */
    9598
    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. */
    119122
    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. */
    143146
    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_; }
    146149
    147     T value_; //!< The stored value
    148 };
     150        T value_; //!< The stored value
     151    };
     152}
    149153
    150154#endif /* _MultiTypeValue_H__ */
  • code/branches/objecthierarchy/src/util/OutputBuffer.h

    r1854 r2111  
    5858        an OutputBuffer and this buffer changes.
    5959    */
    60     class _UtilExport OutputBufferListener
     60    class OutputBufferListener
    6161    {
    6262        friend class OutputBuffer;
  • code/branches/objecthierarchy/src/util/SignalHandler.cc

    r2101 r2111  
    4040#include <cstring>
    4141
    42 SignalHandler * SignalHandler::singletonRef = NULL;
     42namespace orxonox
     43{
     44    SignalHandler * SignalHandler::singletonRef = NULL;
     45}
    4346
    4447#if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32
     
    4952#include <X11/keysym.h>
    5053
    51 bool SignalHandler::bXAutoKeyRepeatOn_ = false;
    52 
    53 SignalHandler::SignalHandler()
     54namespace orxonox
    5455{
     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    }
    55358}
    56359
    57 /**
    58  * register signal handlers for SIGSEGV and SIGABRT
    59  * @param appName path to executable eg argv[0]
    60  * @param filename filename to append backtrace to
    61  */
    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 XAutoKeyRepeat
    68   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     else
    76       bXAutoKeyRepeatOn_ = false;
    77     XCloseDisplay(display);
    78   }
    79   else
    80   {
    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 dontCatch
    87   assert( sigRecList.size() == 0 );
    88 
    89   catchSignal( SIGSEGV );
    90   catchSignal( SIGABRT );
    91   catchSignal( SIGILL );
    92 }
    93 
    94 /**
    95  * restore previous signal handlers
    96  */
    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 sig
    109  * @param sig signal to catch
    110  */
    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 signals
    126  * @param sig
    127  */
    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 process
    179   if ( sigPid == 0 )
    180   {
    181     getInstance()->dontCatch();
    182     // wait for message from parent when it has attached gdb
    183     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 gdb
    209 
    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 gdb
    221 
    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     else
    252       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     else
    289       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 
    354360#endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
  • code/branches/objecthierarchy/src/util/SignalHandler.h

    r2101 r2111  
    4040#include <string>
    4141
    42 typedef int (*SignalCallback)( void * someData );
     42namespace orxonox
     43{
     44    typedef int (*SignalCallback)( void * someData );
     45}
    4346
    4447#if ORXONOX_PLATFORM != ORXONOX_PLATFORM_WIN32
    4548#include <signal.h>
    4649
    47 struct SignalRec
     50namespace orxonox
    4851{
    49   int signal;
    50   sig_t handler;
    51 };
     52    struct SignalRec
     53    {
     54        int signal;
     55        sig_t handler;
     56    };
    5257
    53 struct SignalCallbackRec
    54 {
    55   SignalCallback cb;
    56   void * someData;
    57 };
     58    struct SignalCallbackRec
     59    {
     60        SignalCallback cb;
     61        void * someData;
     62    };
    5863
    5964
    60 typedef std::list<SignalRec> SignalRecList;
    61 typedef std::list<SignalCallbackRec> SignalCallbackList;
     65    typedef std::list<SignalRec> SignalRecList;
     66    typedef std::list<SignalCallbackRec> SignalCallbackList;
    6267
    63 class SignalHandler
    64 {
    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; }
    7075
    71     void registerCallback( SignalCallback cb, void * someData );
     76        void registerCallback( SignalCallback cb, void * someData );
    7277
    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();
    7580
    76   private:
    77     static void sigHandler( int sig );
     81    private:
     82        static void sigHandler( int sig );
    7883
    79     void catchSignal( int sig );
    80     SignalRecList sigRecList;
     84        void catchSignal( int sig );
     85        SignalRecList sigRecList;
    8186
    82     SignalCallbackList callbackList;
     87        SignalCallbackList callbackList;
    8388
    84     static SignalHandler * singletonRef;
     89        static SignalHandler * singletonRef;
    8590
    86     std::string appName;
    87     std::string filename;
     91        std::string appName;
     92        std::string filename;
    8893
    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}
    9298
    9399#else /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
    94100
    95 class _UtilExport SignalHandler
     101namespace orxonox
    96102{
    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 ) {};
    102110
    103   private:
    104     static SignalHandler * singletonRef;
    105 };
     111    private:
     112        static SignalHandler * singletonRef;
     113    };
     114}
    106115
    107116#endif /* ORXONOX_PLATFORM == ORXONOX_PLATFORM_WIN32 */
  • code/branches/objecthierarchy/src/util/Sleep.h

    r1841 r2111  
    4141#include <winbase.h>
    4242
    43 inline void usleep(DWORD dwMicroseconds)
     43namespace orxonox
    4444{
    45   Sleep(dwMicroseconds / 1000);
    46 }
     45    inline void usleep(DWORD dwMicroseconds)
     46    {
     47        Sleep(dwMicroseconds / 1000);
     48    }
    4749
    48 inline void msleep(DWORD dwMilliseconds)
    49 {
    50   Sleep(dwMilliseconds);
    51 }
     50    inline void msleep(DWORD dwMilliseconds)
     51    {
     52        Sleep(dwMilliseconds);
     53    }
    5254
    53 inline void sleep(DWORD dwSeconds)
    54 {
    55   Sleep(dwSeconds * 1000);
     55    inline void sleep(DWORD dwSeconds)
     56    {
     57        Sleep(dwSeconds * 1000);
     58    }
    5659}
    5760
     
    6063#include <unistd.h>
    6164
    62 inline void msleep(unsigned long msec)
     65namespace orxonox
    6366{
    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    }
    6579}
    6680
  • code/branches/objecthierarchy/src/util/String.cc

    r2020 r2111  
    4040#include "Math.h"
    4141
    42 std::string BLANKSTRING("");
    43 
    44 std::string getUniqueNumberString()
     42namespace orxonox
    4543{
    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    }
    47494}
    48 
    49 /**
    50     @brief Removes all whitespaces from a string.
    51     @param str The string to strip
    52 */
    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 strip
    67     @return The stripped line
    68 */
    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 string
    79     @return The modified copy
    80 */
    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 string
    93     @param start The startposition
    94     @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 string
    118     @param pos The position to check
    119     @return True if pos is between two quotes
    120 */
    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 string
    144     @return True if there is something between quotes
    145 */
    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 string
    156     @param The string between the quotes
    157 */
    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     else
    165         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 strip
    171     @return The string with removed quotes
    172 */
    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     else
    205         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 strip
    211     @return The striped string
    212 */
    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 check
    226     @return True = it's a comment
    227 
    228     A comment is defined by a leading '#', '%', ';' or '//'.
    229 */
    230 bool isComment(const std::string& str)
    231 {
    232     // Strip the line, whitespaces are disturbing
    233     std::string teststring = getStripped(str);
    234 
    235     // There are four possible comment-symbols:
    236     //  1) #comment in script-language style
    237     //  2) %comment in matlab style
    238     //  3) ;comment in unreal tournament config-file style
    239     //  4) //comment in code style
    240     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 check
    257     @return True = it's empty
    258 */
    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 check
    268     @return True = it's a number
    269 */
    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             else
    281                 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 manipulate
    291     @return The string with added slashes
    292 */
    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 manipulate
    314     @return The string with removed slashes
    315 */
    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 convert
    349 */
    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 string
    361     @return The copy
    362 */
    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 convert
    373 */
    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 string
    385     @return The copy
    386 */
    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 string
    397     @param s2 Second string
    398 */
    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 reached
    405     while ( (it1!=s1.end()) && (it2!=s2.end()) )
    406     {
    407         if(::toupper(*it1) != ::toupper(*it2)) //letters differ?
    408             // return -1 to indicate smaller than, 1 otherwise
    409             return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
    410         //proceed to the next character in each string
    411         ++it1;
    412         ++it2;
    413     }
    414     size_t size1=s1.size(), size2=s2.size();// cache lengths
    415     //return -1,0 or 1 according to strings' lengths
    416     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 string
    425     @param s2 Second string
    426     @param len Maximal number of chars to compare
    427 */
    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 reached
    436     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 otherwise
    440             return (::toupper(*it1)  < ::toupper(*it2)) ? -1 : 1;
    441         //proceed to the next character in each string
    442         ++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 string
    451     @return True if the string contains a comment
    452 */
    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 string
    461     @return The comment
    462 */
    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 string
    471     @return The position
    472 */
    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 string
    481     @param start The startposition
    482     @return The position
    483 */
    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  
    4040#include <sstream>
    4141
    42 extern _UtilExport std::string BLANKSTRING;
    43 _UtilExport std::string getUniqueNumberString();
     42namespace orxonox
     43{
     44    extern _UtilExport std::string BLANKSTRING;
     45    _UtilExport std::string getUniqueNumberString();
    4446
    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);
    4749
    48 _UtilExport std::string removeTrailingWhitespaces(const std::string& str);
     50    _UtilExport std::string removeTrailingWhitespaces(const std::string& str);
    4951
    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);
    5254
    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);
    5557
    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);
    5860
    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);
    6264
    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);
    6567
    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);
    6870
    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);
    7173
    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);
    7476
    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}
    7982
    8083#endif /* _Util_String_H__ */
  • code/branches/objecthierarchy/src/util/SubString.cc

    r1791 r2111  
    4040#include "SubString.h"
    4141
    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)
     42namespace orxonox
    5543{
    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)
    390541            token = token.substr(0, token.size() - fallBackNeighbours);
    391           /// FINISH
    392           if(emptyEntries || token.size() > 0)
    393           {
     542        if(emptyEntries || token.size() > 0)
     543        {
    394544            ret.push_back(token);
    395545            token.clear();
    396546            bInSafemode.push_back(inSafemode);
    397547            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    }
    548563}
    549 
    550 
    551 /**
    552  * @brief Some nice debug information about this SubString
    553  */
    554 void SubString::debug() const
    555 {
    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  
    6464#include <string>
    6565
    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
     66namespace orxonox
    7267{
    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;
    8486
    8587
    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();
    99101
    100   // operate on the SubString
    101   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); };
    109111
    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        ////////////////////////////////////////
    119121
    120   // retrieve a SubSet from the String
    121   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;
    123125
    124   // retrieve Information from within
    125   /** @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(); };
    143145
    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;
    162164
    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;
    167169
    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}
    172175
    173176#endif /* __SubString_H__ */
  • code/branches/objecthierarchy/src/util/UtilPrereqs.h

    r1747 r2111  
    6060// Forward declarations
    6161//-----------------------------------------------------------------------
    62 class ArgReader;
    63 class Convert;
    64 class ExprParser;
    65 class MultiType;
    66 class SubString;
    6762namespace orxonox
    6863{
     64    class Exception;
     65    class ExprParser;
     66    class IntVector2;
     67    class IntVector3;
     68    class MultiType;
    6969    class OutputBuffer;
    7070    class OutputBufferListener;
    71     class Error;
    7271    class OutputHandler;
     72    class SignalHandler;
     73    class SubString;
    7374}
    7475
Note: See TracChangeset for help on using the changeset viewer.