summaryrefslogtreecommitdiff
path: root/Other/AstarPathfindingDemo/Packages/com.arongranberg.astar/PackageTools/Editor/OptimizationHandler.cs
blob: e3f16667f3e280893052ca5de68845293cf31ea1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
using UnityEngine;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;

namespace Pathfinding {
	/// <summary>
	/// Helper for enabling or disabling compiler directives.
	/// Used only in the editor.
	/// </summary>
	public static class OptimizationHandler {
		public class DefineDefinition {
			public string name;
			public string description;
			public bool enabled;
			public bool consistent;
		}

		/// <summary>
		/// Various build targets that Unity have deprecated.
		/// There is apparently no way to figure out which these are without hard coding them.
		/// </summary>
		static readonly BuildTargetGroup[] deprecatedBuildTargets = new BuildTargetGroup[] {
			BuildTargetGroup.Unknown,
#if UNITY_5_4_OR_NEWER
			(BuildTargetGroup)16, /* BlackBerry */
#endif
#if UNITY_5_5_OR_NEWER
			(BuildTargetGroup)5, /* PS3 */
			(BuildTargetGroup)6, /* XBox360 */
			(BuildTargetGroup)15, /* WP8 */
#endif
#if UNITY_2017_4_OR_NEWER
			(BuildTargetGroup)2, /* WebPlayer */
			(BuildTargetGroup)20, /* PSM */
#endif
#if UNITY_2018_1_OR_NEWER
			(BuildTargetGroup)22, /* SamsungTV */
			(BuildTargetGroup)24, /* WiiU */
#endif
#if UNITY_2018_2_OR_NEWER
			(BuildTargetGroup)17, /* Tizen */
#endif
#if UNITY_2018_3_OR_NEWER
			(BuildTargetGroup)18, /* PSP2 */
			(BuildTargetGroup)23, /* Nintendo3DS */
#endif
		};

		static string GetPackageRootDirectory () {
			var rootDir = EditorResourceHelper.editorAssets + "/../../";

			return rootDir;
		}

		static Dictionary<BuildTargetGroup, List<string> > GetDefineSymbols () {
			var result = new Dictionary<BuildTargetGroup, List<string> >();

			var nonDeprecatedBuildTypes = typeof(BuildTargetGroup)
										  .GetFields(System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static)
										  .Where(fieldInfo => fieldInfo.GetCustomAttributes(typeof(System.ObsoleteAttribute), false).Length == 0)
										  .Select(fieldInfo => (BuildTargetGroup)fieldInfo.GetValue(null)).ToArray();

			for (int i = 0; i < nonDeprecatedBuildTypes.Length; i++) {
				// Kept for compatibility with older versions of Unity which did not always accurately add Obsolete attributes
				// (in particular Unity 2017.4 seems to miss marking the PSM build target as obsolete, the other ones seem accurate)
				if (deprecatedBuildTargets.Contains(nonDeprecatedBuildTypes[i])) continue;

#if UNITY_2021_3_OR_NEWER
				PlayerSettings.GetScriptingDefineSymbols(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(nonDeprecatedBuildTypes[i]), out var defines);
#else
				string defineString = PlayerSettings.GetScriptingDefineSymbolsForGroup(nonDeprecatedBuildTypes[i]);
				if (defineString == null) continue;

				var defines = defineString.Split(';').Select(s => s.Trim());
#endif
				result[nonDeprecatedBuildTypes[i]] = defines.ToList();
			}
			return result;
		}

		static void SetDefineSymbols (Dictionary<BuildTargetGroup, List<string> > symbols) {
			foreach (var pair in symbols) {
#if UNITY_2021_3_OR_NEWER
				string[] symbolsArr = pair.Value.Distinct().ToArray();
				PlayerSettings.SetScriptingDefineSymbols(UnityEditor.Build.NamedBuildTarget.FromBuildTargetGroup(pair.Key), symbolsArr);
#else
				var defineString = string.Join(";", pair.Value.Distinct().ToArray());
				PlayerSettings.SetScriptingDefineSymbolsForGroup(pair.Key, defineString);
#endif
			}
		}

		public static void EnableDefine (string name) {
			name = name.Trim();
			var newSymbols = GetDefineSymbols().ToDictionary(pair => pair.Key, pair => {
				pair.Value.Add(name);
				return pair.Value;
			});
			SetDefineSymbols(newSymbols);
		}

		public static void DisableDefine (string name) {
			name = name.Trim();
			var newSymbols = GetDefineSymbols().ToDictionary(pair => pair.Key, pair => {
				pair.Value.Remove(name);
				return pair.Value;
			});
			SetDefineSymbols(newSymbols);
		}

		public static void IsDefineEnabled (string name, out bool enabled, out bool consistent) {
			name = name.Trim();
			int foundEnabled = 0;
			int foundDisabled = 0;

			foreach (var pair in GetDefineSymbols()) {
				if (pair.Value.Contains(name)) {
					foundEnabled++;
				} else {
					foundDisabled++;
				}
			}

			enabled = foundEnabled > foundDisabled;
			consistent = (foundEnabled > 0) != (foundDisabled > 0);
		}

		public static List<DefineDefinition> FindDefines () {
			var path = GetPackageRootDirectory()+"/defines.csv";

			if (File.Exists(path)) {
				// Read a file consisting of lines with the format
				// NAME;Description
				// Ignore empty lines and lines which do not contain exactly 1 ';'
				var definePairs = File.ReadAllLines(path)
								  .Select(line => line.Trim())
								  .Where(line => line.Length > 0)
								  .Select(line => line.Split(';'))
								  .Where(opts => opts.Length == 2);

				return definePairs.Select(opts => {
					var def = new DefineDefinition { name = opts[0].Trim(), description = opts[1].Trim() };
					IsDefineEnabled(def.name, out def.enabled, out def.consistent);
					return def;
				}).ToList();
			}

			Debug.LogError("Could not find file '"+path+"'");
			return new List<DefineDefinition>();
		}

		public static void ApplyDefines (List<DefineDefinition> defines) {
			foreach (var define in defines) {
				if (define.enabled) {
					EnableDefine(define.name);
				} else {
					DisableDefine(define.name);
				}
			}
		}
	}
}