Maze / Library /PackageCache /com.unity.inputsystem@1.6.1 /InputSystem /Editor /AssetEditor /InputActionAssetManager.cs
| using System; | |
| using System.IO; | |
| using UnityEditor; | |
| ////TODO: ensure that GUIDs in the asset are unique | |
| namespace UnityEngine.InputSystem.Editor | |
| { | |
| /// <summary> | |
| /// Keeps a reference to the asset being edited and maintains a copy of the asset object | |
| /// around for editing. | |
| /// </summary> | |
| [] | |
| internal class InputActionAssetManager : IDisposable | |
| { | |
| [] internal InputActionAsset m_AssetObjectForEditing; | |
| [] private InputActionAsset m_ImportedAssetObject; | |
| [] private string m_AssetGUID; | |
| [] private string m_ImportedAssetJson; | |
| [] private bool m_IsDirty; | |
| private SerializedObject m_SerializedObject; | |
| public string guid => m_AssetGUID; | |
| public string path | |
| { | |
| get | |
| { | |
| Debug.Assert(!string.IsNullOrEmpty(m_AssetGUID), "Asset GUID is empty"); | |
| return AssetDatabase.GUIDToAssetPath(m_AssetGUID); | |
| } | |
| } | |
| public string name | |
| { | |
| get | |
| { | |
| if (m_ImportedAssetObject != null) | |
| return m_ImportedAssetObject.name; | |
| if (!string.IsNullOrEmpty(path)) | |
| return Path.GetFileNameWithoutExtension(path); | |
| return string.Empty; | |
| } | |
| } | |
| private InputActionAsset importedAsset | |
| { | |
| get | |
| { | |
| if (m_ImportedAssetObject == null) | |
| LoadImportedObjectFromGuid(); | |
| return m_ImportedAssetObject; | |
| } | |
| } | |
| public Action<bool> onDirtyChanged { get; set; } | |
| public InputActionAssetManager(InputActionAsset inputActionAsset) | |
| { | |
| m_ImportedAssetObject = inputActionAsset; | |
| bool isGUIDObtained = AssetDatabase.TryGetGUIDAndLocalFileIdentifier(importedAsset, out m_AssetGUID, out long _); | |
| Debug.Assert(isGUIDObtained, $"Failed to get asset {inputActionAsset.name} GUID"); | |
| } | |
| public SerializedObject serializedObject => m_SerializedObject; | |
| public bool dirty => m_IsDirty; | |
| public bool Initialize() | |
| { | |
| if (m_AssetObjectForEditing == null) | |
| { | |
| if (importedAsset == null) | |
| // The asset we want to edit no longer exists. | |
| return false; | |
| CreateWorkingCopyAsset(); | |
| } | |
| else | |
| { | |
| m_SerializedObject = new SerializedObject(m_AssetObjectForEditing); | |
| } | |
| return true; | |
| } | |
| public void Dispose() | |
| { | |
| m_SerializedObject?.Dispose(); | |
| } | |
| public bool ReInitializeIfAssetHasChanged() | |
| { | |
| var asset = importedAsset; | |
| var json = asset.ToJson(); | |
| if (m_ImportedAssetJson == json) | |
| return false; | |
| CreateWorkingCopyAsset(); | |
| return true; | |
| } | |
| private void CreateWorkingCopyAsset() | |
| { | |
| if (m_AssetObjectForEditing != null) | |
| Cleanup(); | |
| // Duplicate the asset along 1:1. Unlike calling Clone(), this will also preserve | |
| // GUIDs. | |
| var asset = importedAsset; | |
| m_AssetObjectForEditing = Object.Instantiate(asset); | |
| m_AssetObjectForEditing.hideFlags = HideFlags.HideAndDontSave; | |
| m_AssetObjectForEditing.name = importedAsset.name; | |
| m_ImportedAssetJson = asset.ToJson(); | |
| m_SerializedObject = new SerializedObject(m_AssetObjectForEditing); | |
| } | |
| public void Cleanup() | |
| { | |
| if (m_AssetObjectForEditing == null) | |
| return; | |
| Object.DestroyImmediate(m_AssetObjectForEditing); | |
| m_AssetObjectForEditing = null; | |
| } | |
| public void LoadImportedObjectFromGuid() | |
| { | |
| // https://fogbugz.unity3d.com/f/cases/1313185/ | |
| // InputActionEditorWindow being an EditorWindow, it will be saved as part of the editor's | |
| // window layout. When a project is opened that has no Library/ folder, the layout from the | |
| // most recently opened project is used. Which means that when opening an .inputactions | |
| // asset in project A, then closing it, and then opening project B, restoring the window layout | |
| // also tries to restore the InputActionEditorWindow having that very same asset open -- which | |
| // will lead nowhere except there happens to be an InputActionAsset with the very same GUID in | |
| // the project. | |
| var assetPath = path; | |
| if (!string.IsNullOrEmpty(assetPath)) | |
| m_ImportedAssetObject = AssetDatabase.LoadAssetAtPath<InputActionAsset>(assetPath); | |
| } | |
| public void ApplyChanges() | |
| { | |
| m_SerializedObject.ApplyModifiedProperties(); | |
| m_SerializedObject.Update(); | |
| } | |
| internal void SaveChangesToAsset() | |
| { | |
| Debug.Assert(importedAsset != null); | |
| // Update JSON. | |
| var asset = m_AssetObjectForEditing; | |
| m_ImportedAssetJson = asset.ToJson(); | |
| // Write out, if changed. | |
| var assetPath = path; | |
| var existingJson = File.ReadAllText(assetPath); | |
| if (m_ImportedAssetJson != existingJson) | |
| { | |
| EditorHelpers.CheckOut(assetPath); | |
| File.WriteAllText(assetPath, m_ImportedAssetJson); | |
| AssetDatabase.ImportAsset(assetPath); | |
| } | |
| m_IsDirty = false; | |
| onDirtyChanged(false); | |
| } | |
| public void SetAssetDirty() | |
| { | |
| m_IsDirty = true; | |
| onDirtyChanged(true); | |
| } | |
| public bool ImportedAssetObjectEquals(InputActionAsset inputActionAsset) | |
| { | |
| if (importedAsset == null) | |
| return false; | |
| return importedAsset.Equals(inputActionAsset); | |
| } | |
| public void UpdateAssetDirtyState() | |
| { | |
| m_SerializedObject.Update(); | |
| m_IsDirty = m_AssetObjectForEditing.ToJson() != importedAsset.ToJson(); | |
| onDirtyChanged(m_IsDirty); | |
| } | |
| } | |
| } | |