acdream/src/AcDream.App/Rendering/Wb/AcSurfaceMetadataTable.cs
Erik 46deed6019 phase(N.4): AcSurfaceMetadata side-table for WB-pristine surface props
Holds Translucency / Luminosity / Diffuse / SurfOpacity / NeedsUvRepeat /
DisableFog keyed by (gfxObjId, surfaceIdx). Populated at extraction time,
queried by the draw dispatcher. ConcurrentDictionary because mesh
extraction happens on background workers.

No fork patches required — keeps WB's MeshBatchData pristine.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-08 13:08:56 +02:00

27 lines
996 B
C#

using System.Collections.Concurrent;
namespace AcDream.App.Rendering.Wb;
/// <summary>
/// Thread-safe side-table mapping <c>(gfxObjId, surfaceIdx)</c> to
/// <see cref="AcSurfaceMetadata"/>. Populated when a GfxObj's mesh data
/// is extracted; queried at draw time.
///
/// <para>
/// Keyed by <c>(gfxObjId, surfaceIdx)</c> not by WB's runtime batch
/// identity because batch objects can be evicted and re-loaded by WB's
/// LRU; the (gfxObj, surface) pair is stable across cycles.
/// </para>
/// </summary>
public sealed class AcSurfaceMetadataTable
{
private readonly ConcurrentDictionary<(ulong gfxObjId, int surfaceIdx), AcSurfaceMetadata> _table = new();
public void Add(ulong gfxObjId, int surfaceIdx, AcSurfaceMetadata meta)
=> _table[(gfxObjId, surfaceIdx)] = meta;
public bool TryLookup(ulong gfxObjId, int surfaceIdx, out AcSurfaceMetadata meta)
=> _table.TryGetValue((gfxObjId, surfaceIdx), out meta!);
public void Clear() => _table.Clear();
}