SRDebugEditor.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. using System;
  2. using System.Collections.Generic;
  3. using System.IO;
  4. using System.Linq;
  5. using UnityEditor;
  6. using UnityEngine;
  7. namespace SRDebugger.Editor
  8. {
  9. public static partial class SRDebugEditor
  10. {
  11. internal const string DisableSRDebuggerCompileDefine = "DISABLE_SRDEBUGGER";
  12. /// <summary>
  13. /// Is SRDebugger currently enabled or disabled.
  14. /// </summary>
  15. public static readonly bool IsEnabled =
  16. #if DISABLE_SRDEBUGGER
  17. false
  18. #else
  19. true
  20. #endif
  21. ;
  22. /// <summary>
  23. /// Set SRDebugger to be enabled or disabled.
  24. /// This is a synchronous operation, which means calling this as part of a build pipeline should be possible.
  25. /// </summary>
  26. /// <param name="enable"></param>
  27. public static void SetEnabled(bool enable)
  28. {
  29. if (EditorApplication.isPlaying || EditorApplication.isCompiling)
  30. {
  31. Debug.LogError(
  32. "[SRDebugger.SetEnabled] Can't change SRDebugger enabled state while in play mode or compiling scripts.");
  33. throw new InvalidOperationException(
  34. "Can't change SRDebugger enabled state while in play mode or compiling scripts.");
  35. }
  36. #if !DISABLE_SRDEBUGGER
  37. AssetDatabase.SaveAssets(); // In case any pending changes to files about to be moved
  38. // Try and unload the settings asset to prevent errors later (harmless error, but annoying)
  39. SRInternalEditorUtil.EditorSettings.ClearCache();
  40. GC.Collect();
  41. EditorUtility.UnloadUnusedAssetsImmediate(true);
  42. #endif
  43. AssetDatabase.ReleaseCachedFileHandles();
  44. SetCompileDefine(DisableSRDebuggerCompileDefine, !enable);
  45. SetResourcesEnabled(enable);
  46. ForceRecompile();
  47. }
  48. /// <summary>
  49. /// Runs through a series of integrity checks that are fast to perform.
  50. /// </summary>
  51. internal static IEnumerable<IntegrityIssue> QuickIntegrityCheck()
  52. {
  53. int enabledCount = 0;
  54. int disabledCount = 0;
  55. foreach (ResourceDirectory directory in GetResourcePaths())
  56. {
  57. if (directory.IsEnabled && directory.IsDisabled)
  58. {
  59. yield return new SomeResourcesAreEnabledAndDisabledIntegrityIssue();
  60. yield break;
  61. }
  62. if (directory.IsEnabled) enabledCount++;
  63. if (directory.IsDisabled) disabledCount++;
  64. }
  65. if (enabledCount > 0 && disabledCount > 0)
  66. {
  67. #if DISABLE_SRDEBUGGER
  68. yield return new SomeResourcesEnabledIntegrityIssue();
  69. #else
  70. yield return new SomeResourcesDisabledIntegrityIssue();
  71. #endif
  72. yield break; // Don't do any further resource-related checks.
  73. }
  74. if (!IsEnabled && enabledCount > 0)
  75. {
  76. yield return new ScriptsDisabledButResourcesEnabled();
  77. }
  78. if (IsEnabled && disabledCount > 0)
  79. {
  80. yield return new ScriptsEnabledButResourcesDisabled();
  81. }
  82. }
  83. internal static void DrawDisabledWindowGui(ref bool isWorking)
  84. {
  85. SRInternalEditorUtil.BeginDrawBackground();
  86. SRInternalEditorUtil.DrawLogo(SRInternalEditorUtil.GetLogo());
  87. SRInternalEditorUtil.EndDrawBackground();
  88. // Draw header/content divider
  89. EditorGUILayout.BeginVertical(SRInternalEditorUtil.Styles.SettingsHeaderBoxStyle);
  90. EditorGUILayout.EndVertical();
  91. GUILayout.Label("SRDebugger Disabled", SRInternalEditorUtil.Styles.InspectorHeaderStyle);
  92. GUILayout.Label(
  93. "SRDebugger is currently disabled. SRDebugger must be enabled in order to access editor features.",
  94. SRInternalEditorUtil.Styles.ParagraphLabel);
  95. EditorGUILayout.HelpBox("Enabling SRDebugger will result in the tools being included in all builds of your game until it is disabled again.", MessageType.Warning);
  96. GUILayout.Label("• "+ DisableSRDebuggerCompileDefine + " compiler define will be removed from all build configurations.", SRInternalEditorUtil.Styles.ListBulletPoint);
  97. GUILayout.Label("• Disabled SRDebugger folders will be renamed so Unity imports them.", SRInternalEditorUtil.Styles.ListBulletPoint);
  98. GUILayout.Label("• You can disable SRDebugger again at any time.", SRInternalEditorUtil.Styles.ListBulletPoint);
  99. if (isWorking && !EditorApplication.isCompiling && !EditorApplication.isUpdating)
  100. {
  101. isWorking = false;
  102. }
  103. if (isWorking)
  104. {
  105. using (new EditorGUI.DisabledGroupScope(true))
  106. {
  107. GUILayout.Button("Working...");
  108. }
  109. }
  110. else if (GUILayout.Button("Enable SRDebugger"))
  111. {
  112. isWorking = true;
  113. try
  114. {
  115. SetEnabled(true);
  116. }
  117. catch (Exception)
  118. {
  119. isWorking = false;
  120. throw;
  121. }
  122. }
  123. }
  124. #if DISABLE_SRDEBUGGER
  125. class SomeResourcesEnabledIntegrityIssue : IntegrityIssue
  126. {
  127. private new const string Title = "Some SRDebugger resources are enabled.";
  128. private new const string Description =
  129. "SRDebugger is disabled, but some SRDebugger resource directories are enabled. \n\n" +
  130. "This can occur if an unhandled error occurs while SRDebugger is being enabled or disabled, or if the resource directories are modified by hand.";
  131. public SomeResourcesEnabledIntegrityIssue() : base(Title, Description)
  132. {
  133. }
  134. protected override IEnumerable<Fix> CreateFixes()
  135. {
  136. yield return new DelegateFix(
  137. "Disable all SRDebugger resources",
  138. "All resource directories will be disabled.",
  139. () => { SetResourcesEnabled(false); });
  140. yield return new DelegateFix(
  141. "Enable SRDebugger",
  142. "Fully enable SRDebugger (activate scripts and enable resources).",
  143. () => { SetEnabled(true); });
  144. }
  145. }
  146. #else
  147. class SomeResourcesDisabledIntegrityIssue : IntegrityIssue
  148. {
  149. private new const string Title = "Some SRDebugger resources are disabled.";
  150. private new const string Description =
  151. "SRDebugger is enabled, but some SRDebugger resource directories are disabled. \n\n" +
  152. "This can occur if an unhandled error occurs while SRDebugger is being enabled or disabled, or if the resource directories are modified by hand.";
  153. public SomeResourcesDisabledIntegrityIssue() : base(Title, Description)
  154. {
  155. }
  156. protected override IEnumerable<Fix> CreateFixes()
  157. {
  158. yield return new DelegateFix(
  159. "Enable all SRDebugger resources",
  160. "All resource directories will be enabled.",
  161. () => { SetResourcesEnabled(true); });
  162. yield return new DelegateFix(
  163. "Disable SRDebugger",
  164. "Fully disable SRDebugger (deactivate scripts, exclude all resources from builds of your game).",
  165. () => { SetEnabled(false); });
  166. }
  167. }
  168. #endif
  169. class SomeResourcesAreEnabledAndDisabledIntegrityIssue : IntegrityIssue
  170. {
  171. private new const string Title = "Duplicate SRDebugger resource directories";
  172. private new const string Description =
  173. "Some SRDebugger resource directories exist in both an enabled and disabled state. \n\n" +
  174. "This can occur if a new version of SRDebugger is installed while SRDebugger is disabled, or if an unhandled error occurs while SRDebugger is being enabled/disabled.";
  175. public SomeResourcesAreEnabledAndDisabledIntegrityIssue() : base(Title, Description)
  176. {
  177. }
  178. protected override IEnumerable<Fix> CreateFixes()
  179. {
  180. if (!IsEnabled)
  181. {
  182. var deletePaths = GetResourcePaths().Where(p => p.IsDisabled && p.IsEnabled).ToList();
  183. string paths = " - " + string.Join("\n - ", deletePaths
  184. .SelectMany(p => new string[] { p.DisabledPath, p.DisabledPathBackupMetaFile }).ToArray());
  185. yield return new DelegateFix(
  186. "Keep enabled resources, disable SRDebugger",
  187. "If you have just installed a new version of SRDebugger, this will keep the most up-to-date resources from the imported package. SRDebugger will be disabled after the old resources are deleted. \n\n The following paths will be deleted: \n\n" + paths,
  188. () =>
  189. {
  190. foreach (ResourceDirectory rd in GetResourcePaths())
  191. {
  192. if (rd.IsEnabled && rd.IsDisabled)
  193. {
  194. Debug.Log("[SRDebugger] Delete Path: " + rd.DisabledPath);
  195. Directory.Delete(rd.DisabledPath, true);
  196. Debug.Log("[SRDebugger] Delete File: " + rd.DisabledPathBackupMetaFile);
  197. File.Delete(rd.DisabledPathBackupMetaFile);
  198. }
  199. }
  200. SetEnabled(false);
  201. });
  202. }
  203. }
  204. }
  205. class ScriptsDisabledButResourcesEnabled : IntegrityIssue
  206. {
  207. private new const string Title = "SRDebugger resources are enabled while scripts are disabled";
  208. private new const string Description =
  209. "SRDebugger's resources directories are enabled, but SRDebugger scripts are disabled. \n" +
  210. "This can occur if the resource directories or if the C# compile defines are modified manually.";
  211. public ScriptsDisabledButResourcesEnabled() : base(Title, Description)
  212. {
  213. }
  214. protected override IEnumerable<Fix> CreateFixes()
  215. {
  216. yield return new DelegateFix(
  217. "Enable SRDebugger scripts",
  218. "Remove compiler define (" + DisableSRDebuggerCompileDefine + ") SRDebugger can be disabled again from the settings menu.",
  219. () =>
  220. {
  221. SetCompileDefine(DisableSRDebuggerCompileDefine, false);
  222. });
  223. yield return new DelegateFix(
  224. "Disable SRDebugger resources",
  225. "Resources will no longer be included in builds of your game (you can enable SRDebugger from the settings menu later)",
  226. () =>
  227. {
  228. SetResourcesEnabled(false);
  229. });
  230. }
  231. }
  232. class ScriptsEnabledButResourcesDisabled : IntegrityIssue
  233. {
  234. private new const string Title = "SRDebugger scripts are enabled while resources are disabled.";
  235. private new const string Description =
  236. "SRDebugger resources directories are disabled, but SRDebugger scripts are still enabled. \n" +
  237. "This can occur if the resource directories or C# compile defines are modified manually.";
  238. public ScriptsEnabledButResourcesDisabled() : base(Title, Description)
  239. {
  240. }
  241. protected override IEnumerable<Fix> CreateFixes()
  242. {
  243. yield return new DelegateFix(
  244. "Disable SRDebugger scripts",
  245. "Add compiler define (" + DisableSRDebuggerCompileDefine + ") to disable SRDebugger scripts (you can re-enable SRDebugger from the settings menu later)",
  246. () =>
  247. {
  248. SetCompileDefine(DisableSRDebuggerCompileDefine, true);
  249. });
  250. yield return new DelegateFix(
  251. "Enable SRDebugger resources",
  252. "Resources will be included in builds of your game (you can disable SRDebugger from the settings menu later)",
  253. () =>
  254. {
  255. SetResourcesEnabled(true);
  256. });
  257. }
  258. }
  259. }
  260. }