feat(streaming): PhysicsDatBundle on LoadedLandblock (datLock fix scaffold)
Carries the parsed dat objects ApplyLoadedTerrainLocked needs so the worker can pre-read them and the apply can run lock-free. Optional field (default null) keeps existing LoadedLandblock construction back-compatible. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
5ab5d3910e
commit
3a0e349c6e
3 changed files with 50 additions and 1 deletions
|
|
@ -5,4 +5,5 @@ namespace AcDream.Core.World;
|
||||||
public sealed record LoadedLandblock(
|
public sealed record LoadedLandblock(
|
||||||
uint LandblockId,
|
uint LandblockId,
|
||||||
LandBlock Heightmap,
|
LandBlock Heightmap,
|
||||||
IReadOnlyList<WorldEntity> Entities);
|
IReadOnlyList<WorldEntity> Entities,
|
||||||
|
PhysicsDatBundle? PhysicsDats = null);
|
||||||
|
|
|
||||||
30
src/AcDream.Core/World/PhysicsDatBundle.cs
Normal file
30
src/AcDream.Core/World/PhysicsDatBundle.cs
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using DatReaderWriter.DBObjs;
|
||||||
|
// Environment collides with System.Environment under implicit usings — alias it.
|
||||||
|
using DatEnvironment = DatReaderWriter.DBObjs.Environment;
|
||||||
|
|
||||||
|
namespace AcDream.Core.World;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The parsed dat objects <c>ApplyLoadedTerrainLocked</c> needs, pre-read by the
|
||||||
|
/// streaming worker under <c>_datLock</c> so the apply makes ZERO DatCollection
|
||||||
|
/// calls and the update thread never blocks on the worker's lock (the FPS
|
||||||
|
/// 30↔200 swing was that lock-wait). Keyed by the same dat id the apply would
|
||||||
|
/// have passed to <c>_dats.Get<T></c>.
|
||||||
|
/// </summary>
|
||||||
|
public sealed record PhysicsDatBundle(
|
||||||
|
LandBlockInfo? Info,
|
||||||
|
IReadOnlyDictionary<uint, EnvCell> EnvCells,
|
||||||
|
IReadOnlyDictionary<uint, DatEnvironment> Environments,
|
||||||
|
IReadOnlyDictionary<uint, Setup> Setups,
|
||||||
|
IReadOnlyDictionary<uint, GfxObj> GfxObjs)
|
||||||
|
{
|
||||||
|
/// <summary>Empty bundle for far-tier landblocks (no cells / buildings /
|
||||||
|
/// entities) and for non-streaming <see cref="LoadedLandblock"/> construction.</summary>
|
||||||
|
public static readonly PhysicsDatBundle Empty = new(
|
||||||
|
null,
|
||||||
|
new Dictionary<uint, EnvCell>(),
|
||||||
|
new Dictionary<uint, DatEnvironment>(),
|
||||||
|
new Dictionary<uint, Setup>(),
|
||||||
|
new Dictionary<uint, GfxObj>());
|
||||||
|
}
|
||||||
18
tests/AcDream.Core.Tests/World/PhysicsDatBundleTests.cs
Normal file
18
tests/AcDream.Core.Tests/World/PhysicsDatBundleTests.cs
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
using AcDream.Core.World;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace AcDream.Core.Tests.World;
|
||||||
|
|
||||||
|
public class PhysicsDatBundleTests
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public void Empty_ReturnsNullInfoAndEmptyMaps()
|
||||||
|
{
|
||||||
|
var b = PhysicsDatBundle.Empty;
|
||||||
|
Assert.Null(b.Info);
|
||||||
|
Assert.Empty(b.EnvCells);
|
||||||
|
Assert.Empty(b.Environments);
|
||||||
|
Assert.Empty(b.Setups);
|
||||||
|
Assert.Empty(b.GfxObjs);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue