A game about forced loneliness, made by TACStudios
at master 141 lines 6.2 kB view raw
1#if UNITY_EDITOR 2using System; 3using System.Diagnostics.CodeAnalysis; 4using System.IO; 5using System.Reflection; 6using UnityEditor; 7 8namespace UnityEngine.InputSystem.Editor 9{ 10 internal static class EditorHelpers 11 { 12 // Provides an abstraction layer on top of EditorGUIUtility to allow replacing the underlying buffer. 13 public static Action<string> SetSystemCopyBufferContents = s => EditorGUIUtility.systemCopyBuffer = s; 14 15 // Provides an abstraction layer on top of EditorGUIUtility to allow replacing the underlying buffer. 16 public static Func<string> GetSystemCopyBufferContents = () => EditorGUIUtility.systemCopyBuffer; 17 18 // Attempts to retrieve the asset GUID associated with the given asset. If asset is null or the asset 19 // is not associated with a GUID or the operation fails for any other reason the return value will be null. 20 public static string GetAssetGUID(Object asset) 21 { 22 return !AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out var assetGuid, out long _) 23 ? null : assetGuid; 24 } 25 26 // SerializedProperty.tooltip *should* give us the tooltip as per [Tooltip] attribute. Alas, for some 27 // reason, it's not happening. 28 public static string GetTooltip(this SerializedProperty property) 29 { 30 if (!string.IsNullOrEmpty(property.tooltip)) 31 return property.tooltip; 32 33 var field = property.GetField(); 34 if (field != null) 35 { 36 var tooltipAttribute = field.GetCustomAttribute<TooltipAttribute>(); 37 if (tooltipAttribute != null) 38 return tooltipAttribute.tooltip; 39 } 40 41 return string.Empty; 42 } 43 44 public static string GetHyperlink(string text, string path) 45 { 46 return "<a href=\"" + path + $"\">{text}</a>"; 47 } 48 49 public static string GetHyperlink(string path) 50 { 51 return GetHyperlink(path, path); 52 } 53 54 public static void RestartEditorAndRecompileScripts(bool dryRun = false) 55 { 56 // The API here are not public. Use reflection to get to them. 57 var editorApplicationType = typeof(EditorApplication); 58 var restartEditorAndRecompileScripts = 59 editorApplicationType.GetMethod("RestartEditorAndRecompileScripts", 60 BindingFlags.NonPublic | BindingFlags.Static); 61 if (!dryRun) 62 restartEditorAndRecompileScripts.Invoke(null, null); 63 else if (restartEditorAndRecompileScripts == null) 64 throw new MissingMethodException(editorApplicationType.FullName, "RestartEditorAndRecompileScripts"); 65 } 66 67 // Attempts to make an asset editable in the underlying version control system and returns true if successful. 68 public static bool CheckOut(string path) 69 { 70 if (string.IsNullOrEmpty(path)) 71 throw new ArgumentNullException(nameof(path)); 72 73 // Make path relative to project folder. 74 var projectPath = Application.dataPath; 75 if (path.StartsWith(projectPath) && path.Length > projectPath.Length && 76 (path[projectPath.Length] == '/' || path[projectPath.Length] == '\\')) 77 path = path.Substring(0, projectPath.Length + 1); 78 79 return AssetDatabase.MakeEditable(path); 80 } 81 82 /// <summary> 83 /// Attempts to checkout an asset for editing at the given path and overwrite its file content with 84 /// the given asset text content. 85 /// </summary> 86 /// <param name="assetPath">Path to asset to be checkout out and overwritten.</param> 87 /// <param name="text">The new file content.</param> 88 /// <returns>true if the file was successfully checkout for editing and the file was written. 89 /// This function may return false if unable to checkout the file for editing in the underlying 90 /// version control system.</returns> 91 internal static bool WriteAsset(string assetPath, string text) 92 { 93 // Attempt to checkout the file path for editing and inform the user if this fails. 94 if (!CheckOut(assetPath)) 95 return false; 96 97 // (Over)write file text content. 98 File.WriteAllText(GetPhysicalPath(assetPath), text); 99 100 // Reimport the asset (indirectly triggers ADB notification callbacks) 101 AssetDatabase.ImportAsset(assetPath); 102 103 return true; 104 } 105 106 /// <summary> 107 /// Saves an asset to the given <c>assetPath</c> with file content corresponding to <c>text</c> 108 /// if the current content of the asset given by <c>assetPath</c> is different or the asset do not exist. 109 /// </summary> 110 /// <param name="assetPath">Destination asset path.</param> 111 /// <param name="text">The new desired text content to be written to the asset.</param> 112 /// <returns><c>true</c> if the asset was successfully modified or created, else <c>false</c>.</returns> 113 internal static bool SaveAsset(string assetPath, string text) 114 { 115 var existingJson = File.Exists(assetPath) ? File.ReadAllText(assetPath) : string.Empty; 116 117 // Return immediately if file content has not changed, i.e. touching the file would not yield a difference. 118 if (text == existingJson) 119 return false; 120 121 // Attempt to write asset to disc (including checkout the file) and inform the user if this fails. 122 if (WriteAsset(assetPath, text)) 123 return true; 124 125 Debug.LogError($"Unable save asset to \"{assetPath}\" since the asset-path could not be checked-out as editable in the underlying version-control system."); 126 return false; 127 } 128 129 // Maps path into a physical path. 130 public static string GetPhysicalPath(string path) 131 { 132 // Note that we can only get physical path for 2021.2 or newer 133#if UNITY_2021_2_OR_NEWER 134 return FileUtil.GetPhysicalPath(path); 135#else 136 return path; 137#endif 138 } 139 } 140} 141#endif // UNITY_EDITOR