attempted ManageScene debugging for hang
parent
c1bde804d4
commit
46df7250b5
|
|
@ -575,6 +575,10 @@ namespace MCPForUnity.Editor
|
|||
response = JsonConvert.SerializeObject(errorResponse);
|
||||
}
|
||||
|
||||
if (IsDebugEnabled())
|
||||
{
|
||||
try { MCPForUnity.Editor.Helpers.McpLog.Info("[MCP] sending framed response", always: false); } catch { }
|
||||
}
|
||||
byte[] responseBytes = System.Text.Encoding.UTF8.GetBytes(response);
|
||||
await WriteFrameAsync(stream, responseBytes);
|
||||
}
|
||||
|
|
@ -858,6 +862,12 @@ namespace MCPForUnity.Editor
|
|||
if (func == null) return null;
|
||||
try
|
||||
{
|
||||
// If mainThreadId is unknown, assume we're on main thread to avoid blocking the editor.
|
||||
if (mainThreadId == 0)
|
||||
{
|
||||
try { return func(); }
|
||||
catch (Exception ex) { throw new InvalidOperationException($"Main thread handler error: {ex.Message}", ex); }
|
||||
}
|
||||
// If we are already on the main thread, execute directly to avoid deadlocks
|
||||
try
|
||||
{
|
||||
|
|
@ -895,13 +905,13 @@ namespace MCPForUnity.Editor
|
|||
}
|
||||
if (captured != null)
|
||||
{
|
||||
return Response.Error($"Main thread handler error: {captured.Message}");
|
||||
throw new InvalidOperationException($"Main thread handler error: {captured.Message}", captured);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Response.Error($"Failed to invoke on main thread: {ex.Message}");
|
||||
throw new InvalidOperationException($"Failed to invoke on main thread: {ex.Message}", ex);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -969,8 +979,9 @@ namespace MCPForUnity.Editor
|
|||
// Maps the command type (tool name) to the corresponding handler's static HandleCommand method
|
||||
// Assumes each handler class has a static method named 'HandleCommand' that takes JObject parameters
|
||||
"manage_script" => ManageScript.HandleCommand(paramsObject),
|
||||
// Run scene operations on the main thread to avoid deadlocks/hangs
|
||||
"manage_scene" => InvokeOnMainThreadWithTimeout(() => ManageScene.HandleCommand(paramsObject), FrameIOTimeoutMs) ?? Response.Error("manage_scene timed out on main thread"),
|
||||
// Run scene operations on the main thread to avoid deadlocks/hangs (with diagnostics under debug flag)
|
||||
"manage_scene" => HandleManageScene(paramsObject)
|
||||
?? throw new TimeoutException($"manage_scene timed out after {FrameIOTimeoutMs} ms on main thread"),
|
||||
"manage_editor" => ManageEditor.HandleCommand(paramsObject),
|
||||
"manage_gameobject" => ManageGameObject.HandleCommand(paramsObject),
|
||||
"manage_asset" => ManageAsset.HandleCommand(paramsObject),
|
||||
|
|
@ -1008,6 +1019,23 @@ namespace MCPForUnity.Editor
|
|||
}
|
||||
}
|
||||
|
||||
private static object HandleManageScene(JObject paramsObject)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (IsDebugEnabled()) Debug.Log("[MCP] manage_scene: dispatching to main thread");
|
||||
var sw = System.Diagnostics.Stopwatch.StartNew();
|
||||
var r = InvokeOnMainThreadWithTimeout(() => ManageScene.HandleCommand(paramsObject), FrameIOTimeoutMs);
|
||||
sw.Stop();
|
||||
if (IsDebugEnabled()) Debug.Log($"[MCP] manage_scene: completed in {sw.ElapsedMilliseconds} ms");
|
||||
return r ?? Response.Error("manage_scene returned null (timeout or error)");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return Response.Error($"manage_scene dispatch error: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
// Helper method to get a summary of parameters for error reporting
|
||||
private static string GetParamsSummary(JObject @params)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ namespace MCPForUnity.Editor.Tools
|
|||
/// </summary>
|
||||
public static object HandleCommand(JObject @params)
|
||||
{
|
||||
try { McpLog.Info("[ManageScene] HandleCommand: start", always: false); } catch { }
|
||||
string action = @params["action"]?.ToString().ToLower();
|
||||
string name = @params["name"]?.ToString();
|
||||
string path = @params["path"]?.ToString(); // Relative to Assets/
|
||||
|
|
@ -76,6 +77,7 @@ namespace MCPForUnity.Editor.Tools
|
|||
}
|
||||
|
||||
// Route action
|
||||
try { McpLog.Info($"[ManageScene] Route action='{action}' name='{name}' path='{path}' buildIndex={(buildIndex.HasValue ? buildIndex.Value.ToString() : "null")}", always: false); } catch { }
|
||||
switch (action)
|
||||
{
|
||||
case "create":
|
||||
|
|
@ -98,9 +100,15 @@ namespace MCPForUnity.Editor.Tools
|
|||
// Save current scene, optionally to a new path
|
||||
return SaveScene(fullPath, relativePath);
|
||||
case "get_hierarchy":
|
||||
return GetSceneHierarchy();
|
||||
try { McpLog.Info("[ManageScene] get_hierarchy: entering", always: false); } catch { }
|
||||
var gh = GetSceneHierarchy();
|
||||
try { McpLog.Info("[ManageScene] get_hierarchy: exiting", always: false); } catch { }
|
||||
return gh;
|
||||
case "get_active":
|
||||
return GetActiveSceneInfo();
|
||||
try { McpLog.Info("[ManageScene] get_active: entering", always: false); } catch { }
|
||||
var ga = GetActiveSceneInfo();
|
||||
try { McpLog.Info("[ManageScene] get_active: exiting", always: false); } catch { }
|
||||
return ga;
|
||||
case "get_build_settings":
|
||||
return GetBuildSettingsScenes();
|
||||
// Add cases for modifying build settings, additive loading, unloading etc.
|
||||
|
|
@ -294,7 +302,9 @@ namespace MCPForUnity.Editor.Tools
|
|||
{
|
||||
try
|
||||
{
|
||||
try { McpLog.Info("[ManageScene] get_active: querying EditorSceneManager.GetActiveScene", always: false); } catch { }
|
||||
Scene activeScene = EditorSceneManager.GetActiveScene();
|
||||
try { McpLog.Info($"[ManageScene] get_active: got scene valid={activeScene.IsValid()} loaded={activeScene.isLoaded} name='{activeScene.name}'", always: false); } catch { }
|
||||
if (!activeScene.IsValid())
|
||||
{
|
||||
return Response.Error("No active scene found.");
|
||||
|
|
@ -314,6 +324,7 @@ namespace MCPForUnity.Editor.Tools
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
try { McpLog.Error($"[ManageScene] get_active: exception {e.Message}"); } catch { }
|
||||
return Response.Error($"Error getting active scene info: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
|
@ -348,7 +359,9 @@ namespace MCPForUnity.Editor.Tools
|
|||
{
|
||||
try
|
||||
{
|
||||
try { McpLog.Info("[ManageScene] get_hierarchy: querying EditorSceneManager.GetActiveScene", always: false); } catch { }
|
||||
Scene activeScene = EditorSceneManager.GetActiveScene();
|
||||
try { McpLog.Info($"[ManageScene] get_hierarchy: got scene valid={activeScene.IsValid()} loaded={activeScene.isLoaded} name='{activeScene.name}'", always: false); } catch { }
|
||||
if (!activeScene.IsValid() || !activeScene.isLoaded)
|
||||
{
|
||||
return Response.Error(
|
||||
|
|
@ -356,16 +369,21 @@ namespace MCPForUnity.Editor.Tools
|
|||
);
|
||||
}
|
||||
|
||||
try { McpLog.Info("[ManageScene] get_hierarchy: fetching root objects", always: false); } catch { }
|
||||
GameObject[] rootObjects = activeScene.GetRootGameObjects();
|
||||
try { McpLog.Info($"[ManageScene] get_hierarchy: rootCount={rootObjects?.Length ?? 0}", always: false); } catch { }
|
||||
var hierarchy = rootObjects.Select(go => GetGameObjectDataRecursive(go)).ToList();
|
||||
|
||||
return Response.Success(
|
||||
var resp = Response.Success(
|
||||
$"Retrieved hierarchy for scene '{activeScene.name}'.",
|
||||
hierarchy
|
||||
);
|
||||
try { McpLog.Info("[ManageScene] get_hierarchy: success", always: false); } catch { }
|
||||
return resp;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
try { McpLog.Error($"[ManageScene] get_hierarchy: exception {e.Message}"); } catch { }
|
||||
return Response.Error($"Error getting scene hierarchy: {e.Message}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue