Răsfoiți Sursa

Merge pull request #19108 from vnen/autoload-fix

Only add autoloads in editor if they have tool scripts
Max Hilbrunner 7 ani în urmă
părinte
comite
9f40a8d270
3 a modificat fișierele cu 128 adăugiri și 100 ștergeri
  1. 117 76
      editor/editor_autoload_settings.cpp
  2. 10 0
      editor/editor_autoload_settings.h
  3. 1 24
      main/main.cpp

+ 117 - 76
editor/editor_autoload_settings.cpp

@@ -52,6 +52,13 @@ void EditorAutoloadSettings::_notification(int p_what) {
 
 			file_dialog->add_filter("*." + E->get());
 		}
+
+		for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
+			AutoLoadInfo &info = E->get();
+			if (info.node && info.in_editor) {
+				get_tree()->get_root()->call_deferred("add_child", info.node);
+			}
+		}
 	}
 }
 
@@ -291,6 +298,36 @@ void EditorAutoloadSettings::_autoload_file_callback(const String &p_path) {
 	autoload_add_name->set_text(p_path.get_file().get_basename());
 }
 
+Node *EditorAutoloadSettings::_create_autoload(const String &p_path) {
+	RES res = ResourceLoader::load(p_path);
+	ERR_EXPLAIN("Can't autoload: " + p_path);
+	ERR_FAIL_COND_V(res.is_null(), NULL);
+	Node *n = NULL;
+	if (res->is_class("PackedScene")) {
+		Ref<PackedScene> ps = res;
+		n = ps->instance();
+	} else if (res->is_class("Script")) {
+		Ref<Script> s = res;
+		StringName ibt = s->get_instance_base_type();
+		bool valid_type = ClassDB::is_parent_class(ibt, "Node");
+		ERR_EXPLAIN("Script does not inherit a Node: " + p_path);
+		ERR_FAIL_COND_V(!valid_type, NULL);
+
+		Object *obj = ClassDB::instance(ibt);
+
+		ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
+		ERR_FAIL_COND_V(obj == NULL, NULL);
+
+		n = Object::cast_to<Node>(obj);
+		n->set_script(s.get_ref_ptr());
+	}
+
+	ERR_EXPLAIN("Path in autoload not a node or script: " + p_path);
+	ERR_FAIL_COND_V(!n, NULL);
+
+	return n;
+}
+
 void EditorAutoloadSettings::update_autoload() {
 
 	if (updating_autoload)
@@ -299,15 +336,11 @@ void EditorAutoloadSettings::update_autoload() {
 	updating_autoload = true;
 
 	Map<String, AutoLoadInfo> to_remove;
-	Map<String, AutoLoadInfo> to_remove_singleton;
-	List<AutoLoadInfo> to_add;
-	List<String> to_add_singleton; // Only for when the node is still the same
+	List<AutoLoadInfo *> to_add;
 
 	for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
-		to_remove.insert(E->get().name, E->get());
-		if (E->get().is_singleton) {
-			to_remove_singleton.insert(E->get().name, E->get());
-		}
+		AutoLoadInfo &info = E->get();
+		to_remove.insert(info.name, info);
 	}
 
 	autoload_cache.clear();
@@ -331,11 +364,6 @@ void EditorAutoloadSettings::update_autoload() {
 		if (name.empty())
 			continue;
 
-		AutoLoadInfo old_info;
-		if (to_remove.has(name)) {
-			old_info = to_remove[name];
-		}
-
 		AutoLoadInfo info;
 		info.is_singleton = path.begins_with("*");
 
@@ -347,28 +375,31 @@ void EditorAutoloadSettings::update_autoload() {
 		info.path = path;
 		info.order = ProjectSettings::get_singleton()->get_order(pi.name);
 
-		if (old_info.name == info.name) {
+		bool need_to_add = true;
+		if (to_remove.has(name)) {
+			AutoLoadInfo &old_info = to_remove[name];
 			if (old_info.path == info.path) {
-				// Still the same resource, check singleton status
-				to_remove.erase(name);
-				if (info.is_singleton) {
-					if (old_info.is_singleton) {
-						to_remove_singleton.erase(name);
+				// Still the same resource, check status
+				info.node = old_info.node;
+				if (info.node) {
+					Ref<Script> scr = info.node->get_script();
+					info.in_editor = scr.is_valid() && scr->is_tool();
+					if (info.is_singleton == old_info.is_singleton && info.in_editor == old_info.in_editor) {
+						to_remove.erase(name);
+						need_to_add = false;
 					} else {
-						to_add_singleton.push_back(name);
+						info.node = NULL;
 					}
 				}
-			} else {
-				// Resource changed
-				to_add.push_back(info);
 			}
-		} else {
-			// New autoload
-			to_add.push_back(info);
 		}
 
 		autoload_cache.push_back(info);
 
+		if (need_to_add) {
+			to_add.push_back(&(autoload_cache.back()->get()));
+		}
+
 		TreeItem *item = tree->create_item(root);
 		item->set_text(0, name);
 		item->set_editable(0, true);
@@ -387,71 +418,54 @@ void EditorAutoloadSettings::update_autoload() {
 		item->set_selectable(3, false);
 	}
 
-	// Remove autoload constants
-	for (Map<String, AutoLoadInfo>::Element *E = to_remove_singleton.front(); E; E = E->next()) {
-		for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-			ScriptServer::get_language(i)->remove_named_global_constant(E->get().name);
-		}
-	}
-
-	// Remove obsolete nodes from the tree
+	// Remove deleted/changed autoloads
 	for (Map<String, AutoLoadInfo>::Element *E = to_remove.front(); E; E = E->next()) {
 		AutoLoadInfo &info = E->get();
-		Node *al = get_node("/root/" + info.name);
-		ERR_CONTINUE(!al);
-		get_tree()->get_root()->remove_child(al);
-		memdelete(al);
-	}
+		if (info.is_singleton) {
+			for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+				ScriptServer::get_language(i)->remove_named_global_constant(info.name);
+			}
+		}
+		if (info.in_editor) {
+			ERR_CONTINUE(!info.node);
+			get_tree()->get_root()->remove_child(info.node);
+		}
 
-	// Register new singletons already in the tree
-	for (List<String>::Element *E = to_add_singleton.front(); E; E = E->next()) {
-		Node *al = get_node("/root/" + E->get());
-		ERR_CONTINUE(!al);
-		for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-			ScriptServer::get_language(i)->add_named_global_constant(E->get(), al);
+		if (info.node) {
+			memdelete(info.node);
+			info.node = NULL;
 		}
 	}
 
-	// Add new nodes to the tree
+	// Load new/changed autoloads
 	List<Node *> nodes_to_add;
-	for (List<AutoLoadInfo>::Element *E = to_add.front(); E; E = E->next()) {
-		AutoLoadInfo &info = E->get();
+	for (List<AutoLoadInfo *>::Element *E = to_add.front(); E; E = E->next()) {
+		AutoLoadInfo *info = E->get();
 
-		RES res = ResourceLoader::load(info.path);
-		ERR_EXPLAIN("Can't autoload: " + info.path);
-		ERR_CONTINUE(res.is_null());
-		Node *n = NULL;
-		if (res->is_class("PackedScene")) {
-			Ref<PackedScene> ps = res;
-			n = ps->instance();
-		} else if (res->is_class("Script")) {
-			Ref<Script> s = res;
-			StringName ibt = s->get_instance_base_type();
-			bool valid_type = ClassDB::is_parent_class(ibt, "Node");
-			ERR_EXPLAIN("Script does not inherit a Node: " + info.path);
-			ERR_CONTINUE(!valid_type);
-
-			Object *obj = ClassDB::instance(ibt);
-
-			ERR_EXPLAIN("Cannot instance script for autoload, expected 'Node' inheritance, got: " + String(ibt));
-			ERR_CONTINUE(obj == NULL);
-
-			n = Object::cast_to<Node>(obj);
-			n->set_script(s.get_ref_ptr());
-		}
+		info->node = _create_autoload(info->path);
 
-		ERR_EXPLAIN("Path in autoload not a node or script: " + info.path);
-		ERR_CONTINUE(!n);
-		n->set_name(info.name);
+		ERR_CONTINUE(!info->node);
+		info->node->set_name(info->name);
 
-		//defer so references are all valid on _ready()
-		nodes_to_add.push_back(n);
+		Ref<Script> scr = info->node->get_script();
+		info->in_editor = scr.is_valid() && scr->is_tool();
 
-		if (info.is_singleton) {
+		if (info->in_editor) {
+			//defer so references are all valid on _ready()
+			nodes_to_add.push_back(info->node);
+		}
+
+		if (info->is_singleton) {
 			for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-				ScriptServer::get_language(i)->add_named_global_constant(info.name, n);
+				ScriptServer::get_language(i)->add_named_global_constant(info->name, info->node);
 			}
 		}
+
+		if (!info->in_editor && !info->is_singleton) {
+			// No reason to keep this node
+			memdelete(info->node);
+			info->node = NULL;
+		}
 	}
 
 	for (List<Node *>::Element *E = nodes_to_add.front(); E; E = E->next()) {
@@ -728,6 +742,24 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
 		info.name = name;
 		info.path = path;
 		info.order = ProjectSettings::get_singleton()->get_order(pi.name);
+		info.node = _create_autoload(path);
+
+		if (info.node) {
+			Ref<Script> scr = info.node->get_script();
+			info.in_editor = scr.is_valid() && scr->is_tool();
+			info.node->set_name(info.name);
+		}
+
+		if (info.is_singleton) {
+			for (int i = 0; i < ScriptServer::get_language_count(); i++) {
+				ScriptServer::get_language(i)->add_named_global_constant(info.name, info.node);
+			}
+		}
+
+		if (!info.is_singleton && !info.in_editor) {
+			memdelete(info.node);
+			info.node = NULL;
+		}
 
 		autoload_cache.push_back(info);
 	}
@@ -796,3 +828,12 @@ EditorAutoloadSettings::EditorAutoloadSettings() {
 
 	add_child(tree, true);
 }
+
+EditorAutoloadSettings::~EditorAutoloadSettings() {
+	for (List<AutoLoadInfo>::Element *E = autoload_cache.front(); E; E = E->next()) {
+		AutoLoadInfo &info = E->get();
+		if (info.node && !info.in_editor) {
+			memdelete(info.node);
+		}
+	}
+}

+ 10 - 0
editor/editor_autoload_settings.h

@@ -52,11 +52,19 @@ class EditorAutoloadSettings : public VBoxContainer {
 		String name;
 		String path;
 		bool is_singleton;
+		bool in_editor;
 		int order;
+		Node *node;
 
 		bool operator==(const AutoLoadInfo &p_info) {
 			return order == p_info.order;
 		}
+
+		AutoLoadInfo() {
+			is_singleton = false;
+			in_editor = false;
+			node = NULL;
+		}
 	};
 
 	List<AutoLoadInfo> autoload_cache;
@@ -78,6 +86,7 @@ class EditorAutoloadSettings : public VBoxContainer {
 	void _autoload_activated();
 	void _autoload_open(const String &fpath);
 	void _autoload_file_callback(const String &p_path);
+	Node *_create_autoload(const String &p_path);
 
 	Variant get_drag_data_fw(const Point2 &p_point, Control *p_control);
 	bool can_drop_data_fw(const Point2 &p_point, const Variant &p_data, Control *p_control) const;
@@ -93,6 +102,7 @@ public:
 	void autoload_remove(const String &p_name);
 
 	EditorAutoloadSettings();
+	~EditorAutoloadSettings();
 };
 
 #endif

+ 1 - 24
main/main.cpp

@@ -1444,7 +1444,7 @@ bool Main::start() {
 		}
 #endif
 
-		if (!project_manager) { // game or editor
+		if (!project_manager && !editor) { // game
 			if (game_path != "" || script != "") {
 				//autoload
 				List<PropertyInfo> props;
@@ -1465,24 +1465,13 @@ bool Main::start() {
 
 					if (global_var) {
 						for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-#ifdef TOOLS_ENABLED
-							if (editor) {
-								ScriptServer::get_language(i)->add_named_global_constant(name, Variant());
-							} else {
-								ScriptServer::get_language(i)->add_global_constant(name, Variant());
-							}
-#else
 							ScriptServer::get_language(i)->add_global_constant(name, Variant());
-#endif
 						}
 					}
 				}
 
 				//second pass, load into global constants
 				List<Node *> to_add;
-#ifdef TOOLS_ENABLED
-				ResourceLoader::set_timestamp_on_load(editor); // Avoid problems when editing
-#endif
 				for (List<PropertyInfo>::Element *E = props.front(); E; E = E->next()) {
 
 					String s = E->get().name;
@@ -1528,23 +1517,11 @@ bool Main::start() {
 
 					if (global_var) {
 						for (int i = 0; i < ScriptServer::get_language_count(); i++) {
-#ifdef TOOLS_ENABLED
-							if (editor) {
-								ScriptServer::get_language(i)->add_named_global_constant(name, n);
-							} else {
-								ScriptServer::get_language(i)->add_global_constant(name, n);
-							}
-#else
 							ScriptServer::get_language(i)->add_global_constant(name, n);
-#endif
 						}
 					}
 				}
 
-#ifdef TOOLS_ENABLED
-				ResourceLoader::set_timestamp_on_load(false);
-#endif
-
 				for (List<Node *>::Element *E = to_add.front(); E; E = E->next()) {
 
 					sml->get_root()->add_child(E->get());