Browse Source

Merge pull request #51211 from pycbouh/editor-resource-picker-cache-3.x

[3.x] Cache `EditorResourcePicker`'s allowed types
Rémi Verschelde 4 years ago
parent
commit
cae29b5267
3 changed files with 38 additions and 8 deletions
  1. 2 0
      editor/editor_node.cpp
  2. 32 8
      editor/editor_resource_picker.cpp
  3. 4 0
      editor/editor_resource_picker.h

+ 2 - 0
editor/editor_node.cpp

@@ -3811,6 +3811,8 @@ void EditorNode::register_editor_types() {
 
 void EditorNode::unregister_editor_types() {
 	_init_callbacks.clear();
+
+	EditorResourcePicker::clear_caches();
 }
 
 void EditorNode::stop_child_process() {

+ 32 - 8
editor/editor_resource_picker.cpp

@@ -38,6 +38,12 @@
 #include "scene/main/viewport.h"
 #include "scene/resources/dynamic_font.h"
 
+HashMap<StringName, List<StringName>> EditorResourcePicker::allowed_types_cache;
+
+void EditorResourcePicker::clear_caches() {
+	allowed_types_cache.clear();
+}
+
 void EditorResourcePicker::_update_resource() {
 	preview_rect->set_texture(Ref<Texture>());
 	assign_button->set_custom_minimum_size(Size2(1, 1));
@@ -464,17 +470,31 @@ void EditorResourcePicker::_get_allowed_types(bool p_with_convert, Set<String> *
 		String base = allowed_types[i].strip_edges();
 		p_vector->insert(base);
 
-		List<StringName> inheriters;
-
-		ClassDB::get_inheriters_from_class(base, &inheriters);
-		for (List<StringName>::Element *E = inheriters.front(); E; E = E->next()) {
-			p_vector->insert(E->get());
-		}
+		// If we hit a familiar base type, take all the data from cache.
+		if (allowed_types_cache.has(base)) {
+			List<StringName> allowed_subtypes = allowed_types_cache[base];
+			for (List<StringName>::Element *E = allowed_subtypes.front(); E; E = E->next()) {
+				p_vector->insert(E->get());
+			}
+		} else {
+			List<StringName> allowed_subtypes;
 
-		for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
-			if (EditorNode::get_editor_data().script_class_is_parent(E->get(), base)) {
+			List<StringName> inheriters;
+			ClassDB::get_inheriters_from_class(base, &inheriters);
+			for (List<StringName>::Element *E = inheriters.front(); E; E = E->next()) {
 				p_vector->insert(E->get());
+				allowed_subtypes.push_back(E->get());
 			}
+
+			for (List<StringName>::Element *E = global_classes.front(); E; E = E->next()) {
+				if (EditorNode::get_editor_data().script_class_is_parent(E->get(), base)) {
+					p_vector->insert(E->get());
+					allowed_subtypes.push_back(E->get());
+				}
+			}
+
+			// Store the subtypes of the base type in the cache for future use.
+			allowed_types_cache[base] = allowed_subtypes;
 		}
 
 		if (p_with_convert) {
@@ -710,6 +730,10 @@ void EditorResourcePicker::set_base_type(const String &p_base_type) {
 			String class_str = (custom_class == StringName() ? edited_resource->get_class() : vformat("%s (%s)", custom_class, edited_resource->get_class()));
 			WARN_PRINT(vformat("Value mismatch between the new base type of this EditorResourcePicker, '%s', and the type of the value it already has, '%s'.", base_type, class_str));
 		}
+	} else {
+		// Call the method to build the cache immediately.
+		Set<String> allowed_types;
+		_get_allowed_types(false, &allowed_types);
 	}
 }
 

+ 4 - 0
editor/editor_resource_picker.h

@@ -40,6 +40,8 @@
 class EditorResourcePicker : public HBoxContainer {
 	GDCLASS(EditorResourcePicker, HBoxContainer);
 
+	static HashMap<StringName, List<StringName>> allowed_types_cache;
+
 	String base_type;
 	RES edited_resource;
 
@@ -95,6 +97,8 @@ protected:
 	void _notification(int p_what);
 
 public:
+	static void clear_caches();
+
 	void set_base_type(const String &p_base_type);
 	String get_base_type() const;
 	Vector<String> get_allowed_types() const;