Skip to content

Commit 94f192b

Browse files
authored
Merge pull request #1291 from Scriptwonder/fix/1276-deferred-reload-compiling
fix: trust the pipeline flag when a domain reload is deferred (#1276)
2 parents 70a96ec + 777e8a9 commit 94f192b

7 files changed

Lines changed: 26 additions & 49 deletions

File tree

MCPForUnity/Editor/Services/EditorStateCache.cs

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -260,8 +260,8 @@ static EditorStateCache()
260260
EditorApplication.playModeStateChanged += _ => ForceUpdate("playmode");
261261

262262
// Tracks whether an assembly compilation is actually running, for
263-
// GetActualIsCompiling's Play-mode check. Statics reset on domain reload
264-
// and this [InitializeOnLoad] ctor re-subscribes, so the flag is per-domain.
263+
// GetActualIsCompiling. Statics reset on domain reload and this
264+
// [InitializeOnLoad] ctor re-subscribes, so the flag is per-domain.
265265
UnityEditor.Compilation.CompilationPipeline.compilationStarted += _ => _pipelineCompilationRunning = true;
266266
UnityEditor.Compilation.CompilationPipeline.compilationFinished += _ => _pipelineCompilationRunning = false;
267267

@@ -288,7 +288,7 @@ private static void OnUpdate()
288288
{
289289
// Throttle to reduce overhead while keeping the snapshot fresh enough for polling clients.
290290
double now = EditorApplication.timeSinceStartup;
291-
// Use GetActualIsCompiling() to avoid Play mode false positives (issue #582)
291+
// Use GetActualIsCompiling() to avoid isCompiling false positives (issues #549, #1276)
292292
bool isCompiling = GetActualIsCompiling();
293293

294294
// Check for compilation edge transitions (always update on these)
@@ -543,10 +543,12 @@ public static JObject GetSnapshot()
543543
private static bool _pipelineCompilationRunning;
544544

545545
/// <summary>
546-
/// Returns the actual compilation state, working around a known Unity quirk where
547-
/// EditorApplication.isCompiling can return false positives in Play mode (e.g. a
548-
/// recompile deferred by Recompile-After-Finished-Playing keeps it true for the
549-
/// whole play session). See: https://github.com/CoplayDev/unity-mcp/issues/549
546+
/// Returns the actual compilation state, working around known Unity quirks where
547+
/// EditorApplication.isCompiling reports false positives while no compilation is
548+
/// running: a recompile deferred by Recompile-After-Finished-Playing keeps it true
549+
/// for the whole play session (issue #549), and a project holding
550+
/// EditorApplication.LockReloadAssemblies keeps it true until the lock is released
551+
/// (issue #1276). In both cases the event-tracked pipeline flag is authoritative.
550552
/// </summary>
551553
internal static bool GetActualIsCompiling()
552554
{
@@ -556,16 +558,9 @@ internal static bool GetActualIsCompiling()
556558
return false;
557559
}
558560

559-
// In Play mode, trust the event-tracked pipeline state instead: a deferred
560-
// recompile keeps EditorApplication.isCompiling true without any compilation
561-
// actually running.
562-
if (EditorApplication.isPlaying)
563-
{
564-
return _pipelineCompilationRunning;
565-
}
566-
567-
// Outside Play mode the raw signal is reliable.
568-
return true;
561+
// Otherwise trust the event-tracked pipeline state: isCompiling stays true for as
562+
// long as an assembly reload is deferred, with no compilation actually running.
563+
return _pipelineCompilationRunning;
569564
}
570565
}
571566
}

MCPForUnity/Editor/Services/StdioBridgeReloadHandler.cs

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -114,14 +114,8 @@ private static void OnAfterAssemblyReload()
114114
}
115115

