Browse Source

Fix slow load/save of scenes with many instances of the same script

Pedro J. Estébanez 4 years ago
parent
commit
2ca6b9c610

+ 9 - 5
modules/gdscript/gdscript.cpp

@@ -360,7 +360,7 @@ PlaceHolderScriptInstance *GDScript::placeholder_instance_create(Object *p_this)
 #ifdef TOOLS_ENABLED
 	PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(GDScriptLanguage::get_singleton(), Ref<Script>(this), p_this));
 	placeholders.insert(si);
-	_update_exports();
+	_update_exports(nullptr, false, si);
 	return si;
 #else
 	return nullptr;
@@ -584,7 +584,7 @@ void GDScript::_update_doc() {
 }
 #endif
 
-bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) {
+bool GDScript::_update_exports(bool *r_err, bool p_recursive_call, PlaceHolderScriptInstance *p_instance_to_update) {
 #ifdef TOOLS_ENABLED
 
 	static Vector<GDScript *> base_caches;
@@ -721,15 +721,19 @@ bool GDScript::_update_exports(bool *r_err, bool p_recursive_call) {
 		}
 	}
 
-	if (placeholders.size()) { //hm :(
+	if ((changed || p_instance_to_update) && placeholders.size()) { //hm :(
 
 		// update placeholders if any
 		Map<StringName, Variant> values;
 		List<PropertyInfo> propnames;
 		_update_exports_values(values, propnames);
 
-		for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
-			E->get()->update(propnames, values);
+		if (changed) {
+			for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
+				E->get()->update(propnames, values);
+			}
+		} else {
+			p_instance_to_update->update(propnames, values);
 		}
 	}
 

+ 1 - 1
modules/gdscript/gdscript.h

@@ -148,7 +148,7 @@ class GDScript : public Script {
 
 #endif
 
-	bool _update_exports(bool *r_err = nullptr, bool p_recursive_call = false);
+	bool _update_exports(bool *r_err = nullptr, bool p_recursive_call = false, PlaceHolderScriptInstance *p_instance_to_update = nullptr);
 
 	void _save_orphaned_subclasses();
 	void _init_rpc_methods_properties();

+ 9 - 5
modules/mono/csharp_script.cpp

@@ -2370,7 +2370,7 @@ void CSharpScript::_update_member_info_no_exports() {
 }
 #endif
 
-bool CSharpScript::_update_exports() {
+bool CSharpScript::_update_exports(PlaceHolderScriptInstance *p_instance_to_update) {
 #ifdef TOOLS_ENABLED
 	bool is_editor = Engine::get_singleton()->is_editor_hint();
 	if (is_editor) {
@@ -2542,14 +2542,18 @@ bool CSharpScript::_update_exports() {
 	if (is_editor) {
 		placeholder_fallback_enabled = false;
 
-		if (placeholders.size()) {
+		if ((changed || p_instance_to_update) && placeholders.size()) {
 			// Update placeholders if any
 			Map<StringName, Variant> values;
 			List<PropertyInfo> propnames;
 			_update_exports_values(values, propnames);
 
-			for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
-				E->get()->update(propnames, values);
+			if (changed) {
+				for (Set<PlaceHolderScriptInstance *>::Element *E = placeholders.front(); E; E = E->next()) {
+					E->get()->update(propnames, values);
+				}
+			} else {
+				p_instance_to_update->update(propnames, values);
 			}
 		}
 	}
@@ -3230,7 +3234,7 @@ PlaceHolderScriptInstance *CSharpScript::placeholder_instance_create(Object *p_t
 #ifdef TOOLS_ENABLED
 	PlaceHolderScriptInstance *si = memnew(PlaceHolderScriptInstance(CSharpLanguage::get_singleton(), Ref<Script>(this), p_this));
 	placeholders.insert(si);
-	_update_exports();
+	_update_exports(si);
 	return si;
 #else
 	return nullptr;

+ 1 - 1
modules/mono/csharp_script.h

@@ -163,7 +163,7 @@ private:
 	void load_script_signals(GDMonoClass *p_class, GDMonoClass *p_native_class);
 	bool _get_signal(GDMonoClass *p_class, GDMonoMethod *p_delegate_invoke, Vector<SignalParameter> &params);
 
-	bool _update_exports();
+	bool _update_exports(PlaceHolderScriptInstance *p_instance_to_update = nullptr);
 
 	bool _get_member_export(IMonoClassMember *p_member, bool p_inspect_export, PropertyInfo &r_prop_info, bool &r_exported);
 #ifdef TOOLS_ENABLED