mirror of
				https://github.com/godotengine/godot.git
				synced 2025-11-04 07:31:16 +00:00 
			
		
		
		
	Merge pull request #77750 from RandomShaper/tidy_shader_data_items
Let editor workaround a case of inconsistency in compound scenes
This commit is contained in:
		
						commit
						ad85ecef8d
					
				
					 7 changed files with 70 additions and 1 deletions
				
			
		| 
						 | 
					@ -179,6 +179,12 @@
 | 
				
			||||||
				Returns mesh previews rendered at the given size as an [Array] of [Texture2D]s.
 | 
									Returns mesh previews rendered at the given size as an [Array] of [Texture2D]s.
 | 
				
			||||||
			</description>
 | 
								</description>
 | 
				
			||||||
		</method>
 | 
							</method>
 | 
				
			||||||
 | 
							<method name="mark_scene_as_unsaved">
 | 
				
			||||||
 | 
								<return type="void" />
 | 
				
			||||||
 | 
								<description>
 | 
				
			||||||
 | 
									Marks the current scene tab as unsaved.
 | 
				
			||||||
 | 
								</description>
 | 
				
			||||||
 | 
							</method>
 | 
				
			||||||
		<method name="open_scene_from_path">
 | 
							<method name="open_scene_from_path">
 | 
				
			||||||
			<return type="void" />
 | 
								<return type="void" />
 | 
				
			||||||
			<param index="0" name="scene_filepath" type="String" />
 | 
								<param index="0" name="scene_filepath" type="String" />
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,6 +36,7 @@
 | 
				
			||||||
#include "editor/editor_resource_preview.h"
 | 
					#include "editor/editor_resource_preview.h"
 | 
				
			||||||
#include "editor/editor_scale.h"
 | 
					#include "editor/editor_scale.h"
 | 
				
			||||||
#include "editor/editor_settings.h"
 | 
					#include "editor/editor_settings.h"
 | 
				
			||||||
 | 
					#include "editor/editor_undo_redo_manager.h"
 | 
				
			||||||
#include "editor/filesystem_dock.h"
 | 
					#include "editor/filesystem_dock.h"
 | 
				
			||||||
#include "editor/gui/editor_run_bar.h"
 | 
					#include "editor/gui/editor_run_bar.h"
 | 
				
			||||||
#include "editor/inspector_dock.h"
 | 
					#include "editor/inspector_dock.h"
 | 
				
			||||||