116116
// If the editor is not compiling, attempt an immediate restart without relying on editor focus.
117-
bool isCompiling = EditorApplication.isCompiling;
118-
try
119-
{
120-
var pipeline = Type.GetType("UnityEditor.Compilation.CompilationPipeline, UnityEditor");
121-
var prop = pipeline?.GetProperty("isCompiling", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
122-
if (prop != null) isCompiling |= (bool)prop.GetValue(null);
123-
}
124-
catch { }
117+
// Routed through EditorStateCache so a deferred reload (issue #1276) does not block resume.
118+
bool isCompiling = EditorStateCache.GetActualIsCompiling();
125119

126120
if (!isCompiling)
127121
{

MCPForUnity/Editor/Services/TestJobManager.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -502,7 +502,7 @@ internal static TestJob GetJob(string jobId)
502502
{
503503
long now = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
504504
long initTimeout = job.InitTimeoutMs > 0 ? job.InitTimeoutMs : DefaultInitializationTimeoutMs;
505-
if (!EditorApplication.isCompiling && !EditorApplication.isUpdating && now - job.StartedUnixMs > initTimeout)
505+
if (!EditorStateCache.GetActualIsCompiling() && !EditorApplication.isUpdating && now - job.StartedUnixMs > initTimeout)
506506
{
507507
McpLog.Warn($"[TestJobManager] Job {jobId} failed to initialize within {initTimeout}ms, auto-failing");
508508
job.Status = TestJobStatus.Failed;
@@ -589,7 +589,7 @@ private static string GetBlockedReason(TestJob job)
589589
return "editor_unfocused";
590590
}
591591

592-
if (EditorApplication.isCompiling)
592+
if (EditorStateCache.GetActualIsCompiling())
593593
{
594594
return "compiling";
595595
}

MCPForUnity/Editor/Services/Transport/Transports/StdioBridgeHost.cs

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -237,24 +237,10 @@ private static void EnsureStartedOnEditorIdle()
237237
}
238238
}
239239

240-
private static bool IsCompiling()
241-
{
242-
if (EditorApplication.isCompiling)
243-
{
244-
return true;
245-
}
246-
try
247-
{
248-
Type pipeline = Type.GetType("UnityEditor.Compilation.CompilationPipeline, UnityEditor");
249-
var prop = pipeline?.GetProperty("isCompiling", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Static);
250-
if (prop != null)
251-
{
252-
return (bool)prop.GetValue(null);
253-
}
254-
}
255-
catch { }
256-
return false;
257-
}
240+
// Routed through EditorStateCache so a deferred domain reload (issue #1276) does not
241+
// pin the bridge off: raw EditorApplication.isCompiling stays true for as long as the
242+
// reload is held, and this gates bridge startup.
243+
private static bool IsCompiling() => EditorStateCache.GetActualIsCompiling();
258244

259245
public static void Start()
260246
{

MCPForUnity/Editor/Tools/ManageScriptableObject.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
using System.Linq;
55
using System.Text.RegularExpressions;
66
using MCPForUnity.Editor.Helpers;
7+
using MCPForUnity.Editor.Services;
78
using Newtonsoft.Json.Linq;
89
using UnityEditor;
910
using UnityEngine;
@@ -44,7 +45,7 @@ public static object HandleCommand(JObject @params)
4445
return new ErrorResponse(CodeInvalidParams);
4546
}
4647

47-
if (EditorApplication.isCompiling || EditorApplication.isUpdating)
48+
if (EditorStateCache.GetActualIsCompiling() || EditorApplication.isUpdating)
4849
{
4950
// Unity is transient; treat as retryable on the client side.
5051
return new ErrorResponse(CodeCompilingOrReloading, new { hint = "retry" });

MCPForUnity/Editor/Tools/RefreshUnity.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ await WaitForUnityReadyAsync(
109109
}
110110
}
111111

112-
string resultingState = EditorApplication.isCompiling
112+
string resultingState = EditorStateCache.GetActualIsCompiling()
113113
? "compiling"
114114
: (EditorApplication.isUpdating ? "asset_import" : "idle");
115115

@@ -146,7 +146,7 @@ void Tick()
146146
return;
147147
}
148148

149-
if (!EditorApplication.isCompiling
149+
if (!EditorStateCache.GetActualIsCompiling()
150150
&& !EditorApplication.isUpdating
151151
&& !TestRunStatus.IsRunning
152152
&& !EditorApplication.isPlayingOrWillChangePlaymode)

MCPForUnity/Editor/Tools/UnityReflect.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using System.Runtime.CompilerServices;
77
using System.Text.RegularExpressions;
88
using MCPForUnity.Editor.Helpers;
9+
using MCPForUnity.Editor.Services;
910
using MCPForUnity.Runtime.Helpers;
1011
using Newtonsoft.Json.Linq;
1112
using UnityEditor;
@@ -99,7 +100,7 @@ private static Dictionary<string, Type[]> GetAssemblyTypeCache()
99100

100101
public static object HandleCommand(JObject @params)
101102
{
102-
if (EditorApplication.isCompiling)
103+
if (EditorStateCache.GetActualIsCompiling())
103104
return new ErrorResponse("Cannot reflect while Unity is compiling. Wait for domain reload to complete.");
104105

105106
if (@params == null)

0 commit comments

Comments
 (0)