Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed VARIANT_ENUM/BITFIELD_CAST to show the correct names #956

Merged
merged 1 commit into from
Jan 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions binding_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
if is_included_type(builtin_api["name"]):
if "enums" in builtin_api:
for enum_api in builtin_api["enums"]:
builtin_binds.append(f"VARIANT_ENUM_CAST({builtin_api['name']}, {enum_api['name']});")
builtin_binds.append(f"VARIANT_ENUM_CAST({builtin_api['name']}::{enum_api['name']});")

builtin_binds.append("")
builtin_binds.append("#endif // ! GODOT_CPP_BUILTIN_BINDS_HPP")
Expand Down Expand Up @@ -1381,9 +1381,9 @@ def generate_engine_class_header(class_api, used_classes, fully_used_classes, us
if "enums" in class_api and class_name != "Object":
for enum_api in class_api["enums"]:
if enum_api["is_bitfield"]:
result.append(f'VARIANT_BITFIELD_CAST({class_name}, {class_name}::{enum_api["name"]});')
result.append(f'VARIANT_BITFIELD_CAST({class_name}::{enum_api["name"]});')
else:
result.append(f'VARIANT_ENUM_CAST({class_name}, {class_name}::{enum_api["name"]});')
result.append(f'VARIANT_ENUM_CAST({class_name}::{enum_api["name"]});')
result.append("")

result.append(f"#endif // ! {header_guard}")
Expand Down Expand Up @@ -1621,7 +1621,7 @@ def generate_global_constant_binds(api, output_dir):
if enum_def["name"].startswith("Variant."):
continue

header.append(f'VARIANT_ENUM_CAST(, godot::{enum_def["name"]});')
header.append(f'VARIANT_ENUM_CAST(godot::{enum_def["name"]});')

header.append("")

Expand Down
76 changes: 38 additions & 38 deletions include/godot_cpp/core/binder_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,46 +41,46 @@

namespace godot {

#define VARIANT_ENUM_CAST(m_class, m_enum) \
namespace godot { \
MAKE_ENUM_TYPE_INFO(m_class, m_enum) \
template <> \
struct VariantCaster<m_class::m_enum> { \
static _FORCE_INLINE_ m_class::m_enum cast(const Variant &p_variant) { \
return (m_class::m_enum)p_variant.operator int64_t(); \
} \
}; \
template <> \
struct PtrToArg<m_class::m_enum> { \
_FORCE_INLINE_ static m_class::m_enum convert(const void *p_ptr) { \
return m_class::m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \
} \
typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(m_class::m_enum p_val, void *p_ptr) { \
*reinterpret_cast<int64_t *>(p_ptr) = p_val; \
} \
}; \
#define VARIANT_ENUM_CAST(m_enum) \
namespace godot { \
MAKE_ENUM_TYPE_INFO(m_enum) \
template <> \
struct VariantCaster<m_enum> { \
static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
return (m_enum)p_variant.operator int64_t(); \
} \
}; \
template <> \
struct PtrToArg<m_enum> { \
_FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
return m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \
} \
typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(m_enum p_val, void *p_ptr) { \
*reinterpret_cast<int64_t *>(p_ptr) = p_val; \
} \
}; \
}

#define VARIANT_BITFIELD_CAST(m_class, m_enum) \
namespace godot { \
MAKE_BITFIELD_TYPE_INFO(m_class, m_enum) \
template <> \
struct VariantCaster<BitField<m_class::m_enum>> { \
static _FORCE_INLINE_ BitField<m_class::m_enum> cast(const Variant &p_variant) { \
return BitField<m_class::m_enum>(p_variant.operator int64_t()); \
} \
}; \
template <> \
struct PtrToArg<BitField<m_class::m_enum>> { \
_FORCE_INLINE_ static BitField<m_class::m_enum> convert(const void *p_ptr) { \
return BitField<m_class::m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
} \
typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(BitField<m_class::m_enum> p_val, void *p_ptr) { \
*reinterpret_cast<int64_t *>(p_ptr) = p_val; \
} \
}; \
#define VARIANT_BITFIELD_CAST(m_enum) \
namespace godot { \
MAKE_BITFIELD_TYPE_INFO(m_enum) \
template <> \
struct VariantCaster<BitField<m_enum>> { \
static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
return BitField<m_enum>(p_variant.operator int64_t()); \
} \
}; \
template <> \
struct PtrToArg<BitField<m_enum>> { \
_FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
} \
typedef int64_t EncodeT; \
_FORCE_INLINE_ static void encode(BitField<m_enum> p_val, void *p_ptr) { \
*reinterpret_cast<int64_t *>(p_ptr) = p_val; \
} \
}; \
}

template <class T>
Expand Down
52 changes: 31 additions & 21 deletions include/godot_cpp/core/type_info.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -214,21 +214,31 @@ struct GetTypeInfo<const T *, typename EnableIf<TypeInherits<Object, T>::value>:
}
};

