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);