OptimizationHandler.cs 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. using UnityEngine;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using UnityEditor;
  6. namespace Pathfinding {
  7. /// <summary>
  8. /// Helper for enabling or disabling compiler directives.
  9. /// Used only in the editor.
  10. /// </summary>
  11. public static class OptimizationHandler {
  12. public class DefineDefinition {
  13. public string name;
  14. public string description;
  15. public bool enabled;
  16. public bool consistent;
  17. }
  18. /// <summary>
  19. /// Various build targets that Unity have deprecated.
  20. /// There is apparently no way to figure out which these are without hard coding them.
  21. /// </summary>
  22. static readonly BuildTargetGroup[] deprecatedBuildTargets = new BuildTargetGroup[] {
  23. BuildTargetGroup.Unknown,
  24. #if UNITY_5_4_OR_NEWER
  25. (BuildTargetGroup)16, /* BlackBerry */
  26. #endif
  27. #if UNITY_5_5_OR_NEWER
  28. (BuildTargetGroup)5, /* PS3 */
  29. (BuildTargetGroup)6, /* XBox360 */
  30. (BuildTargetGroup)15, /* WP8 */
  31. #endif
  32. #if UNITY_2017_4_OR_NEWER
  33. (BuildTargetGroup)2, /* WebPlayer */
  34. (BuildTargetGroup)20, /* PSM */
  35. #endif
  36. #if UNITY_2018_1_OR_NEWER
  37. (BuildTargetGroup)22, /* SamsungTV */
  38. (BuildTargetGroup)24, /* WiiU */
  39. #endif
  40. #if UNITY_2018_2_OR_NEWER
  41. (BuildTargetGroup)17, /* Tizen */
  42. #endif
  43. #if UNITY_2018_3_OR_NEWER
  44. (BuildTargetGroup)18, /* PSP2 */
  45. (BuildTargetGroup)23, /* Nintendo3DS */
  46. #endif
  47. };
  48. static string GetPackageRootDirectory () {
  49. var rootDir = EditorResourceHelper.editorAssets + "/../../";
  50. return rootDir;
  51. }
  52. static Dictionary<BuildTargetGroup, List<string> > GetDefineSymbols () {
  53. var result = new Dictionary<BuildTargetGroup, List<string> >();
  54. var nonDeprecatedBuildTypes = typeof(BuildTargetGroup)
  55. .GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)
  56. .Where(fieldInfo => fieldInfo.GetCustomAttributes(typeof(System.ObsoleteAttribute), false).Length == 0)
  57. .Select(fieldInfo => (BuildTargetGroup)fieldInfo.GetValue(null)).ToArray();
  58. for (int i = 0; i < nonDeprecatedBuildTypes.Length; i++) {
  59. // Kept for compatibility with older versions of Unity which did not always accurately add Obsolete attributes
  60. // (in particular Unity 2017.4 seems to miss marking the PSM build target as obsolete, the other ones seem accurate)
  61. if (deprecatedBuildTargets.Contains(nonDeprecatedBuildTypes[i])) continue;
  62. #if UNITY_2021_3_OR_NEWER
  63. PlayerSettings.GetScriptingDefineSymbols(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(nonDeprecatedBuildTypes[i]), out var defines);
  64. #else
  65. string defineString = PlayerSettings.GetScriptingDefineSymbolsForGroup(nonDeprecatedBuildTypes[i]);
  66. if (defineString == null) continue;
  67. var defines = defineString.Split(';').Select(s => s.Trim());
  68. #endif
  69. result[nonDeprecatedBuildTypes[i]] = defines.ToList();
  70. }
  71. return result;
  72. }
  73. static void SetDefineSymbols (Dictionary<BuildTargetGroup, List<string> > symbols) {
  74. foreach (var pair in symbols) {
  75. #if UNITY_2021_3_OR_NEWER
  76. string[] symbolsArr = pair.Value.Distinct().ToArray();
  77. PlayerSettings.SetScriptingDefineSymbols(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(pair.Key), symbolsArr);
  78. #else
  79. var defineString = string.Join(";", pair.Value.Distinct().ToArray());
  80. PlayerSettings.SetScriptingDefineSymbolsForGroup(pair.Key, defineString);
  81. #endif
  82. }
  83. }
  84. public static void EnableDefine (string name) {
  85. name = name.Trim();
  86. var newSymbols = GetDefineSymbols().ToDictionary(pair => pair.Key, pair => {
  87. pair.Value.Add(name);
  88. return pair.Value;
  89. });
  90. SetDefineSymbols(newSymbols);
  91. }
  92. public static void DisableDefine (string name) {
  93. name = name.Trim();
  94. var newSymbols = GetDefineSymbols().ToDictionary(pair => pair.Key, pair => {
  95. pair.Value.Remove(name);
  96. return pair.Value;
  97. });
  98. SetDefineSymbols(newSymbols);
  99. }
  100. public static void IsDefineEnabled (string name, out bool enabled, out bool consistent) {
  101. name = name.Trim();
  102. int foundEnabled = 0;
  103. int foundDisabled = 0;
  104. foreach (var pair in GetDefineSymbols()) {
  105. if (pair.Value.Contains(name)) {
  106. foundEnabled++;
  107. } else {
  108. foundDisabled++;
  109. }
  110. }
  111. enabled = foundEnabled > foundDisabled;
  112. consistent = (foundEnabled > 0) != (foundDisabled > 0);
  113. }
  114. public static List<DefineDefinition> FindDefines () {
  115. var path = GetPackageRootDirectory()+"/defines.csv";
  116. if (File.Exists(path)) {
  117. // Read a file consisting of lines with the format
  118. // NAME;Description
  119. // Ignore empty lines and lines which do not contain exactly 1 ';'
  120. var definePairs = File.ReadAllLines(path)
  121. .Select(line => line.Trim())
  122. .Where(line => line.Length > 0)
  123. .Select(line => line.Split(';'))
  124. .Where(opts => opts.Length == 2);
  125. return definePairs.Select(opts => {
  126. var def = new DefineDefinition { name = opts[0].Trim(), description = opts[1].Trim() };
  127. IsDefineEnabled(def.name, out def.enabled, out def.consistent);
  128. return def;
  129. }).ToList();
  130. }
  131. Debug.LogError("Could not find file '"+path+"'");
  132. return new List<DefineDefinition>();
  133. }
  134. public static void ApplyDefines (List<DefineDefinition> defines) {
  135. foreach (var define in defines) {
  136. if (define.enabled) {
  137. EnableDefine(define.name);
  138. } else {
  139. DisableDefine(define.name);
  140. }
  141. }
  142. }
  143. }
  144. }