feat(render) Campaign FW1: the walk event vocabulary

WalkEvent mirrors the FW0 oracle-trace vocabulary one-to-one (Landscape,
Building, DrawInside, DrawCells) as the conformance surface RetailFrameWalk
emits; the FW2 ordered draw stream layers on later without changing it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Erik 2026-08-30 09:36:51 +02:00
parent d1fc4a0986
commit 0926b55eaf

View file

@ -0,0 +1,58 @@
namespace AcDream.App.Rendering.Walk;
/// <summary>
/// Campaign FW1 — the frame walk's observable event stream. These events
/// mirror the FW0 oracle-trace vocabulary one-to-one
/// (docs/research/2026-08-30-fw-walk-oracle/README.md): the conformance
/// contract is that <c>RetailFrameWalk</c>, fed the same world state and
/// camera pose as a capture, emits the identical sequence. Richer draw
/// commands (mesh/state/stage tuples for the FW2 ordered stream) layer on
/// later; this vocabulary stays the conformance surface.
/// </summary>
public enum WalkEventKind
{
/// <summary><c>LScape::draw</c> @0x00506330 ran (outdoor root, or drawn
/// through an interior frame's exit views).</summary>
Landscape,
/// <summary><c>RenderDeviceD3D::DrawBuilding</c> @0x0059f2a0 entered for
/// one building (identified by its position cell id).</summary>
Building,
/// <summary><c>PView::DrawInside</c> @0x005a5860 entered — the frame is
/// rooted at this interior cell.</summary>
DrawInside,
/// <summary><c>PView::DrawCells</c> @0x005a4840 entered with the flood's
/// cell list (far-to-near iteration happens inside; the event carries the
/// list in storage order, matching the oracle dump).</summary>
DrawCells,
}
public readonly record struct WalkEvent(
WalkEventKind Kind,
uint CellId,
int OutsideViewCount,
IReadOnlyList<uint> Cells)
{
public static WalkEvent Landscape()
=> new(WalkEventKind.Landscape, 0, 0, Array.Empty<uint>());
public static WalkEvent Building(uint positionCellId)
=> new(WalkEventKind.Building, positionCellId, 0, Array.Empty<uint>());
public static WalkEvent DrawInside(uint cellId)
=> new(WalkEventKind.DrawInside, cellId, 0, Array.Empty<uint>());
public static WalkEvent DrawCells(int outsideViewCount, IReadOnlyList<uint> cells)
=> new(WalkEventKind.DrawCells, 0, outsideViewCount, cells);
}
/// <summary>
/// The sink a walk emits into. FW1 conformance tests collect events; FW2's
/// production sink will additionally receive the ordered draw stream.
/// </summary>
public interface IWalkEventSink
{
void Emit(in WalkEvent walkEvent);
}