| 
						 | 
					@ -332,6 +333,10 @@ void EditorInterface::save_scene_as(const String &p_scene, bool p_with_preview)
 | 
				
			||||||
	EditorNode::get_singleton()->save_scene_to_path(p_scene, p_with_preview);
 | 
						EditorNode::get_singleton()->save_scene_to_path(p_scene, p_with_preview);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EditorInterface::mark_scene_as_unsaved() {
 | 
				
			||||||
 | 
						EditorUndoRedoManager::get_singleton()->set_history_as_unsaved(EditorNode::get_editor_data().get_current_edited_scene_history_id());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Scene playback.
 | 
					// Scene playback.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void EditorInterface::play_main_scene() {
 | 
					void EditorInterface::play_main_scene() {
 | 
				
			||||||
| 
						 | 
					@ -430,6 +435,8 @@ void EditorInterface::_bind_methods() {
 | 
				
			||||||
	ClassDB::bind_method(D_METHOD("save_scene"), &EditorInterface::save_scene);
 | 
						ClassDB::bind_method(D_METHOD("save_scene"), &EditorInterface::save_scene);
 | 
				
			||||||
	ClassDB::bind_method(D_METHOD("save_scene_as", "path", "with_preview"), &EditorInterface::save_scene_as, DEFVAL(true));
 | 
						ClassDB::bind_method(D_METHOD("save_scene_as", "path", "with_preview"), &EditorInterface::save_scene_as, DEFVAL(true));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ClassDB::bind_method(D_METHOD("mark_scene_as_unsaved"), &EditorInterface::mark_scene_as_unsaved);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Scene playback.
 | 
						// Scene playback.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ClassDB::bind_method(D_METHOD("play_main_scene"), &EditorInterface::play_main_scene);
 | 
						ClassDB::bind_method(D_METHOD("play_main_scene"), &EditorInterface::play_main_scene);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,6 +129,7 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Error save_scene();
 | 
						Error save_scene();
 | 
				
			||||||
	void save_scene_as(const String &p_scene, bool p_with_preview = true);
 | 
						void save_scene_as(const String &p_scene, bool p_with_preview = true);
 | 
				
			||||||
 | 
						void mark_scene_as_unsaved();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Scene playback.
 | 
						// Scene playback.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4109,6 +4109,13 @@ void EditorNode::add_io_error(const String &p_error) {
 | 
				
			||||||
	EditorInterface::get_singleton()->popup_dialog_centered_ratio(singleton->load_error_dialog, 0.5);
 | 
						EditorInterface::get_singleton()->popup_dialog_centered_ratio(singleton->load_error_dialog, 0.5);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void EditorNode::add_io_warning(const String &p_warning) {
 | 
				
			||||||
 | 
						DEV_ASSERT(Thread::get_caller_id() == Thread::get_main_id());
 | 
				
			||||||
 | 
						singleton->load_errors->add_image(singleton->gui_base->get_theme_icon(SNAME("Warning"), SNAME("EditorIcons")));
 | 
				
			||||||
 | 
						singleton->load_errors->add_text(p_warning + "\n");
 | 
				
			||||||
 | 
						EditorInterface::get_singleton()->popup_dialog_centered_ratio(singleton->load_error_dialog, 0.5);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const {
 | 
					bool EditorNode::_find_scene_in_use(Node *p_node, const String &p_path) const {
 | 
				
			||||||
	if (p_node->get_scene_file_path() == p_path) {
 | 
						if (p_node->get_scene_file_path() == p_path) {
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
| 
						 | 
					@ -6814,6 +6821,11 @@ EditorNode::EditorNode() {
 | 
				
			||||||
	ResourceLoader::set_error_notify_func(&EditorNode::add_io_error);
 | 
						ResourceLoader::set_error_notify_func(&EditorNode::add_io_error);
 | 
				
			||||||
	ResourceLoader::set_dependency_error_notify_func(&EditorNode::_dependency_error_report);
 | 
						ResourceLoader::set_dependency_error_notify_func(&EditorNode::_dependency_error_report);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SceneState::set_instantiation_warning_notify_func([](const String &p_warning) {
 | 
				
			||||||
 | 
							add_io_warning(p_warning);
 | 
				
			||||||
 | 
							callable_mp(EditorInterface::get_singleton(), &EditorInterface::mark_scene_as_unsaved).call_deferred();
 | 
				
			||||||
 | 
						});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	{
 | 
						{
 | 
				
			||||||
		// Register importers at the beginning, so dialogs are created with the right extensions.
 | 
							// Register importers at the beginning, so dialogs are created with the right extensions.
 | 
				
			||||||
		Ref<ResourceImporterTexture> import_texture;
 | 
							Ref<ResourceImporterTexture> import_texture;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -731,6 +731,7 @@ public:
 | 
				
			||||||
	static bool has_unsaved_changes() { return singleton->unsaved_cache; }
 | 
						static bool has_unsaved_changes() { return singleton->unsaved_cache; }
 | 
				
			||||||
	static void disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames);
 | 
						static void disambiguate_filenames(const Vector<String> p_full_paths, Vector<String> &r_filenames);
 | 
				
			||||||
	static void add_io_error(const String &p_error);
 | 
						static void add_io_error(const String &p_error);
 | 
				
			||||||
 | 
						static void add_io_warning(const String &p_warning);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static void progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel = false);
 | 
						static void progress_add_task(const String &p_task, const String &p_label, int p_steps, bool p_can_cancel = false);
 | 
				
			||||||
	static bool progress_task_step(const String &p_task, const String &p_state, int p_step = -1, bool p_force_refresh = true);
 | 
						static bool progress_task_step(const String &p_task, const String &p_state, int p_step = -1, bool p_force_refresh = true);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,10 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define PACKED_SCENE_VERSION 3
 | 
					#define PACKED_SCENE_VERSION 3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef TOOLS_ENABLED
 | 
				
			||||||
 | 
					SceneState::InstantiationWarningNotify SceneState::instantiation_warn_notify = nullptr;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool SceneState::can_instantiate() const {
 | 
					bool SceneState::can_instantiate() const {
 | 
				
			||||||
	return nodes.size() > 0;
 | 
						return nodes.size() > 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -380,7 +384,33 @@ Node *SceneState::instantiate(GenEditState p_edit_state) const {
 | 
				
			||||||
				//if node was not part of instance, must set its name, parenthood and ownership
 | 
									//if node was not part of instance, must set its name, parenthood and ownership
 | 
				
			||||||
				if (i > 0) {
 | 
									if (i > 0) {
 | 
				
			||||||
					if (parent) {
 | 
										if (parent) {
 | 
				
			||||||
						parent->_add_child_nocheck(node, snames[n.name]);
 | 
											bool pending_add = true;
 | 
				
			||||||
 | 
					#ifdef TOOLS_ENABLED
 | 
				
			||||||
 | 
											if (Engine::get_singleton()->is_editor_hint()) {
 | 
				
			||||||
 | 
												Node *existing = parent->_get_child_by_name(snames[n.name]);
 | 
				
			||||||
 | 
												if (existing) {
 | 
				
			||||||
 | 
													// There's already a node in the same parent with the same name.
 | 
				
			||||||
 | 
													// This means that somehow the node was added both to the scene being
 | 
				
			||||||
 | 
													// loaded and another one instantiated in the former, maybe because of
 | 
				
			||||||
 | 
													// manual editing, or a bug in scene saving, or a loophole in the workflow
 | 
				
			||||||
 | 
													// (with any of the bugs possibly already fixed).
 | 
				
			||||||
 | 
													// Bring consistency back by letting it be assigned a non-clashing name.
 | 
				
			||||||
 | 
													// This simple workaround at least avoids leaks and helps the user realize
 | 
				
			||||||
 | 
													// something awkward has happened.
 | 
				
			||||||
 | 
													if (instantiation_warn_notify) {
 | 
				
			||||||
 | 
														instantiation_warn_notify(vformat(
 | 
				
			||||||
 | 
																TTR("An incoming node's name clashes with %s already in the scene (presumably, from a more nested instance).\nThe less nested node will be renamed. Please fix and re-save the scene."),
 | 
				
			||||||
 | 
																ret_nodes[0]->get_path_to(existing)));
 | 
				
			||||||
 | 
													}
 | 
				
			||||||
 | 
													node->set_name(snames[n.name]);
 | 
				
			||||||
 | 
													parent->add_child(node, true);
 | 
				
			||||||
 | 
													pending_add = false;
 | 
				
			||||||
 | 
												}
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
											if (pending_add) {
 | 
				
			||||||
 | 
												parent->_add_child_nocheck(node, snames[n.name]);
 | 
				
			||||||
 | 
											}
 | 
				
			||||||
						if (n.index >= 0 && n.index < parent->get_child_count() - 1) {
 | 
											if (n.index >= 0 && n.index < parent->get_child_count() - 1) {
 | 
				
			||||||
							parent->move_child(node, n.index);
 | 
												parent->move_child(node, n.index);
 | 
				
			||||||
						}
 | 
											}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -102,6 +102,14 @@ class SceneState : public RefCounted {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int _find_base_scene_node_remap_key(int p_idx) const;
 | 
						int _find_base_scene_node_remap_key(int p_idx) const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef TOOLS_ENABLED
 | 
				
			||||||
 | 
					public:
 | 
				
			||||||
 | 
						typedef void (*InstantiationWarningNotify)(const String &p_warning);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					private:
 | 
				
			||||||
 | 
						static InstantiationWarningNotify instantiation_warn_notify;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	static void _bind_methods();
 | 
						static void _bind_methods();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -201,6 +209,10 @@ public:
 | 
				
			||||||
	// Used when saving pointers (saves a path property instead).
 | 
						// Used when saving pointers (saves a path property instead).
 | 
				
			||||||
	static String get_meta_pointer_property(const String &p_property);
 | 
						static String get_meta_pointer_property(const String &p_property);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef TOOLS_ENABLED
 | 
				
			||||||
 | 
						static void set_instantiation_warning_notify_func(InstantiationWarningNotify p_warn_notify) { instantiation_warn_notify = p_warn_notify; }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SceneState();
 | 
						SceneState();
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue