#ifndef UTILS_GODOT_MACROS_HPP #define UTILS_GODOT_MACROS_HPP /*! \file godot_macros.hpp * \brief C-style preprocessor macros to simplify using godot's C++ API. */ #include #include #include #define MACRO_STRING_INNER(_Arg) #_Arg #define MACRO_STRING(_Arg) MACRO_STRING_INNER(_Arg) /*! \def GDPROPERTY(PropName_, PropType_) * \brief Register property. * * Register variable CLASSNAME::PropName_ with variant type PropType_. * Requires setting CLASSNAME as a #define first. Also requires a CLASSNAME::get_PropName_ and CLASSNAME::set_PropName_ to exist. */ #define GDPROPERTY(PropName_, PropType_) \ godot::ClassDB::bind_method(godot::D_METHOD("get_" #PropName_), &CLASSNAME::get_##PropName_); \ godot::ClassDB::bind_method(godot::D_METHOD("set_" #PropName_, "value"), &CLASSNAME::set_##PropName_); \ godot::ClassDB::add_property(MACRO_STRING(CLASSNAME), godot::PropertyInfo(PropType_, #PropName_), "set_" #PropName_, "get_" #PropName_) /*! \def GDPROPERTY_HINTED(PropName_, PropType_, ...) * \brief Register a hinted property. * * Register variable CLASSNAME::PropName_ with variant type PropType_. * Requires setting CLASSNAME as a #define first, and CLASSNAME::get_PropName and CLASSNAME::set_PropName_ to exist. */ #define GDPROPERTY_HINTED(PropName_, PropType_, ...) \ godot::ClassDB::bind_method(godot::D_METHOD("get_" #PropName_), &CLASSNAME::get_##PropName_); \ godot::ClassDB::bind_method(godot::D_METHOD("set_" #PropName_, "value"), &CLASSNAME::set_##PropName_); \ godot::ClassDB::add_property(MACRO_STRING(CLASSNAME), godot::PropertyInfo(PropType_, #PropName_, __VA_ARGS__), "set_" #PropName_, "get_" #PropName_) /*! \def GDFUNCTION(FnName_) * \brief Register a function CLASSNAME::FnName_() to godot. * * Requires setting CLASSNAME as a #define first. */ #define GDFUNCTION(FnName_) godot::ClassDB::bind_method(godot::D_METHOD(#FnName_), &CLASSNAME::FnName_) /*! \def GDFUNCTION_ARGS(FnName_, ...) * \brief Register a function CLASSNAME::FnName_(...) to godot. * * Requires setting CLASSNAME as a #define first. */ #define GDFUNCTION_ARGS(FnName_, ...) godot::ClassDB::bind_method(godot::D_METHOD(#FnName_, __VA_ARGS__), &CLASSNAME::FnName_) /*! \def GDFUNCTION_STATIC(FnName_) * \brief Register a static member function CLASSNAME::FnName_() to godot. * * Requires setting CLASSNAME as a #define first. */ #define GDFUNCTION_STATIC(FnName_) godot::ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), godot::D_METHOD(#FnName_), &CLASSNAME::_FnName) /*! \def GDFUNCTION_STATIC_ARGS(FnName_, ...) * \brief Register a static member function CLASSNAME::FnName_(...) to godot. * * Requires setting CLASSNAME as a #define first. */ #define GDFUNCTION_STATIC_ARGS(FnName_, ...) godot::ClassDB::bind_static_method(MACRO_STRING(CLASSNAME), godot::D_METHOD(#FnName_, __VA_ARGS__), &CLASSNAME::FnName_) /*! \def GDSIGNAL(...) * \brief Declare a godot Observer signal. */ #define GDSIGNAL(...) godot::ClassDB::add_signal(MACRO_STRING(CLASSNAME), godot::MethodInfo(__VA_ARGS__)) /*! \def GDRESOURCETYPE(Class_) * \brief Construct godot resource type hint. * * Use when registering properties of arrays of resource classes. */ #define GDRESOURCETYPE(Class_) godot::vformat("%s/%s:%s", godot::Variant::OBJECT, godot::PROPERTY_HINT_RESOURCE_TYPE, Class_) #define GDNODETYPE(Class_) godot::vformat("%s/%s:%s", godot::Variant::OBJECT, godot::PROPERTY_HINT_NODE_TYPE, Class_) #define GDENUMTYPE(EnumString_) godot::vformat("%s/%s:%s", godot::Variant::INT, godot::PROPERTY_HINT_ENUM, EnumString_) /*! \def GDEDITORONLY() * \brief Execute the rest of the function only if currently running as editor. * * Useful for _ready, _enter/_exit, _process, etc. functions. */ #define GDEDITORONLY() if(!godot::Engine::get_singleton()->is_editor_hint()) return; /*! \def GDGAMEONLY() * \brief Execute the rest of the function only if currently running as game. * * Useful for _ready, _enter/_exit, _process, etc. functions. */ #define GDGAMEONLY() if(godot::Engine::get_singleton()->is_editor_hint()) return; /*! \def GDENUM(Name_, ...) * \brief Declare a scoped enum struct. * * Declares a struct Name_ with an enum Value and a single variable and a get_property_hint() function. */ #define GDENUM(Name_, ...)\ struct Name_ {\ public:\ enum Value : uint32_t {__VA_ARGS__};\ private:\ Value value{};\ public:\ static inline godot::String get_property_hint() { return godot::String(#__VA_ARGS__); }\ inline Name_(Value value) : value{value} {}\ inline Name_(uint32_t value) : value{value} {}\ inline Name_(int value) : value{static_cast(value)} {}\ inline Name_(Name_ const &value) : value{value.value} {}\ inline bool operator==(Name_ const &rhs) const { return this->value == rhs.value; }\ inline bool operator==(Value const &rhs) const { return this->value == rhs; }\ inline bool operator!=(Name_ const &rhs) const { return this->value != rhs.value; }\ inline bool operator!=(Value const &rhs) const { return this->value != rhs; }\ inline operator Value() const { return this->value; }\ inline operator uint32_t() const { return this->value; }\ inline operator int() const { return static_cast(this->value); }\ } #endif // !UTILS_GODOT_MACROS_HPP