Prechádzať zdrojové kódy

Prevent `changed` signal spam on resource reload.

Pāvels Nadtočajevs 5 mesiacov pred
rodič
commit
da767ebfa2
2 zmenil súbory, kde vykonal 32 pridanie a 0 odobranie
  1. 23 0
      core/io/resource.cpp
  2. 9 0
      core/io/resource.h

+ 23 - 0
core/io/resource.cpp

@@ -36,6 +36,10 @@
 #include "scene/main/node.h" //only so casting works
 
 void Resource::emit_changed() {
+	if (emit_changed_state != EMIT_CHANGED_UNBLOCKED) {
+		emit_changed_state = EMIT_CHANGED_BLOCKED_PENDING_EMIT;
+		return;
+	}
 	if (ResourceLoader::is_within_load() && !Thread::is_main_thread()) {
 		ResourceLoader::resource_changed_emit(this);
 		return;
@@ -44,6 +48,20 @@ void Resource::emit_changed() {
 	emit_signal(CoreStringName(changed));
 }
 
+void Resource::_block_emit_changed() {
+	if (emit_changed_state == EMIT_CHANGED_UNBLOCKED) {
+		emit_changed_state = EMIT_CHANGED_BLOCKED;
+	}
+}
+
+void Resource::_unblock_emit_changed() {
+	bool emit = (emit_changed_state == EMIT_CHANGED_BLOCKED_PENDING_EMIT);
+	emit_changed_state = EMIT_CHANGED_UNBLOCKED;
+	if (emit) {
+		emit_changed();
+	}
+}
+
 void Resource::_resource_path_changed() {
 }
 
@@ -205,6 +223,8 @@ Error Resource::copy_from(const Ref<Resource> &p_resource) {
 		return ERR_INVALID_PARAMETER;
 	}
 
+	_block_emit_changed();
+
 	reset_state(); // May want to reset state.
 
 	List<PropertyInfo> pi;
@@ -220,6 +240,9 @@ Error Resource::copy_from(const Ref<Resource> &p_resource) {
 
 		set(E.name, p_resource->get(E.name));
 	}
+
+	_unblock_emit_changed();
+
 	return OK;
 }
 

+ 9 - 0
core/io/resource.h

@@ -72,6 +72,12 @@ private:
 	String import_path;
 #endif
 
+	enum EmitChangedState {
+		EMIT_CHANGED_UNBLOCKED,
+		EMIT_CHANGED_BLOCKED,
+		EMIT_CHANGED_BLOCKED_PENDING_EMIT,
+	};
+	EmitChangedState emit_changed_state = EMIT_CHANGED_UNBLOCKED;
 	bool local_to_scene = false;
 	friend class SceneState;
 	Node *local_scene = nullptr;
@@ -85,6 +91,9 @@ protected:
 	virtual void _resource_path_changed();
 	static void _bind_methods();
 
+	void _block_emit_changed();
+	void _unblock_emit_changed();
+
 	void _set_path(const String &p_path);
 	void _take_over_path(const String &p_path);