Kaynağa Gözat

Merge pull request #6747 from RandomShaper/unify-serial-naming

Make node serial naming per-project and universal
Rémi Verschelde 9 yıl önce
ebeveyn
işleme
e0e21984d8

+ 68 - 77
scene/main/node.cpp

@@ -1249,51 +1249,12 @@ void Node::set_human_readable_collision_renaming(bool p_enabled) {
 }
 
 
+#ifdef TOOLS_ENABLED
+String Node::validate_child_name(Node* p_child) {
 
-String Node::validate_child_name(const String& p_name) const {
-
-	//this approach to autoset node names is human readable but very slow
-	//it's turned on while running in the editor
-
-	String basename = p_name;
-
-	if (basename==String()) {
-
-		return String();
-	}
-
-	int val=1;
-
-	for(;;) {
-
-		String attempted = val > 1 ? (basename + " " +itos(val) ) : basename;
-
-		bool found=false;
-
-		for (int i=0;i<data.children.size();i++) {
-
-			//if (data.children[i]==p_child)
-			//	continue;
-			if (data.children[i]->get_name() == attempted) {
-				found=true;
-				break;
-			}
-
-		}
-
-		if (found) {
-
-			val++;
-			continue;
-		}
-
-		return attempted;
-		break;
-	}
-
-	return basename;
-
+	return _generate_serial_child_name(p_child);
 }
+#endif
 
 void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
 
@@ -1304,41 +1265,8 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
 		//this approach to autoset node names is human readable but very slow
 		//it's turned on while running in the editor
 
-		String basename = p_child->data.name;
-
-		if (basename=="") {
-
-			basename = p_child->get_type();
-		}
-
-		int val=1;
-
-		for(;;) {
-
-			String attempted = val > 1 ? (basename + " " +itos(val) ) : basename;
-
-			bool found=false;
-
-			for (int i=0;i<data.children.size();i++) {
-
-				if (data.children[i]==p_child)
-					continue;
-				if (data.children[i]->get_name() == attempted) {
-					found=true;
-					break;
-				}
+		p_child->data.name=_generate_serial_child_name(p_child);
 
-			}
-
-			if (found) {
-
-				val++;
-				continue;
-			}
-
-			p_child->data.name=attempted;
-			break;
-		}
 	} else {
 
 		//this approach to autoset node names is fast but not as readable
@@ -1373,6 +1301,54 @@ void Node::_validate_child_name(Node *p_child, bool p_force_human_readable) {
 	}
 }
 
