Clear ADV History presentation on exit
This commit is contained in:
@@ -1393,6 +1393,12 @@ Label and independently animated wait marker. Native rendering gets this layerin
|
|||||||
part of retained composition; the port must state it explicitly because those two elements are separate
|
part of retained composition; the port must state it explicitly because those two elements are separate
|
||||||
Godot overlays. They reappear with the same parked page after the modal frame returns.
|
Godot overlays. They reappear with the same parked page after the modal frame returns.
|
||||||
|
|
||||||
|
History's target-layout render batches are likewise presentation bindings, not part of the retained backlog.
|
||||||
|
`HISTORY.BIN@0x1100` re-enables recording with op `0x1bb(1)` after erasing its object range and releasing
|
||||||
|
surfaces `0xc0/0xc1`; that existing exit boundary now tells the host to discard all bound History batches.
|
||||||
|
The semantic text/index records remain untouched, so reopening History rebuilds fresh rows while exiting
|
||||||
|
cannot leave the old labels above the resumed ADV page.
|
||||||
|
|
||||||
History's remaining work is stored voice replay through `0x1bd` and the `0xd3/0xd4/0xd5` smooth-scroll
|
History's remaining work is stored voice replay through `0x1bd` and the `0xd3/0xd4/0xd5` smooth-scroll
|
||||||
callback scheduler. None changes backlog ownership or requires choosing a save/profile backend.
|
callback scheduler. None changes backlog ownership or requires choosing a save/profile backend.
|
||||||
|
|
||||||
|
|||||||
@@ -1801,6 +1801,12 @@ class of inherited-state bridges.
|
|||||||
Godot also suppresses the parked page's ordinary dialogue Label and wait indicator while any nested timed
|
Godot also suppresses the parked page's ordinary dialogue Label and wait indicator while any nested timed
|
||||||
raw-input frame owns the modal screen, then restores them on return. Root Control anchor presets are now
|
raw-input frame owns the modal screen, then restores them on return. Root Control anchor presets are now
|
||||||
applied after parenting, removing the remaining occurrence of the associated runtime layout diagnostic.
|
applied after parenting, removing the remaining occurrence of the associated runtime layout diagnostic.
|
||||||
|
|
||||||
|
A follow-up exit check found that the host retained the last History render batches after the script had
|
||||||
|
erased its objects and re-enabled recording. Op `0x1bb(1)` at `HISTORY.BIN@0x1100` is now the presentation
|
||||||
|
end boundary: it clears only the host's transient layout bindings, leaving the engine-owned backlog intact
|
||||||
|
for the next opening. The real interaction regression requires zero active History batches after return.
|
||||||
|
|
||||||
Validation: engine 198/198, zero-warning Godot build, threaded `SELFTEST OK`, and vm0 RECOVER clean.
|
Validation: engine 198/198, zero-warning Godot build, threaded `SELFTEST OK`, and vm0 RECOVER clean.
|
||||||
|
|
||||||
**Next:** manually recheck the five History rows and overlay cleanup against the original. If they match, proceed
|
**Next:** manually recheck the five History rows and overlay cleanup against the original. If they match, proceed
|
||||||
|
|||||||
@@ -167,6 +167,8 @@ public class HistoryInteractionOpsTests
|
|||||||
Assert.True(host.SawRenderedText);
|
Assert.True(host.SawRenderedText);
|
||||||
Assert.True(host.HistoryReturned);
|
Assert.True(host.HistoryReturned);
|
||||||
Assert.Equal(1, host.Waits); // the enclosing ADV page was never released or re-entered
|
Assert.Equal(1, host.Waits); // the enclosing ADV page was never released or re-entered
|
||||||
|
Assert.Equal(1, host.HistoryPresentationEnds);
|
||||||
|
Assert.Empty(host.ActiveHistoryRenders);
|
||||||
|
|
||||||
var historyButtons = host.FirstHistoryFrame
|
var historyButtons = host.FirstHistoryFrame
|
||||||
.Where(render => render.Handle >= 0xd2fa && render.Handle <= 0xd300)
|
.Where(render => render.Handle >= 0xd2fa && render.Handle <= 0xd300)
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ internal class RecordingHost : IHost
|
|||||||
public readonly List<(int Slot, int X, int Y)> TextCursors = new();
|
public readonly List<(int Slot, int X, int Y)> TextCursors = new();
|
||||||
public readonly List<(int Surface, int X, int Y, string Text)> SurfaceStrings = new();
|
public readonly List<(int Surface, int X, int Y, string Text)> SurfaceStrings = new();
|
||||||
public readonly List<AdvTextHistoryRenderBatch> HistoryRenders = new();
|
public readonly List<AdvTextHistoryRenderBatch> HistoryRenders = new();
|
||||||
|
public readonly Dictionary<int, AdvTextHistoryRenderBatch> ActiveHistoryRenders = new();
|
||||||
|
public int HistoryPresentationEnds;
|
||||||
public readonly List<int> ClearedTextLayouts = new();
|
public readonly List<int> ClearedTextLayouts = new();
|
||||||
public readonly List<SurfaceRectFill> SurfaceFills = new();
|
public readonly List<SurfaceRectFill> SurfaceFills = new();
|
||||||
public readonly List<(long First, long Count)> PresentedRanges = new();
|
public readonly List<(long First, long Count)> PresentedRanges = new();
|
||||||
@@ -38,8 +40,21 @@ internal class RecordingHost : IHost
|
|||||||
=> SurfaceStrings.Add((surfaceSlot, x, y, text));
|
=> SurfaceStrings.Add((surfaceSlot, x, y, text));
|
||||||
public void DrawStringToSurface(int surfaceSlot, int x, int y, string text, AdvTextStyle style)
|
public void DrawStringToSurface(int surfaceSlot, int x, int y, string text, AdvTextStyle style)
|
||||||
=> SurfaceStrings.Add((surfaceSlot, x, y, text));
|
=> SurfaceStrings.Add((surfaceSlot, x, y, text));
|
||||||
public void ClearRenderedAdvTextLayout(int layoutSlot) => ClearedTextLayouts.Add(layoutSlot);
|
public void ClearRenderedAdvTextLayout(int layoutSlot)
|
||||||
public void RenderTextHistory(AdvTextHistoryRenderBatch batch) => HistoryRenders.Add(batch);
|
{
|
||||||
|
ClearedTextLayouts.Add(layoutSlot);
|
||||||
|
ActiveHistoryRenders.Remove(layoutSlot);
|
||||||
|
}
|
||||||
|
public void RenderTextHistory(AdvTextHistoryRenderBatch batch)
|
||||||
|
{
|
||||||
|
HistoryRenders.Add(batch);
|
||||||
|
ActiveHistoryRenders[batch.LayoutSlot] = batch;
|
||||||
|
}
|
||||||
|
public void EndTextHistoryPresentation()
|
||||||
|
{
|
||||||
|
HistoryPresentationEnds++;
|
||||||
|
ActiveHistoryRenders.Clear();
|
||||||
|
}
|
||||||
public int MessageWindowAlphaSetting { get; set; }
|
public int MessageWindowAlphaSetting { get; set; }
|
||||||
public void FillSurfaceRect(SurfaceRectFill fill) => SurfaceFills.Add(fill);
|
public void FillSurfaceRect(SurfaceRectFill fill) => SurfaceFills.Add(fill);
|
||||||
public void PresentObjectRange(GfxState gfx, long firstHandle, long count)
|
public void PresentObjectRange(GfxState gfx, long firstHandle, long count)
|
||||||
|
|||||||
@@ -24,6 +24,9 @@ public interface IHost
|
|||||||
=> DrawStringToSurface(surfaceSlot, x, y, text);
|
=> DrawStringToSurface(surfaceSlot, x, y, text);
|
||||||
void ClearRenderedAdvTextLayout(int layoutSlot) { }
|
void ClearRenderedAdvTextLayout(int layoutSlot) { }
|
||||||
void RenderTextHistory(AdvTextHistoryRenderBatch batch) { }
|
void RenderTextHistory(AdvTextHistoryRenderBatch batch) { }
|
||||||
|
// History render batches are transient bindings, unlike the retained backlog itself. HISTORY.BIN's
|
||||||
|
// recording re-enable at exit ends that presentation and drops every bound target layout.
|
||||||
|
void EndTextHistoryPresentation() { }
|
||||||
int MessageWindowAlphaSetting => 0;
|
int MessageWindowAlphaSetting => 0;
|
||||||
void FillSurfaceRect(SurfaceRectFill fill) { }
|
void FillSurfaceRect(SurfaceRectFill fill) { }
|
||||||
void PresentObjectRange(GfxState gfx, long firstHandle, long count) { }
|
void PresentObjectRange(GfxState gfx, long firstHandle, long count) { }
|
||||||
|
|||||||
@@ -772,7 +772,12 @@ public sealed class VirtualMachine
|
|||||||
case "reset-message-voice-state": // 0x1bc resets native per-message voice/queued-voice state
|
case "reset-message-voice-state": // 0x1bc resets native per-message voice/queued-voice state
|
||||||
_autoVoicePending = false; return pc + 1;
|
_autoVoicePending = false; return pc + 1;
|
||||||
case "set-text-history-recording": // 0x1bb: HISTORY.BIN suppresses recording its own UI
|
case "set-text-history-recording": // 0x1bb: HISTORY.BIN suppresses recording its own UI
|
||||||
if (Read(a[0]) is 0 or 1) TextHistory.SetRecordingEnabled(Read(a[0]) == 1);
|
if (Read(a[0]) is 0 or 1)
|
||||||
|
{
|
||||||
|
bool enabled = Read(a[0]) == 1;
|
||||||
|
TextHistory.SetRecordingEnabled(enabled);
|
||||||
|
if (enabled) _host.EndTextHistoryPresentation();
|
||||||
|
}
|
||||||
return pc + 1;
|
return pc + 1;
|
||||||
case "append-text-history-metadata": // 0x1d2: typed value attached to the current group
|
case "append-text-history-metadata": // 0x1d2: typed value attached to the current group
|
||||||
TextHistory.AppendMetadata(Read(a[0]), Read(a[1]), _advTextStyle); return pc + 1;
|
TextHistory.AppendMetadata(Read(a[0]), Read(a[1]), _advTextStyle); return pc + 1;
|
||||||
|
|||||||
@@ -149,6 +149,12 @@ public sealed class GodotAdvHost : IHost
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void EndTextHistoryPresentation()
|
||||||
|
{
|
||||||
|
lock (_textLock) _historyText.Clear();
|
||||||
|
_timeline?.Event("history-presentation-end");
|
||||||
|
}
|
||||||
|
|
||||||
public IReadOnlyList<AdvTextHistoryRenderBatch> SnapshotRenderedTextHistory()
|
public IReadOnlyList<AdvTextHistoryRenderBatch> SnapshotRenderedTextHistory()
|
||||||
{
|
{
|
||||||
lock (_textLock) return _historyText.Values.OrderBy(batch => batch.LayoutSlot).ToArray();
|
lock (_textLock) return _historyText.Values.OrderBy(batch => batch.LayoutSlot).ToArray();
|
||||||
|
|||||||
Reference in New Issue
Block a user