acdream/tests/AcDream.Core.Tests/Streaming/GpuWorldStateTwoTierTests.cs
Erik fb10c3fa8c feat(A.5 T14): GpuWorldState RemoveEntitiesFromLandblock + AddEntitiesToExisting
Two new methods on GpuWorldState, used by two-tier streaming (T13):

- RemoveEntitiesFromLandblock(id): drop all entities from an LB while
  keeping the terrain. Used for Near->Far demote (player walks past the
  inner ring; LB stays loaded but entities leave).
- AddEntitiesToExistingLandblock(id, entities): merge new entities into
  an already-loaded LB record. Used for Far->Near promote (terrain is
  already on the GPU; just streaming the entity layer in).

Falls back to the pending bucket if the LB hasn't loaded yet.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-10 07:53:34 +02:00

76 lines
2.2 KiB
C#

using System.Linq;
using AcDream.App.Streaming;
using AcDream.Core.World;
using DatReaderWriter.DBObjs;
using Xunit;
namespace AcDream.Core.Tests.Streaming;
public class GpuWorldStateTwoTierTests
{
private static LoadedLandblock MakeStubLandblock(uint canonicalId, params WorldEntity[] entities)
=> new(canonicalId, new LandBlock(), entities);
private static WorldEntity MakeStubEntity(uint id)
=> new()
{
Id = id,
SourceGfxObjOrSetupId = 0x01000001u,
Position = System.Numerics.Vector3.Zero,
Rotation = System.Numerics.Quaternion.Identity,
MeshRefs = System.Array.Empty<MeshRef>(),
};
[Fact]
public void RemoveEntitiesFromLandblock_KeepsLandblockButDropsEntities()
{
var state = new GpuWorldState();
var lb = MakeStubLandblock(0xAAAAFFFFu,
MakeStubEntity(1),
MakeStubEntity(2));
state.AddLandblock(lb);
Assert.Equal(2, state.Entities.Count);
state.RemoveEntitiesFromLandblock(0xAAAAFFFFu);
Assert.Empty(state.Entities);
Assert.True(state.IsLoaded(0xAAAAFFFFu)); // landblock still resident
}
[Fact]
public void AddEntitiesToExistingLandblock_MergesIntoExistingRecord()
{
var state = new GpuWorldState();
var lb = MakeStubLandblock(0xAAAAFFFFu, MakeStubEntity(1));
state.AddLandblock(lb);
state.AddEntitiesToExistingLandblock(0xAAAAFFFFu, new[]
{
MakeStubEntity(2),
MakeStubEntity(3),
});
Assert.Equal(3, state.Entities.Count);
}
[Fact]
public void AddEntitiesToExistingLandblock_LandblockNotYetLoaded_ParksInPending()
{
var state = new GpuWorldState();
// Landblock not loaded yet.
state.AddEntitiesToExistingLandblock(0xAAAAFFFFu, new[]
{
MakeStubEntity(1),
MakeStubEntity(2),
});
// Nothing in the flat view yet.
Assert.Empty(state.Entities);
Assert.Equal(2, state.PendingLiveEntityCount);
// Now load the landblock — pending entities should merge in.
state.AddLandblock(MakeStubLandblock(0xAAAAFFFFu));
Assert.Equal(2, state.Entities.Count);
}
}