+String Node::_generate_serial_child_name(Node *p_child) {
+
+	String name = p_child->data.name;
+
+	if (name=="") {
+
+		name = p_child->get_type();
+	}
+
+	String nums;
+	for(int i=name.length()-1;i>=0;i--) {
+		CharType n=name[i];
+		if (n>='0' && n<='9') {
+			nums=String::chr(name[i])+nums;
+		} else {
+			break;
+		}
+	}
+
+	int num=nums.to_int();
+	if (num<1)
+		num=1;
+
+	String nnsep=_get_name_num_separator();
+	name = name.substr(0,name.length()-nums.length()).strip_edges();
+	if ( name.substr(name.length()-nnsep.length(),nnsep.length()) == nnsep) {
+		name = name.substr(0,name.length()-nnsep.length());
+	}
+
+	for(;;) {
+		String attempt = (name + (num > 1 ? nnsep + itos(num) : "")).strip_edges();
+		bool found=false;
+		for(int i=0;i<data.children.size();i++) {
+			if (data.children[i]==p_child)
+				continue;
+			if (data.children[i]->data.name==attempt) {
+				found=true;
+				break;
+			}
+		}
+		if (!found) {
+			return attempt;
+		} else {
+			num++;
+		}
+	}
+}
+
 void Node::_add_child_nocheck(Node* p_child,const StringName& p_name) {
 	//add a child node quickly, without name validation
 
@@ -2811,6 +2787,10 @@ bool Node::is_displayed_folded() const {
 
 void Node::_bind_methods() {
 
+	_GLOBAL_DEF("node/name_num_separator",0);
+	Globals::get_singleton()->set_custom_property_info("node/name_num_separator",PropertyInfo(Variant::INT,"node/name_num_separator",PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash"));
+
+
 	ObjectTypeDB::bind_method(_MD("_add_child_below_node","node:Node","child_node:Node","legible_unique_name"),&Node::add_child_below_node,DEFVAL(false));
 
 	ObjectTypeDB::bind_method(_MD("set_name","name"),&Node::set_name);
@@ -2979,6 +2959,17 @@ void Node::_bind_methods() {
 }
 
 
+String Node::_get_name_num_separator() {
+	switch(Globals::get_singleton()->get("node/name_num_separator").operator int()) {
+		case 0: return "";
+		case 1: return " ";
+		case 2: return "_";
+		case 3: return "-";
+	}
+	return " ";
+}
+
+
 Node::Node() {
 
 	data.pos=-1;

+ 7 - 2
scene/main/node.h

@@ -29,6 +29,7 @@
 #ifndef NODE_H
 #define NODE_H
 
+#include "globals.h"
 #include "object.h"
 #include "path_db.h"
 #include "map.h"
@@ -150,7 +151,8 @@ private:
 
 	void _replace_connections_target(Node* p_new_target);
 
-	void _validate_child_name(Node *p_name, bool p_force_human_readable=false);
+	void _validate_child_name(Node *p_child, bool p_force_human_readable=false);
+	String _generate_serial_child_name(Node *p_child);
 
 	void _propagate_reverse_notification(int p_notification);
 	void _propagate_deferred_notification(int p_notification, bool p_reverse);
@@ -193,6 +195,7 @@ protected:
 	void _propagate_replace_owner(Node *p_owner,Node* p_by_owner);
 
 	static void _bind_methods();
+	static String _get_name_num_separator();
 
 friend class SceneState;
 
@@ -335,7 +338,9 @@ public:
 
 	static void print_stray_nodes();
 
-	String validate_child_name(const String& p_name) const;
+#ifdef TOOLS_ENABLED
+	String validate_child_name(Node* p_child);
+#endif
 
 	void queue_delete();
 

+ 0 - 2
tools/editor/editor_settings.cpp

@@ -565,8 +565,6 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
 	set("text_editor/restore_scripts_on_load",true);
 
 
-	set("scenetree_editor/duplicate_node_name_num_separator",0);
-	hints["scenetree_editor/duplicate_node_name_num_separator"]=PropertyInfo(Variant::INT,"scenetree_editor/duplicate_node_name_num_separator",PROPERTY_HINT_ENUM, "None,Space,Underscore,Dash");
 	//set("scenetree_editor/display_old_action_buttons",false);
 	set("scenetree_editor/start_create_dialog_fully_expanded",false);
 	set("scenetree_editor/draw_relationship_lines",false);

+ 9 - 47
tools/editor/scene_tree_dock.cpp

@@ -227,7 +227,7 @@ void SceneTreeDock::_perform_instance_scenes(const Vector<String>& p_files,Node*
 		editor_data->get_undo_redo().add_do_reference(instanced_scene);
 		editor_data->get_undo_redo().add_undo_method(parent,"remove_child",instanced_scene);
 
-		String new_name = parent->validate_child_name(instanced_scene->get_name());
+		String new_name = parent->validate_child_name(instanced_scene);
 		ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
 		editor_data->get_undo_redo().add_do_method(sed,"live_debug_instance_node",edited_scene->get_path_to(parent),p_files[i],new_name);
 		editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name));
@@ -257,17 +257,6 @@ bool SceneTreeDock::_cyclical_dependency_exists(const String& p_target_scene_pat
 }
 
 
-static String _get_name_num_separator() {
-	switch(EditorSettings::get_singleton()->get("scenetree_editor/duplicate_node_name_num_separator").operator int()) {
-		case 0: return "";
-		case 1: return " ";
-		case 2: return "_";
-		case 3: return "-";
-	}
-	return " ";
-}
-
-
 void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 
 	current_option=p_tool;
@@ -474,37 +463,7 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 				if (selection.size()==1)
 					dupsingle=dup;
 
-				String name = node->get_name();
-
-				String nums;
-				for(int i=name.length()-1;i>=0;i--) {
-					CharType n=name[i];
-					if (n>='0' && n<='9') {
-						nums=String::chr(name[i])+nums;
-					} else {
-						break;
-					}
-				}
-
-				int num=nums.to_int();
-				if (num<1)
-					num=1;
-				else
-					num++;
-
-				String nnsep = _get_name_num_separator();
-				name = name.substr(0,name.length()-nums.length()).strip_edges();
-				if ( name.substr(name.length()-nnsep.length(),nnsep.length()) == nnsep) {
-					name = name.substr(0,name.length()-nnsep.length());
-				}
-				String attempt = (name + nnsep + itos(num)).strip_edges();
-
-				while(parent->has_node(attempt)) {
-					num++;
-					attempt = (name + nnsep + itos(num)).strip_edges();
-				}
-
-				dup->set_name(attempt);
+				dup->set_name(parent->validate_child_name(dup));
 
 				editor_data->get_undo_redo().add_do_method(parent,"_add_child_below_node",node, dup);
 				for (List<Node*>::Element *F=owned.front();F;F=F->next()) {
@@ -522,8 +481,8 @@ void SceneTreeDock::_tool_selected(int p_tool, bool p_confirm_override) {
 
 				ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
 
-				editor_data->get_undo_redo().add_do_method(sed,"live_debug_duplicate_node",edited_scene->get_path_to(node),attempt);
-				editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+attempt));
+				editor_data->get_undo_redo().add_do_method(sed,"live_debug_duplicate_node",edited_scene->get_path_to(node),dup->get_name());
+				editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+dup->get_name()));
 
 				//parent->add_child(dup);
 				//reselect.push_back(dup);
@@ -1109,6 +1068,7 @@ void SceneTreeDock::_do_reparent(Node* p_new_parent,int p_position_in_parent,Vec
 	editor_data->get_undo_redo().create_action(TTR("Reparent Node"));
 
 	List<Pair<NodePath,NodePath> > path_renames;
+	Vector<StringName> former_names;
 
 	int inc=0;
 
@@ -1118,6 +1078,7 @@ void SceneTreeDock::_do_reparent(Node* p_new_parent,int p_position_in_parent,Vec
 		Node *node = p_nodes[ni];
 
 		fill_path_renames(node,new_parent,&path_renames);
+		former_names.push_back(node->get_name());
 
 		List<Node*> owned;
 		node->get_owned_by(node->get_owner(),&owned);
@@ -1140,7 +1101,7 @@ void SceneTreeDock::_do_reparent(Node* p_new_parent,int p_position_in_parent,Vec
 			editor_data->get_undo_redo().add_do_method(new_parent,"move_child",node,p_position_in_parent+inc);
 
 		ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
-		String new_name = new_parent->validate_child_name(node->get_name());
+		String new_name = new_parent->validate_child_name(node);
 		editor_data->get_undo_redo().add_do_method(sed,"live_debug_reparent_node",edited_scene->get_path_to(node),edited_scene->get_path_to(new_parent),new_name,-1);
 		editor_data->get_undo_redo().add_undo_method(sed,"live_debug_reparent_node",NodePath(String(edited_scene->get_path_to(new_parent))+"/"+new_name),edited_scene->get_path_to(node->get_parent()),node->get_name(),node->get_index());
 
@@ -1159,6 +1120,7 @@ void SceneTreeDock::_do_reparent(Node* p_new_parent,int p_position_in_parent,Vec
 			editor_data->get_undo_redo().add_do_method(AnimationPlayerEditor::singleton->get_key_editor(),"set_root",node);
 
 		editor_data->get_undo_redo().add_undo_method(new_parent,"remove_child",node);
+		editor_data->get_undo_redo().add_undo_method(node,"set_name",former_names[ni]);
 
 		inc++;
 
@@ -1360,7 +1322,7 @@ void SceneTreeDock::_create() {
 			editor_data->get_undo_redo().add_undo_method(parent,"remove_child",child);
 
 
-			String new_name = parent->validate_child_name(child->get_type());
+			String new_name = parent->validate_child_name(child);
 			ScriptEditorDebugger *sed = ScriptEditor::get_singleton()->get_debugger();
 			editor_data->get_undo_redo().add_do_method(sed,"live_debug_create_node",edited_scene->get_path_to(parent),child->get_type(),new_name);
 			editor_data->get_undo_redo().add_undo_method(sed,"live_debug_remove_node",NodePath(String(edited_scene->get_path_to(parent))+"/"+new_name));