WbMeshAdapter now actually constructs the WB pipeline: - OpenGLGraphicsDevice(gl, logger, DebugRenderSettings) - DefaultDatReaderWriter(datDir) — opens its own file handles for now (memory cost ~50-100MB of duplicate index caches, acceptable for foundation work per plan Adjustment 1) - ObjectMeshManager(graphicsDevice, dats, NullLogger) InstancedMeshRenderer.EnsureUploaded routes through the adapter when ACDREAM_USE_WB_FOUNDATION=1 is set; uses a WbManagedSentinel entry in the local cache to mark "this GfxObj lives in WB now". CollectGroups skips sentinel entries; both Draw passes skip them; Dispose skips them (no GL resources to free — ObjectMeshManager owns those). Task 22's WbDrawDispatcher will eventually draw WB-managed objects. With flag off, behavior is byte-identical to before. WbMeshAdapter constructor signature changed from (GL, DatCollection, Logger) to (GL, string datDir, Logger). Updated tests to use CreateUninitialized() for behavior tests and single null-GL guard test for constructor validation. GameWindow updated to pass _datDir and to wire _wbMeshAdapter into InstancedMeshRenderer. AcDream.App.csproj gets direct ProjectReferences to WorldBuilder.Shared and Chorizite.OpenGLSDLBackend — project refs are not transitive in .NET, so AcDream.App must list them explicitly even though AcDream.Core already references them. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
49 lines
1.6 KiB
C#
49 lines
1.6 KiB
C#
using System;
|
|
using AcDream.App.Rendering.Wb;
|
|
using Microsoft.Extensions.Logging.Abstractions;
|
|
using Silk.NET.OpenGL;
|
|
|
|
namespace AcDream.Core.Tests.Rendering.Wb;
|
|
|
|
public sealed class WbMeshAdapterTests
|
|
{
|
|
[Fact]
|
|
public void Construct_WithNullGl_ThrowsArgumentNull()
|
|
{
|
|
// GL is the first guarded parameter; verifies the constructor validates inputs.
|
|
// We can't pass a real GL (no context in tests), so we verify only the
|
|
// null-GL guard. The real pipeline is tested via integration.
|
|
Assert.Throws<ArgumentNullException>(() =>
|
|
new WbMeshAdapter(gl: null!, datDir: "some/path", logger: NullLogger<WbMeshAdapter>.Instance));
|
|
}
|
|
|
|
[Fact]
|
|
public void Dispose_OnUninitializedAdapter_DoesNotThrow()
|
|
{
|
|
var adapter = WbMeshAdapter.CreateUninitialized();
|
|
adapter.Dispose(); // no-op when fields are null
|
|
adapter.Dispose(); // idempotent
|
|
}
|
|
|
|
[Fact]
|
|
public void IncrementRefCount_OnUninitializedAdapter_NoOps()
|
|
{
|
|
var adapter = WbMeshAdapter.CreateUninitialized();
|
|
// Should not throw, even though there's no underlying mesh manager.
|
|
adapter.IncrementRefCount(0x01000001ul);
|
|
}
|
|
|
|
[Fact]
|
|
public void DecrementRefCount_OnUninitializedAdapter_NoOps()
|
|
{
|
|
var adapter = WbMeshAdapter.CreateUninitialized();
|
|
adapter.DecrementRefCount(0x01000001ul);
|
|
}
|
|
|
|
[Fact]
|
|
public void GetRenderData_OnUninitializedAdapter_ReturnsNull()
|
|
{
|
|
var adapter = WbMeshAdapter.CreateUninitialized();
|
|
Assert.Null(adapter.GetRenderData(0x01000001ul));
|
|
}
|
|
}
|