Sleeping Wombat Common Library  0.50.0
swCommonLibrary
Classes
Reflection

Biblioteka zapewnia dynamiczną kontrolę typów obiektów oraz mechanizmy rejestrowania metainformacji. More...

Classes

class  Object
 Base clas for all objects in sleeping wombat libraries. More...
 

Detailed Description

Biblioteka zapewnia dynamiczną kontrolę typów obiektów oraz mechanizmy rejestrowania metainformacji.

Silnik wykorzystuje bibliotekę RTTR autorstwa Axela Menzela udostępnianą na licencji MIT z małymi przeróbkami. Dokumentacja i przykłady znajdują się na stronie: http://www.rttr.org/

Tworzenie własnych klas

Przy tworzeniu własnych klas należy dodawać do nich metainformacje, aby edytor mógł je poprawnie wyświetlić. Wszystkie klasy powinny mieć na samym szczycie hierarchi dziedziczenia obiekt Object. Jeżeli dziedziczy się po jakiejś silnikowej klasie aktora, to Object w tej hierarchi na pewno się znajduje.

Pamiętać o tym należy tylko wtedy, gdy tworzy się jakąś strukturę lub klasę, która będzie polem w klasie aktora. Aby edytor mógł wyświetlać propertisy takiej zagnieżdżonej klasy trzeba jawnie odziedziczyć po Object.

Należy mieć na uwadze, że klasa Object deklaruje metody virtualne biblioteki RTTR, w związku z czym wszystkie klasy dziedziczące będą miały dodatkowe pole ze wskaźnikiem na vtable, co zwiększy rozmiar takiej struktury. Z tego powodu lepiej jest, gdy aktorzy nie mają płaską strukturę i takich zagnieżdżonych strutkur się nie używa, ale nikt nie zabrania.

Todo:
W obecnej wersji silnika wymaganie posiadania Object w hierarchii nie jest już konieczne z punktu widzenia edytora. W kolejnych wersjach trzeba zmienić mechanizmy serializacji, żeby potrafiły zapisywać również takie struktury.

Deklarowanie typów obiektów

Biblioteka RTTR wymaga deklarowania nowych typów dla które mają być przez nią obsługiwane. Typy proste, które nie mają być wyświetlane w edytorze, ale ma być dla nich używana statyczna kontrola typu, mogą zostać zadeklarowane w następujący sposób:

// Plik .h
struct NewType
{};
//Plik .cpp
RTTR_REGISTRATION
{
using namespace rttr;
RTTR_REGISTRATION_STANDARD_TYPE_VARIANTS( NewType )
}

Jeżeli dla klasy ma być używana dynamiczna kontrola typów, trzeba zadeklarować hierarchię dziedziczenia w każdej z klas. Robi się to w następujący sposób:

// Plik .h
class StaticActor : public Object
{
RTTR_ENABLE( Object )
//...
};

Następnie w pliku .cpp można dodać metadane klasy. Nazwy własciwości nie powinny zawierać białych znaków, ponieważ to może powodować problemy przy serializacji do XMLa.

RTTR_REGISTRATION
{
rttr::registration::class_< StaticActor >( "StaticActor" )
.property( "Position", &StaticActor::position )
(
rttr::metadata( MetaDataType::Category, "Transformation" ),
rttr::policy::prop::BindAsPtr()
)
.property( "Orientation", &StaticActor::orientation )
(
rttr::metadata( MetaDataType::Category, "Transformation" ),
rttr::policy::prop::BindAsPtr()
);
}

Aktorzy z klasami zagnieżdżonymi

Typy złożone jak DirectX::XMFLOAT3 powinny być deklarowane z polityką rttr::policy::prop::BindAsPtr() (Tak jak w przykładzie powyżej). W przeciwnym razie edytor nie będzie mógł ich odczytywać i zapisywać. Podobnie sprawa ma się ze strutkurami wewnątrz klasy np:

struct Nested : public Object
{
int variable1;
int variable2;
};
class Actor : public StaticActor
{
public:
Nested nestedField;
}

W takim przypadku trzeba dodać informację o propertisach również dla klasy Nested:

// Plik .cpp
RTTR_REGISTRATION
{
rttr::registration::class_< Nested >( "Nested" )
.property( "variable1", &Nested::variable1 )
.property( "variable2", &Nested::variable2 );
rttr::registration::class_< Actor >( "Actor" )
.property( "nestedField", &Actor::nestedField )
(
rttr::metadata( MetaDataType::Category, "OwnCategory" ),
rttr::policy::prop::BindAsPtr()
)
}
#endcode
Typy podstawowe jak
- int
- float
- double
- bool
nie mogą być deklarowane z polityką BindAsPtr.
@subsection PrivateMembers Prywatne składowe klasy
W przypadku prywatnych składowych, deklaracja metadanych nie skompiluje się, ponieważ prywatne pola są niedostępne
na zewnątrz klasy. Aby móc je zadeklarować należy dodać makro RTTR_REGISTRATION_FRIEND.
@code
class StaticActor : public Object
{
RTTR_ENABLE( Object )
RTTR_REGISTRATION_FRIEND
//...
};