From da767ebfa2aa01e4401aa2b60d4608ebbc24b3ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pa=CC=84vels=20Nadtoc=CC=8Cajevs?= <7645683+bruvzg@users.noreply.github.com> Date: Mon, 10 Feb 2025 11:49:26 +0200 Subject: [PATCH] Prevent `changed` signal spam on resource reload. --- core/io/resource.cpp | 23 +++++++++++++++++++++++ core/io/resource.h | 9 +++++++++ 2 files changed, 32 insertions(+) diff --git a/core/io/resource.cpp b/core/io/resource.cpp index 886ec6f5e10..703d25ab761 100644 --- a/core/io/resource.cpp +++ b/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 &p_resource) { return ERR_INVALID_PARAMETER; } + _block_emit_changed(); + reset_state(); // May want to reset state. List pi; @@ -220,6 +240,9 @@ Error Resource::copy_from(const Ref &p_resource) { set(E.name, p_resource->get(E.name)); } + + _unblock_emit_changed(); + return OK; } diff --git a/core/io/resource.h b/core/io/resource.h index ebc82ceebf9..6d93356d717 100644 --- a/core/io/resource.h +++ b/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);