fix: dispatch lifecycle exit through live document
This commit is contained in:
@@ -330,22 +330,17 @@ internal sealed class FirstLimitedApplyAutomationCoordinator
|
|||||||
{
|
{
|
||||||
if (exitHandlerSubscribed) AcadApplication.Idle -= OnExitIdle;
|
if (exitHandlerSubscribed) AcadApplication.Idle -= OnExitIdle;
|
||||||
exitHandlerSubscribed = false;
|
exitHandlerSubscribed = false;
|
||||||
// LifecycleProbe deliberately opens no drawing. It is already
|
// LifecycleProbe opens no fixture document, but the real startup
|
||||||
// executing in the first verified Idle callback, where the managed
|
// document is available at this point (observed as Drawing1.dwg).
|
||||||
// quit API has been runtime-confirmed to terminate AutoCAD cleanly.
|
// Use that live document only to queue native QUIT; never retain it
|
||||||
if (document is null && string.Equals(config?.Phase, "LifecycleProbe", StringComparison.OrdinalIgnoreCase))
|
// past this callback or use it for fixture/Plant work.
|
||||||
{
|
var exitDocument = document ?? AcadApplication.DocumentManager.MdiActiveDocument;
|
||||||
transitions.Add("LifecycleProbeApplicationQuitRequested");
|
if (exitDocument is null) throw new InvalidOperationException("AUTOMATION_EXIT_DOCUMENT_UNAVAILABLE");
|
||||||
TryWriteEvidence(state == CoordinatorState.Completed, null);
|
|
||||||
AcadApplication.Quit();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (document is null) throw new InvalidOperationException("AUTOMATION_EXIT_DOCUMENT_UNAVAILABLE");
|
|
||||||
transitions.Add("NativeQuitCommandQueued");
|
transitions.Add("NativeQuitCommandQueued");
|
||||||
// Persist the exit boundary before handing control back to AutoCAD;
|
// Persist the exit boundary before handing control back to AutoCAD;
|
||||||
// process termination can otherwise prevent the final evidence flush.
|
// process termination can otherwise prevent the final evidence flush.
|
||||||
TryWriteEvidence(state == CoordinatorState.Completed, null);
|
TryWriteEvidence(state == CoordinatorState.Completed, null);
|
||||||
document.SendStringToExecute("_.QUIT _N ", true, false, false);
|
exitDocument.SendStringToExecute("_.QUIT _N ", true, false, false);
|
||||||
document = null;
|
document = null;
|
||||||
automationOpenedDocuments.Clear();
|
automationOpenedDocuments.Clear();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -105,7 +105,7 @@ public sealed class FoundationTests
|
|||||||
Assert.Contains("AcadApplication.Idle += OnExitIdle", source);
|
Assert.Contains("AcadApplication.Idle += OnExitIdle", source);
|
||||||
Assert.Contains("NativeQuitCommandQueued", source);
|
Assert.Contains("NativeQuitCommandQueued", source);
|
||||||
Assert.Contains("document.SendStringToExecute(\"_.QUIT _N \", true, false, false);", source);
|
Assert.Contains("document.SendStringToExecute(\"_.QUIT _N \", true, false, false);", source);
|
||||||
Assert.Contains("LifecycleProbeApplicationQuitRequested", source);
|
Assert.Contains("var exitDocument = document ?? AcadApplication.DocumentManager.MdiActiveDocument;", source);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact] public void Callback_AfterDocumentDestroyed_DoesNotAccessDocument()
|
[Fact] public void Callback_AfterDocumentDestroyed_DoesNotAccessDocument()
|
||||||
@@ -120,7 +120,7 @@ public sealed class FoundationTests
|
|||||||
var source = File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "FirstLimitedApplyAutomation.cs"));
|
var source = File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "FirstLimitedApplyAutomation.cs"));
|
||||||
Assert.DoesNotContain("MdiActiveDocument", source[source.IndexOf("private void DispatchNativeQuit", StringComparison.Ordinal)..]);
|
Assert.DoesNotContain("MdiActiveDocument", source[source.IndexOf("private void DispatchNativeQuit", StringComparison.Ordinal)..]);
|
||||||
Assert.Contains("AUTOMATION_EXIT_DOCUMENT_UNAVAILABLE", source);
|
Assert.Contains("AUTOMATION_EXIT_DOCUMENT_UNAVAILABLE", source);
|
||||||
Assert.Contains("if (document is null && string.Equals(config?.Phase, \"LifecycleProbe\"", source);
|
Assert.Contains("if (exitDocument is null) throw new InvalidOperationException", source);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact] public void TerminalState_IgnoresFurtherCallbacks()
|
[Fact] public void TerminalState_IgnoresFurtherCallbacks()
|
||||||
@@ -160,7 +160,7 @@ public sealed class FoundationTests
|
|||||||
var source = File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "FirstLimitedApplyAutomation.cs"));
|
var source = File.ReadAllText(Path.Combine(ProjectRoot, "src", "PRecAnnot.Plant3D2026", "FirstLimitedApplyAutomation.cs"));
|
||||||
var controlledExit = source[source.IndexOf("private void RequestControlledExit", StringComparison.Ordinal)..];
|
var controlledExit = source[source.IndexOf("private void RequestControlledExit", StringComparison.Ordinal)..];
|
||||||
Assert.DoesNotContain("document.CloseAndDiscard", controlledExit);
|
Assert.DoesNotContain("document.CloseAndDiscard", controlledExit);
|
||||||
Assert.DoesNotContain("MdiActiveDocument", controlledExit);
|
Assert.Contains("var exitDocument = document ?? AcadApplication.DocumentManager.MdiActiveDocument;", controlledExit);
|
||||||
Assert.Contains("document = null;", controlledExit);
|
Assert.Contains("document = null;", controlledExit);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user