Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ internal class InputActionsEditorWindow : EditorWindow
{
private static readonly string k_FileExtension = "." + InputActionAsset.Extension;
private int m_AssetId;
private string m_AssetPath;
private string m_AssetJson;
private bool m_IsDirty;

[OnOpenAsset]
public static bool OpenAsset(int instanceId, int line)
Expand All @@ -51,6 +54,7 @@ public static bool OpenAsset(int instanceId, int line)
window.Focus();
return true;
}
window.m_IsDirty = false;
window.m_AssetId = instanceId;
window.titleContent = new GUIContent("Input Actions Editor");
window.SetAsset(asset);
Expand All @@ -74,8 +78,10 @@ private static InputActionsEditorWindow GetOrCreateWindow(int id, out bool isAlr

private void SetAsset(InputActionAsset asset)
{
m_AssetPath = AssetDatabase.GetAssetPath(asset);
var serializedAsset = new SerializedObject(asset);
m_State = new InputActionsEditorState(serializedAsset);
m_AssetJson = File.ReadAllText(m_AssetPath);
bool isGUIDObtained = AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out m_AssetGUID, out long _);
Debug.Assert(isGUIDObtained, $"Failed to get asset {asset.name} GUID");

Expand All @@ -95,6 +101,8 @@ private void CreateGUI()
if (m_State.serializedObject == null)
{
var asset = GetAssetFromDatabase();
m_AssetPath = AssetDatabase.GetAssetPath(asset);
m_AssetJson = File.ReadAllText(m_AssetPath);
var serializedAsset = new SerializedObject(asset);
Comment thread
ritamerkl marked this conversation as resolved.
m_State = new InputActionsEditorState(m_State, serializedAsset);
}
Expand All @@ -119,10 +127,70 @@ private void BuildUI()

private void OnStateChanged(InputActionsEditorState newState)
{
DirtyInputActionsEditorWindow(newState);
if (InputEditorUserSettings.autoSaveInputActionAssets)
SaveAsset(m_State.serializedObject);
}

private void DirtyInputActionsEditorWindow(InputActionsEditorState newState)
{
var isWindowDirty = !InputEditorUserSettings.autoSaveInputActionAssets && HasAssetChanged(newState.serializedObject);
if (m_IsDirty == isWindowDirty)
return;
m_IsDirty = isWindowDirty;
titleContent = m_IsDirty ? new GUIContent("(*) Input Actions Editor") : new GUIContent("Input Actions Editor");
Comment thread
ritamerkl marked this conversation as resolved.
}

private bool HasAssetChanged(SerializedObject serializedAsset)
{
var asset = (InputActionAsset)serializedAsset.targetObject;
var newAssetJson = asset.ToJson();
return newAssetJson != m_AssetJson;
}

private void OnDestroy()
{
ConfirmSaveChangesIfNeeded();
}

private void ConfirmSaveChangesIfNeeded()
{
// Do we have unsaved changes?
if (!m_IsDirty)
return;

var result = EditorUtility.DisplayDialogComplex("Input Action Asset has been modified", $"Do you want to save the changes you made in:\n{m_AssetPath}\n\nYour changes will be lost if you don't save them.", "Save", "Cancel", "Don't Save");
switch (result)
{
case 0: // Save
SaveAsset(m_State.serializedObject, this);
break;
case 1: // Cancel editor quit. (open new editor window with the edited asset)
ReshowEditorWindowWithUnsavedChanges();
break;
case 2: // Don't save, quit - reload the old asset from the json to prevent the asset from being dirtied
AssetDatabase.ImportAsset(m_AssetPath);
break;
}
}

private void ReshowEditorWindowWithUnsavedChanges()
{
var window = CreateWindow<InputActionsEditorWindow>();
CopyOldStatsToNewWindow(window);
window.BuildUI();
Comment thread
ritamerkl marked this conversation as resolved.
window.Show();
}

private void CopyOldStatsToNewWindow(InputActionsEditorWindow window)
{
window.m_AssetId = m_AssetId;
window.m_State = m_State;
window.m_AssetPath = m_AssetPath;
window.m_AssetJson = m_AssetJson;
window.m_IsDirty = true;
}

private InputActionAsset GetAssetFromDatabase()
{
Debug.Assert(!string.IsNullOrEmpty(m_AssetGUID), "Asset GUID is empty");
Expand All @@ -133,18 +201,21 @@ private InputActionAsset GetAssetFromDatabase()
[SerializeField] private InputActionsEditorState m_State;
[SerializeField] private string m_AssetGUID;

public static void SaveAsset(SerializedObject serializedAsset)
public static void SaveAsset(SerializedObject serializedAsset, InputActionsEditorWindow currentWindow = null)
{
if ((focusedWindow == null || focusedWindow is not InputActionsEditorWindow) && currentWindow == null)
return;
currentWindow = currentWindow ? currentWindow : (InputActionsEditorWindow)focusedWindow;
var asset = (InputActionAsset)serializedAsset.targetObject;
var assetPath = AssetDatabase.GetAssetPath(asset);
var assetJson = asset.ToJson();

var existingJson = File.ReadAllText(assetPath);
var existingJson = File.ReadAllText(currentWindow.m_AssetPath);
if (assetJson != existingJson)
{
EditorHelpers.CheckOut(assetPath);
File.WriteAllText(assetPath, assetJson);
AssetDatabase.ImportAsset(assetPath);
EditorHelpers.CheckOut(currentWindow.m_AssetPath);
File.WriteAllText(currentWindow.m_AssetPath, assetJson);
AssetDatabase.ImportAsset(currentWindow.m_AssetPath);
currentWindow.m_AssetJson = assetJson;
}
}
}
Expand Down