Examples » Core » Reflection » Basic Usage

Defining and using reflectable types.

Lets say you have a type Person, which you want to be able to reflect. You can declare it as reflectable using the macro CUBOS_REFLECT, for example, in your header, like this:

#include <cubos/core/reflection/reflect.hpp>

struct Person
{
    CUBOS_REFLECT;
    int age;
    float weight;
};

The file core/reflection/reflect.hpp is a very lightweight header which you should include when declaring types as reflectable. It only defines the reflection macros and the reflection function. Avoid including other unnecessary reflection headers, which might be heavier, in order to reduce compile times.

In your source file, you must define the reflection data for your type. This is done through the CUBOS_REFLECT_IMPL macro:

#include <cubos/core/reflection/type.hpp>

using cubos::core::reflection::Type;

CUBOS_REFLECT_IMPL(Person)
{
    return Type::create("Person");
}

To access this reflection data, you should use the cubos::core::reflection::reflect function, which is also defined in the core/reflection/reflect.hpp header.

int main()
{
    using cubos::core::reflection::reflect;

    const auto& personType = reflect<Person>();
    CUBOS_ASSERT(personType.name() == "Person");

Lets say you want to associate your own data to your types, to describe them further. For example, imagine you're making a GUI editor for your game and you which to display the fields of your types in a tree view, with different colors for different types. You could associate colors to your types by defining a trait:

struct ColorTrait
{
    CUBOS_REFLECT;
    float r, g, b;
};

Now, when you define your type reflection, you add your trait with the Type::with method.

CUBOS_REFLECT_IMPL(ColorTrait)
{
    return Type::create("ColorTrait");
}

CUBOS_REFLECT_IMPL(Position)
{
    return Type::create("Position").with(ColorTrait{.r = 0.0F, .g = 1.0F, .b = 0.0F});
}

To check if a type has a trait, you use the Type::has method.

    const auto& positionType = reflect<Position>();
    CUBOS_ASSERT(positionType.has<ColorTrait>());
    CUBOS_ASSERT(!personType.has<ColorTrait>());

To actually access the trait data, you use the Type::get method.

    const auto& colorTrait = positionType.get<ColorTrait>();
    CUBOS_ASSERT(colorTrait.r == 0.0F);
    CUBOS_ASSERT(colorTrait.g == 1.0F);
    CUBOS_ASSERT(colorTrait.b == 0.0F);
    return 0;
}