Skip to content

Reflect entities

Julien SOYSOUVANH edited this page Nov 4, 2021 · 9 revisions

Index

There are a few ways to reflect entities. The most conventional way to do this is to attach a macro to the reflected entity declaration, but it is also possible to reflect multiple entities at once.

Reflection macro

Struct

struct STRUCT() ExampleStruct
{
    ExampleStruct_GENERATED //Inject code in the struct
};

Class

class CLASS() ExampleClass
{
    ExampleClass_GENERATED //Inject code in the class
};

Note: For nested structs and classes, the generated macro name contains the names of the outer entities as well to avoid name collisions:

namespace ReflectedNamespace NAMESPACE()
{
    class CLASS() ExampleClass
    {
        ReflectedNamespace_ExampleClass_GENERATED
    };
}
class CLASS() OuterClass
{
    class CLASS() ExampleClass
    {
        OuterClass_ExampleClass_GENERATED
    };

    OuterClass_GENERATED
};

Class/Struct template

//TestClassTemplate.h

template <typename T>
class CLASS() TestClassTemplate
{
    TestClassTemplate_T_GENERATED
};

File_TestClassTemplate_GENERATED //file macro

//Must write 1 explicit instantiation AFTER the file macro
//The template parameter type doesn't matter
template class CLASS() TestClassTemplate<int>;

Field / Static field

class CLASS() ExampleClass
{
    FIELD()
    int reflectedField;

    //Can be written inline as well
    FIELD() static int reflectedStaticField;

    ExampleClass_GENERATED
};

Method / Static method

class CLASS() ExampleClass
{
    METHOD()
    void reflectedMethod();

    //Can be written inline as well
    METHOD() static void reflectedStaticMethod();

    ExampleClass_GENERATED
};

Enum / Enum class

//Just remove class keyword for a simple enum
enum class ENUM() ExampleEnum
{
};

Enum value

When an enum/enum class is reflected, all its enum values are also reflected by default. The enum value macro can still be used to attach properties to enum values:

enum class ENUM() ExampleEnum
{
    Value1 ENUMVALUE(CustomProperty) = 0
};

Function

FUNCTION()
void reflectedFunction();

//Can be written inline as well
FUNCTION() void reflectedFunction2();

Variable

VARIABLE()
int reflectedVariable;

//Can be written inline as well
VARIABLE() float reflectedVariable2;

Namespace

//Note that the macro is AFTER the namespace name
namespace reflected_namespace NAMESPACE()
{
}

C++17 nested namespace declaration is also supported, but note that all namespaces will be assigned the same properties:

namespace reflected_namespace::nested_namespace NAMESPACE()
{
}

Change reflection macro names

The reflection macro name for each entity can be changed by updating the values of [Entity]macroName in the RefurekuSettings.toml file:

[ParsingSettings]
enumMacroName = "MYENUM"

We can now write:

enum class MYENUM() ReflectedEnum {};

Warning: You must ensure that entity macro names don't collide with other symbol names in the program, or it will lead to weird compilation errors. For example enum (c++ keyword) and Enum (rfk::Enum) are forbidden.

ParseAllNested property

See here.

Code generator setting

In the RefurekuSettings.toml file, it is possible to turn the shouldParseAllEntities option to true to automatically reflect all entities contained in parsed files.

[ParsingSettings]
shouldParseAllEntities = true