Merge pull request #40161 from vnen/classdb-info-methods

Add methods in ClassDB to get property/method/constant/enum info
This commit is contained in:
Rémi Verschelde 2020-07-20 16:29:33 +02:00 committed by GitHub
commit 818bfbc5b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 152 additions and 22 deletions

View File

@ -548,6 +548,29 @@ void ClassDB::_add_class2(const StringName &p_class, const StringName &p_inherit
} }
} }
#ifdef DEBUG_METHODS_ENABLED
static MethodInfo info_from_bind(MethodBind *p_method) {
MethodInfo minfo;
minfo.name = p_method->get_name();
minfo.id = p_method->get_method_id();
for (int i = 0; i < p_method->get_argument_count(); i++) {
minfo.arguments.push_back(p_method->get_argument_info(i));
}
minfo.return_val = p_method->get_return_info();
minfo.flags = p_method->get_hint_flags();
for (int i = 0; i < p_method->get_argument_count(); i++) {
if (p_method->has_default_argument(i)) {
minfo.default_arguments.push_back(p_method->get_default_argument(i));
}
}
return minfo;
}
#endif
void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) { void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance, bool p_exclude_from_properties) {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
@ -570,29 +593,12 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
} }
for (List<StringName>::Element *E = type->method_order.front(); E; E = E->next()) { for (List<StringName>::Element *E = type->method_order.front(); E; E = E->next()) {
MethodBind *method = type->method_map.get(E->get()); if (p_exclude_from_properties && type->methods_in_properties.has(E->get())) {
MethodInfo minfo;
minfo.name = E->get();
minfo.id = method->get_method_id();
if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name)) {
continue; continue;
} }
for (int i = 0; i < method->get_argument_count(); i++) { MethodBind *method = type->method_map.get(E->get());
//Variant::Type t=method->get_argument_type(i); MethodInfo minfo = info_from_bind(method);
minfo.arguments.push_back(method->get_argument_info(i));
}
minfo.return_val = method->get_return_info();
minfo.flags = method->get_hint_flags();
for (int i = 0; i < method->get_argument_count(); i++) {
if (method->has_default_argument(i)) {
minfo.default_arguments.push_back(method->get_default_argument(i));
}
}
p_methods->push_back(minfo); p_methods->push_back(minfo);
} }
@ -618,6 +624,57 @@ void ClassDB::get_method_list(StringName p_class, List<MethodInfo> *p_methods, b
} }
} }
bool ClassDB::get_method_info(StringName p_class, StringName p_method, MethodInfo *r_info, bool p_no_inheritance, bool p_exclude_from_properties) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
if (type->disabled) {
if (p_no_inheritance) {
break;
}
type = type->inherits_ptr;
continue;
}
#ifdef DEBUG_METHODS_ENABLED
MethodBind **method = type->method_map.getptr(p_method);
if (method && *method) {
if (r_info != nullptr) {
MethodInfo minfo = info_from_bind(*method);
*r_info = minfo;
}
return true;
} else if (type->virtual_methods_map.has(p_method)) {
if (r_info) {
*r_info = type->virtual_methods_map[p_method];
}
return true;
}
#else
if (type->method_map.has(p_method)) {
if (r_info) {
MethodBind *m = type->method_map[p_method];
MethodInfo mi;
mi.name = m->get_name();
*r_info = mi;
}
return true;
}
#endif
if (p_no_inheritance) {
break;
}
type = type->inherits_ptr;
}
return false;
}
MethodBind *ClassDB::get_method(StringName p_class, StringName p_name) { MethodBind *ClassDB::get_method(StringName p_class, StringName p_name) {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
@ -718,6 +775,25 @@ int ClassDB::get_integer_constant(const StringName &p_class, const StringName &p
return 0; return 0;
} }
bool ClassDB::has_integer_constant(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
if (type->constant_map.has(p_name)) {
return true;
}
if (p_no_inheritance) {
return false;
}
type = type->inherits_ptr;
}
return false;
}
StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) { StringName ClassDB::get_integer_constant_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
@ -784,6 +860,25 @@ void ClassDB::get_enum_constants(const StringName &p_class, const StringName &p_
} }
} }
bool ClassDB::has_enum(const StringName &p_class, const StringName &p_name, bool p_no_inheritance) {
OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class);
while (type) {
if (type->enum_map.has(p_name)) {
return true;
}
if (p_no_inheritance) {
return false;
}
type = type->inherits_ptr;
}
return false;
}
void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) { void ClassDB::add_signal(StringName p_class, const MethodInfo &p_signal) {
OBJTYPE_WLOCK; OBJTYPE_WLOCK;
@ -825,7 +920,7 @@ void ClassDB::get_signal_list(StringName p_class, List<MethodInfo> *p_signals, b
} }
} }
bool ClassDB::has_signal(StringName p_class, StringName p_signal) { bool ClassDB::has_signal(StringName p_class, StringName p_signal, bool p_no_inheritance) {
OBJTYPE_RLOCK; OBJTYPE_RLOCK;
ClassInfo *type = classes.getptr(p_class); ClassInfo *type = classes.getptr(p_class);
ClassInfo *check = type; ClassInfo *check = type;
@ -833,6 +928,9 @@ bool ClassDB::has_signal(StringName p_class, StringName p_signal) {
if (check->signal_map.has(p_signal)) { if (check->signal_map.has(p_signal)) {
return true; return true;
} }
if (p_no_inheritance) {
return false;
}
check = check->inherits_ptr; check = check->inherits_ptr;
} }
@ -910,6 +1008,7 @@ void ClassDB::add_property(StringName p_class, const PropertyInfo &p_pinfo, cons
OBJTYPE_WLOCK OBJTYPE_WLOCK
type->property_list.push_back(p_pinfo); type->property_list.push_back(p_pinfo);
type->property_map[p_pinfo.name] = p_pinfo;
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
if (mb_get) { if (mb_get) {
type->methods_in_properties.insert(p_getter); type->methods_in_properties.insert(p_getter);
@ -959,6 +1058,30 @@ void ClassDB::get_property_list(StringName p_class, List<PropertyInfo> *p_list,
} }
} }
bool ClassDB::get_property_info(StringName p_class, StringName p_property, PropertyInfo *r_info, bool p_no_inheritance, const Object *p_validator) {
OBJTYPE_RLOCK;
ClassInfo *check = classes.getptr(p_class);
while (check) {
if (check->property_map.has(p_property)) {
PropertyInfo pinfo = check->property_map[p_property];
if (p_validator) {
p_validator->_validate_property(pinfo);
}
if (r_info) {
*r_info = pinfo;
}
return true;
}
if (p_no_inheritance) {
break;
}
check = check->inherits_ptr;
}
return false;
}
bool ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid) { bool ClassDB::set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid) {
ClassInfo *type = classes.getptr(p_object->get_class_name()); ClassInfo *type = classes.getptr(p_object->get_class_name());
ClassInfo *check = type; ClassInfo *check = type;
@ -1239,6 +1362,7 @@ void ClassDB::add_virtual_method(const StringName &p_class, const MethodInfo &p_
mi.flags |= METHOD_FLAG_VIRTUAL; mi.flags |= METHOD_FLAG_VIRTUAL;
} }
classes[p_class].virtual_methods.push_back(mi); classes[p_class].virtual_methods.push_back(mi);
classes[p_class].virtual_methods_map[p_method.name] = mi;
#endif #endif
} }

