using System; using System.Runtime.CompilerServices; using System.Diagnostics; using System.Linq; using System.Reflection; using System.Diagnostics.CodeAnalysis; #if UNITY_EDITOR using PackageInfo = UnityEditor.PackageManager.PackageInfo; #endif [assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Editor.Tests")] namespace UnityEngine.Rendering { /// /// Attribute to define the help url /// /// /// [CoreRPHelpURLAttribute("Volume")] /// public class Volume : MonoBehaviour /// [Conditional("UNITY_EDITOR")] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false)] public class CoreRPHelpURLAttribute : HelpURLAttribute { /// /// The constructor of the attribute /// /// The name of the documentation page. /// The package name, defaulting to "com.unity.render-pipelines.core". public CoreRPHelpURLAttribute(string pageName, string packageName = "com.unity.render-pipelines.core") : base(DocumentationInfo.GetPageLink(packageName, pageName, "")) { } /// /// The constructor of the attribute /// /// The name of the documentation page. /// The hash specifying a section within the page. /// The package name, defaulting to "com.unity.render-pipelines.core". public CoreRPHelpURLAttribute(string pageName, string pageHash, string packageName = "com.unity.render-pipelines.core") : base(DocumentationInfo.GetPageLink(packageName, pageName, pageHash)) { } } /// /// Use this attribute to define the help URP. /// /// /// [CoreRPHelpURLAttribute("Volume")] /// public class Volume : MonoBehaviour /// [Conditional("UNITY_EDITOR")] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false)] public class CurrentPipelineHelpURLAttribute : HelpURLAttribute { private string pageName { get; } /// /// The constructor of the attribute /// /// The name of the documentation page. public CurrentPipelineHelpURLAttribute(string pageName) : base(null) { this.pageName = pageName; } /// /// Returns the URL to the given page in the current Render Pipeline package documentation site. /// public override string URL { get { #if UNITY_EDITOR if (DocumentationUtils.TryGetPackageInfoForType(GraphicsSettings.currentRenderPipeline?.GetType() ?? typeof(DocumentationInfo), out var package, out var version)) { return DocumentationInfo.GetPackageLink(package, version, this.pageName); } #endif return string.Empty; } } } //We need to have only one version number amongst packages (so public) /// /// Documentation Info class. /// public class DocumentationInfo { const string fallbackVersion = "13.1"; const string url = "https://docs.unity3d.com/Packages/{0}@{1}/manual/{2}.html{3}"; /// /// Current version of the documentation. /// public static string version { get { #if UNITY_EDITOR if (DocumentationUtils.TryGetPackageInfoForType(typeof(DocumentationInfo), out _, out var version)) return version; #endif return fallbackVersion; } } /// /// Generates a help URL for the given package and page name. /// /// The package name. /// The package version. /// The page name without the extension. /// The full URL of the page. public static string GetPackageLink(string packageName, string packageVersion, string pageName) => string.Format(url, packageName, packageVersion, pageName, ""); /// /// Generates a help url for the given package and page name /// /// The package name /// The page name without the extension. /// The full URL of the page. public static string GetPageLink(string packageName, string pageName) => string.Format(url, packageName, version, pageName, ""); /// /// Generates a help url for the given package and page name /// /// The package name /// The page name without the extension. /// The page hash /// The full URL of the page. public static string GetPageLink(string packageName, string pageName, string pageHash) => string.Format(url, packageName, version, pageName, pageHash); } /// /// Set of utils for documentation /// public static class DocumentationUtils { /// /// Obtains the help url from an enum /// /// The enum with a /// [Optional] The current value of the enum /// The full url public static string GetHelpURL(TEnum mask = default) where TEnum : struct, IConvertible { var helpURLAttribute = (HelpURLAttribute)mask .GetType() .GetCustomAttributes(typeof(HelpURLAttribute), false) .FirstOrDefault(); return helpURLAttribute == null ? string.Empty : $"{helpURLAttribute.URL}#{mask}"; } /// /// Obtains the help URL from a type. /// /// The type decorated with the HelpURL attribute. /// The full URL from the HelpURL attribute. If the attribute is not present, this value is null. /// Returns true if the attribute is present, and false otherwise. public static bool TryGetHelpURL(Type type, out string url) { var attribute = type.GetCustomAttribute(false); url = attribute?.URL; return attribute != null; } #if UNITY_EDITOR /// /// Obtain package informations from a specific type /// /// The type used to retrieve package information /// The name of the package containing the given type /// The version number of the package containing the given type. Only Major.Minor will be returned as fix is not used for documentation /// public static bool TryGetPackageInfoForType([DisallowNull] Type type, [NotNullWhen(true)] out string packageName, [NotNullWhen(true)] out string version) { var packageInfo = PackageInfo.FindForAssembly(type.Assembly); if (packageInfo == null) { packageName = null; version = null; return false; } packageName = packageInfo.name; version = packageInfo.version.Substring(0, packageInfo.version.LastIndexOf('.')); return true; } #endif } }