Skip to content
Open
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
6 changes: 3 additions & 3 deletions core/io/resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -751,9 +751,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"));
Expand Down
164 changes: 33 additions & 131 deletions core/object/class_db.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -461,15 +461,15 @@ 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);
}

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

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);
}
}

Expand Down Expand Up @@ -883,7 +883,7 @@ bool ClassDB::is_virtual(const StringName &p_class) {
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();
Expand Down Expand Up @@ -1158,168 +1158,87 @@ 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);
}
}

int64_t ClassDB::get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success) {
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;
}

bool ClassDB::has_integer_constant(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->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);
}
}

void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_enum, List<StringName> *p_constants, bool p_no_inheritance) {
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);

if (constants) {
for (const List<StringName>::Element *E = constants->constants.front(); E; E = E->next()) {
p_constants->push_back(E->get());
}
}
const GDType::EnumInfo *const *enum_info = type->gdtype->get_enum_map(p_no_inheritance).getptr(p_enum);
ERR_FAIL_NULL(enum_info);

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);
}
}

Expand Down Expand Up @@ -1354,38 +1273,21 @@ 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);
ERR_FAIL_NULL_V(enum_info, false);

return false;
return (*enum_info)->is_bitfield;
}

void ClassDB::add_signal(const StringName &p_class, const MethodInfo &p_signal) {
Expand Down Expand Up @@ -1724,7 +1626,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;
Expand Down
19 changes: 6 additions & 13 deletions core/object/class_db.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ MethodDefinition D_METHOD(const char *p_name, const VarArgs... p_args) {

class ClassDB {
friend class Object;
friend class GDType;

public:
enum APIType {
Expand All @@ -123,25 +124,18 @@ class ClassDB {
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;
Expand Down Expand Up @@ -219,7 +213,7 @@ class ClassDB {
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;
Expand Down Expand Up @@ -507,7 +501,6 @@ class ClassDB {
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);
Expand Down Expand Up @@ -551,13 +544,13 @@ class ClassDB {
};

#define BIND_ENUM_CONSTANT(m_constant) \
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_enum_name(m_constant), #m_constant, m_constant);
get_gdtype_static_mutable().bind_integer_constant(__constant_get_enum_name(m_constant), #m_constant, m_constant);

#define BIND_BITFIELD_FLAG(m_constant) \
::ClassDB::bind_integer_constant(get_class_static(), __constant_get_bitfield_name(m_constant), #m_constant, m_constant, true);
get_gdtype_static_mutable().bind_integer_constant(__constant_get_bitfield_name(m_constant), #m_constant, m_constant, true);

#define BIND_CONSTANT(m_constant) \
::ClassDB::bind_integer_constant(get_class_static(), StringName(), #m_constant, m_constant);
get_gdtype_static_mutable().bind_integer_constant(StringName(), #m_constant, m_constant);

#ifdef DEBUG_ENABLED

Expand Down
Loading