Bläddra i källkod

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

Add methods in ClassDB to get property/method/constant/enum info
Rémi Verschelde 5 år sedan
förälder
incheckning
818bfbc5b5
2 ändrade filer med 152 tillägg och 22 borttagningar
  1. 145 21
      core/class_db.cpp
  2. 7 1
      core/class_db.h

+ 145 - 21
core/class_db.cpp

@@ -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());
-			MethodInfo minfo;
-			minfo.name = E->get();
-			minfo.id = method->get_method_id();
-
-			if (p_exclude_from_properties && type->methods_in_properties.has(minfo.name)) {
+			if (p_exclude_from_properties && type->methods_in_properties.has(E->get())) {
 				continue;
 				continue;
 			}
 			}
 
 
-			for (int i = 0; i < method->get_argument_count(); i++) {
-				//Variant::Type t=method->get_argument_type(i);
-
-				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));
-				}
-			}
+			MethodBind *method = type->method_map.get(E->get());
+			MethodInfo minfo = info_from_bind(method);
 
 
 			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
 }
 }

+ 7 - 1
core/class_db.h

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