A game about forced loneliness, made by TACStudios
1using System;
2using System.Runtime.CompilerServices;
3using System.Diagnostics;
4using System.Linq;
5using System.Reflection;
6using System.Diagnostics.CodeAnalysis;
7#if UNITY_EDITOR
8using PackageInfo = UnityEditor.PackageManager.PackageInfo;
9#endif
10
11[assembly: InternalsVisibleTo("Unity.RenderPipelines.Core.Editor.Tests")]
12
13namespace UnityEngine.Rendering
14{
15 /// <summary>
16 /// Attribute to define the help url
17 /// </summary>
18 /// <example>
19 /// [CoreRPHelpURLAttribute("Volume")]
20 /// public class Volume : MonoBehaviour
21 /// </example>
22 [Conditional("UNITY_EDITOR")]
23 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false)]
24 public class CoreRPHelpURLAttribute : HelpURLAttribute
25 {
26 /// <summary>
27 /// The constructor of the attribute
28 /// </summary>
29 /// <param name="pageName">The name of the documentation page.</param>
30 /// <param name="packageName">The package name, defaulting to "com.unity.render-pipelines.core".</param>
31 public CoreRPHelpURLAttribute(string pageName, string packageName = "com.unity.render-pipelines.core")
32 : base(DocumentationInfo.GetPageLink(packageName, pageName, ""))
33 {
34 }
35
36 /// <summary>
37 /// The constructor of the attribute
38 /// </summary>
39 /// <param name="pageName">The name of the documentation page.</param>
40 /// <param name="pageHash">The hash specifying a section within the page.</param>
41 /// <param name="packageName">The package name, defaulting to "com.unity.render-pipelines.core".</param>
42 public CoreRPHelpURLAttribute(string pageName, string pageHash, string packageName = "com.unity.render-pipelines.core")
43 : base(DocumentationInfo.GetPageLink(packageName, pageName, pageHash))
44 {
45 }
46 }
47
48 /// <summary>
49 /// Use this attribute to define the help URP.
50 /// </summary>
51 /// <example>
52 /// [CoreRPHelpURLAttribute("Volume")]
53 /// public class Volume : MonoBehaviour
54 /// </example>
55 [Conditional("UNITY_EDITOR")]
56 [AttributeUsage(AttributeTargets.Class | AttributeTargets.Enum, AllowMultiple = false)]
57 public class CurrentPipelineHelpURLAttribute : HelpURLAttribute
58 {
59 private string pageName { get; }
60 /// <summary>
61 /// The constructor of the attribute
62 /// </summary>
63 /// <param name="pageName">The name of the documentation page.</param>
64 public CurrentPipelineHelpURLAttribute(string pageName)
65 : base(null)
66 {
67 this.pageName = pageName;
68 }
69
70 /// <summary>
71 /// Returns the URL to the given page in the current Render Pipeline package documentation site.
72 /// </summary>
73 public override string URL
74 {
75 get
76 {
77#if UNITY_EDITOR
78 if (DocumentationUtils.TryGetPackageInfoForType(GraphicsSettings.currentRenderPipeline?.GetType() ?? typeof(DocumentationInfo), out var package, out var version))
79 {
80 return DocumentationInfo.GetPackageLink(package, version, this.pageName);
81 }
82#endif
83 return string.Empty;
84 }
85 }
86 }
87
88 //We need to have only one version number amongst packages (so public)
89 /// <summary>
90 /// Documentation Info class.
91 /// </summary>
92 public class DocumentationInfo
93 {
94 const string fallbackVersion = "13.1";
95 const string url = "https://docs.unity3d.com/Packages/{0}@{1}/manual/{2}.html#{3}";
96
97 /// <summary>
98 /// Current version of the documentation.
99 /// </summary>
100 public static string version
101 {
102 get
103 {
104#if UNITY_EDITOR
105 if (DocumentationUtils.TryGetPackageInfoForType(typeof(DocumentationInfo), out _, out var version))
106 return version;
107#endif
108 return fallbackVersion;
109 }
110 }
111
112 /// <summary>
113 /// Generates a help URL for the given package and page name.
114 /// </summary>
115 /// <param name="packageName">The package name.</param>
116 /// <param name="packageVersion">The package version.</param>
117 /// <param name="pageName">The page name without the extension.</param>
118 /// <returns>The full URL of the page.</returns>
119 public static string GetPackageLink(string packageName, string packageVersion, string pageName) => string.Format(url, packageName, packageVersion, pageName, "");
120
121 /// <summary>
122 /// Generates a help url for the given package and page name
123 /// </summary>
124 /// <param name="packageName">The package name</param>
125 /// <param name="pageName">The page name without the extension.</param>
126 /// <returns>The full URL of the page.</returns>
127 public static string GetPageLink(string packageName, string pageName) => string.Format(url, packageName, version, pageName, "");
128
129 /// <summary>
130 /// Generates a help url for the given package and page name
131 /// </summary>
132 /// <param name="packageName">The package name</param>
133 /// <param name="pageName">The page name without the extension.</param>
134 /// <param name="pageHash">The page hash</param>
135 /// <returns>The full URL of the page.</returns>
136 public static string GetPageLink(string packageName, string pageName, string pageHash) => string.Format(url, packageName, version, pageName, pageHash);
137 }
138
139 /// <summary>
140 /// Set of utils for documentation
141 /// </summary>
142 public static class DocumentationUtils
143 {
144 /// <summary>
145 /// Obtains the help url from an enum
146 /// </summary>
147 /// <typeparam name="TEnum">The enum with a <see cref="HelpURLAttribute"/></typeparam>
148 /// <param name="mask">[Optional] The current value of the enum</param>
149 /// <returns>The full url</returns>
150 public static string GetHelpURL<TEnum>(TEnum mask = default)
151 where TEnum : struct, IConvertible
152 {
153 var helpURLAttribute = (HelpURLAttribute)mask
154 .GetType()
155 .GetCustomAttributes(typeof(HelpURLAttribute), false)
156 .FirstOrDefault();
157
158 return helpURLAttribute == null ? string.Empty : $"{helpURLAttribute.URL}#{mask}";
159 }
160
161 /// <summary>
162 /// Obtains the help URL from a type.
163 /// </summary>
164 /// <param name="type">The type decorated with the HelpURL attribute.</param>
165 /// <param name="url">The full URL from the HelpURL attribute. If the attribute is not present, this value is null.</param>
166 /// <returns>Returns true if the attribute is present, and false otherwise.</returns>
167 public static bool TryGetHelpURL(Type type, out string url)
168 {
169 var attribute = type.GetCustomAttribute<HelpURLAttribute>(false);
170 url = attribute?.URL;
171 return attribute != null;
172 }
173
174#if UNITY_EDITOR
175 /// <summary>
176 /// Obtain package informations from a specific type
177 /// </summary>
178 /// <param name="type">The type used to retrieve package information</param>
179 /// <param name="packageName">The name of the package containing the given type</param>
180 /// <param name="version">The version number of the package containing the given type. Only Major.Minor will be returned as fix is not used for documentation</param>
181 /// <returns></returns>
182 public static bool TryGetPackageInfoForType([DisallowNull] Type type, [NotNullWhen(true)] out string packageName, [NotNullWhen(true)] out string version)
183 {
184 var packageInfo = PackageInfo.FindForAssembly(type.Assembly);
185 if (packageInfo == null)
186 {
187 packageName = null;
188 version = null;
189 return false;
190 }
191
192 packageName = packageInfo.name;
193 version = packageInfo.version.Substring(0, packageInfo.version.LastIndexOf('.'));
194 return true;
195 }
196#endif
197 }
198}