Skip to content

Native properties

Julien SOYSOUVANH edited this page Jun 5, 2022 · 6 revisions

Index

All native properties must be written with their namespace. The code generator will not work properly if one writes:

namespace ExampleNamespace NAMESPACE(ParseAllNested) {}

instead of:

namespace ExampleNamespace NAMESPACE(kodgen::ParseAllNested) {}

ParseAllNested

Valid entities: Namespace, Struct, Class
Header file: Refureku/Properties/ParseAllNested.h

The ParseAllNested property is a hint to the code generator to reflect all nested entities automatically.

#include <Refureku/Properties/ParseAllNested.h>

namespace ExampleNamespace NAMESPACE(kodgen::ParseAllNested)
{
    //This enum is reflected even without the ENUM() macro
    enum class ExampleEnum {};
};

Instantiator

Valid entity: Static method returning rfk::SharedPtr<OuterClass> or rfk::UniquePtr<OuterClass>.
Header file: Refureku/Properties/Instantiator.h

The Instantiator property is used to provide custom ways of instantiating a struct or class through the rfk::Struct::makeSharedInstance and rfk::makeUniqueInstance methods. An Instantiator tagged method MUST be static and return a rfk::SharedPtr or rfk::UniquePtr to the outer class. If the method doesn't fulfill those requirements, the compilation will fail with an explicit error message.

Using the Instantiator property on a parameterless method will override the default instantiator of the class (which is a simple call to the default constructor if it exists).

#include <Refureku/Properties/Instantiator.h>

class CLASS() ExampleClass
{
    private:
        METHOD(rfk::Instantiator)
        static rfk::SharedPtr<ExampleClass> customInstantiator(int i, float f)
        {
            return rfk::makeShared<ExampleClass>(i, f);
        }

    public:
        ExampleClass(int i, float f) {}

    ExampleClass_GENERATED
};

Now, the rfk::Struct::makeSharedInstance will automatically call the customInstantiator method if the provided parameters match:

rfk::Class const* c = ExampleClass::staticGetArchetype();

//ExampleClass will be instantiated through customInstantiator
rfk::SharedPtr<ExampleClass> instance = c.makeSharedInstance<ExampleClass>(42, 3.14f);

Instantiators returning rfk::SharedPtr are usable only through a rfk::Struct::makeSharedInstance call.
Instantiators returning rfk::UniquePtr are usable through both rfk::Struct::makeUniqueInstance and rfk::Struct::makeSharedInstance. However, note that there is a small performance overhead when the rfk::Struct::makeSharedInstance internally uses a unique instantiator since it first instantiates a rfk::UniquePtr which pointer is released and then passed to a new rfk::SharedPtr.

Unique and shared instantiators are split to allow providing custom deleters, which is only possible for shared pointers without changing the actual return type (the custom deleter type is erased).

PropertySettings

Valid entity: Struct or Class deriving from rfk::Property
Header file: Refureku/Properties/PropertySettings.h

PropertySettings allows to define how a property should be used. It takes 3 parameters (the 2nd and 3rd ones being optional):

  1. targetEntityKind: The kind of entities the property can be attached to. Use the | operator to make a mask of all entities the property can be attached to.
  2. allowMultiple: Is this property allowed to be attached multiple times to the same entity?
  3. shouldInherit: This argument is only relevant if targetEntityKind contains at least one of Struct, Class or Method. When set to true, this property will be inherited by structs/classes inheriting from any struct/class using this property. It works the same for methods override.
#include <Refureku/Properties/PropertySettings.h>

class CLASS(rfk::PropertySettings(rfk::EEntityKind::Class | rfk::EEntityKind::Function, false, true))
    ExampleProperty : public rfk::Property
{
    public:
        int value = 0;

        ExampleProperty(int v = 0):
            value{v}
        {}

    ExampleProperty_GENERATED
};
//OK
FUNCTION(ExampleProperty)
void func();
//Compilation error, ExampleProperty can't be used more than once per entity (allowMultiple: false)
FUNCTION(ExampleProperty, ExampleProperty)
void func2();
//Compilation error since rfk::EEntityKind::Enum is not part of the targetEntityKind mask of ExampleProperty
enum class ENUM(ExampleProperty) TestEnum {};
//OK
class CLASS(ExampleProperty) TestClass { TestClass_GENERATED };

//TestClass2 inherits from TestClass' ExampleProperty
class CLASS() TestClass2 : public TestClass { TestClass2_GENERATED };

TestClass2::staticGetArchetype().getProperty<ExampleProperty>() != nullptr; //true
//allowMultiple is false, so override the inherited ExampleProperty
class CLASS(ExampleProperty(42)) TestClass3 : public TestClass
{
    TestClass3_GENERATED
};

TestClass3::staticGetArchetype().getProperty<ExampleProperty>()->value == 42; //true
Clone this wiki locally