#if UNITY_EDITOR using System; using System.Diagnostics.CodeAnalysis; using System.IO; using System.Reflection; using UnityEditor; namespace UnityEngine.InputSystem.Editor { internal static class EditorHelpers { // Provides an abstraction layer on top of EditorGUIUtility to allow replacing the underlying buffer. public static Action SetSystemCopyBufferContents = s => EditorGUIUtility.systemCopyBuffer = s; // Provides an abstraction layer on top of EditorGUIUtility to allow replacing the underlying buffer. public static Func GetSystemCopyBufferContents = () => EditorGUIUtility.systemCopyBuffer; // Attempts to retrieve the asset GUID associated with the given asset. If asset is null or the asset // is not associated with a GUID or the operation fails for any other reason the return value will be null. public static string GetAssetGUID(Object asset) { return !AssetDatabase.TryGetGUIDAndLocalFileIdentifier(asset, out var assetGuid, out long _) ? null : assetGuid; } // SerializedProperty.tooltip *should* give us the tooltip as per [Tooltip] attribute. Alas, for some // reason, it's not happening. public static string GetTooltip(this SerializedProperty property) { if (!string.IsNullOrEmpty(property.tooltip)) return property.tooltip; var field = property.GetField(); if (field != null) { var tooltipAttribute = field.GetCustomAttribute(); if (tooltipAttribute != null) return tooltipAttribute.tooltip; } return string.Empty; } public static string GetHyperlink(string text, string path) { return "{text}"; } public static string GetHyperlink(string path) { return GetHyperlink(path, path); } public static void RestartEditorAndRecompileScripts(bool dryRun = false) { // The API here are not public. Use reflection to get to them. var editorApplicationType = typeof(EditorApplication); var restartEditorAndRecompileScripts = editorApplicationType.GetMethod("RestartEditorAndRecompileScripts", BindingFlags.NonPublic | BindingFlags.Static); if (!dryRun) restartEditorAndRecompileScripts.Invoke(null, null); else if (restartEditorAndRecompileScripts == null) throw new MissingMethodException(editorApplicationType.FullName, "RestartEditorAndRecompileScripts"); } // Attempts to make an asset editable in the underlying version control system and returns true if successful. public static bool CheckOut(string path) { if (string.IsNullOrEmpty(path)) throw new ArgumentNullException(nameof(path)); // Make path relative to project folder. var projectPath = Application.dataPath; if (path.StartsWith(projectPath) && path.Length > projectPath.Length && (path[projectPath.Length] == '/' || path[projectPath.Length] == '\\')) path = path.Substring(0, projectPath.Length + 1); return AssetDatabase.MakeEditable(path); } /// /// Attempts to checkout an asset for editing at the given path and overwrite its file content with /// the given asset text content. /// /// Path to asset to be checkout out and overwritten. /// The new file content. /// true if the file was successfully checkout for editing and the file was written. /// This function may return false if unable to checkout the file for editing in the underlying /// version control system. internal static bool WriteAsset(string assetPath, string text) { // Attempt to checkout the file path for editing and inform the user if this fails. if (!CheckOut(assetPath)) return false; // (Over)write file text content. File.WriteAllText(GetPhysicalPath(assetPath), text); // Reimport the asset (indirectly triggers ADB notification callbacks) AssetDatabase.ImportAsset(assetPath); return true; } /// /// Saves an asset to the given assetPath with file content corresponding to text /// if the current content of the asset given by assetPath is different or the asset do not exist. /// /// Destination asset path. /// The new desired text content to be written to the asset. /// true if the asset was successfully modified or created, else false. internal static bool SaveAsset(string assetPath, string text) { var existingJson = File.Exists(assetPath) ? File.ReadAllText(assetPath) : string.Empty; // Return immediately if file content has not changed, i.e. touching the file would not yield a difference. if (text == existingJson) return false; // Attempt to write asset to disc (including checkout the file) and inform the user if this fails. if (WriteAsset(assetPath, text)) return true; Debug.LogError($"Unable save asset to \"{assetPath}\" since the asset-path could not be checked-out as editable in the underlying version-control system."); return false; } // Maps path into a physical path. public static string GetPhysicalPath(string path) { // Note that we can only get physical path for 2021.2 or newer #if UNITY_2021_2_OR_NEWER return FileUtil.GetPhysicalPath(path); #else return path; #endif } } } #endif // UNITY_EDITOR