diff --git a/Assets/Editor/CompileCheckWindow/CompileCheckerExample.cs b/Assets/Editor/CompileCheckWindow/CompileCheckerExample.cs index 6513290c47..c30e590bdf 100644 --- a/Assets/Editor/CompileCheckWindow/CompileCheckerExample.cs +++ b/Assets/Editor/CompileCheckWindow/CompileCheckerExample.cs @@ -30,6 +30,7 @@ public static async void TestCompileChecker() CompileResult result = await compileController.TryCompileAsync( forceRecompile: false, + pausePointWarning: null, ct: CancellationToken.None); CompilerMessage[] err = result.Errors; CompilerMessage[] warning = result.Warnings; @@ -71,6 +72,7 @@ public static async void TestForceCompileChecker() // Example of forced re-compilation CompileResult result = await compileController.TryCompileAsync( forceRecompile: true, + pausePointWarning: null, ct: CancellationToken.None); CompilerMessage[] err = result.Errors; CompilerMessage[] warning = result.Warnings; diff --git a/Assets/Editor/CompileCheckWindow/CompileEditorWindow.cs b/Assets/Editor/CompileCheckWindow/CompileEditorWindow.cs index dcece94e45..db97f157a4 100644 --- a/Assets/Editor/CompileCheckWindow/CompileEditorWindow.cs +++ b/Assets/Editor/CompileCheckWindow/CompileEditorWindow.cs @@ -135,7 +135,7 @@ private async Task ExecuteCompileAsync() return; } - CompileResult result = await _compileController.TryCompileAsync(_forceRecompile, CancellationToken.None); + CompileResult result = await _compileController.TryCompileAsync(_forceRecompile, pausePointWarning: null, CancellationToken.None); if (ShouldRunExecuteDynamicCodeReadinessAfterCompile(result)) { _isPostCompileReadinessRunning = true; diff --git a/Assets/Tests/Editor/CompilePausePointWarningBuilderTests.cs b/Assets/Tests/Editor/CompilePausePointWarningBuilderTests.cs new file mode 100644 index 0000000000..02c62a15dd --- /dev/null +++ b/Assets/Tests/Editor/CompilePausePointWarningBuilderTests.cs @@ -0,0 +1,49 @@ +using NUnit.Framework; + +using io.github.hatayama.UnityCliLoop.FirstPartyTools; + +namespace io.github.hatayama.UnityCliLoop.Tests.Editor +{ + /// + /// Verifies the compile Warning text only appears when Play Mode was active with at least + /// one enabled pause point, and states the domain-reload loss when it does. + /// + [TestFixture] + public sealed class CompilePausePointWarningBuilderTests + { + [Test] + public void BuildWarning_WhenNotPlayingAtRequestStart_ReturnsNull() + { + // Verifies no warning is produced when Play Mode was not active, regardless of marker count. + string warning = CompilePausePointWarningBuilder.BuildWarning( + wasPlayingAtRequestStart: false, + activePausePointCount: 3); + + Assert.That(warning, Is.Null); + } + + [Test] + public void BuildWarning_WhenPlayingButNoActivePausePoints_ReturnsNull() + { + // Verifies no warning is produced when Play Mode was active but no pause point is enabled. + string warning = CompilePausePointWarningBuilder.BuildWarning( + wasPlayingAtRequestStart: true, + activePausePointCount: 0); + + Assert.That(warning, Is.Null); + } + + [Test] + public void BuildWarning_WhenPlayingWithActivePausePoints_MentionsCountAndDomainReloadLoss() + { + // Verifies the warning names the active count and explains what the domain reload discards. + string warning = CompilePausePointWarningBuilder.BuildWarning( + wasPlayingAtRequestStart: true, + activePausePointCount: 2); + + Assert.That(warning, Does.Contain("2 enabled pause point")); + Assert.That(warning, Does.Contain("Play session state")); + Assert.That(warning, Does.Contain("pause point patches")); + } + } +} diff --git a/Assets/Tests/Editor/CompilePausePointWarningBuilderTests.cs.meta b/Assets/Tests/Editor/CompilePausePointWarningBuilderTests.cs.meta new file mode 100644 index 0000000000..376f488350 --- /dev/null +++ b/Assets/Tests/Editor/CompilePausePointWarningBuilderTests.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: b619b8f058fc54c9d855b5ae93c5d746 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Tests/Editor/CompileResponseFactoryTests.cs b/Assets/Tests/Editor/CompileResponseFactoryTests.cs index fde03ad9bf..01d2677bac 100644 --- a/Assets/Tests/Editor/CompileResponseFactoryTests.cs +++ b/Assets/Tests/Editor/CompileResponseFactoryTests.cs @@ -42,7 +42,7 @@ public void CreateResponse_WhenNormalCompileCompletes_MapsDetailedIssues() warnings: new[] { warning }); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: false); + CompileResponseFactory.CreateResponse(result, forceRecompile: false, pausePointWarning: null); Assert.That(response.Success, Is.False); Assert.That(response.ErrorCount, Is.EqualTo(1)); @@ -75,7 +75,7 @@ public void CreateResponse_WhenForceCompileIsUnknown_ExplainsNullDetails() message: null); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: true); + CompileResponseFactory.CreateResponse(result, forceRecompile: true, pausePointWarning: null); Assert.That(response.Success, Is.False); Assert.That(response.ErrorCount, Is.Null); @@ -102,7 +102,7 @@ public void CreateResponse_WhenForceCompileHasOutcome_ExplainsNullDetails() message: "Internal force compile status message."); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: true); + CompileResponseFactory.CreateResponse(result, forceRecompile: true, pausePointWarning: null); Assert.That(response.Success, Is.False); Assert.That(response.ErrorCount, Is.Null); @@ -144,7 +144,7 @@ public void CreateResponse_WhenIndeterminateNonForceCompileHasCounts_PreservesCo message: null); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: false); + CompileResponseFactory.CreateResponse(result, forceRecompile: false, pausePointWarning: null); Assert.That(response.Success, Is.False); Assert.That(response.ErrorCount, Is.EqualTo(1)); @@ -179,7 +179,7 @@ public void CreateResponse_WhenForceCompileHasPreservedFailure_MapsDetailedIssue preserveDetailsWhenForceRecompile: true); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: true); + CompileResponseFactory.CreateResponse(result, forceRecompile: true, pausePointWarning: null); Assert.That(response.Success, Is.False); Assert.That(response.ErrorCount, Is.EqualTo(1)); @@ -210,7 +210,7 @@ public void CreateResponse_WhenExternalSceneCannotBeResolved_AddsNextActions() message: error.message); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: false); + CompileResponseFactory.CreateResponse(result, forceRecompile: false, pausePointWarning: null); Assert.That(response.NextActions, Is.Not.Null); Assert.That(response.NextActions, Has.Length.EqualTo(2)); @@ -245,7 +245,7 @@ public void CreateResponse_WhenExternalSceneCannotBeReloaded_AddsNextActions() message: error.message); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: false); + CompileResponseFactory.CreateResponse(result, forceRecompile: false, pausePointWarning: null); Assert.That(response.NextActions, Is.Not.Null); Assert.That(response.NextActions, Has.Length.EqualTo(2)); @@ -275,7 +275,7 @@ public void CreateResponse_WhenExternalSceneStopMessageUsesDifferentWording_Does message: error.message); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: false); + CompileResponseFactory.CreateResponse(result, forceRecompile: false, pausePointWarning: null); Assert.That(response.NextActions, Is.Null); } @@ -301,7 +301,7 @@ public void CreateResponse_WhenUnityTestFrameworkSymbolIsMissing_AddsTestAsmdefH warnings: Array.Empty()); CompileResponse response = - CompileResponseFactory.CreateResponse(result, forceRecompile: false); + CompileResponseFactory.CreateResponse(result, forceRecompile: false, pausePointWarning: null); Assert.That(response.Message, Does.Contain("TestAssemblies")); Assert.That(response.Message, Does.Contain("com.unity.test-framework")); diff --git a/Assets/Tests/Editor/CompileSessionResultStoreTests.cs b/Assets/Tests/Editor/CompileSessionResultStoreTests.cs index ef0938d60a..e3c7750320 100644 --- a/Assets/Tests/Editor/CompileSessionResultStoreTests.cs +++ b/Assets/Tests/Editor/CompileSessionResultStoreTests.cs @@ -97,9 +97,9 @@ public void StoreCompileResult_WhenEquivalentNormalResponsesAreStoredTwice_Write errors: Array.Empty(), warnings: new[] { warning }); CompileResponse firstResponse = - CompileResponseFactory.CreateResponse(result, forceRecompile: false); + CompileResponseFactory.CreateResponse(result, forceRecompile: false, pausePointWarning: null); CompileResponse secondResponse = - CompileResponseFactory.CreateResponse(result, forceRecompile: false); + CompileResponseFactory.CreateResponse(result, forceRecompile: false, pausePointWarning: null); CompileSessionResultStore.StoreCompileResult( compileResultSessionRepository, diff --git a/Assets/Tests/Editor/CompileUseCaseTests.cs b/Assets/Tests/Editor/CompileUseCaseTests.cs index 4c7970c3e5..73f81e6910 100644 --- a/Assets/Tests/Editor/CompileUseCaseTests.cs +++ b/Assets/Tests/Editor/CompileUseCaseTests.cs @@ -49,7 +49,7 @@ public async Task CompileAsync_WhenExecutionLayerStoresDelayedSuccess_DoesNotSto compileSessionLifecycleService, compileResultSessionRepository, pendingCompileSessionRepository); - useCase.SetCompilationExecutionForTesting((compileRequest, ct) => + useCase.SetCompilationExecutionForTesting((compileRequest, pausePointWarning, ct) => { ct.ThrowIfCancellationRequested(); CompileResultSessionRecorder.RecordCompileResult( @@ -67,6 +67,8 @@ public async Task CompileAsync_WhenExecutionLayerStoresDelayedSuccess_DoesNotSto Assert.That(compileResultSessionRepository.StoreCount, Is.EqualTo(1)); Assert.That(response.Success, Is.True); Assert.That(response.ProjectRoot, Is.Not.Empty); + // Verifies no pause-point Warning appears outside Play Mode (the only state an EditMode test can exercise). + Assert.That(response.Warning, Is.Null); UnityCliLoopStoredCompileResult storedResult = compileResultSessionRepository.GetCompileResult("compile_test_request"); Assert.That(storedResult.ResultJson, Does.Contain("\"ProjectRoot\":")); diff --git a/Packages/src/Editor/FirstPartyTools/Compile/CompilationExecutionService.cs b/Packages/src/Editor/FirstPartyTools/Compile/CompilationExecutionService.cs index d89e208d62..ada3400089 100644 --- a/Packages/src/Editor/FirstPartyTools/Compile/CompilationExecutionService.cs +++ b/Packages/src/Editor/FirstPartyTools/Compile/CompilationExecutionService.cs @@ -34,8 +34,9 @@ public CompilationExecutionService( /// Execute compilation asynchronously /// /// Compile request with force and delayed-result settings. + /// Optional Warning to carry onto the shaped response, e.g. when Play Mode was active with enabled pause points. /// Compilation result - public async Task ExecuteCompilationAsync(CompileSchema request, CancellationToken ct) + public async Task ExecuteCompilationAsync(CompileSchema request, string pausePointWarning, CancellationToken ct) { if (request == null) { @@ -47,7 +48,7 @@ public async Task ExecuteCompilationAsync(CompileSchema request, _pendingCompileSessionRepository); compileController.SetResultRecordingContext(CompileResultRecordingContext.Create(request)); compileController.SetExternalSceneChangePolicy(request.ReloadExternalSceneChanges); - return await compileController.TryCompileAsync(request.ForceRecompile, ct).ConfigureAwait(false); + return await compileController.TryCompileAsync(request.ForceRecompile, pausePointWarning, ct).ConfigureAwait(false); } } } diff --git a/Packages/src/Editor/FirstPartyTools/Compile/CompileController.cs b/Packages/src/Editor/FirstPartyTools/Compile/CompileController.cs index 15b06c64e9..71b6091282 100644 --- a/Packages/src/Editor/FirstPartyTools/Compile/CompileController.cs +++ b/Packages/src/Editor/FirstPartyTools/Compile/CompileController.cs @@ -22,6 +22,7 @@ public class CompileController : IDisposable private List _compileMessages = new(); private TaskCompletionSource _currentCompileTask; private bool _isForceCompile = false; + private string _pendingPausePointWarning; private bool _reloadExternalSceneChanges = true; private CompileResultRecordingContext _resultRecordingContext = CompileResultRecordingContext.Disabled(); private DateTime _compileStartedAtUtc = DateTime.MinValue; @@ -96,6 +97,7 @@ internal void SetExternalSceneChangePolicy(bool reloadExternalSceneChanges) /// Executes compilation asynchronously. /// /// Whether to force a recompile. + /// Optional Warning to carry onto the shaped response, e.g. when Play Mode was active with enabled pause points. /// Cancellation token for the compile execution. /// The compilation result. /// Thrown when the task is not found during compilation. @@ -103,8 +105,10 @@ internal void SetExternalSceneChangePolicy(bool reloadExternalSceneChanges) /// Callers must validate editor compilation state before invoking compile execution; /// the production pipeline does this in CompileUseCase. /// - public async Task TryCompileAsync(bool forceRecompile, CancellationToken ct) + public async Task TryCompileAsync(bool forceRecompile, string pausePointWarning, CancellationToken ct) { + _pendingPausePointWarning = pausePointWarning; + if (_isCompiling) { // If compilation is already in progress, wait for the current task. @@ -136,7 +140,7 @@ public async Task TryCompileAsync(bool forceRecompile, Cancellati }); CompileResult result = CompileResultFactory.CreateExternalSceneChangeFailureResult(sceneChangeResult); - RecordCompileResultIfNeeded(result); + RecordCompileResultIfNeeded(result, pausePointWarning: null); return result; } @@ -321,7 +325,7 @@ private void CompleteCompileRequest(CompileResult result, bool unregisterEvents) // Completion subscribers are outside this controller, so state cleanup cannot depend on them returning. try { - RecordCompileResultIfNeeded(result); + RecordCompileResultIfNeeded(result, _pendingPausePointWarning); if (unregisterEvents) { @@ -341,13 +345,14 @@ private void CompleteCompileRequest(CompileResult result, bool unregisterEvents) _isForceCompile = false; _resultRecordingContext = CompileResultRecordingContext.Disabled(); _compileStartedAtUtc = DateTime.MinValue; + _pendingPausePointWarning = null; } task?.TrySetResult(result); } } - private void RecordCompileResultIfNeeded(CompileResult result) + private void RecordCompileResultIfNeeded(CompileResult result, string pausePointWarning) { UnityEngine.Debug.Assert(result != null, "result must not be null"); @@ -362,7 +367,8 @@ private void RecordCompileResultIfNeeded(CompileResult result) _resultRecordingContext.RequestId, _resultRecordingContext.ForceRecompile, result, - _resultRecordingContext.RequestId); + _resultRecordingContext.RequestId, + pausePointWarning); } /// @@ -462,6 +468,7 @@ public void Cleanup() _reloadExternalSceneChanges = true; _resultRecordingContext = CompileResultRecordingContext.Disabled(); _compileStartedAtUtc = DateTime.MinValue; + _pendingPausePointWarning = null; } /// diff --git a/Packages/src/Editor/FirstPartyTools/Compile/CompilePausePointWarningBuilder.cs b/Packages/src/Editor/FirstPartyTools/Compile/CompilePausePointWarningBuilder.cs new file mode 100644 index 0000000000..6825e0e288 --- /dev/null +++ b/Packages/src/Editor/FirstPartyTools/Compile/CompilePausePointWarningBuilder.cs @@ -0,0 +1,22 @@ +namespace io.github.hatayama.UnityCliLoop.FirstPartyTools +{ + /// + /// Builds the compile Warning text for the case where Play Mode was active with enabled + /// pause points at the moment compile was requested: the domain reload that follows discards + /// both the Play session state and every pause-point Harmony patch. + /// + internal static class CompilePausePointWarningBuilder + { + public static string BuildWarning(bool wasPlayingAtRequestStart, int activePausePointCount) + { + if (!wasPlayingAtRequestStart || activePausePointCount <= 0) + { + return null; + } + + return "Play Mode was active with " + activePausePointCount + " enabled pause point(s). " + + "The compile stops Play Mode and the domain reload discards the Play session state " + + "and all pause point patches — re-enable pause points after the compile completes."; + } + } +} diff --git a/Packages/src/Editor/FirstPartyTools/Compile/CompilePausePointWarningBuilder.cs.meta b/Packages/src/Editor/FirstPartyTools/Compile/CompilePausePointWarningBuilder.cs.meta new file mode 100644 index 0000000000..075a1fa46b --- /dev/null +++ b/Packages/src/Editor/FirstPartyTools/Compile/CompilePausePointWarningBuilder.cs.meta @@ -0,0 +1,11 @@ +fileFormatVersion: 2 +guid: 0fd68b00b4e134f7bbd52a920ebea900 +MonoImporter: + externalObjects: {} + serializedVersion: 2 + defaultReferences: [] + executionOrder: 0 + icon: {instanceID: 0} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Packages/src/Editor/FirstPartyTools/Compile/CompileResponse.cs b/Packages/src/Editor/FirstPartyTools/Compile/CompileResponse.cs index a3cd64c8e7..9532967598 100644 --- a/Packages/src/Editor/FirstPartyTools/Compile/CompileResponse.cs +++ b/Packages/src/Editor/FirstPartyTools/Compile/CompileResponse.cs @@ -73,6 +73,12 @@ public class CompileResponse : UnityCliLoopToolResponse /// public string ProjectRoot { get; set; } + /// + /// Optional warning about a condition compile does not block on, e.g. Play Mode being + /// active with enabled pause points whose patches the domain reload will discard. + /// + public string Warning { get; set; } + /// /// Create a new CompileResponse /// diff --git a/Packages/src/Editor/FirstPartyTools/Compile/CompileResponseFactory.cs b/Packages/src/Editor/FirstPartyTools/Compile/CompileResponseFactory.cs index 03816741c8..cf051a27a5 100644 --- a/Packages/src/Editor/FirstPartyTools/Compile/CompileResponseFactory.cs +++ b/Packages/src/Editor/FirstPartyTools/Compile/CompileResponseFactory.cs @@ -27,24 +27,27 @@ internal static class CompileResponseFactory internal static CompileResponse CreateResponse( CompileResult result, - bool forceRecompile) + bool forceRecompile, + string pausePointWarning) { Debug.Assert(result != null, "result must not be null"); if (forceRecompile && !result.PreserveDetailsWhenForceRecompile) { - return CreateForceCompileResult(result); + return CreateForceCompileResult(result, pausePointWarning); } if (result.IsIndeterminate) { - return new CompileResponse( + CompileResponse indeterminateResponse = new CompileResponse( success: result.Success == true, errorCount: result.ErrorCount, warningCount: result.WarningCount, errors: null, warnings: null, message: result.Message ?? "Compilation status is unknown. Use get-logs to inspect the compiler output."); + indeterminateResponse.Warning = pausePointWarning; + return indeterminateResponse; } CompileResponse response = new CompileResponse( @@ -55,6 +58,7 @@ internal static CompileResponse CreateResponse( warnings: ToIssues(result.Warnings), message: AddMissingTestFrameworkReferenceHint(result.Message, result.Errors)); response.NextActions = CreateExternalSceneChangeNextActions(result.Message); + response.Warning = pausePointWarning; return response; } @@ -73,7 +77,7 @@ private static string[] CreateExternalSceneChangeNextActions(string message) return ExternalSceneChangeNextActions; } - private static CompileResponse CreateForceCompileResult(CompileResult result) + private static CompileResponse CreateForceCompileResult(CompileResult result, string pausePointWarning) { ForceCompileUnknownResult unknownResult = ForceCompileUnknownResult.Create(); CompileResponse response = new CompileResponse( @@ -85,6 +89,7 @@ private static CompileResponse CreateForceCompileResult(CompileResult result) message: unknownResult.Message); response.ErrorCode = ForceCompileUnknownResult.ErrorCodeText; response.NextActions = new[] { ForceCompileUnknownResult.NextActionText }; + response.Warning = pausePointWarning; return response; } diff --git a/Packages/src/Editor/FirstPartyTools/Compile/CompileResultSessionRecorder.cs b/Packages/src/Editor/FirstPartyTools/Compile/CompileResultSessionRecorder.cs index de6034ccf6..4b6c4a4470 100644 --- a/Packages/src/Editor/FirstPartyTools/Compile/CompileResultSessionRecorder.cs +++ b/Packages/src/Editor/FirstPartyTools/Compile/CompileResultSessionRecorder.cs @@ -16,14 +16,15 @@ internal static CompileResponse RecordCompileResult( string requestId, bool forceRecompile, CompileResult result, - string correlationId) + string correlationId, + string pausePointWarning = null) { Debug.Assert(compileResultSessionRepository != null, "compileResultSessionRepository must not be null"); Debug.Assert(pendingCompileSessionRepository != null, "pendingCompileSessionRepository must not be null"); Debug.Assert(!string.IsNullOrWhiteSpace(requestId), "requestId must not be null or whitespace"); Debug.Assert(result != null, "result must not be null"); - CompileResponse response = CompileResponseFactory.CreateResponse(result, forceRecompile); + CompileResponse response = CompileResponseFactory.CreateResponse(result, forceRecompile, pausePointWarning); return RecordCompileResponse( compileResultSessionRepository, pendingCompileSessionRepository, diff --git a/Packages/src/Editor/FirstPartyTools/Compile/CompileUseCase.cs b/Packages/src/Editor/FirstPartyTools/Compile/CompileUseCase.cs index a864833350..35c9edd120 100644 --- a/Packages/src/Editor/FirstPartyTools/Compile/CompileUseCase.cs +++ b/Packages/src/Editor/FirstPartyTools/Compile/CompileUseCase.cs @@ -5,6 +5,7 @@ using UnityEngine; using io.github.hatayama.UnityCliLoop.Domain; +using io.github.hatayama.UnityCliLoop.Runtime; using io.github.hatayama.UnityCliLoop.ToolContracts; namespace io.github.hatayama.UnityCliLoop.FirstPartyTools @@ -21,7 +22,7 @@ public class CompileUseCase private readonly UnityCliLoopCompileSessionLifecycleService _compileSessionLifecycleService; private readonly ICompileResultSessionRepository _compileResultSessionRepository; private readonly IPendingCompileSessionRepository _pendingCompileSessionRepository; - private Func> _executeCompilationAsync; + private Func> _executeCompilationAsync; public CompileUseCase( UnityCliLoopCompileSessionLifecycleService compileSessionLifecycleService, @@ -44,7 +45,7 @@ public CompileUseCase( /// /// Replaces compilation execution for tests that must not start Unity's real compilation pipeline. /// - internal void SetCompilationExecutionForTesting(Func> executeCompilationAsync) + internal void SetCompilationExecutionForTesting(Func> executeCompilationAsync) { Debug.Assert(executeCompilationAsync != null, "executeCompilationAsync must not be null"); _executeCompilationAsync = executeCompilationAsync ?? @@ -68,6 +69,11 @@ public async Task CompileAsync(CompileSchema request, Cancellat string correlationId = ResolveCorrelationId(request); LogCompileRequestReceived(request, correlationId); + // Captured before PlayMode preparation can stop Play Mode, so the warning reflects + // the state compile was actually requested in, not the state after this method mutates it. + bool wasPlayingAtRequestStart = EditorApplication.isPlaying; + int activePausePointCountAtRequestStart = UloopPausePointRegistry.GetActiveCount(); + DateTime utcNow = DateTime.UtcNow; _compileSessionLifecycleService.ClearExpiredCompileResult(utcNow); _compileSessionLifecycleService.ClearExpiredPendingCompileRequest(utcNow); @@ -153,12 +159,15 @@ public async Task CompileAsync(CompileSchema request, Cancellat } // 3. Compilation execution + string pausePointWarning = CompilePausePointWarningBuilder.BuildWarning( + wasPlayingAtRequestStart, + activePausePointCountAtRequestStart); ct.ThrowIfCancellationRequested(); - CompileResult result = await _executeCompilationAsync(request, ct).ConfigureAwait(false); + CompileResult result = await _executeCompilationAsync(request, pausePointWarning, ct).ConfigureAwait(false); // 4. Result formatting CompileResponse successResponse = - CompileResponseFactory.CreateResponse(result, request.ForceRecompile); + CompileResponseFactory.CreateResponse(result, request.ForceRecompile, pausePointWarning); StampProjectRootForDelayedResponseIfNeeded(request, successResponse); return successResponse; } @@ -347,14 +356,14 @@ private static string CreateRequestId() return $"compile_{unixTimeMilliseconds}_{correlationId}"; } - private Task ExecuteCompilationWithDefaultServiceAsync(CompileSchema request, CancellationToken ct) + private Task ExecuteCompilationWithDefaultServiceAsync(CompileSchema request, string pausePointWarning, CancellationToken ct) { Debug.Assert(request != null, "request must not be null"); CompilationExecutionService executionService = new( _compileResultSessionRepository, _pendingCompileSessionRepository); - return executionService.ExecuteCompilationAsync(request, ct); + return executionService.ExecuteCompilationAsync(request, pausePointWarning, ct); } } } diff --git a/Packages/src/Editor/FirstPartyTools/Compile/UnityCLILoop.FirstPartyTools.Compile.Editor.asmdef b/Packages/src/Editor/FirstPartyTools/Compile/UnityCLILoop.FirstPartyTools.Compile.Editor.asmdef index acb1fb1610..a220a2bc0a 100644 --- a/Packages/src/Editor/FirstPartyTools/Compile/UnityCLILoop.FirstPartyTools.Compile.Editor.asmdef +++ b/Packages/src/Editor/FirstPartyTools/Compile/UnityCLILoop.FirstPartyTools.Compile.Editor.asmdef @@ -5,7 +5,8 @@ "GUID:5c4588558a3624eacbce0f50007cf1eb", "GUID:e5952ef560e1641f68b2687e6045bf5b", "GUID:d427b32aad9cb44fc8e962437c9dbcd8", - "GUID:fc3fd32eddbee40e39c2d76dc184957b" + "GUID:fc3fd32eddbee40e39c2d76dc184957b", + "GUID:527f26a36b5043c2bd4d4036d04cd76d" ], "includePlatforms": [ "Editor" diff --git a/Packages/src/Runtime/PausePoints/AssemblyInfo.cs b/Packages/src/Runtime/PausePoints/AssemblyInfo.cs index 19745d9168..06ed62d813 100644 --- a/Packages/src/Runtime/PausePoints/AssemblyInfo.cs +++ b/Packages/src/Runtime/PausePoints/AssemblyInfo.cs @@ -7,6 +7,7 @@ [assembly: InternalsVisibleTo("UnityCLILoop.FirstPartyTools.SimulateMouseUi.Editor")] [assembly: InternalsVisibleTo("UnityCLILoop.FirstPartyTools.ExecuteDynamicCode.Editor")] [assembly: InternalsVisibleTo("UnityCLILoop.FirstPartyTools.Common.Preflight.Editor")] +[assembly: InternalsVisibleTo("UnityCLILoop.FirstPartyTools.Compile.Editor")] [assembly: InternalsVisibleTo("UnityCLILoop.Infrastructure")] [assembly: InternalsVisibleTo("UnityCLILoop.Tests.Editor")] [assembly: InternalsVisibleTo("UnityCLILoop.Tests.PlayMode")] diff --git a/Packages/src/Runtime/PausePoints/UloopPausePointRegistry.cs b/Packages/src/Runtime/PausePoints/UloopPausePointRegistry.cs index 21b753a4e8..7a48565d46 100644 --- a/Packages/src/Runtime/PausePoints/UloopPausePointRegistry.cs +++ b/Packages/src/Runtime/PausePoints/UloopPausePointRegistry.cs @@ -224,6 +224,23 @@ public static bool IsArmed(string id) return Entries.TryGetValue(id, out UloopPausePointEntry entry) && entry.IsEnabled; } + /// + /// Counts entries still armed (IsEnabled), i.e. markers whose Harmony patch is currently + /// installed and would be lost on the next domain reload. + /// + public static int GetActiveCount() + { + int count = 0; + foreach (UloopPausePointEntry entry in Entries.Values) + { + if (entry.IsEnabled) + { + count++; + } + } + return count; + } + private static UloopPausePointSnapshot HitCore( string id, UloopPausePointCapturedVariableFrame capturedFrame, diff --git a/tests/contracts/compile_status_response_contract.json b/tests/contracts/compile_status_response_contract.json index e5366231cd..fff442079d 100644 --- a/tests/contracts/compile_status_response_contract.json +++ b/tests/contracts/compile_status_response_contract.json @@ -14,7 +14,8 @@ "Message": "Compile result is available.", "ErrorCode": null, "NextActions": null, - "ProjectRoot": null + "ProjectRoot": null, + "Warning": null }, "Message": "Compile result is available." }