You.i Engine
YiRtti.h File Reference

This file contains the classes and macros used to implement RTTI in You.i Engine. More...

#include "utility/YiPreprocessorMacros.h"
#include "utility/YiString.h"
#include "utility/YiRtti.inl"

Go to the source code of this file.

Classes

class  CYIRuntimeTypeInfo
 The abstract runtime representation of a C++ type. More...
 
class  CYIRuntimeTypeInfoTyped< CLASS, BASES >
 The runtime representation of a C++ type. More...
 
class  RTTISampleClass
 This is a sample class to document the RTTI functions inserted into classes by the YI_TYPE_BASES(...) macro. More...
 

Macros

#define YI_TYPE_BASES(CLASS, BASES...)
 
#define YI_TYPE_DEF(CLASS, BASES...)
 
#define YI_TYPE_DEF_WITH_NAME(CLASS, NAME, BASES...)
 
#define YI_TYPE_DEF_INST(CLASS, BASES...)
 
#define YI_TYPE_DEF_INST_WITH_NAME(CLASS, NAME, BASES...)
 

Functions

template<typename TARGET , typename SOURCE >
TARGET * YiDynamicCast (SOURCE *pObject)
 Casts the pointer pObject to type T*. More...
 
template<typename TARGET , typename SOURCE >
std::shared_ptr< TARGET > YiDynamicPointerCast (const std::shared_ptr< SOURCE > &pObject)
 Casts the shared pointer pObject to shared pointer type T*. More...
 
template<typename TARGET , typename SOURCE >
std::shared_ptr< TARGET > YiDynamicCast (const std::shared_ptr< SOURCE > &pObject)
 Casts the shared pointer pObject to shared pointer type T*. More...
 
template<typename T >
std::unique_ptr< T > YiRTTINew (CYIStringView name)
 Creates a new instance of the type identifed by name. More...
 
const CYIRuntimeTypeInfoYiGetTypeInfo (const char *pTypeName)
 
const CYIRuntimeTypeInfoYiGetTypeInfo (CYIStringView typeName)
 
template<typename T >
const CYIRuntimeTypeInfoYiGetTypeInfo (T *pObject)
 

Detailed Description

This file contains the classes and macros used to implement RTTI in You.i Engine.

The two main uses of the You.i Engine RTTI are to enable runtime-instantiation of classes based on their name, and to allow downcasting runtime types. This is implemented in the YiRTTINew<T>() and YiDynamicCast<T>(P*) functions.

All subclasses of CYISceneView must contain RTTI type information in order to enable runtime instantiation of those views.

To declare a custom type as being an RTTI type, add the YI_TYPE_BASES(...) macro to its class declaration (header), and the YI_TYPE_DEF(...) macro to its class definition (implementation).

Note
Prevously a different macro, YI_TYPE_DEF_INST, needed to be used to indicate that a class could be default-instantiated. This is no longer necessary as the RTTI system automatically recognises when classes can be instantiated with a default constructor.

This is an example of the use of RTTI:

// Header (.h)
class RttiSampleView : public CYISceneView
{
public:
RttiSampleView();
void Foo();
// The first parameter is the name of this class, and the second is the parent class
YI_TYPE_BASES(RttiSampleView, CYISceneView)
};
// Implementation (.cpp)
// The parameters passed to this macro must match those passed to YI_TYPE_BASES.
YI_TYPE_DEF(RttiSampleView, CYISceneView)
RttiSampleView::RttiSampleView()
{
}
void RttiSampleView::Foo()
{
// Foo implementation
}
// Usage
void RttiExampleCalls()
{
// Creating an object using RTTI
std::unique_ptr<CYISceneView> pView = YiRTTINew<CYISceneView>("RttiSampleView");
// Casting using RTTI
RttiSampleView *pActual = YiDynamicCast<RttiSampleView>(pView.get());
pActual->Foo();
// Obtaining a type object
const CYIRuntimeTypeInfo &dynamicType = pView->GetRuntimeTypeInfo();
const CYIRuntimeTypeInfo &staticType = RttiSampleView::GetClassTypeInfo();
// Comparing types
if (dynamicType == staticType)
{
std::cout << "Types are equal." << std::endl;
}
// Checking casting ability and accessing type name
if (pActual->GetRuntimeTypeInfo().CanCastTo<CYISceneView>())
{
std::cout << "Type '" << pActual->GetRuntimeTypeInfo().GetName() << "' can cast to CYISceneView." << std::endl;
}
}

In some cases, it's necessary to mark a class as non-instantiable (e.g. if code for a header is conditionally-compiled). This can be done by adding a (public) tag to the required class. For example:

class MyClass
{
public:
using RTTIInstantiatability = CYIRuntimeTypeInfo::NonInstantiableTag;
};

Similar tags are available to mark a class as instantiable, which is useful for subclasses, or to re-enable autodetection of instantiatability.