[Add] Hot Reload
This commit is contained in:
@@ -0,0 +1,584 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using SingularityGroup.HotReload.DTO;
|
||||
using SingularityGroup.HotReload.Localization;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Compilation;
|
||||
using UnityEditor.PackageManager;
|
||||
using UnityEditor.PackageManager.Requests;
|
||||
using UnityEngine;
|
||||
using Translations = SingularityGroup.HotReload.Editor.Localization.Translations;
|
||||
|
||||
namespace SingularityGroup.HotReload.Editor {
|
||||
|
||||
internal static class HotReloadSuggestionsHelper {
|
||||
internal static void SetSuggestionsShown(HotReloadSuggestionKind hotReloadSuggestionKind) {
|
||||
if (MultiplayerPlaymodeHelper.IsClone) {
|
||||
return;
|
||||
}
|
||||
if (EditorPrefs.GetBool($"HotReloadWindow.SuggestionsShown.{hotReloadSuggestionKind}")) {
|
||||
return;
|
||||
}
|
||||
EditorPrefs.SetBool($"HotReloadWindow.SuggestionsActive.{hotReloadSuggestionKind}", true);
|
||||
EditorPrefs.SetBool($"HotReloadWindow.SuggestionsShown.{hotReloadSuggestionKind}", true);
|
||||
AlertEntry entry;
|
||||
if (suggestionMap.TryGetValue(hotReloadSuggestionKind, out entry) && !HotReloadTimelineHelper.Suggestions.Contains(entry)) {
|
||||
HotReloadTimelineHelper.Suggestions.Insert(0, entry);
|
||||
HotReloadState.ShowingRedDot = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal static bool CheckSuggestionActive(HotReloadSuggestionKind hotReloadSuggestionKind) {
|
||||
return EditorPrefs.GetBool($"HotReloadWindow.SuggestionsActive.{hotReloadSuggestionKind}");
|
||||
}
|
||||
|
||||
internal static bool CheckSuggestionShown(HotReloadSuggestionKind hotReloadSuggestionKind) {
|
||||
return EditorPrefs.GetBool($"HotReloadWindow.SuggestionsShown.{hotReloadSuggestionKind}");
|
||||
}
|
||||
|
||||
internal static bool CanShowServerSuggestion(HotReloadSuggestionKind hotReloadSuggestionKind) {
|
||||
if (hotReloadSuggestionKind == HotReloadSuggestionKind.FieldInitializerWithSideEffects) {
|
||||
return !HotReloadState.ShowedFieldInitializerWithSideEffects;
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.FieldInitializerExistingInstancesEdited) {
|
||||
return !HotReloadState.ShowedFieldInitializerExistingInstancesEdited;
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.FieldInitializerExistingInstancesUnedited) {
|
||||
return !HotReloadState.ShowedFieldInitializerExistingInstancesUnedited;
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.AddMonobehaviourMethod) {
|
||||
return !HotReloadState.ShowedAddMonobehaviourMethods;
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.DetailedErrorReportingIsEnabled) {
|
||||
return !CheckSuggestionShown(HotReloadSuggestionKind.DetailedErrorReportingIsEnabled);
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.UTF8EncodingRequired) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static void SetServerSuggestionShown(HotReloadSuggestionKind hotReloadSuggestionKind) {
|
||||
if (MultiplayerPlaymodeHelper.IsClone) {
|
||||
return;
|
||||
}
|
||||
if (hotReloadSuggestionKind == HotReloadSuggestionKind.DetailedErrorReportingIsEnabled) {
|
||||
HotReloadSuggestionsHelper.SetSuggestionsShown(hotReloadSuggestionKind);
|
||||
return;
|
||||
}
|
||||
if (hotReloadSuggestionKind == HotReloadSuggestionKind.FieldInitializerWithSideEffects) {
|
||||
HotReloadState.ShowedFieldInitializerWithSideEffects = true;
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.FieldInitializerExistingInstancesEdited) {
|
||||
HotReloadState.ShowedFieldInitializerExistingInstancesEdited = true;
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.FieldInitializerExistingInstancesUnedited) {
|
||||
HotReloadState.ShowedFieldInitializerExistingInstancesUnedited = true;
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.AddMonobehaviourMethod) {
|
||||
HotReloadState.ShowedAddMonobehaviourMethods = true;
|
||||
} else if (hotReloadSuggestionKind == HotReloadSuggestionKind.UTF8EncodingRequired) {
|
||||
// Allow showing it multiple times
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
HotReloadSuggestionsHelper.SetSuggestionActive(hotReloadSuggestionKind);
|
||||
}
|
||||
|
||||
// used for cases where suggestion might need to be shown more than once
|
||||
internal static void SetSuggestionActive(HotReloadSuggestionKind hotReloadSuggestionKind) {
|
||||
if (MultiplayerPlaymodeHelper.IsClone) {
|
||||
return;
|
||||
}
|
||||
if (EditorPrefs.GetBool($"HotReloadWindow.SuggestionsShown.{hotReloadSuggestionKind}")) {
|
||||
return;
|
||||
}
|
||||
EditorPrefs.SetBool($"HotReloadWindow.SuggestionsActive.{hotReloadSuggestionKind}", true);
|
||||
|
||||
AlertEntry entry;
|
||||
if (suggestionMap.TryGetValue(hotReloadSuggestionKind, out entry) && !HotReloadTimelineHelper.Suggestions.Contains(entry)) {
|
||||
HotReloadTimelineHelper.Suggestions.Insert(0, entry);
|
||||
HotReloadState.ShowingRedDot = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal static void SetSuggestionInactive(HotReloadSuggestionKind hotReloadSuggestionKind) {
|
||||
if (MultiplayerPlaymodeHelper.IsClone) {
|
||||
return;
|
||||
}
|
||||
EditorPrefs.SetBool($"HotReloadWindow.SuggestionsActive.{hotReloadSuggestionKind}", false);
|
||||
AlertEntry entry;
|
||||
if (suggestionMap.TryGetValue(hotReloadSuggestionKind, out entry)) {
|
||||
HotReloadTimelineHelper.Suggestions.Remove(entry);
|
||||
}
|
||||
}
|
||||
|
||||
private static void InitSuggestions() {
|
||||
foreach (HotReloadSuggestionKind value in Enum.GetValues(typeof(HotReloadSuggestionKind))) {
|
||||
if (!CheckSuggestionActive(value)) {
|
||||
continue;
|
||||
}
|
||||
AlertEntry entry;
|
||||
if (suggestionMap.TryGetValue(value, out entry) && !HotReloadTimelineHelper.Suggestions.Contains(entry)) {
|
||||
HotReloadTimelineHelper.Suggestions.Insert(0, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal static HotReloadSuggestionKind? FindSuggestionKind(AlertEntry targetEntry) {
|
||||
foreach (KeyValuePair<HotReloadSuggestionKind, AlertEntry> pair in suggestionMap) {
|
||||
if (pair.Value.Equals(targetEntry)) {
|
||||
return pair.Key;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
internal static readonly OpenURLButton recompileTroubleshootingButton = new OpenURLButton(Translations.Suggestions.ButtonDocs, Constants.RecompileTroubleshootingURL);
|
||||
internal static readonly OpenURLButton featuresDocumentationButton = new OpenURLButton(Translations.Suggestions.ButtonDocs, Constants.FeaturesDocumentationURL);
|
||||
internal static readonly OpenURLButton multipleEditorsDocumentationButton = new OpenURLButton(Translations.Suggestions.ButtonDocs, Constants.MultipleEditorsURL);
|
||||
internal static readonly OpenURLButton debuggerDocumentationButton = new OpenURLButton(Translations.Suggestions.ButtonMoreInfo, Constants.DebuggerURL);
|
||||
public static Dictionary<HotReloadSuggestionKind, AlertEntry> suggestionMap = new Dictionary<HotReloadSuggestionKind, AlertEntry> {
|
||||
{ HotReloadSuggestionKind.UnityBestDevelopmentToolAward2023, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.Award2023Title,
|
||||
Translations.Suggestions.Award2023Message,
|
||||
actionData: () => {
|
||||
GUILayout.Space(6f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonVote)) {
|
||||
Application.OpenURL(Constants.VoteForAwardURL);
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.UnityBestDevelopmentToolAward2023);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout
|
||||
)},
|
||||
{ HotReloadSuggestionKind.UnsupportedChanges, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.UnsupportedChangesTitle,
|
||||
Translations.Suggestions.UnsupportedChangesMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
featuresDocumentationButton.OnGUI();
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout
|
||||
)},
|
||||
{ HotReloadSuggestionKind.UnsupportedPackages, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.UnsupportedPackagesTitle,
|
||||
Translations.Suggestions.UnsupportedPackagesMessage,
|
||||
iconType: AlertType.UnsupportedChange,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
HotReloadAboutTab.contactButton.OnGUI();
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout
|
||||
)},
|
||||
{ HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.AutoRecompiledPlaymodeTitle,
|
||||
Translations.Suggestions.AutoRecompiledPlaymodeMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
recompileTroubleshootingButton.OnGUI();
|
||||
GUILayout.Space(5f);
|
||||
HotReloadAboutTab.discordButton.OnGUI();
|
||||
GUILayout.Space(5f);
|
||||
HotReloadAboutTab.contactButton.OnGUI();
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout
|
||||
)},
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
{ HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges2022, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.AutoRecompiled2022Title,
|
||||
Translations.Suggestions.AutoRecompiled2022Message,
|
||||
iconType: AlertType.UnsupportedChange,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonUseBuildTimeOnlyAtlas)) {
|
||||
if (EditorSettings.spritePackerMode == SpritePackerMode.SpriteAtlasV2) {
|
||||
EditorSettings.spritePackerMode = SpritePackerMode.SpriteAtlasV2Build;
|
||||
} else {
|
||||
EditorSettings.spritePackerMode = SpritePackerMode.BuildTimeOnlyAtlas;
|
||||
}
|
||||
}
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonOpenSettings)) {
|
||||
SettingsService.OpenProjectSettings("Project/Editor");
|
||||
}
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonIgnoreSuggestion)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges2022);
|
||||
}
|
||||
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
hasExitButton: false
|
||||
)},
|
||||
#endif
|
||||
{ HotReloadSuggestionKind.MultidimensionalArrays, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.MultidimensionalArraysTitle,
|
||||
Translations.Suggestions.MultidimensionalArraysMessage,
|
||||
iconType: AlertType.UnsupportedChange,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonLearnMore)) {
|
||||
string url;
|
||||
if (PackageConst.DefaultLocaleField == Locale.SimplifiedChinese) {
|
||||
url = "https://learn.microsoft.com/zh-cn/dotnet/fundamentals/code-analysis/quality-rules/ca1814";
|
||||
} else {
|
||||
url = "https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1814";
|
||||
}
|
||||
Application.OpenURL(url);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout
|
||||
)},
|
||||
{ HotReloadSuggestionKind.EditorsWithoutHRRunning, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.EditorsWithoutHRTitle,
|
||||
Translations.Suggestions.EditorsWithoutHRMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonStopHotReload)) {
|
||||
EditorCodePatcher.StopCodePatcher().Forget();
|
||||
}
|
||||
GUILayout.Space(5f);
|
||||
|
||||
multipleEditorsDocumentationButton.OnGUI();
|
||||
GUILayout.Space(5f);
|
||||
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonDontShowAgain)) {
|
||||
HotReloadSuggestionsHelper.SetSuggestionsShown(HotReloadSuggestionKind.EditorsWithoutHRRunning);
|
||||
HotReloadSuggestionsHelper.SetSuggestionInactive(HotReloadSuggestionKind.EditorsWithoutHRRunning);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.UnsupportedChange
|
||||
)},
|
||||
// Not in use (never reported from the server)
|
||||
{ HotReloadSuggestionKind.FieldInitializerWithSideEffects, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.FieldInitializerSideEffectsTitle,
|
||||
Translations.Suggestions.FieldInitializerSideEffectsMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonOK)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.FieldInitializerWithSideEffects);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonDontShowAgain)) {
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.FieldInitializerWithSideEffects);
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.FieldInitializerWithSideEffects);
|
||||
}
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.Suggestion
|
||||
)},
|
||||
{ HotReloadSuggestionKind.DetailedErrorReportingIsEnabled, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.DetailedErrorReportingTitle,
|
||||
Translations.Suggestions.DetailedErrorReportingMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
GUILayout.Space(4f);
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonOKPadded)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.DetailedErrorReportingIsEnabled);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonDisable)) {
|
||||
HotReloadSettingsTab.DisableDetailedErrorReportingInner(true);
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.DetailedErrorReportingIsEnabled);
|
||||
}
|
||||
GUILayout.Space(10f);
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.Suggestion
|
||||
)},
|
||||
// Not in use (never reported from the server)
|
||||
{ HotReloadSuggestionKind.FieldInitializerExistingInstancesEdited, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.FieldInitializerEditedTitle,
|
||||
Translations.Suggestions.FieldInitializerEditedMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonTurnOff)) {
|
||||
#pragma warning disable CS0618
|
||||
HotReloadSettingsTab.ApplyApplyFieldInitializerEditsToExistingClassInstances(false);
|
||||
#pragma warning restore CS0618
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.FieldInitializerExistingInstancesEdited);
|
||||
}
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonOpenSettings)) {
|
||||
HotReloadWindow.Current.SelectTab(typeof(HotReloadSettingsTab));
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonDontShowAgain)) {
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.FieldInitializerExistingInstancesEdited);
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.FieldInitializerExistingInstancesEdited);
|
||||
}
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.Suggestion
|
||||
)},
|
||||
{ HotReloadSuggestionKind.FieldInitializerExistingInstancesUnedited, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.FieldInitializerUneditedTitle,
|
||||
Translations.Suggestions.FieldInitializerUneditedMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(8f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonOK)) {
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.FieldInitializerExistingInstancesUnedited);
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.FieldInitializerExistingInstancesUnedited);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.Suggestion
|
||||
)},
|
||||
{ HotReloadSuggestionKind.AddMonobehaviourMethod, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.AddMonobehaviourMethodTitle,
|
||||
Translations.Suggestions.AddMonobehaviourMethodMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(8f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonOK)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.AddMonobehaviourMethod);
|
||||
}
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonAutoRecompile)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.AddMonobehaviourMethod);
|
||||
HotReloadPrefs.AutoRecompilePartiallyUnsupportedChanges = true;
|
||||
HotReloadPrefs.DisplayNewMonobehaviourMethodsAsPartiallySupported = true;
|
||||
HotReloadRunTab.RecompileWithChecks();
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonDontShowAgain)) {
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.AddMonobehaviourMethod);
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.AddMonobehaviourMethod);
|
||||
}
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.Suggestion
|
||||
)},
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
{ HotReloadSuggestionKind.SwitchToDebugModeForInlinedMethods, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.SwitchToDebugModeTitle,
|
||||
Translations.Suggestions.SwitchToDebugModeMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(10f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonSwitchToDebugMode) && HotReloadRunTab.ConfirmExitPlaymode(Translations.Suggestions.SwitchToDebugModeConfirmation)) {
|
||||
HotReloadRunTab.SwitchToDebugMode();
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.UnsupportedChange
|
||||
)},
|
||||
#endif
|
||||
{ HotReloadSuggestionKind.HotReloadWhileDebuggerIsAttached, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.DebuggerAttachedTitle,
|
||||
Translations.Suggestions.DebuggerAttachedMessagePaused,
|
||||
actionData: () => {
|
||||
GUILayout.Space(8f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonKeepEnabledDuringDebugging)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.HotReloadWhileDebuggerIsAttached);
|
||||
HotReloadPrefs.AutoDisableHotReloadWithDebugger = false;
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
debuggerDocumentationButton.OnGUI();
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonDontShowAgain)) {
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.HotReloadWhileDebuggerIsAttached);
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.HotReloadWhileDebuggerIsAttached);
|
||||
}
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.Suggestion
|
||||
)},
|
||||
{ HotReloadSuggestionKind.HotReloadedMethodsWhenDebuggerIsAttached, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.DebuggerMethodsTitle,
|
||||
Translations.Suggestions.DebuggerMethodsMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(8f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonRecompile)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.HotReloadedMethodsWhenDebuggerIsAttached);
|
||||
if (HotReloadRunTab.ConfirmExitPlaymode(Translations.Suggestions.DebuggerMethodsConfirmation)) {
|
||||
HotReloadRunTab.Recompile();
|
||||
}
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
debuggerDocumentationButton.OnGUI();
|
||||
GUILayout.Space(8f);
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.UnsupportedChange,
|
||||
hasExitButton: false
|
||||
)},
|
||||
{ HotReloadSuggestionKind.UTF8EncodingRequired, new AlertEntry(
|
||||
AlertType.Suggestion,
|
||||
Translations.Suggestions.UTF8EncodingRequiredTitle,
|
||||
Translations.Suggestions.UTF8EncodingRequiredMessage,
|
||||
actionData: () => {
|
||||
GUILayout.Space(8f);
|
||||
using (new EditorGUILayout.HorizontalScope()) {
|
||||
if (GUILayout.Button(Translations.Suggestions.ButtonOK)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.UTF8EncodingRequired);
|
||||
}
|
||||
GUILayout.FlexibleSpace();
|
||||
}
|
||||
},
|
||||
timestamp: DateTime.Now,
|
||||
entryType: EntryType.Foldout,
|
||||
iconType: AlertType.UnsupportedChange,
|
||||
hasExitButton: false
|
||||
)},
|
||||
};
|
||||
|
||||
static ListRequest listRequest;
|
||||
static string[] unsupportedPackages = new[] {
|
||||
"com.unity.entities",
|
||||
"com.firstgeargames.fishnet",
|
||||
};
|
||||
static List<string> unsupportedPackagesList;
|
||||
static DateTime lastPlaymodeChange;
|
||||
|
||||
public static void Init() {
|
||||
if (MultiplayerPlaymodeHelper.IsClone) {
|
||||
return;
|
||||
}
|
||||
listRequest = Client.List(offlineMode: false, includeIndirectDependencies: true);
|
||||
|
||||
EditorApplication.playModeStateChanged += state => {
|
||||
lastPlaymodeChange = DateTime.UtcNow;
|
||||
};
|
||||
CompilationPipeline.compilationStarted += obj => {
|
||||
if (DateTime.UtcNow - lastPlaymodeChange < TimeSpan.FromSeconds(1) && !HotReloadState.RecompiledUnsupportedChangesOnExitPlaymode) {
|
||||
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges2022);
|
||||
#else
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges);
|
||||
#endif
|
||||
}
|
||||
HotReloadState.RecompiledUnsupportedChangesOnExitPlaymode = false;
|
||||
};
|
||||
InitSuggestions();
|
||||
}
|
||||
|
||||
private static DateTime lastCheckedUnityInstances = DateTime.UtcNow;
|
||||
public static void Check() {
|
||||
if (MultiplayerPlaymodeHelper.IsClone) {
|
||||
return;
|
||||
}
|
||||
if (listRequest.IsCompleted &&
|
||||
unsupportedPackagesList == null)
|
||||
{
|
||||
unsupportedPackagesList = new List<string>();
|
||||
if (listRequest.Result != null) {
|
||||
foreach (var packageInfo in listRequest.Result) {
|
||||
if (unsupportedPackages.Contains(packageInfo.name)) {
|
||||
unsupportedPackagesList.Add(packageInfo.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unsupportedPackagesList.Count > 0) {
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.UnsupportedPackages);
|
||||
}
|
||||
}
|
||||
|
||||
CheckEditorsWithoutHR();
|
||||
|
||||
#if UNITY_2022_1_OR_NEWER
|
||||
if (EditorSettings.spritePackerMode == SpritePackerMode.AlwaysOnAtlas || EditorSettings.spritePackerMode == SpritePackerMode.SpriteAtlasV2) {
|
||||
SetSuggestionsShown(HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges2022);
|
||||
} else if (CheckSuggestionActive(HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges2022)) {
|
||||
SetSuggestionInactive(HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges2022);
|
||||
EditorPrefs.SetBool($"HotReloadWindow.SuggestionsShown.{HotReloadSuggestionKind.AutoRecompiledWhenPlaymodeStateChanges2022}", false);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
private static void CheckEditorsWithoutHR() {
|
||||
if (!ServerHealthCheck.I.IsServerHealthy) {
|
||||
HotReloadSuggestionsHelper.SetSuggestionInactive(HotReloadSuggestionKind.EditorsWithoutHRRunning);
|
||||
return;
|
||||
}
|
||||
if (checkingEditorsWihtoutHR ||
|
||||
(DateTime.UtcNow - lastCheckedUnityInstances).TotalSeconds < 5)
|
||||
{
|
||||
return;
|
||||
}
|
||||
CheckEditorsWithoutHRAsync().Forget();
|
||||
}
|
||||
|
||||
|
||||
static bool checkingEditorsWihtoutHR;
|
||||
private static async Task CheckEditorsWithoutHRAsync() {
|
||||
try {
|
||||
checkingEditorsWihtoutHR = true;
|
||||
var editorsWithoutHr = await RequestHelper.RequestEditorsWithoutHRRunning();
|
||||
if (editorsWithoutHr == null) {
|
||||
return;
|
||||
}
|
||||
var showSuggestion = editorsWithoutHr.editorsWithoutHRRunning;
|
||||
if (!showSuggestion) {
|
||||
HotReloadSuggestionsHelper.SetSuggestionInactive(HotReloadSuggestionKind.EditorsWithoutHRRunning);
|
||||
return;
|
||||
}
|
||||
if (!HotReloadState.ShowedEditorsWithoutHR && ServerHealthCheck.I.IsServerHealthy) {
|
||||
HotReloadSuggestionsHelper.SetSuggestionActive(HotReloadSuggestionKind.EditorsWithoutHRRunning);
|
||||
}
|
||||
} finally {
|
||||
checkingEditorsWihtoutHR = false;
|
||||
lastCheckedUnityInstances = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user