View File

@ -120,11 +120,13 @@ public:
HashMap<StringName, List<StringName>> enum_map; HashMap<StringName, List<StringName>> enum_map;
HashMap<StringName, MethodInfo> signal_map; HashMap<StringName, MethodInfo> signal_map;
List<PropertyInfo> property_list; List<PropertyInfo> property_list;
HashMap<StringName, PropertyInfo> property_map;
#ifdef DEBUG_METHODS_ENABLED #ifdef DEBUG_METHODS_ENABLED
List<StringName> constant_order; List<StringName> constant_order;
List<StringName> method_order; List<StringName> method_order;
Set<StringName> methods_in_properties; Set<StringName> methods_in_properties;
List<MethodInfo> virtual_methods; List<MethodInfo> virtual_methods;
Map<StringName, MethodInfo> virtual_methods_map;
StringName category; StringName category;
#endif #endif
HashMap<StringName, PropertySetGet> property_setget; HashMap<StringName, PropertySetGet> property_setget;
@ -328,7 +330,7 @@ public:
} }
static void add_signal(StringName p_class, const MethodInfo &p_signal); static void add_signal(StringName p_class, const MethodInfo &p_signal);
static bool has_signal(StringName p_class, StringName p_signal); static bool has_signal(StringName p_class, StringName p_signal, bool p_no_inheritance = false);
static bool get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal); static bool get_signal(StringName p_class, StringName p_signal, MethodInfo *r_signal);
static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false); static void get_signal_list(StringName p_class, List<MethodInfo> *p_signals, bool p_no_inheritance = false);
@ -337,6 +339,7 @@ public:
static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1); static void add_property(StringName p_class, const PropertyInfo &p_pinfo, const StringName &p_setter, const StringName &p_getter, int p_index = -1);
static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default); static void set_property_default_value(StringName p_class, const StringName &p_name, const Variant &p_default);
static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr); static void get_property_list(StringName p_class, List<PropertyInfo> *p_list, bool p_no_inheritance = false, const Object *p_validator = nullptr);
static bool get_property_info(StringName p_class, StringName p_property, PropertyInfo *r_info, bool p_no_inheritance = false, const Object *p_validator = nullptr);
static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = nullptr); static bool set_property(Object *p_object, const StringName &p_property, const Variant &p_value, bool *r_valid = nullptr);
static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value); static bool get_property(Object *p_object, const StringName &p_property, Variant &r_value);
static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false); static bool has_property(const StringName &p_class, const StringName &p_property, bool p_no_inheritance = false);
@ -349,6 +352,7 @@ public:
static void set_method_flags(StringName p_class, StringName p_method, int p_flags); static void set_method_flags(StringName p_class, StringName p_method, int p_flags);
static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false); static void get_method_list(StringName p_class, List<MethodInfo> *p_methods, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
static bool get_method_info(StringName p_class, StringName p_method, MethodInfo *r_info, bool p_no_inheritance = false, bool p_exclude_from_properties = false);
static MethodBind *get_method(StringName p_class, StringName p_name); static MethodBind *get_method(StringName p_class, StringName p_name);
static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true); static void add_virtual_method(const StringName &p_class, const MethodInfo &p_method, bool p_virtual = true);
@ -357,10 +361,12 @@ public:
static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant); static void bind_integer_constant(const StringName &p_class, const StringName &p_enum, const StringName &p_name, int p_constant);
static void get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance = false); static void get_integer_constant_list(const StringName &p_class, List<String> *p_constants, bool p_no_inheritance = false);
static int get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success = nullptr); static int get_integer_constant(const StringName &p_class, const StringName &p_name, bool *p_success = nullptr);
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_enum(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_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 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);
static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid = nullptr); static Variant class_get_default_property_value(const StringName &p_class, const StringName &p_property, bool *r_valid = nullptr);