Browse Source

Merge pull request #71322 from EricEzaM/55856-proj-settings-initial-array-dict-shared-instance

Fix Project Settings array/dicts initial value being shared instances of the current value.
Rémi Verschelde 2 years ago
parent
commit
27fdb06fed

+ 6 - 2
core/config/project_settings.cpp

@@ -221,7 +221,9 @@ String ProjectSettings::localize_path(const String &p_path) const {
 
 void ProjectSettings::set_initial_value(const String &p_name, const Variant &p_value) {
 	ERR_FAIL_COND_MSG(!props.has(p_name), "Request for nonexistent project setting: " + p_name + ".");
-	props[p_name].initial = p_value;
+
+	// Duplicate so that if value is array or dictionary, changing the setting will not change the stored initial value.
+	props[p_name].initial = p_value.duplicate();
 }
 
 void ProjectSettings::set_restart_if_changed(const String &p_name, bool p_restart) {
@@ -1116,7 +1118,9 @@ bool ProjectSettings::_property_get_revert(const StringName &p_name, Variant &r_
 		return false;
 	}
 
-	r_property = props[p_name].initial;
+	// Duplicate so that if value is array or dictionary, changing the setting will not change the stored initial value.
+	r_property = props[p_name].initial.duplicate();
+
 	return true;
 }
 

+ 15 - 0
editor/action_map_editor.cpp

@@ -198,6 +198,14 @@ void ActionMapEditor::_tree_button_pressed(Object *p_item, int p_column, int p_i
 
 			emit_signal(SNAME("action_edited"), action_name, action);
 		} break;
+		case ActionMapEditor::BUTTON_REVERT_ACTION: {
+			ERR_FAIL_COND_MSG(!item->has_meta("__action_initial"), "Tree Item for action which can be reverted is expected to have meta value with initial value of action.");
+
+			Dictionary action = item->get_meta("__action_initial").duplicate();
+			String action_name = item->get_meta("__name");
+
+			emit_signal(SNAME("action_edited"), action_name, action);
+		} break;
 		default:
 			break;
 	}
@@ -427,6 +435,13 @@ void ActionMapEditor::update_action_list(const Vector<ActionInfo> &p_action_info
 		action_item->set_range(1, deadzone);
 
 		// Third column - buttons
+		if (action_info.has_initial) {
+			bool deadzone_eq = action_info.action_initial["deadzone"] == action_info.action["deadzone"];
+			bool events_eq = Shortcut::is_event_array_equal(action_info.action_initial["events"], action_info.action["events"]);
+			bool action_eq = deadzone_eq && events_eq;
+			action_item->set_meta("__action_initial", action_info.action_initial);
+			action_item->add_button(2, action_tree->get_theme_icon(SNAME("ReloadSmall"), SNAME("EditorIcons")), BUTTON_REVERT_ACTION, action_eq, action_eq ? TTR("Cannot Revert - Action is same as initial") : TTR("Revert Action"));
+		}
 		action_item->add_button(2, action_tree->get_theme_icon(SNAME("Add"), SNAME("EditorIcons")), BUTTON_ADD_EVENT, false, TTR("Add Event"));
 		action_item->add_button(2, action_tree->get_theme_icon(SNAME("Remove"), SNAME("EditorIcons")), BUTTON_REMOVE_ACTION, !action_info.editable, action_info.editable ? TTR("Remove Action") : TTR("Cannot Remove Action"));
 

+ 3 - 0
editor/action_map_editor.h

@@ -49,6 +49,8 @@ public:
 	struct ActionInfo {
 		String name;
 		Dictionary action;
+		bool has_initial = false;
+		Dictionary action_initial;
 
 		Ref<Texture2D> icon = Ref<Texture2D>();
 		bool editable = true;
@@ -60,6 +62,7 @@ private:
 		BUTTON_EDIT_EVENT,
 		BUTTON_REMOVE_ACTION,
 		BUTTON_REMOVE_EVENT,
+		BUTTON_REVERT_ACTION,
 	};
 
 	Vector<ActionInfo> actions_cache;

+ 3 - 11
editor/project_settings_editor.cpp

@@ -370,17 +370,7 @@ void ProjectSettingsEditor::_action_edited(const String &p_name, const Dictionar
 
 	} else {
 		// Events changed
-		int act_event_count = ((Array)p_action["events"]).size();
-		int old_event_count = ((Array)old_val["events"]).size();
-
-		if (act_event_count == old_event_count) {
-			undo_redo->create_action(TTR("Edit Input Action Event"));
-		} else if (act_event_count > old_event_count) {
-			undo_redo->create_action(TTR("Add Input Action Event"));
-		} else {
-			undo_redo->create_action(TTR("Remove Input Action Event"));
-		}
-
+		undo_redo->create_action(TTR("Change Input Action Event(s)"));
 		undo_redo->add_do_method(ProjectSettings::get_singleton(), "set", property_name, p_action);
 		undo_redo->add_undo_method(ProjectSettings::get_singleton(), "set", property_name, old_val);
 	}
@@ -527,6 +517,8 @@ void ProjectSettingsEditor::_update_action_map_editor() {
 		if (is_builtin_input) {
 			action_info.editable = false;
 			action_info.icon = builtin_icon;
+			action_info.has_initial = true;
+			action_info.action_initial = ProjectSettings::get_singleton()->property_get_revert(property_name);
 		}
 
 		actions.push_back(action_info);