#define TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_impl) \
template <> \
struct GetTypeInfo<m_impl> { \
static const Variant::Type VARIANT_TYPE = Variant::INT; \
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
static inline PropertyInfo get_class_info() { \
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, #m_class "." #m_enum); \
} \
inline String enum_qualified_name_to_class_info_name(const String &p_qualified_name) {
PackedStringArray parts = p_qualified_name.split("::", false);
if (parts.size() <= 2) {
return String(".").join(parts);
}
// Contains namespace. We only want the class and enum names.
return parts[parts.size() - 2] + "." + parts[parts.size() - 1];
}

#define TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_impl) \
template <> \
struct GetTypeInfo<m_impl> { \
static const Variant::Type VARIANT_TYPE = Variant::INT; \
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
static inline PropertyInfo get_class_info() { \
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, \
enum_qualified_name_to_class_info_name(#m_enum)); \
} \
};

#define MAKE_ENUM_TYPE_INFO(m_class, m_enum) \
TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum) \
TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum const) \
TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum &) \
TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, const m_class::m_enum &)
#define MAKE_ENUM_TYPE_INFO(m_enum) \
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum) \
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum const) \
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum &) \
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, const m_enum &)

template <typename T>
inline StringName __constant_get_enum_name(T param, StringName p_constant) {
Expand All @@ -251,14 +261,14 @@ class BitField {
_FORCE_INLINE_ operator Variant() const { return value; }
};

#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_impl) \
#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_impl) \
template <> \
struct GetTypeInfo<m_impl> { \
static const Variant::Type VARIANT_TYPE = Variant::INT; \
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
static inline PropertyInfo get_class_info() { \
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
#m_class "." #m_enum); \
enum_qualified_name_to_class_info_name(#m_enum)); \
} \
}; \
template <> \
Expand All @@ -267,15 +277,15 @@ class BitField {
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
static inline PropertyInfo get_class_info() { \
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
#m_class "." #m_enum); \
enum_qualified_name_to_class_info_name(#m_enum)); \
} \
};

#define MAKE_BITFIELD_TYPE_INFO(m_class, m_enum) \
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum) \
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum const) \
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum &) \
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, const m_enum &)
#define MAKE_BITFIELD_TYPE_INFO(m_enum) \
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum) \
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum const) \
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum &) \
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, const m_enum &)

template <typename T>
inline StringName __constant_get_bitfield_name(T param, StringName p_constant) {
Expand Down
6 changes: 6 additions & 0 deletions test/demo/main.gd
Original file line number Diff line number Diff line change
Expand Up @@ -73,5 +73,11 @@ func _ready():
prints(" ANSWER_TO_EVERYTHING", $Example.ANSWER_TO_EVERYTHING)
prints(" CONSTANT_WITHOUT_ENUM", $Example.CONSTANT_WITHOUT_ENUM)

prints("BitFields")
prints(" FLAG_ONE", Example.FLAG_ONE)
prints(" FLAG_TWO", Example.FLAG_TWO)
prints(" returned BitField", $Example.test_bitfield(0))
prints(" returned BitField", $Example.test_bitfield(Example.FLAG_ONE | Example.FLAG_TWO))

func _on_Example_custom_signal(signal_name, value):
prints("Example emitted:", signal_name, value)
11 changes: 11 additions & 0 deletions test/src/example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ void Example::_bind_methods() {
ClassDB::bind_method(D_METHOD("test_string_ops"), &Example::test_string_ops);
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_ops);

ClassDB::bind_method(D_METHOD("test_bitfield", "flags"), &Example::test_bitfield);

ClassDB::bind_method(D_METHOD("def_args", "a", "b"), &Example::def_args, DEFVAL(100), DEFVAL(200));

ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
Expand Down Expand Up @@ -169,7 +171,11 @@ void Example::_bind_methods() {
BIND_ENUM_CONSTANT(FIRST);
BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);

BIND_BITFIELD_FLAG(FLAG_ONE);
BIND_BITFIELD_FLAG(FLAG_TWO);

BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
}

Example::Example() {
Expand Down Expand Up @@ -304,6 +310,11 @@ Dictionary Example::test_dictionary() const {
return dict;
}

BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
UtilityFunctions::print(" Got BitField: ", String::num(flags));
return flags;
}

// Properties.
void Example::set_custom_position(const Vector2 &pos) {
custom_position = pos;
Expand Down
15 changes: 14 additions & 1 deletion test/src/example.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,11 @@ class Example : public Control {
ANSWER_TO_EVERYTHING = 42,
};

enum Flags {
FLAG_ONE = 1,
FLAG_TWO = 2,
};

enum {
CONSTANT_WITHOUT_ENUM = 314,
};
Expand Down Expand Up @@ -104,6 +109,8 @@ class Example : public Control {
String test_string_ops() const;
int test_vector_ops() const;

BitField<Flags> test_bitfield(BitField<Flags> flags);

// Property.
void set_custom_position(const Vector2 &pos);
Vector2 get_custom_position() const;
Expand All @@ -117,7 +124,13 @@ class Example : public Control {
virtual bool _has_point(const Vector2 &point) const override;
};

VARIANT_ENUM_CAST(Example, Constants);
VARIANT_ENUM_CAST(Example::Constants);
VARIANT_BITFIELD_CAST(Example::Flags);

enum EnumWithoutClass {
OUTSIDE_OF_CLASS = 512
};
VARIANT_ENUM_CAST(EnumWithoutClass);

class ExampleVirtual : public Object {
GDCLASS(ExampleVirtual, Object);
Expand Down