|
| 1 | + |
| 2 | +/// |
| 3 | +/// @page miscellaneous Miscellaneous |
| 4 | +/// |
| 5 | +/// This page contains generral information about some objects that are sued globally in the ModAPI. |
| 6 | +/// |
| 7 | +/// @tableofcontents |
| 8 | +/// |
| 9 | +/// @section eastl EASTL, containers and the STL |
| 10 | +/// |
| 11 | +/// In C++, when you want to create a vector, you normally include the <vector.h> class and use a std::vector. |
| 12 | +/// In Spore, that is different; Spore uses its own containers included in the EASTL (which is included in the ModAPI). |
| 13 | +/// Instead of including <vector.h>, you need to include <EASTL\vector.h>; instead of std::vector, you must use eastl::vector |
| 14 | +/// (note that most ModAPI headers have a "using namespace eastl" directive, making the 'eastl::' part unnecessary most of the times). |
| 15 | +/// |
| 16 | +/// @section objects Objects and memory management |
| 17 | +/// |
| 18 | +/// Memory management in C++ can be a bit troubling. Spore and the ModAPI use a method for all its classes known as |
| 19 | +/// reference counting. Basically, instead of using naked pointers, like IEffect*, you wrap them into an |
| 20 | +/// eastl::intrusive_ptr<IEffect>. Everytime the pointer is assigned, it will increase or decrease the reference count |
| 21 | +/// accordingly; when the reference count reaches 0, the object will delete itself. |
| 22 | +/// ~~~~~~~~~~~~~~~~~~~~~~~{.cpp} |
| 23 | +/// intrusive_ptr<Window> pEffect = new Window(); |
| 24 | +/// // you don't have to worry about deleting the object |
| 25 | +/// ~~~~~~~~~~~~~~~~~~~~~~~ |
| 26 | +/// Most methods don't take intrusive_ptrs as parameters, but normal pointers. To get the pointer value, use the .get() method: |
| 27 | +/// ~~~~~~~~~~~~~~~~~~~~~~~{.cpp} |
| 28 | +/// intrusive_ptr<App::PropertyList> pProp; |
| 29 | +/// ... |
| 30 | +/// bool bValue = false; |
| 31 | +/// // The first parameter is an App::PropertyList* |
| 32 | +/// App::Property::GetBool(pProp.get(), 0x00B13042, bValue); |
| 33 | +/// ~~~~~~~~~~~~~~~~~~~~~~~ |
| 34 | +/// You must be aware, however, of cyclic intrusion. Imagine that object A has an intrusive_ptr member that points to object B, |
| 35 | +/// and object B has an intrusive_ptr member that points to object A. Those objects would never be deleted because they |
| 36 | +/// would always have another object pointing to them. Therefore, you must be aware of the structure of your objects when |
| 37 | +/// using intrusive_ptrs. |
| 38 | +/// |
| 39 | +/// Most interfaces and classes in the ModAPI declare an AddRef() and Release() method, which are necessary for reference |
| 40 | +/// counting and therefore automatic memory management. Some classes have already defined its implementation; sometimes, |
| 41 | +/// however, you will have to implement them. Here is a simple example of how they work: |
| 42 | +/// ~~~~~~~~~~~~~~~~~~~~~~~{.cpp} |
| 43 | +/// // assuming 'MyClass' has an int member called 'mnRefCount', which must be initialized to 0 in the constructor. |
| 44 | +/// int AddRef() |
| 45 | +/// { |
| 46 | +/// mnRefCount++; |
| 47 | +/// return mnRefCount; |
| 48 | +/// } |
| 49 | +/// int Release() |
| 50 | +/// { |
| 51 | +/// mnRefCount--; |
| 52 | +/// if (mnRefCount == 0) delete this; |
| 53 | +/// return mnRefCount; |
| 54 | +/// } |
| 55 | +/// ~~~~~~~~~~~~~~~~~~~~~~~ |
| 56 | +/// |
| 57 | +/// The class Object is a standard class that is the base of a lot of classes in the ModAPI. It is reference counted. |
| 58 | +/// An interesting thing is the Object::Cast() and object_cast. Dynamic casting is not used in Spore, but this is the alternative. |
| 59 | +/// Classes that inherit the Object class define a Cast method which can be used to dynamically cast an object to another type. |
| 60 | +/// The Cast method takes an uint32_t as a paramter; that type identifier is a static member called 'TYPE' in most of the |
| 61 | +/// classes that support this type of casting. For example: |
| 62 | +/// ~~~~~~~~~~~~~~~~~~~~~~~{.cpp} |
| 63 | +/// // All mean the same |
| 64 | +/// auto pImageDrawable = object_cast<UTFWin::IImageDrawable>(pDrawable); |
| 65 | +/// UTFWin::IImageDrawable* pImageDrawable = object_cast<UTFWin::IImageDrawable>(pDrawable); |
| 66 | +/// UTFWin::IImageDrawable* pImageDrawable = (UTFWin::IImageDrawable*) pDrawable->Cast(UTFWin::IImageDrawable::TYPE); |
| 67 | +/// ~~~~~~~~~~~~~~~~~~~~~~~ |
| 68 | +/// If 'pDrawable' is of type IImageDrawable, that will be returned; otherwise, Cast must return nullptr. That can be |
| 69 | +/// used to check in runtime whether an object is of an specific type. |
| 70 | +/// |
| 71 | +/// Using the "ModAPI Object" item template will create a new Object class that supports casting and reference counting, |
| 72 | +/// with a unique TYPE value. |
| 73 | +/// |
| 74 | +/// @section resource_keys IDs and resource keys |
| 75 | +/// |
| 76 | +/// If you look at Spore files, you will always end up seeing something like #4f803d98. That's an hexadecimal integer number; |
| 77 | +/// to simplify, we usually call them hashes. They are used to identify files, types, etc, so they are often called IDs as well. |
| 78 | +/// Even if you see a normal name, that's just the string representation of an ID. To get the hash ID from a certain name, use the |
| 79 | +/// id() function inside the Hash.h header. |
| 80 | +/// ~~~~~~~~~~~~~~~~~~~~~~~{.cpp} |
| 81 | +/// // We want to get the effect "SG_ufo_scan_HitGround", but we don't know what ID that is. |
| 82 | +/// uint32_t effectID = id("SG_ufo_scan_HitGround"); |
| 83 | +/// ~~~~~~~~~~~~~~~~~~~~~~~ |
| 84 | +/// |
| 85 | +/// The ResourceKey class is very common. If you have had a look inside .package files in Spore, you will have noticed |
| 86 | +/// that a file always has three things: the name of the file, the extension, and the folder. In technical terms, those |
| 87 | +/// are the instance ID, type ID and group ID, respectively. To identify a file, Spore uses the ResourceKey struct, |
| 88 | +/// which just contains those three IDs. |
| 89 | +/// |
| 90 | +/// @section math The Math namespace |
| 91 | +/// |
| 92 | +/// The ModAPI contains a namespace called Math with multiple classes that represent mathematical objects such as vectors, |
| 93 | +/// matrices and colors. Apart from some specific methods, these are just containers with no functionalities; therefore, |
| 94 | +/// you will probably need other libraries in order to make advanced operations with these types. |
| 95 | +/// |
| 96 | +/// @section localization Localization |
| 97 | +/// |
| 98 | +/// Spore supports multiple languages. In order to use localized strings (i.e. text that depends on the current language |
| 99 | +/// of the game) you need to use the LocalizedString class in the LocalizedString.h header. Localized texts are identified by |
| 100 | +/// a table ID and an instance ID. The table ID is the ID of a .locale file in the locale~ folder, which contains the translation. |
| 101 | +/// The instance ID is the specific ID of that translation inside that file. |
| 102 | +/// |
0 commit comments