Merge pull request #113586 from Ivorforce/gdtype-noms-enums

Move enum registration from `ClassDB` / `ClassInfo` to `GDType`.
This commit is contained in:
Rémi Verschelde committed 2026-03-14 12:15:44 +01:00
commit 422be7031a
10 files changed
+233 -204

No files matched your search

+3 -3
View File
@@ -760,9 +760,9 @@ void Resource::_bind_methods() {
// For the bindings, it's much more natural to expose this enum from the Variant realm via Resource.
// Therefore, we can't use BIND_ENUM_CONSTANT here because we need some customization.
ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_NONE", RESOURCE_DEEP_DUPLICATE_NONE);
ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_INTERNAL", RESOURCE_DEEP_DUPLICATE_INTERNAL);
ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_ALL", RESOURCE_DEEP_DUPLICATE_ALL);
get_gdtype_static_mutable().bind_integer_constant(StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_NONE", RESOURCE_DEEP_DUPLICATE_NONE);
get_gdtype_static_mutable().bind_integer_constant(StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_INTERNAL", RESOURCE_DEEP_DUPLICATE_INTERNAL);
get_gdtype_static_mutable().bind_integer_constant(StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_ALL", RESOURCE_DEEP_DUPLICATE_ALL);
ADD_SIGNAL(MethodInfo("changed"));
ADD_SIGNAL(MethodInfo("setup_local_to_scene_requested"));
+38 -131
View File
@@ -461,7 +461,7 @@ uint32_t ClassDB::get_api_hash(APIType p_api) {
List<StringName> snames;
for (const KeyValue<StringName, int64_t> &F : t->constant_map) {
for (const KeyValue<StringName, int64_t> &F : t->gdtype->get_integer_constant_map(true)) {
snames.push_back(F.key);
}
@@ -469,7 +469,7 @@ uint32_t ClassDB::get_api_hash(APIType p_api) {
for (const StringName &F : snames) {
hash = hash_murmur3_one_64(F.hash(), hash);
hash = hash_murmur3_one_64(uint64_t(t->constant_map[F]), hash);
hash = hash_murmur3_one_64(uint64_t(t->gdtype->get_integer_constant_map(true)[F]), hash);
}
}
@@ -883,7 +883,7 @@ use_script:
return scr.is_valid() && scr->is_valid() && scr->is_abstract();
}
void ClassDB::_add_class(const GDType &p_class, const GDType *p_inherits) {
void ClassDB::_add_class(GDType &p_class, const GDType *p_inherits) {
Locker::Lock lock(Locker::STATE_WRITE);
const StringName &name = p_class.get_name();
@@ -1158,61 +1158,19 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
Locker::Lock lock(Locker::STATE_WRITE);
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_NULL(type);
if (type->constant_map.has(p_name)) {
ERR_FAIL();
}
type->constant_map[p_name] = p_constant;
String enum_name = p_enum;
if (!enum_name.is_empty()) {
if (enum_name.contains_char('.')) {
enum_name = enum_name.get_slicec('.', 1);
}
ClassInfo::EnumInfo *constants_list = type->enum_map.getptr(enum_name);
if (constants_list) {
constants_list->constants.push_back(p_name);
constants_list->is_bitfield = p_is_bitfield;
} else {
ClassInfo::EnumInfo new_list;
new_list.is_bitfield = p_is_bitfield;
new_list.constants.push_back(p_name);
type->enum_map[enum_name] = new_list;
}
}
#ifdef DEBUG_ENABLED
type->constant_order.push_back(p_name);
#endif // DEBUG_ENABLED
type->gdtype->bind_integer_constant(p_enum, p_name, p_constant, p_is_bitfield);
}
void ClassDB::get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance) {
Locker::Lock lock(Locker::STATE_READ);
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_NULL(type);
while (type) {
#ifdef DEBUG_ENABLED
for (const StringName &E : type->constant_order) {
p_constants->push_back(E);
}
#else
for (const KeyValue<StringName, int64_t> &E : type->constant_map) {
p_constants->push_back(E.key);
}
#endif // DEBUG_ENABLED
if (p_no_inheritance) {
break;
}
type = type->inherits_ptr;
for (const KeyValue<StringName, int64_t> &E : type->gdtype->get_integer_constant_map(p_no_inheritance)) {
p_constants->push_back(E.key);
}
}
@@ -1220,23 +1178,19 @@ int64_t ClassDB::get_integer_constant(const StringName &p_class, const StringNam
Locker::Lock lock(Locker::STATE_READ);
ClassInfo *type = classes.getptr(p_class);
while (type) {
int64_t *constant = type->constant_map.getptr(p_name);
if (type) {
const int64_t *constant = type->gdtype->get_integer_constant_map(false).getptr(p_name);
if (constant) {
if (p_success) {
*p_success = true;
}
return *constant;
}
type = type->inherits_ptr;
}
if (p_success) {
*p_success = false;
}
return 0;
}
@@ -1244,60 +1198,33 @@ bool ClassDB::has_integer_constant(const StringName &p_class, const StringName &
Locker::Lock lock(Locker::STATE_READ);
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_NULL_V(type, false);
while (type) {
if (type->constant_map.has(p_name)) {
return true;
}
if (p_no_inheritance) {
return false;
}
type = type->inherits_ptr;
}
return false;
return type->gdtype->get_integer_constant_map(p_no_inheritance).has(p_name);
}
StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
Locker::Lock lock(Locker::STATE_READ);
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_NULL_V(type, StringName());
while (type) {
for (KeyValue<StringName, ClassInfo::EnumInfo> &E : type->enum_map) {
List<StringName> &constants_list = E.value.constants;
const List<StringName>::Element *found = constants_list.find(p_name);
if (found) {
return E.key;
}
}
if (p_no_inheritance) {
break;
}
type = type->inherits_ptr;
}
return StringName();
const GDType::EnumInfo *enum_info = type->gdtype->get_integer_constant_enum(p_name, p_no_inheritance);
return enum_info ? enum_info->name : StringName();
}
void ClassDB::get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance) {
Locker::Lock lock(Locker::STATE_READ);
ClassInfo *type = classes.getptr(p_class);
if (!type) {
// TODO This should probably error, but didn't previously.
// Making this error leads to a few prints during unit tests.
return;
}
while (type) {
for (KeyValue<StringName, ClassInfo::EnumInfo> &E : type->enum_map) {
p_enums->push_back(E.key);
}
if (p_no_inheritance) {
break;
}
type = type->inherits_ptr;
for (const KeyValue<StringName, const GDType::EnumInfo *> &E : type->gdtype->get_enum_map(p_no_inheritance)) {
p_enums->push_back(E.key);
}
}
@@ -1305,21 +1232,13 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_
Locker::Lock lock(Locker::STATE_READ);
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_NULL(type);
while (type) {
const ClassInfo::EnumInfo *constants = type->enum_map.getptr(p_enum);
const GDType::EnumInfo *const *enum_info = type->gdtype->get_enum_map(p_no_inheritance).getptr(p_enum);
ERR_FAIL_NULL(enum_info);
if (constants) {
for (const List<StringName>::Element *E = constants->constants.front(); E; E = E->next()) {
p_constants->push_back(E->get());
}
}
if (p_no_inheritance) {
break;
}
type = type->inherits_ptr;
for (const KeyValue<StringName, int64_t> &kv : (*enum_info)->values) {
p_constants->push_back(kv.key);
}
}
@@ -1354,38 +1273,25 @@ bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool
Locker::Lock lock(Locker::STATE_READ);
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_NULL_V(type, false);
while (type) {
if (type->enum_map.has(p_name)) {
return true;
}
if (p_no_inheritance) {
return false;
}
type = type->inherits_ptr;
}
return false;
return type->gdtype->get_enum_map(p_no_inheritance).has(p_name);
}
bool ClassDB::is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
Locker::Lock lock(Locker::STATE_READ);
ClassInfo *type = classes.getptr(p_class);
ERR_FAIL_NULL_V(type, false);
while (type) {
if (type->enum_map.has(p_name) && type->enum_map[p_name].is_bitfield) {
return true;
}
if (p_no_inheritance) {
return false;
}
type = type->inherits_ptr;
const GDType::EnumInfo *const *enum_info = type->gdtype->get_enum_map(p_no_inheritance).getptr(p_name);
// FIXME This fails unexpectedly often. Keeping legacy behavior to silently fail for now.
//ERR_FAIL_NULL_V(enum_info, false);
if (!enum_info) {
return false;
}
return false;
return (*enum_info)->is_bitfield;
}
void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
@@ -1727,7 +1633,7 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
return true;
}
const int64_t *c = check->constant_map.getptr(p_property); //constants count
const int64_t *c = check->gdtype->get_integer_constant_map(true).getptr(p_property); //constants count
if (c) {
r_value = *c;
return true;
@@ -2446,8 +2352,9 @@ void ClassDB::cleanup() {
native_structs.clear();
for (GDType **type : gdtype_autorelease_pool) {
if (!type) {
if (!*type) {
WARN_PRINT("GDType in autorelease pool was cleaned up before being auto-released. Ignoring.");
continue;
}
memdelete(*type);
*type = nullptr;
+6 -13
View File
@@ -95,6 +95,7 @@ MethodDefinition D_METHOD(const char *p_name, const VarArgs... p_args) {
class ClassDB {
friend class Object;
friend class GDType;
public:
enum APIType {
@@ -119,25 +120,18 @@ public:
APIType api = API_NONE;
ClassInfo *inherits_ptr = nullptr;
void *class_ptr = nullptr;
const GDType *gdtype = nullptr;
GDType *gdtype = nullptr;
ObjectGDExtension *gdextension = nullptr;
HashMap<StringName, MethodBind *> method_map;
HashMap<StringName, LocalVector<MethodBind *>> method_map_compatibility;
AHashMap<StringName, int64_t> constant_map;
struct EnumInfo {
List<StringName> constants;
bool is_bitfield = false;
};
HashMap<StringName, EnumInfo> enum_map;
AHashMap<StringName, MethodInfo> signal_map;
List<PropertyInfo> property_list;
HashMap<StringName, PropertyInfo> property_map;
#ifdef DEBUG_ENABLED
List<StringName> constant_order;
List<StringName> method_order;
HashSet<StringName> methods_in_properties;
List<MethodInfo> virtual_methods;
@@ -215,7 +209,7 @@ public:
static APIType current_api;
static HashMap<APIType, uint32_t> api_hashes_cache;
static void _add_class(const GDType &p_class, const GDType *p_inherits);
static void _add_class(GDType &p_class, const GDType *p_inherits);
static HashMap<StringName, HashMap<StringName, Variant>> default_values;
static HashSet<StringName> default_values_cached;
@@ -507,7 +501,6 @@ public:
static bool has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
static StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
static StringName get_integer_constant_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false);
static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false);
static bool has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
@@ -551,13 +544,13 @@ public:
};
#define BIND_ENUM_CONSTANT(m_constant) \
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant), __constant_get_enum_value_name(#m_constant), m_constant);
get_gdtype_static_mutable().bind_integer_constant(__constant_get_enum_name(m_constant), __constant_get_enum_value_name(#m_constant), m_constant);
#define BIND_BITFIELD_FLAG(m_constant) \
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_bitfield_name(m_constant), __constant_get_enum_value_name(#m_constant), m_constant, true);
get_gdtype_static_mutable().bind_integer_constant(__constant_get_bitfield_name(m_constant), __constant_get_enum_value_name(#m_constant), m_constant, true);
#define BIND_CONSTANT(m_constant) \
::ClassDB::bind_integer_constant(get_class_static(), StringName(), __constant_get_enum_value_name(#m_constant), m_constant);
get_gdtype_static_mutable().bind_integer_constant(StringName(), __constant_get_enum_value_name(#m_constant), m_constant);
#ifdef DEBUG_ENABLED
+68
View File
@@ -30,6 +30,10 @@
#include "gdtype.h"
#include "core/object/class_db.h"
#include "core/os/thread.h"
#include "core/variant/variant.h"
GDType::GDType(const GDType *p_super_type, StringName p_name) :
super_type(p_super_type), name(std::move(p_name)) {
name_hierarchy.push_back(name);
@@ -40,3 +44,67 @@ GDType::GDType(const GDType *p_super_type, StringName p_name) :
}
}
}
GDType::~GDType() {
for (const KeyValue<StringName, const EnumInfo *> &kv : self_enum_map) {
memdelete(const_cast<EnumInfo *>(kv.value));
}
}
void GDType::initialize() {
ERR_FAIL_COND(init_state != InitState::UNINITIALIZED);
if (super_type) {
// Now that a subtype is registered, the supertype cannot change anymore.
// Otherwise, our caches would become invalid.
// This shouldn't be a problem, since classes should register all their
// parts in _bind_methods, which is called on registration.
super_type->init_state = InitState::FINALIZED;
constant_map = super_type->constant_map;
enum_map = super_type->enum_map;
}
init_state = InitState::MUTABLE;
}
void GDType::bind_integer_constant(const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield) {
ERR_FAIL_COND(!Thread::is_main_thread());
ERR_FAIL_COND(init_state != InitState::MUTABLE);
ERR_FAIL_COND(self_constant_map.has(p_name));
constant_map[p_name] = p_constant;
self_constant_map[p_name] = p_constant;
String enum_name = p_enum;
if (!enum_name.is_empty()) {
if (enum_name.contains_char('.')) {
enum_name = enum_name.get_slicec('.', 1);
}
const EnumInfo **_enum_info = self_enum_map.getptr(enum_name);
if (_enum_info != nullptr) {
EnumInfo *enum_info = const_cast<EnumInfo *>(*_enum_info);
enum_info->values.insert(p_name, p_constant);
enum_info->is_bitfield = p_is_bitfield;
} else {
EnumInfo *enum_info = memnew(EnumInfo);
enum_info->name = enum_name;
enum_info->is_bitfield = p_is_bitfield;
enum_info->values.insert(p_name, p_constant);
self_enum_map[enum_name] = enum_info;
enum_map[enum_name] = enum_info;
}
}
}
const GDType::EnumInfo *GDType::get_integer_constant_enum(const StringName &p_name, bool p_no_inheritance) const {
for (const KeyValue<StringName, const EnumInfo *> &kv : get_enum_map(p_no_inheritance)) {
if (kv.value->values.has(p_name)) {
return kv.value;
}
}
return nullptr;
}
+32
View File
@@ -31,20 +31,52 @@
#pragma once
#include "core/string/string_name.h"
#include "core/templates/a_hash_map.h"
#include "core/templates/local_vector.h"
#include "core/templates/vector.h"
class GDType {
public:
enum class InitState {
UNINITIALIZED,
MUTABLE,
FINALIZED,
};
struct EnumInfo {
StringName name;
AHashMap<StringName, int64_t> values;
bool is_bitfield = false;
};
protected:
const GDType *super_type;
mutable InitState init_state = InitState::UNINITIALIZED;
StringName name;
/// Contains all the class names in order:
/// `name` is the first element and `Object` is the last.
Vector<StringName> name_hierarchy;
AHashMap<StringName, int64_t> constant_map;
AHashMap<StringName, int64_t> self_constant_map;
AHashMap<StringName, const EnumInfo *> enum_map;
AHashMap<StringName, const EnumInfo *> self_enum_map;
public:
GDType(const GDType *p_super_type, StringName p_name);
~GDType();
InitState get_init_state() const { return init_state; }
void initialize();
const GDType *get_super_type() const { return super_type; }
const StringName &get_name() const { return name; }
const Vector<StringName> &get_name_hierarchy() const { return name_hierarchy; }
void bind_integer_constant(const StringName &p_enum, const StringName &p_name, int64_t p_constant, bool p_is_bitfield = false);
const AHashMap<StringName, int64_t> &get_integer_constant_map(bool p_no_inheritance = false) const { return p_no_inheritance ? self_constant_map : constant_map; }
const AHashMap<StringName, const EnumInfo *> &get_enum_map(bool p_no_inheritance = false) const { return p_no_inheritance ? self_enum_map : enum_map; }
const EnumInfo *get_integer_constant_enum(const StringName &p_name, bool p_no_inheritance = false) const;
};
+16 -17
View File
@@ -235,6 +235,7 @@ void ObjectGDExtension::create_gdtype() {
ERR_FAIL_COND(gdtype);
gdtype = memnew(GDType(ClassDB::get_gdtype(parent_class_name), class_name));
gdtype->initialize();
}
void ObjectGDExtension::destroy_gdtype() {
@@ -1441,6 +1442,10 @@ void Object::_reset_gdtype() const {
}
}
void Object::autorelease_gdtype(GDType **r_type) {
ClassDB::gdtype_autorelease_pool.push_back(r_type);
}
void Object::_add_user_signal(const String &p_name, const Array &p_args) {
// this version of add_user_signal is meant to be used from scripts or external apis
// without access to ADD_SIGNAL in bind_methods
@@ -1793,10 +1798,18 @@ Variant Object::_get_indexed_bind(const NodePath &p_name) const {
void Object::initialize_class() {
static bool initialized = false;
if (initialized) {
if (likely(initialized)) {
return;
}
_add_class_to_classdb(get_gdtype_static(), nullptr);
static BinaryMutex __init_mutex;
MutexLock lock(__init_mutex);
if (initialized) {
// Initialized on another thread while we were waiting.
return;
}
_add_class_to_classdb(get_gdtype_static_mutable(), nullptr);
get_gdtype_static_mutable().initialize();
_bind_methods();
_bind_compatibility_methods();
initialized = true;
@@ -1872,7 +1885,7 @@ void Object::_clear_internal_resource_paths(const Variant &p_var) {
}
}
void Object::_add_class_to_classdb(const GDType &p_type, const GDType *p_inherits) {
void Object::_add_class_to_classdb(GDType &p_type, const GDType *p_inherits) {
ClassDB::_add_class(p_type, p_inherits);
}
@@ -2407,20 +2420,6 @@ void Object::detach_from_objectdb() {
}
}
void Object::assign_type_static(GDType **type_ptr, const char *p_name, const GDType *super_type) {
static BinaryMutex _mutex;
MutexLock lock(_mutex);
GDType *type = *type_ptr;
if (type) {
// Assigned while we were waiting.
return;
}
type = memnew(GDType(super_type, StringName(p_name)));
*type_ptr = type;
ClassDB::gdtype_autorelease_pool.push_back(type_ptr);
}
Object::~Object() {
if (_emitting) {
//@todo this may need to actually reach the debugger prioritarily somehow because it may crash before
+50 -17
View File
@@ -372,7 +372,7 @@ struct ObjectGDExtension {
/// A type for this Object extension.
/// This is not exposed through the GDExtension API (yet) so it is inferred from above parameters.
const GDType *gdtype;
GDType *gdtype;
void create_gdtype();
void destroy_gdtype();
@@ -491,17 +491,31 @@ private:
private: \
void operator=(const m_class &p_rval) {} \
friend class ::ClassDB; \
\
static GDType &get_gdtype_static_mutable() { \
static GDType *gdtype = nullptr; \
static bool initialized = false; \
if (likely(initialized)) { \
return *gdtype; \
} \
\
static BinaryMutex __init_mutex; \
MutexLock lock(__init_mutex); \
if (initialized) { \
return *gdtype; \
} \
gdtype = memnew(GDType(&super_type::get_gdtype_static(), StringName(#m_class))); \
m_class::autorelease_gdtype(&gdtype); \
initialized = true; \
return *gdtype; \
} \
\
public: \
virtual const GDType &_get_typev() const override { \
return get_gdtype_static(); \
} \
static const GDType &get_gdtype_static() { \
static GDType *_class_static; \
if (unlikely(!_class_static)) { \
assign_type_static(&_class_static, #m_class, &super_type::get_gdtype_static()); \
} \
return *_class_static; \
return get_gdtype_static_mutable(); \
} \
static const StringName &get_class_static() { \
return get_gdtype_static().get_name(); \
@@ -518,11 +532,18 @@ protected: \
public: \
static void initialize_class() { \
static bool initialized = false; \
if (likely(initialized)) { \
return; \
} \
\
static BinaryMutex __init_mutex; \
MutexLock lock(__init_mutex); \
if (initialized) { \
return; \
} \
m_inherits::initialize_class(); \
_add_class_to_classdb(get_gdtype_static(), &super_type::get_gdtype_static()); \
_add_class_to_classdb(get_gdtype_static_mutable(), &super_type::get_gdtype_static()); \
get_gdtype_static_mutable().initialize(); \
if (m_class::_get_bind_methods() != m_inherits::_get_bind_methods()) { \
_bind_methods(); \
} \
@@ -672,6 +693,24 @@ private:
mutable const GDType *_gdtype_ptr = nullptr;
void _reset_gdtype() const;
static GDType &get_gdtype_static_mutable() {
static GDType *gdtype = nullptr;
static bool initialized = false;
if (likely(initialized)) {
return *gdtype;
}
static BinaryMutex __init_mutex;
MutexLock lock(__init_mutex);
if (initialized) {
return *gdtype;
}
gdtype = memnew(GDType(nullptr, StringName("Object")));
autorelease_gdtype(&gdtype);
initialized = true;
return *gdtype;
}
void _add_user_signal(const String &p_name, const Array &p_args = Array());
bool _has_user_signal(const StringName &p_name) const;
void _remove_user_signal(const StringName &p_name);
@@ -780,6 +819,8 @@ protected:
Variant _call_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
Variant _call_deferred_bind(const Variant **p_args, int p_argcount, Callable::CallError &r_error);
static void autorelease_gdtype(GDType **r_type);
virtual const GDType &_get_typev() const { return get_gdtype_static(); }
TypedArray<StringName> _get_meta_list_bind() const;
@@ -791,7 +832,7 @@ protected:
friend class ::ClassDB;
friend class PlaceholderExtensionInstance;
static void _add_class_to_classdb(const GDType &p_class, const GDType *p_inherits);
static void _add_class_to_classdb(GDType &p_class, const GDType *p_inherits);
static void _get_property_list_from_classdb(const StringName &p_class, List<PropertyInfo> *p_list, bool p_no_inheritance, const Object *p_validator);
bool _disconnect(const StringName &p_signal, const Callable &p_callable, bool p_force = false);
@@ -860,15 +901,7 @@ public:
};
/* TYPE API */
static void assign_type_static(GDType **type_ptr, const char *p_name, const GDType *super_type);
static const GDType &get_gdtype_static() {
static GDType *_class_static;
if (unlikely(!_class_static)) {
assign_type_static(&_class_static, "Object", nullptr);
}
return *_class_static;
}
static const GDType &get_gdtype_static() { return get_gdtype_static_mutable(); }
const GDType &get_gdtype() const;
+2 -2
View File
@@ -122,7 +122,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
List<StringName> snames;
for (const KeyValue<StringName, int64_t> &F : t->constant_map) {
for (const KeyValue<StringName, int64_t> &F : t->gdtype->get_integer_constant_map(true)) {
snames.push_back(F.key);
}
@@ -135,7 +135,7 @@ void class_db_api_to_json(const String &p_output_file, ClassDB::APIType p_api) {
constants.push_back(constant_dict);
constant_dict["name"] = F;
constant_dict["value"] = t->constant_map[F];
constant_dict["value"] = t->gdtype->get_integer_constant_map(true)[F];
}
if (!constants.is_empty()) {
+10 -13
View File
@@ -4352,10 +4352,10 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
List<String> constants;
ClassDB::get_integer_constant_list(type_cname, &constants, true);
const HashMap<StringName, ClassDB::ClassInfo::EnumInfo> &enum_map = class_info->enum_map;
const AHashMap<StringName, const GDType::EnumInfo *> &enum_map = class_info->gdtype->get_enum_map(true);
for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &E : enum_map) {
StringName enum_proxy_cname = E.key;
for (const KeyValue<StringName, const GDType::EnumInfo *> &kv : enum_map) {
StringName enum_proxy_cname = kv.key;
String enum_proxy_name = pascal_to_pascal_case(enum_proxy_cname.operator String());
if (itype.find_property_by_proxy_name(enum_proxy_name) || itype.find_method_by_proxy_name(enum_proxy_name) || itype.find_signal_by_proxy_name(enum_proxy_name)) {
// In case the enum name conflicts with other PascalCase members,
@@ -4364,15 +4364,12 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
enum_proxy_name += "Enum";
enum_proxy_cname = StringName(enum_proxy_name);
}
EnumInterface ienum(enum_proxy_cname, enum_proxy_name, E.value.is_bitfield);
const List<StringName> &enum_constants = E.value.constants;
for (const StringName &constant_cname : enum_constants) {
String constant_name = constant_cname.operator String();
int64_t *value = class_info->constant_map.getptr(constant_cname);
ERR_FAIL_NULL_V(value, false);
constants.erase(constant_name);
EnumInterface ienum(enum_proxy_cname, enum_proxy_name, kv.value->is_bitfield);
for (const KeyValue<StringName, int64_t> &kv_case : kv.value->values) {
String constant_name = kv_case.key.operator String();
constants.erase(kv_case.key);
ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), *value);
ConstantInterface iconstant(constant_name, snake_to_pascal_case(constant_name, true), kv_case.value);
iconstant.const_doc = nullptr;
for (int i = 0; i < itype.class_doc->constants.size(); i++) {
@@ -4405,7 +4402,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
TypeInterface enum_itype;
enum_itype.is_enum = true;
enum_itype.name = itype.name + "." + String(E.key);
enum_itype.name = itype.name + "." + String(kv.key);
enum_itype.cname = StringName(enum_itype.name);
enum_itype.proxy_name = itype.proxy_name + "." + enum_proxy_name;
TypeInterface::postsetup_enum_type(enum_itype);
@@ -4413,7 +4410,7 @@ bool BindingsGenerator::_populate_object_type_interfaces() {
}
for (const String &constant_name : constants) {
int64_t *value = class_info->constant_map.getptr(StringName(constant_name));
const int64_t *value = class_info->gdtype->get_integer_constant_map(true).getptr(StringName(constant_name));
ERR_FAIL_NULL_V(value, false);
String constant_proxy_name = snake_to_pascal_case(constant_name, true);
+8 -8
View File
@@ -764,18 +764,18 @@ void add_exposed_classes(Context &r_context) {
List<String> constants;
ClassDB::get_integer_constant_list(class_name, &constants, true);
const HashMap<StringName, ClassDB::ClassInfo::EnumInfo> &enum_map = class_info->enum_map;
const AHashMap<StringName, const GDType::EnumInfo *> &enum_map = class_info->gdtype->get_enum_map(true);
for (const KeyValue<StringName, ClassDB::ClassInfo::EnumInfo> &K : enum_map) {
for (const KeyValue<StringName, const GDType::EnumInfo *> &kv_enum : enum_map) {
EnumData enum_;
enum_.name = K.key;
enum_.name = kv_enum.key;
for (const StringName &E : K.value.constants) {
const StringName &constant_name = E;
for (const KeyValue<StringName, int64_t> &kv_case : kv_enum.value->values) {
const StringName &constant_name = kv_case.key;
TEST_FAIL_COND(String(constant_name).contains("::"),
"Enum constant contains '::', check bindings to remove the scope: '",
String(class_name), ".", String(enum_.name), ".", String(constant_name), "'.");
int64_t *value = class_info->constant_map.getptr(constant_name);
const int64_t *value = class_info->gdtype->get_integer_constant_map(false).getptr(constant_name);
TEST_FAIL_COND(!value, "Missing enum constant value: '",
String(class_name), ".", String(enum_.name), ".", String(constant_name), "'.");
constants.erase(constant_name);
@@ -789,7 +789,7 @@ void add_exposed_classes(Context &r_context) {
exposed_class.enums.push_back(enum_);
r_context.enum_types.push_back(String(class_name) + "." + String(K.key));
r_context.enum_types.push_back(String(class_name) + "." + String(kv_enum.key));
}
for (const String &E : constants) {
@@ -797,7 +797,7 @@ void add_exposed_classes(Context &r_context) {
TEST_FAIL_COND(constant_name.contains("::"),
"Constant contains '::', check bindings to remove the scope: '",
String(class_name), ".", constant_name, "'.");
int64_t *value = class_info->constant_map.getptr(StringName(E));
const int64_t *value = class_info->gdtype->get_integer_constant_map(false).getptr(StringName(E));
TEST_FAIL_COND(!value, "Missing constant value: '", String(class_name), ".", String(constant_name), "'.");
ConstantData constant;