= MultiType = [[TracNav(TracNav/TOC_Development)]] [[TOC]] == Introduction == The !MultiType is a fancy class, designed to accept values of almost every type and to return exactly this value in almost every other type - depending on your needs. This allows you to assign a string, for example "105.3", to a !MultiType and to let the !MultiType return 105.3 as a float. But what is this good for? Well, just think of an XML level. You write all values as strings, the [wiki:Loader] loads the level, creates new objects and passes the values to the objects. But how should the Loader know, which type a value has? It just loads a string! Thats why the Loader puts the string into a !MultiType and passes it to the new object. The object receives the !MultiType and C++ does an implicit conversion to the requested type. == Introducing example == This is what you got: {{{ SomeType value = XXXX; // a value void function(OtherType value); // a function }}} This is what you want: {{{ function(value); // call the function with the value }}} This is what you know about SomeType and OtherType: {{{ // nothing }}} This is how you're doing it: {{{ function(MultiType(value)); }}} Isn't it cool? Sure it is! Of course SomeType and OtherTypecan't be anything, otherwise the class would be called AnyType and probably being useless. Read the [wiki:MultiType#Types chapter about the supported types] for more information. == Usage == === Assign a value === There are three ways to assign a value to a !MultiType: * '''Constructor''': !MultiType myMT = 10; * Assignment '''operator=''': !MultiType myMT myMT = 10; * '''setValue('''''value''''')''': !MultiType myMT myMT.setValue(10); Important: If you assign a value of a specific type and then assign a new value of another type, the new value will be converted to the first type. Read the [wiki:MultiType#Internaltype section below] for detailed information. === Retrieve a value === There are four three to retrieve a value from a !MultiType: * '''Implicit''' conversion: float value = myMT; (or float value = (float)myMT;) * Get by pointer: '''getValue('''''pointer''''')''': float value = 0; myMT.getValue(&value); * Explicit function call: '''getXXXX()''' float value = myMT.getFloat(). If the current value of the !MultiType has another type, it will be converted to the implicitly or explicitly requested type. === Internal type === It's very important to know the !MultiType has some sort of an internal type. It's the type of the first assigned value. If you assign another value of another type, it will be converted to the first type. If you don't know about this, you may get many unnecessary conversions. But if you know about it, you can save much CPU time. Example: * Think about a function, receiving a float, and a !MultiType, containing a string. If you want to call the function 100'000 times, you will convert the string every f***ing time into a float. So you better create a !MultiType with internal type ''float'' and assign the string afterward. This way the string gets already converted when assigned and you save 99'999 conversions. But of course you can change this type: === Change type === There are three possible ways to change the internal type of a !MultiType: * '''setType<'''''type'''''>()''': This changes the type and resets the value. * '''convert<'''''type'''''>()''': This changes the type and converts the current value to the new type. * '''setValue<'''''type'''''>('''''value''''')''': This changes the type and assigns a new value. The new value may be of another value than ''type'', it will be converted. === Interaction with other !MultiTypes === * You can assign a !MultiType to another !MultiType. The value of the other !MultiType will then be converted to the internal type of the first !MultiType: myMT '''=''' otherMT; or myMT.'''setValue('''''otherMT''''')'''; * If you don't want to convert the value of the other !MultiType but assigning value AND type, use myMT.'''copy('''''otherMT''''')'''. * You can convert the value of a !MultiType to the type of another !MultiType by calling myMT.'''convert('''''otherMT''''')'''. * You can do the same with myMT.'''setType('''''otherMT''''')'''. * Of course myMT.'''setValue<'''''type'''''>('''''otherMT''''')''' works too. == Types == These are the types supported by !MultiType: * All primitives: * char * unsigned char * short * unsigned short * int * unsigned int * long * unsigned long * long long * unsigned long long * float * double * long double * bool * All pointers (but be careful with inheritance, in fact it's just handled as a void pointer) * std::string * Math objects: * Vector2 * Vector3 * Vector4 * Quaternion * ColourValue * Radian * Degree == Examples == {{{ MultiType value = 10; // internal type: int, value: 10 value = 12.3; // internal type: int, value: 12 // Note: The internal type is still int value.setValue("100"); // internal type: int, value: 100 // Note: The string was converted to an int value.setValue(12.3); // internal type: float, value: 12.3f // Note: Now we changed the type to float and the value // 12.3 can now be assigned without loss of precision value.convert(); // internal type: int, value: 12 // Note: We converted the value back to int, so it's 12 again value.setValue("50"); // internal type: float, value: 50.0f // Note: We changed the type to float We assigned the string "50" The string was converted to the float 50.0f }}} {{{ MultiType value1 = "10"; // value1: internal type: string, value: "10" MultiType value2; // value2: currently empty value2.setType(); // value2: internal type: float, value: 0.0f value2 = value1; // value2: internal type: float, value: 10.0f }}} {{{ MultiType value1 = 10; // value1: internal type: int, value: 10 MultiType value2 = 12.3; // value2: internal type: float, value: 12.3 value2.convert(value1); // value2: internal type: int, value: 12 // Note: The internal type of value2 was converted to the internal type of value1 (int) // Therefore the value of value2 is now 12 instead of 12.3 }}}