Fixed variant casting for enum and bitfield
parent
860182fe01
commit
6528c7177f
|
@ -336,7 +336,7 @@ def generate_builtin_bindings(api, output_dir, build_config):
|
||||||
if is_included_type(builtin_api["name"]):
|
if is_included_type(builtin_api["name"]):
|
||||||
if "enums" in builtin_api:
|
if "enums" in builtin_api:
|
||||||
for enum_api in builtin_api["enums"]:
|
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("")
|
||||||
builtin_binds.append("#endif // ! GODOT_CPP_BUILTIN_BINDS_HPP")
|
builtin_binds.append("#endif // ! GODOT_CPP_BUILTIN_BINDS_HPP")
|
||||||
|
@ -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":
|
if "enums" in class_api and class_name != "Object":
|
||||||
for enum_api in class_api["enums"]:
|
for enum_api in class_api["enums"]:
|
||||||
if enum_api["is_bitfield"]:
|
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:
|
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("")
|
||||||
|
|
||||||
result.append(f"#endif // ! {header_guard}")
|
result.append(f"#endif // ! {header_guard}")
|
||||||
|
@ -1621,7 +1621,7 @@ def generate_global_constant_binds(api, output_dir):
|
||||||
if enum_def["name"].startswith("Variant."):
|
if enum_def["name"].startswith("Variant."):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
header.append(f'VARIANT_ENUM_CAST(, godot::{enum_def["name"]});')
|
header.append(f'VARIANT_ENUM_CAST(godot::{enum_def["name"]});')
|
||||||
|
|
||||||
header.append("")
|
header.append("")
|
||||||
|
|
||||||
|
|
|
@ -41,46 +41,46 @@
|
||||||
|
|
||||||
namespace godot {
|
namespace godot {
|
||||||
|
|
||||||
#define VARIANT_ENUM_CAST(m_class, m_enum) \
|
#define VARIANT_ENUM_CAST(m_enum) \
|
||||||
namespace godot { \
|
namespace godot { \
|
||||||
MAKE_ENUM_TYPE_INFO(m_class, m_enum) \
|
MAKE_ENUM_TYPE_INFO(m_enum) \
|
||||||
template <> \
|
template <> \
|
||||||
struct VariantCaster<m_class::m_enum> { \
|
struct VariantCaster<m_enum> { \
|
||||||
static _FORCE_INLINE_ m_class::m_enum cast(const Variant &p_variant) { \
|
static _FORCE_INLINE_ m_enum cast(const Variant &p_variant) { \
|
||||||
return (m_class::m_enum)p_variant.operator int64_t(); \
|
return (m_enum)p_variant.operator int64_t(); \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
template <> \
|
template <> \
|
||||||
struct PtrToArg<m_class::m_enum> { \
|
struct PtrToArg<m_enum> { \
|
||||||
_FORCE_INLINE_ static m_class::m_enum convert(const void *p_ptr) { \
|
_FORCE_INLINE_ static m_enum convert(const void *p_ptr) { \
|
||||||
return m_class::m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \
|
return m_enum(*reinterpret_cast<const int64_t *>(p_ptr)); \
|
||||||
} \
|
} \
|
||||||
typedef int64_t EncodeT; \
|
typedef int64_t EncodeT; \
|
||||||
_FORCE_INLINE_ static void encode(m_class::m_enum p_val, void *p_ptr) { \
|
_FORCE_INLINE_ static void encode(m_enum p_val, void *p_ptr) { \
|
||||||
*reinterpret_cast<int64_t *>(p_ptr) = p_val; \
|
*reinterpret_cast<int64_t *>(p_ptr) = p_val; \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define VARIANT_BITFIELD_CAST(m_class, m_enum) \
|
#define VARIANT_BITFIELD_CAST(m_enum) \
|
||||||
namespace godot { \
|
namespace godot { \
|
||||||
MAKE_BITFIELD_TYPE_INFO(m_class, m_enum) \
|
MAKE_BITFIELD_TYPE_INFO(m_enum) \
|
||||||
template <> \
|
template <> \
|
||||||
struct VariantCaster<BitField<m_class::m_enum>> { \
|
struct VariantCaster<BitField<m_enum>> { \
|
||||||
static _FORCE_INLINE_ BitField<m_class::m_enum> cast(const Variant &p_variant) { \
|
static _FORCE_INLINE_ BitField<m_enum> cast(const Variant &p_variant) { \
|
||||||
return BitField<m_class::m_enum>(p_variant.operator int64_t()); \
|
return BitField<m_enum>(p_variant.operator int64_t()); \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
template <> \
|
template <> \
|
||||||
struct PtrToArg<BitField<m_class::m_enum>> { \
|
struct PtrToArg<BitField<m_enum>> { \
|
||||||
_FORCE_INLINE_ static BitField<m_class::m_enum> convert(const void *p_ptr) { \
|
_FORCE_INLINE_ static BitField<m_enum> convert(const void *p_ptr) { \
|
||||||
return BitField<m_class::m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
|
return BitField<m_enum>(*reinterpret_cast<const int64_t *>(p_ptr)); \
|
||||||
} \
|
} \
|
||||||
typedef int64_t EncodeT; \
|
typedef int64_t EncodeT; \
|
||||||
_FORCE_INLINE_ static void encode(BitField<m_class::m_enum> p_val, void *p_ptr) { \
|
_FORCE_INLINE_ static void encode(BitField<m_enum> p_val, void *p_ptr) { \
|
||||||
*reinterpret_cast<int64_t *>(p_ptr) = p_val; \
|
*reinterpret_cast<int64_t *>(p_ptr) = p_val; \
|
||||||
} \
|
} \
|
||||||
}; \
|
}; \
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
|
|
@ -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) \
|
inline String enum_qualified_name_to_class_info_name(const String &p_qualified_name) {
|
||||||
template <> \
|
PackedStringArray parts = p_qualified_name.split("::", false);
|
||||||
struct GetTypeInfo<m_impl> { \
|
if (parts.size() <= 2) {
|
||||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
return String(".").join(parts);
|
||||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
}
|
||||||
static inline PropertyInfo get_class_info() { \
|
// Contains namespace. We only want the class and enum names.
|
||||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_ENUM, #m_class "." #m_enum); \
|
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) \
|
#define MAKE_ENUM_TYPE_INFO(m_enum) \
|
||||||
TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum) \
|
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum) \
|
||||||
TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum const) \
|
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum const) \
|
||||||
TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, m_class::m_enum &) \
|
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, m_enum &) \
|
||||||
TEMPL_MAKE_ENUM_TYPE_INFO(m_class, m_enum, const m_class::m_enum &)
|
TEMPL_MAKE_ENUM_TYPE_INFO(m_enum, const m_enum &)
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline StringName __constant_get_enum_name(T param, StringName p_constant) {
|
inline StringName __constant_get_enum_name(T param, StringName p_constant) {
|
||||||
|
@ -251,14 +261,14 @@ public:
|
||||||
_FORCE_INLINE_ operator Variant() const { return value; }
|
_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 <> \
|
template <> \
|
||||||
struct GetTypeInfo<m_impl> { \
|
struct GetTypeInfo<m_impl> { \
|
||||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||||
static inline PropertyInfo get_class_info() { \
|
static inline PropertyInfo get_class_info() { \
|
||||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
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 <> \
|
template <> \
|
||||||
|
@ -267,15 +277,15 @@ public:
|
||||||
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
static const GDExtensionClassMethodArgumentMetadata METADATA = GDEXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||||
static inline PropertyInfo get_class_info() { \
|
static inline PropertyInfo get_class_info() { \
|
||||||
return make_property_info(Variant::Type::INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
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) \
|
#define MAKE_BITFIELD_TYPE_INFO(m_enum) \
|
||||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum) \
|
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum) \
|
||||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum const) \
|
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum const) \
|
||||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_enum &) \
|
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, m_enum &) \
|
||||||
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, const m_enum &)
|
TEMPL_MAKE_BITFIELD_TYPE_INFO(m_enum, const m_enum &)
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline StringName __constant_get_bitfield_name(T param, StringName p_constant) {
|
inline StringName __constant_get_bitfield_name(T param, StringName p_constant) {
|
||||||
|
|
|
@ -73,5 +73,11 @@ func _ready():
|
||||||
prints(" ANSWER_TO_EVERYTHING", $Example.ANSWER_TO_EVERYTHING)
|
prints(" ANSWER_TO_EVERYTHING", $Example.ANSWER_TO_EVERYTHING)
|
||||||
prints(" CONSTANT_WITHOUT_ENUM", $Example.CONSTANT_WITHOUT_ENUM)
|
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):
|
func _on_Example_custom_signal(signal_name, value):
|
||||||
prints("Example emitted:", signal_name, value)
|
prints("Example emitted:", signal_name, value)
|
||||||
|
|
|
@ -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_string_ops"), &Example::test_string_ops);
|
||||||
ClassDB::bind_method(D_METHOD("test_vector_ops"), &Example::test_vector_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_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);
|
ClassDB::bind_static_method("Example", D_METHOD("test_static", "a", "b"), &Example::test_static);
|
||||||
|
@ -169,7 +171,11 @@ void Example::_bind_methods() {
|
||||||
BIND_ENUM_CONSTANT(FIRST);
|
BIND_ENUM_CONSTANT(FIRST);
|
||||||
BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);
|
BIND_ENUM_CONSTANT(ANSWER_TO_EVERYTHING);
|
||||||
|
|
||||||
|
BIND_BITFIELD_FLAG(FLAG_ONE);
|
||||||
|
BIND_BITFIELD_FLAG(FLAG_TWO);
|
||||||
|
|
||||||
BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
|
BIND_CONSTANT(CONSTANT_WITHOUT_ENUM);
|
||||||
|
BIND_ENUM_CONSTANT(OUTSIDE_OF_CLASS);
|
||||||
}
|
}
|
||||||
|
|
||||||
Example::Example() {
|
Example::Example() {
|
||||||
|
@ -304,6 +310,11 @@ Dictionary Example::test_dictionary() const {
|
||||||
return dict;
|
return dict;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BitField<Example::Flags> Example::test_bitfield(BitField<Flags> flags) {
|
||||||
|
UtilityFunctions::print(" Got BitField: ", String::num(flags));
|
||||||
|
return flags;
|
||||||
|
}
|
||||||
|
|
||||||
// Properties.
|
// Properties.
|
||||||
void Example::set_custom_position(const Vector2 &pos) {
|
void Example::set_custom_position(const Vector2 &pos) {
|
||||||
custom_position = pos;
|
custom_position = pos;
|
||||||
|
|
|
@ -75,6 +75,11 @@ public:
|
||||||
ANSWER_TO_EVERYTHING = 42,
|
ANSWER_TO_EVERYTHING = 42,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Flags {
|
||||||
|
FLAG_ONE = 1,
|
||||||
|
FLAG_TWO = 2,
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
CONSTANT_WITHOUT_ENUM = 314,
|
CONSTANT_WITHOUT_ENUM = 314,
|
||||||
};
|
};
|
||||||
|
@ -104,6 +109,8 @@ public:
|
||||||
String test_string_ops() const;
|
String test_string_ops() const;
|
||||||
int test_vector_ops() const;
|
int test_vector_ops() const;
|
||||||
|
|
||||||
|
BitField<Flags> test_bitfield(BitField<Flags> flags);
|
||||||
|
|
||||||
// Property.
|
// Property.
|
||||||
void set_custom_position(const Vector2 &pos);
|
void set_custom_position(const Vector2 &pos);
|
||||||
Vector2 get_custom_position() const;
|
Vector2 get_custom_position() const;
|
||||||
|
@ -117,7 +124,13 @@ public:
|
||||||
virtual bool _has_point(const Vector2 &point) const override;
|
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 {
|
class ExampleVirtual : public Object {
|
||||||
GDCLASS(ExampleVirtual, Object);
|
GDCLASS(ExampleVirtual, Object);
|
||||||
|
|
Loading…
Reference in New Issue