From c68beca4812ceddfa46e992ee137056d2a927cb7 Mon Sep 17 00:00:00 2001 From: gamer147 Date: Mon, 3 Aug 2026 10:13:10 -0400 Subject: [PATCH] Split diagnostic and lifecycle host contracts --- docs/PROJECT-STRUCTURE.md | 6 ++++++ docs/remake-architecture-and-roadmap.md | 15 +++++++++++---- engine/Age.Engine/Hosting/IDiagnosticHost.cs | 11 +++++++++++ engine/Age.Engine/Hosting/IHost.cs | 18 +----------------- engine/Age.Engine/Hosting/ILifecycleHost.cs | 20 ++++++++++++++++++++ 5 files changed, 49 insertions(+), 21 deletions(-) create mode 100644 engine/Age.Engine/Hosting/IDiagnosticHost.cs create mode 100644 engine/Age.Engine/Hosting/ILifecycleHost.cs diff --git a/docs/PROJECT-STRUCTURE.md b/docs/PROJECT-STRUCTURE.md index e53096e..e58e6be 100644 --- a/docs/PROJECT-STRUCTURE.md +++ b/docs/PROJECT-STRUCTURE.md @@ -160,6 +160,12 @@ transitions, diagnostic snapshots, frame/completion publication, and mask teardo control, and blocking BGM fades; presentation/input retains the message-skip, reset, and frame-pulse consumers of that state through the sealed partial class. +`engine/Age.Engine/Hosting/IHost.cs` remains the aggregate runtime host accepted by the VM and existing host +implementations. `engine/Age.Engine/Hosting/IDiagnosticHost.cs` owns recoverable-warning and modal-diagnostic +reporting contracts, while `engine/Age.Engine/Hosting/ILifecycleHost.cs` owns script-context entry/exit, sleep and +timed-deadline waiting, frame yield, and scene reset. `IHost` inherits both focused contracts; their required and +default behavior is unchanged. + `engine/Age.Engine/Model/GfxState.cs` retains cross-domain retained-graphics coordination. `engine/Age.Engine/Model/GfxState.Contracts.cs` owns its public render, transition, diagnostic, persistence, animation, numeric-glyph, and handle-range contracts. `engine/Age.Engine/Model/GfxState.Surfaces.cs` owns surface diff --git a/docs/remake-architecture-and-roadmap.md b/docs/remake-architecture-and-roadmap.md index b0bc425..40dfe00 100644 --- a/docs/remake-architecture-and-roadmap.md +++ b/docs/remake-architecture-and-roadmap.md @@ -759,6 +759,12 @@ do not mix mechanical moves with semantic changes. headless defaults and diagnostics; interface cleanup must not turn intentionally unsupported presentation into false success. + **Progress (2026-08-03):** the first bounded contract slice introduced `IDiagnosticHost` for recoverable + warnings and modal diagnostic messages and `ILifecycleHost` for script-context entry/exit, sleep and timed + deadline waiting, frame yield, and scene reset. `IHost` inherits both contracts and remains the aggregate VM + entry point; all required members, default implementations, existing hosts, and transport-record locations + are unchanged. Runtime validation remains green. + 4. **Make the build graph express source ownership.** Stop linking production `.cs` files from `godot/` and `tools/movie-corpus-gate/` into `Age.Engine.Tests`. Extract the platform-neutral frontend/movie/diagnostic code into a small production project referenced by Godot, tests, and the corpus gate. Retain both existing @@ -1117,9 +1123,10 @@ layer's rendering diverges from ADV; save layout. --- ## 8. Immediate next step -Begin step 3 of the **codebase consolidation** maintenance slice: clarify runtime contracts without changing -behavior or the aggregate host accepted by the VM. Start with a bounded interface-only slice that introduces -diagnostic and lifecycle host contracts beneath `IHost`, preserving current default implementations and existing -host classes before separating the larger ADV, graphics, audio, movie, and input surfaces. +Continue step 3 of the **codebase consolidation** maintenance slice: clarify runtime contracts without changing +behavior or the aggregate host accepted by the VM. With diagnostic and lifecycle contracts established beneath +`IHost`, introduce the audio host contract next as the smallest remaining self-contained domain, preserving every +required/default member and all existing host implementations before tackling interdependent ADV/input/graphics +surfaces. Concrete playthrough blockers may still preempt this bounded maintenance work; the consolidation effort does not replace Phase B gameplay validation or the open cross-platform gates. diff --git a/engine/Age.Engine/Hosting/IDiagnosticHost.cs b/engine/Age.Engine/Hosting/IDiagnosticHost.cs new file mode 100644 index 0000000..0a6d63a --- /dev/null +++ b/engine/Age.Engine/Hosting/IDiagnosticHost.cs @@ -0,0 +1,11 @@ +namespace Age.Engine.Hosting; + +public interface IDiagnosticHost +{ + /// Report a recoverable runtime discrepancy while allowing script execution to continue. + void ReportWarning(string message) => System.Console.Error.WriteLine(message); + + /// Present a modal diagnostic and return only after the user dismisses it. + void ShowDiagnosticMessage(DiagnosticMessage message) + => System.Console.Error.WriteLine($"{message.Caption}: {message.Text}"); +} diff --git a/engine/Age.Engine/Hosting/IHost.cs b/engine/Age.Engine/Hosting/IHost.cs index b85c0a2..fb8b137 100644 --- a/engine/Age.Engine/Hosting/IHost.cs +++ b/engine/Age.Engine/Hosting/IHost.cs @@ -48,19 +48,11 @@ public enum SurfaceBlackFadeDirection ToBlack, } -public interface IHost +public interface IHost : IDiagnosticHost, ILifecycleHost { - /// Report a recoverable runtime discrepancy while allowing script execution to continue. - void ReportWarning(string message) => System.Console.Error.WriteLine(message); - /// Present a modal diagnostic and return only after the user dismisses it. - void ShowDiagnosticMessage(DiagnosticMessage message) - => System.Console.Error.WriteLine($"{message.Caption}: {message.Text}"); /// Present AGERc's modal full-width editor. Cancel preserves CurrentText. FullwidthTextEditResult EditFullwidthString(FullwidthTextEditRequest request) => new(false, request.CurrentText); - // Script context is retained for diagnostics/page location; resource operands are universal packed ids. - void EnterScriptContext(string scriptName) { } - void ExitScriptContext() { } void ShowText(int offset, string text); void ShowText(AdvLiveTextRun run, int glyphDelayMilliseconds) => ShowText(run.SourceOffset, run.Text); @@ -140,14 +132,6 @@ public interface IHost long InputClockMilliseconds => Environment.TickCount64; void SetCursorResource(long resourceId) { } void ClearCursorResource() { } - void Sleep(long duration); - // Native op-0xd5 pacing sleeps inside run-state 0x40 without publishing retained gfx state. - // Interactive hosts must keep this distinct from presentation-capable script op-0xc8 sleep. - void WaitForTimedCallbackDeadline(long duration) => Sleep(duration); - void FrameYield(); - // Native op 0x9 resets scene-owned host services before reloading root script resource 0. - // Global banks, engine configuration, decoded-asset caches, and persistent profile state survive. - void ResetSceneContext() { } // Native 0x1c7/0x1cc query two distinct ADV skip channels. Headless and non-interactive // hosts default to normal playback; the Godot host supplies the live interactive values. void SetMessageSkipActive(bool active) { } diff --git a/engine/Age.Engine/Hosting/ILifecycleHost.cs b/engine/Age.Engine/Hosting/ILifecycleHost.cs new file mode 100644 index 0000000..4020816 --- /dev/null +++ b/engine/Age.Engine/Hosting/ILifecycleHost.cs @@ -0,0 +1,20 @@ +namespace Age.Engine.Hosting; + +public interface ILifecycleHost +{ + // Script context is retained for diagnostics/page location; resource operands are universal packed ids. + void EnterScriptContext(string scriptName) { } + void ExitScriptContext() { } + + void Sleep(long duration); + + // Native op-0xd5 pacing sleeps inside run-state 0x40 without publishing retained gfx state. + // Interactive hosts must keep this distinct from presentation-capable script op-0xc8 sleep. + void WaitForTimedCallbackDeadline(long duration) => Sleep(duration); + + void FrameYield(); + + // Native op 0x9 resets scene-owned host services before reloading root script resource 0. + // Global banks, engine configuration, decoded-asset caches, and persistent profile state survive. + void ResetSceneContext() { } +}