Skip to content

Commit e04b21c

Browse files
committed
Move enum registration from ClassDB / ClassInfo to GDType.
Create caches across supertypes for faster lookup.
1 parent fbc9539 commit e04b21c

File tree

10 files changed

+194
-201
lines changed

10 files changed

+194
-201
lines changed

core/io/resource.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -751,9 +751,9 @@ void Resource::_bind_methods() {
751751

752752
// For the bindings, it's much more natural to expose this enum from the Variant realm via Resource.
753753
// Therefore, we can't use BIND_ENUM_CONSTANT here because we need some customization.
754-
ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_NONE", RESOURCE_DEEP_DUPLICATE_NONE);
755-
ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_INTERNAL", RESOURCE_DEEP_DUPLICATE_INTERNAL);
756-
ClassDB::bind_integer_constant(get_class_static(), StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_ALL", RESOURCE_DEEP_DUPLICATE_ALL);
754+
get_gdtype_static_mutable().bind_integer_constant(StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_NONE", RESOURCE_DEEP_DUPLICATE_NONE);
755+
get_gdtype_static_mutable().bind_integer_constant(StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_INTERNAL", RESOURCE_DEEP_DUPLICATE_INTERNAL);
756+
get_gdtype_static_mutable().bind_integer_constant(StringName("DeepDuplicateMode"), "DEEP_DUPLICATE_ALL", RESOURCE_DEEP_DUPLICATE_ALL);
757757

758758
ADD_SIGNAL(MethodInfo("changed"));
759759
ADD_SIGNAL(MethodInfo("setup_local_to_scene_requested"));

core/object/class_db.cpp

Lines changed: 33 additions & 131 deletions
Original file line numberDiff line numberDiff line change
@@ -461,15 +461,15 @@ uint32_t ClassDB::get_api_hash(APIType p_api) {
461461

462462
List<StringName> snames;
463463

464-
for (const KeyValue<StringName, int64_t> &F : t->constant_map) {
464+
for (const KeyValue<StringName, int64_t> &F : t->gdtype->get_integer_constant_map(true)) {
465465
snames.push_back(F.key);
466466
}
467467

468468
snames.sort_custom<StringName::AlphCompare>();
469469

470470
for (const StringName &F : snames) {
471471
hash = hash_murmur3_one_64(F.hash(), hash);
472-
hash = hash_murmur3_one_64(uint64_t(t->constant_map[F]), hash);
472+
hash = hash_murmur3_one_64(uint64_t(t->gdtype->get_integer_constant_map(true)[F]), hash);
473473
}
474474
}
475475

@@ -883,7 +883,7 @@ bool ClassDB::is_virtual(const StringName &p_class) {
883883
return scr.is_valid() && scr->is_valid() && scr->is_abstract();
884884
}
885885

886-
void ClassDB::_add_class(const GDType &p_class, const GDType *p_inherits) {
886+
void ClassDB::_add_class(GDType &p_class, const GDType *p_inherits) {
887887
Locker::Lock lock(Locker::STATE_WRITE);
888888

889889
const StringName &name = p_class.get_name();
@@ -1158,168 +1158,87 @@ void ClassDB::bind_integer_constant(const StringName &p_class, const StringName
11581158
Locker::Lock lock(Locker::STATE_WRITE);
11591159

11601160
ClassInfo *type = classes.getptr(p_class);
1161-
11621161
ERR_FAIL_NULL(type);
11631162

1164-
if (type->constant_map.has(p_name)) {
1165-
ERR_FAIL();
1166-
}
1167-
1168-
type->constant_map[p_name] = p_constant;
1169-
1170-
String enum_name = p_enum;
1171-
if (!enum_name.is_empty()) {
1172-
if (enum_name.contains_char('.')) {
1173-
enum_name = enum_name.get_slicec('.', 1);
1174-
}
1175-
1176-
ClassInfo::EnumInfo *constants_list = type->enum_map.getptr(enum_name);
1177-
1178-
if (constants_list) {
1179-
constants_list->constants.push_back(p_name);
1180-
constants_list->is_bitfield = p_is_bitfield;
1181-
} else {
1182-
ClassInfo::EnumInfo new_list;
1183-
new_list.is_bitfield = p_is_bitfield;
1184-
new_list.constants.push_back(p_name);
1185-
type->enum_map[enum_name] = new_list;
1186-
}
1187-
}
1188-
1189-
#ifdef DEBUG_ENABLED
1190-
type->constant_order.push_back(p_name);
1191-
#endif // DEBUG_ENABLED
1163+
type->gdtype->bind_integer_constant(p_enum, p_name, p_constant, p_is_bitfield);
11921164
}
11931165

11941166
void ClassDB::get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance) {
11951167
Locker::Lock lock(Locker::STATE_READ);
11961168

11971169
ClassInfo *type = classes.getptr(p_class);
1170+
ERR_FAIL_NULL(type);
11981171

1199-
while (type) {
1200-
#ifdef DEBUG_ENABLED
1201-
for (const StringName &E : type->constant_order) {
1202-
p_constants->push_back(E);
1203-
}
1204-
#else
1205-
1206-
for (const KeyValue<StringName, int64_t> &E : type->constant_map) {
1207-
p_constants->push_back(E.key);
1208-
}
1209-
1210-
#endif // DEBUG_ENABLED
1211-
if (p_no_inheritance) {
1212-
break;
1213-
}
1214-
1215-
type = type->inherits_ptr;
1172+
for (const KeyValue<StringName, int64_t> &E : type->gdtype->get_integer_constant_map(p_no_inheritance)) {
1173+
p_constants->push_back(E.key);
12161174
}
12171175
}
12181176

12191177
int64_t ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success) {
12201178
Locker::Lock lock(Locker::STATE_READ);
12211179

12221180
ClassInfo *type = classes.getptr(p_class);
1223-
1224-
while (type) {
1225-
int64_t *constant = type->constant_map.getptr(p_name);
1181+
if (type) {
1182+
const int64_t *constant = type->gdtype->get_integer_constant_map(false).getptr(p_name);
12261183
if (constant) {
12271184
if (p_success) {
12281185
*p_success = true;
12291186
}
12301187
return *constant;
12311188
}
1232-
1233-
type = type->inherits_ptr;
12341189
}
12351190

12361191
if (p_success) {
12371192
*p_success = false;
12381193
}
1239-
12401194
return 0;
12411195
}
12421196

12431197
bool ClassDB::has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
12441198
Locker::Lock lock(Locker::STATE_READ);
12451199

12461200
ClassInfo *type = classes.getptr(p_class);
1201+
ERR_FAIL_NULL_V(type, false);
12471202

1248-
while (type) {
1249-
if (type->constant_map.has(p_name)) {
1250-
return true;
1251-
}
1252-
if (p_no_inheritance) {
1253-
return false;
1254-
}
1255-
1256-
type = type->inherits_ptr;
1257-
}
1258-
1259-
return false;
1203+
return type->gdtype->get_integer_constant_map(p_no_inheritance).has(p_name);
12601204
}
12611205

12621206
StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
12631207
Locker::Lock lock(Locker::STATE_READ);
12641208

12651209
ClassInfo *type = classes.getptr(p_class);
1210+
ERR_FAIL_NULL_V(type, StringName());
12661211

1267-
while (type) {
1268-
for (KeyValue<StringName, ClassInfo::EnumInfo> &E : type->enum_map) {
1269-
List<StringName> &constants_list = E.value.constants;
1270-
const List<StringName>::Element *found = constants_list.find(p_name);
1271-
if (found) {
1272-
return E.key;
1273-
}
1274-
}
1275-
1276-
if (p_no_inheritance) {
1277-
break;
1278-
}
1279-
1280-
type = type->inherits_ptr;
1281-
}
1282-
1283-
return StringName();
1212+
const GDType::EnumInfo *enum_info = type->gdtype->get_integer_constant_enum(p_name, p_no_inheritance);
1213+
return enum_info ? enum_info->name : StringName();
12841214
}
12851215

12861216
void ClassDB::get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance) {
12871217
Locker::Lock lock(Locker::STATE_READ);
12881218

12891219
ClassInfo *type = classes.getptr(p_class);
1220+
if (!type) {
1221+
// TODO This should probably error, but didn't previously.
1222+
// Making this error leads to a few prints during unit tests.
1223+
return;
1224+
}
12901225

1291-
while (type) {
1292-
for (KeyValue<StringName, ClassInfo::EnumInfo> &E : type->enum_map) {
1293-
p_enums->push_back(E.key);
1294-
}
1295-
1296-
if (p_no_inheritance) {
1297-
break;
1298-
}
1299-
1300-
type = type->inherits_ptr;
1226+
for (const KeyValue<StringName, const GDType::EnumInfo *> &E : type->gdtype->get_enum_map(p_no_inheritance)) {
1227+
p_enums->push_back(E.key);
13011228
}
13021229
}
13031230

13041231
void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance) {
13051232
Locker::Lock lock(Locker::STATE_READ);
13061233

13071234
ClassInfo *type = classes.getptr(p_class);
1235+
ERR_FAIL_NULL(type);
13081236

1309-
while (type) {
1310-
const ClassInfo::EnumInfo *constants = type->enum_map.getptr(p_enum);
1311-
1312-
if (constants) {
1313-
for (const List<StringName>::Element *E = constants->constants.front(); E; E = E->next()) {
1314-
p_constants->push_back(E->get());
1315-
}
1316-
}
1237+
const GDType::EnumInfo *const *enum_info = type->gdtype->get_enum_map(p_no_inheritance).getptr(p_enum);
1238+
ERR_FAIL_NULL(enum_info);
13171239

1318-
if (p_no_inheritance) {
1319-
break;
1320-
}
1321-
1322-
type = type->inherits_ptr;
1240+
for (const KeyValue<StringName, int64_t> &kv : (*enum_info)->values) {
1241+
p_constants->push_back(kv.key);
13231242
}
13241243
}
13251244

@@ -1354,38 +1273,21 @@ bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool
13541273
Locker::Lock lock(Locker::STATE_READ);
13551274

13561275
ClassInfo *type = classes.getptr(p_class);
1276+
ERR_FAIL_NULL_V(type, false);
13571277

1358-
while (type) {
1359-
if (type->enum_map.has(p_name)) {
1360-
return true;
1361-
}
1362-
if (p_no_inheritance) {
1363-
return false;
1364-
}
1365-
1366-
type = type->inherits_ptr;
1367-
}
1368-
1369-
return false;
1278+
return type->gdtype->get_enum_map(p_no_inheritance).has(p_name);
13701279
}
13711280

13721281
bool ClassDB::is_enum_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
13731282
Locker::Lock lock(Locker::STATE_READ);
13741283

13751284
ClassInfo *type = classes.getptr(p_class);
1285+
ERR_FAIL_NULL_V(type, false);
13761286

1377-
while (type) {
1378-
if (type->enum_map.has(p_name) && type->enum_map[p_name].is_bitfield) {
1379-
return true;
1380-
}
1381-
if (p_no_inheritance) {
1382-
return false;
1383-
}
1384-
1385-
type = type->inherits_ptr;
1386-
}
1287+
const GDType::EnumInfo *const *enum_info = type->gdtype->get_enum_map(p_no_inheritance).getptr(p_name);
1288+
ERR_FAIL_NULL_V(enum_info, false);
13871289

1388-
return false;
1290+
return (*enum_info)->is_bitfield;
13891291
}
13901292

13911293
void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
@@ -1724,7 +1626,7 @@ bool ClassDB::get_property(Object *p_object, const StringName &p_property, Varia
17241626
return true;
17251627
}
17261628

1727-
const int64_t *c = check->constant_map.getptr(p_property); //constants count
1629+
const int64_t *c = check->gdtype->get_integer_constant_map(true).getptr(p_property); //constants count
17281630
if (c) {
17291631
r_value = *c;
17301632
return true;

core/object/class_db.h

Lines changed: 6 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ MethodDefinition D_METHOD(const char *p_name, const VarArgs... p_args) {
9999

100100
class ClassDB {
101101
friend class Object;
102+
friend class GDType;
102103

103104
public:
104105
enum APIType {
@@ -123,25 +124,18 @@ class ClassDB {
123124
APIType api = API_NONE;
124125
ClassInfo *inherits_ptr = nullptr;
125126
void *class_ptr = nullptr;
126-
const GDType *gdtype = nullptr;
127+
GDType *gdtype = nullptr;
127128

128129
ObjectGDExtension *gdextension = nullptr;
129130

130131
HashMap<StringName, MethodBind *> method_map;
131132
HashMap<StringName, LocalVector<MethodBind *>> method_map_compatibility;
132-
AHashMap<StringName, int64_t> constant_map;
133-
struct EnumInfo {
134-
List<StringName> constants;
135-
bool is_bitfield = false;
136-
};
137133

138-
HashMap<StringName, EnumInfo> enum_map;
139134
AHashMap<StringName, MethodInfo> signal_map;
140135
List<PropertyInfo> property_list;
141136
HashMap<StringName, PropertyInfo> property_map;
142137

143138
#ifdef DEBUG_ENABLED
144-
List<StringName> constant_order;
145139
List<StringName> method_order;
146140
HashSet<StringName> methods_in_properties;
147141
List<MethodInfo> virtual_methods;
@@ -219,7 +213,7 @@ class ClassDB {
219213
static APIType current_api;
220214
static HashMap<APIType, uint32_t> api_hashes_cache;
221215

222-
static void _add_class(const GDType &p_class, const GDType *p_inherits);
216+
static void _add_class(GDType &p_class, const GDType *p_inherits);
223217

224218
static HashMap<StringName, HashMap<StringName, Variant>> default_values;
225219
static HashSet<StringName> default_values_cached;
@@ -507,7 +501,6 @@ class ClassDB {
507501
static bool has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
508502

509503
static StringName get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
510-
static StringName get_integer_constant_bitfield(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
511504
static void get_enum_list(const StringName &p_class, List<StringName> *p_enums, bool p_no_inheritance = false);
512505
static void get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance = false);
513506
static bool has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance = false);
@@ -551,13 +544,13 @@ class ClassDB {
551544
};
552545

553546
#define BIND_ENUM_CONSTANT(m_constant) \
554-
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant), #m_constant, m_constant);
547+
get_gdtype_static_mutable().bind_integer_constant(__constant_get_enum_name(m_constant), #m_constant, m_constant);
555548

556549
#define BIND_BITFIELD_FLAG(m_constant) \
557-
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_bitfield_name(m_constant), #m_constant, m_constant, true);
550+
get_gdtype_static_mutable().bind_integer_constant(__constant_get_bitfield_name(m_constant), #m_constant, m_constant, true);
558551

559552
#define BIND_CONSTANT(m_constant) \
560-
::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
553+
get_gdtype_static_mutable().bind_integer_constant(StringName(), #m_constant, m_constant);
561554

562555
#ifdef DEBUG_ENABLED
563556

0 commit comments

Comments
 (0)