Merge pull request #783 from bruvzg/bitfields
commit
9fc3fd7196
|
@ -1064,7 +1064,10 @@ 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"]:
|
||||
result.append(f'VARIANT_ENUM_CAST({class_name}, {class_name}::{enum_api["name"]});')
|
||||
if enum_api["is_bitfield"]:
|
||||
result.append(f'VARIANT_BITFIELD_CAST({class_name}, {class_name}::{enum_api["name"]});')
|
||||
else:
|
||||
result.append(f'VARIANT_ENUM_CAST({class_name}, {class_name}::{enum_api["name"]});')
|
||||
result.append("")
|
||||
|
||||
result.append(f"#endif // ! {header_guard}")
|
||||
|
@ -1194,7 +1197,7 @@ def generate_engine_class_source(class_api, used_classes, fully_used_classes, us
|
|||
result.append(method_call)
|
||||
|
||||
if vararg and ("return_value" in method and method["return_value"]["type"] != "void"):
|
||||
return_type = method["return_value"]["type"].replace("enum::", "")
|
||||
return_type = get_enum_fullname(method["return_value"]["type"])
|
||||
if return_type != "Variant":
|
||||
result.append(f"\treturn VariantCaster<{return_type}>::cast(ret);")
|
||||
else:
|
||||
|
@ -1712,18 +1715,35 @@ def needs_copy_instead_of_move(type_name):
|
|||
|
||||
|
||||
def is_enum(type_name):
|
||||
return type_name.startswith("enum::")
|
||||
return type_name.startswith("enum::") or type_name.startswith("bitfield::")
|
||||
|
||||
|
||||
def is_bitfield(type_name):
|
||||
return type_name.startswith("bitfield::")
|
||||
|
||||
|
||||
def get_enum_class(enum_name: str):
|
||||
if "." in enum_name:
|
||||
return enum_name.replace("enum::", "").split(".")[0]
|
||||
if is_bitfield(enum_name):
|
||||
return enum_name.replace("bitfield::", "").split(".")[0]
|
||||
else:
|
||||
return enum_name.replace("enum::", "").split(".")[0]
|
||||
else:
|
||||
return "GlobalConstants"
|
||||
|
||||
|
||||
def get_enum_fullname(enum_name: str):
|
||||
if is_bitfield(enum_name):
|
||||
return enum_name.replace("bitfield::", "BitField<") + ">"
|
||||
else:
|
||||
return enum_name.replace("enum::", "")
|
||||
|
||||
|
||||
def get_enum_name(enum_name: str):
|
||||
return enum_name.replace("enum::", "").split(".")[-1]
|
||||
if is_bitfield(enum_name):
|
||||
return enum_name.replace("bitfield::", "").split(".")[-1]
|
||||
else:
|
||||
return enum_name.replace("enum::", "").split(".")[-1]
|
||||
|
||||
|
||||
def is_variant(type_name):
|
||||
|
@ -1781,10 +1801,16 @@ def correct_type(type_name, meta=None):
|
|||
if type_name in type_conversion:
|
||||
return type_conversion[type_name]
|
||||
if is_enum(type_name):
|
||||
base_class = get_enum_class(type_name)
|
||||
if base_class == "GlobalConstants":
|
||||
return f"{get_enum_name(type_name)}"
|
||||
return f"{base_class}::{get_enum_name(type_name)}"
|
||||
if is_bitfield(type_name):
|
||||
base_class = get_enum_class(type_name)
|
||||
if base_class == "GlobalConstants":
|
||||
return f"BitField<{get_enum_name(type_name)}>"
|
||||
return f"BitField<{base_class}::{get_enum_name(type_name)}>"
|
||||
else:
|
||||
base_class = get_enum_class(type_name)
|
||||
if base_class == "GlobalConstants":
|
||||
return f"{get_enum_name(type_name)}"
|
||||
return f"{base_class}::{get_enum_name(type_name)}"
|
||||
if is_refcounted(type_name):
|
||||
return f"Ref<{type_name}>"
|
||||
if type_name == "Object" or is_engine_class(type_name):
|
||||
|
@ -1807,6 +1833,9 @@ def get_gdnative_type(type_name):
|
|||
"float": "double",
|
||||
}
|
||||
|
||||
if type_name.startswith("BitField<"):
|
||||
return "int64_t"
|
||||
|
||||
if type_name in type_conversion_map:
|
||||
return type_conversion_map[type_name]
|
||||
return type_name
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -540,7 +540,7 @@ typedef struct {
|
|||
|
||||
void (*classdb_register_extension_class)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_parent_class_name, const GDNativeExtensionClassCreationInfo *p_extension_funcs);
|
||||
void (*classdb_register_extension_class_method)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativeExtensionClassMethodInfo *p_method_info);
|
||||
void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value);
|
||||
void (*classdb_register_extension_class_integer_constant)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, bool p_is_bitfield);
|
||||
void (*classdb_register_extension_class_property)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const GDNativePropertyInfo *p_info, const char *p_setter, const char *p_getter);
|
||||
void (*classdb_register_extension_class_property_group)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_group_name, const char *p_prefix);
|
||||
void (*classdb_register_extension_class_property_subgroup)(const GDNativeExtensionClassLibraryPtr p_library, const char *p_class_name, const char *p_subgroup_name, const char *p_prefix);
|
||||
|
|
|
@ -62,6 +62,27 @@ namespace godot {
|
|||
}; \
|
||||
}
|
||||
|
||||
#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, const void *p_ptr) { \
|
||||
*(int64_t *)p_ptr = p_val; \
|
||||
} \
|
||||
}; \
|
||||
}
|
||||
|
||||
template <class T>
|
||||
struct VariantCaster {
|
||||
static _FORCE_INLINE_ T cast(const Variant &p_variant) {
|
||||
|
|
|
@ -116,7 +116,7 @@ public:
|
|||
static void add_property_subgroup(const char *p_class, const char *p_name, const char *p_prefix);
|
||||
static void add_property(const char *p_class, const PropertyInfo &p_pinfo, const char *p_setter, const char *p_getter, int p_index = -1);
|
||||
static void add_signal(const char *p_class, const MethodInfo &p_signal);
|
||||
static void bind_integer_constant(const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value);
|
||||
static void bind_integer_constant(const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, bool p_is_bitfield = false);
|
||||
static void bind_virtual_method(const char *p_class, const char *p_method, GDNativeExtensionClassCallVirtual p_call);
|
||||
|
||||
static MethodBind *get_method(const char *p_class, const char *p_method);
|
||||
|
@ -133,6 +133,9 @@ public:
|
|||
#define BIND_ENUM_CONSTANT(m_constant) \
|
||||
godot::ClassDB::bind_integer_constant(get_class_static(), godot::__constant_get_enum_name(m_constant, #m_constant), #m_constant, m_constant);
|
||||
|
||||
#define BIND_BITFIELD_FLAG(m_constant) \
|
||||
godot::ClassDB::bind_integer_constant(get_class_static(), godot::__constant_get_bitfield_name(m_constant, #m_constant), #m_constant, m_constant, true);
|
||||
|
||||
#define BIND_VIRTUAL_METHOD(m_class, m_method) \
|
||||
{ \
|
||||
auto ___call##m_method = [](GDNativeObjectPtr p_instance, const GDNativeTypePtr *p_args, GDNativeTypePtr p_ret) -> void { \
|
||||
|
|
|
@ -219,6 +219,53 @@ inline const char *__constant_get_enum_name(T param, const char *p_constant) {
|
|||
return GetTypeInfo<T>::get_class_info().class_name;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
class BitField {
|
||||
uint32_t value = 0;
|
||||
|
||||
public:
|
||||
_FORCE_INLINE_ void set_flag(T p_flag) { value |= p_flag; }
|
||||
_FORCE_INLINE_ bool has_flag(T p_flag) const { return value & p_flag; }
|
||||
_FORCE_INLINE_ void clear_flag(T p_flag) { return value &= ~p_flag; }
|
||||
_FORCE_INLINE_ BitField(uint32_t p_value) { value = p_value; }
|
||||
_FORCE_INLINE_ operator uint32_t() const { return value; }
|
||||
_FORCE_INLINE_ operator Variant() const { return value; }
|
||||
};
|
||||
|
||||
#define TEMPL_MAKE_BITFIELD_TYPE_INFO(m_class, m_enum, m_impl) \
|
||||
template <> \
|
||||
struct GetTypeInfo<m_impl> { \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline GDNativePropertyInfo get_class_info() { \
|
||||
return PropertyInfo(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
||||
#m_class "." #m_enum); \
|
||||
} \
|
||||
}; \
|
||||
template <> \
|
||||
struct GetTypeInfo<BitField<m_impl>> { \
|
||||
static const Variant::Type VARIANT_TYPE = Variant::INT; \
|
||||
static const GDNativeExtensionClassMethodArgumentMetadata METADATA = GDNATIVE_EXTENSION_METHOD_ARGUMENT_METADATA_NONE; \
|
||||
static inline GDNativePropertyInfo get_class_info() { \
|
||||
return PropertyInfo(GDNATIVE_VARIANT_TYPE_INT, "", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_CLASS_IS_BITFIELD, \
|
||||
#m_class "." #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 &)
|
||||
|
||||
template <typename T>
|
||||
inline const char *__constant_get_bitfield_name(T param, const char *p_constant) {
|
||||
if (GetTypeInfo<T>::VARIANT_TYPE == Variant::NIL) {
|
||||
ERR_PRINT(("Missing VARIANT_ENUM_CAST for constant's bitfield: " + String(p_constant)).utf8().get_data());
|
||||
}
|
||||
return GetTypeInfo<BitField<T>>::get_class_info().class_name;
|
||||
}
|
||||
|
||||
#define CLASS_INFO(m_type) (GetTypeInfo<m_type *>::get_class_info())
|
||||
|
||||
} // namespace godot
|
||||
|
|
|
@ -249,7 +249,7 @@ void ClassDB::add_signal(const char *p_class, const MethodInfo &p_signal) {
|
|||
internal::gdn_interface->classdb_register_extension_class_signal(internal::library, cl.name, p_signal.name, parameters.data(), parameters.size());
|
||||
}
|
||||
|
||||
void ClassDB::bind_integer_constant(const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value) {
|
||||
void ClassDB::bind_integer_constant(const char *p_class_name, const char *p_enum_name, const char *p_constant_name, GDNativeInt p_constant_value, bool p_is_bitfield) {
|
||||
std::unordered_map<std::string, ClassInfo>::iterator type_it = classes.find(p_class_name);
|
||||
|
||||
ERR_FAIL_COND_MSG(type_it == classes.end(), "Class doesn't exist.");
|
||||
|
@ -263,7 +263,7 @@ void ClassDB::bind_integer_constant(const char *p_class_name, const char *p_enum
|
|||
type.constant_names.insert(p_constant_name);
|
||||
|
||||
// Register it with Godot
|
||||
internal::gdn_interface->classdb_register_extension_class_integer_constant(internal::library, p_class_name, p_enum_name, p_constant_name, p_constant_value);
|
||||
internal::gdn_interface->classdb_register_extension_class_integer_constant(internal::library, p_class_name, p_enum_name, p_constant_name, p_constant_value, p_is_bitfield);
|
||||
}
|
||||
|
||||
GDNativeExtensionClassCallVirtual ClassDB::get_virtual_func(void *p_userdata, const char *p_name) {
|
||||
|
|
|
@ -12,8 +12,8 @@ config_version=5
|
|||
|
||||
config/name="GDExtension Test Project"
|
||||
run/main_scene="res://main.tscn"
|
||||
config/icon="res://icon.png"
|
||||
config/features=PackedStringArray("4.0")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[native_extensions]
|
||||
|
||||
|
|
Loading…
Reference in New Issue