phase(N.4) Task 12: wire LandblockSpawnAdapter into GpuWorldState
GpuWorldState's constructor accepts an optional LandblockSpawnAdapter. AddLandblock calls OnLandblockLoaded with the post-merge loaded record; RemoveLandblock calls OnLandblockUnloaded with the landblock id at the top of the method (before state mutation). Both calls are gated behind WbFoundationFlag.IsEnabled — no behavioral change with flag off (existing tests pass without modification). GameWindow constructs the adapter under the flag and threads it into GpuWorldState. With flag on, atlas-tier scenery now drives WB ref counts; per-instance entities (ServerGuid != 0) are filtered out by the adapter and don't reach WB. Foundation for Task 13 (memory budget verification under stress). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
669768d9da
commit
931a690c4c
2 changed files with 25 additions and 1 deletions
|
|
@ -65,7 +65,7 @@ public sealed class GameWindow : IDisposable
|
||||||
|
|
||||||
// Phase A.1: streaming fields replacing the one-shot _entities list.
|
// Phase A.1: streaming fields replacing the one-shot _entities list.
|
||||||
private AcDream.App.Streaming.LandblockStreamer? _streamer;
|
private AcDream.App.Streaming.LandblockStreamer? _streamer;
|
||||||
private readonly AcDream.App.Streaming.GpuWorldState _worldState = new();
|
private AcDream.App.Streaming.GpuWorldState _worldState = new();
|
||||||
private AcDream.App.Streaming.StreamingController? _streamingController;
|
private AcDream.App.Streaming.StreamingController? _streamingController;
|
||||||
private int _streamingRadius = 2; // default 5×5
|
private int _streamingRadius = 2; // default 5×5
|
||||||
private uint? _lastLivePlayerLandblockId;
|
private uint? _lastLivePlayerLandblockId;
|
||||||
|
|
@ -1438,6 +1438,17 @@ public sealed class GameWindow : IDisposable
|
||||||
Console.WriteLine("[N.4] WbFoundation flag is ENABLED — routing static content through ObjectMeshManager.");
|
Console.WriteLine("[N.4] WbFoundation flag is ENABLED — routing static content through ObjectMeshManager.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Phase N.4 Task 12: construct LandblockSpawnAdapter under the feature flag
|
||||||
|
// and rebuild _worldState so it threads the adapter in. _worldState starts
|
||||||
|
// as an unadorned GpuWorldState (field initializer); here we replace it with
|
||||||
|
// one that carries the adapter so AddLandblock/RemoveLandblock notify WB.
|
||||||
|
{
|
||||||
|
AcDream.App.Rendering.Wb.LandblockSpawnAdapter? wbSpawnAdapter = null;
|
||||||
|
if (AcDream.App.Rendering.Wb.WbFoundationFlag.IsEnabled && _wbMeshAdapter is not null)
|
||||||
|
wbSpawnAdapter = new AcDream.App.Rendering.Wb.LandblockSpawnAdapter(_wbMeshAdapter);
|
||||||
|
_worldState = new AcDream.App.Streaming.GpuWorldState(wbSpawnAdapter);
|
||||||
|
}
|
||||||
|
|
||||||
_staticMesh = new InstancedMeshRenderer(_gl, _meshShader, _textureCache, _wbMeshAdapter);
|
_staticMesh = new InstancedMeshRenderer(_gl, _meshShader, _textureCache, _wbMeshAdapter);
|
||||||
|
|
||||||
// Phase G.1 sky renderer — its own shader (sky.vert / sky.frag)
|
// Phase G.1 sky renderer — its own shader (sky.vert / sky.frag)
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Numerics;
|
using System.Numerics;
|
||||||
|
using AcDream.App.Rendering.Wb;
|
||||||
using AcDream.Core.World;
|
using AcDream.Core.World;
|
||||||
|
|
||||||
namespace AcDream.App.Streaming;
|
namespace AcDream.App.Streaming;
|
||||||
|
|
@ -38,6 +39,13 @@ namespace AcDream.App.Streaming;
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed class GpuWorldState
|
public sealed class GpuWorldState
|
||||||
{
|
{
|
||||||
|
private readonly LandblockSpawnAdapter? _wbSpawnAdapter;
|
||||||
|
|
||||||
|
public GpuWorldState(LandblockSpawnAdapter? wbSpawnAdapter = null)
|
||||||
|
{
|
||||||
|
_wbSpawnAdapter = wbSpawnAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
private readonly Dictionary<uint, LoadedLandblock> _loaded = new();
|
private readonly Dictionary<uint, LoadedLandblock> _loaded = new();
|
||||||
private readonly Dictionary<uint, (Vector3 Min, Vector3 Max)> _aabbs = new();
|
private readonly Dictionary<uint, (Vector3 Min, Vector3 Max)> _aabbs = new();
|
||||||
|
|
||||||
|
|
@ -132,6 +140,8 @@ public sealed class GpuWorldState
|
||||||
}
|
}
|
||||||
|
|
||||||
_loaded[landblock.LandblockId] = landblock;
|
_loaded[landblock.LandblockId] = landblock;
|
||||||
|
if (WbFoundationFlag.IsEnabled && _wbSpawnAdapter is not null)
|
||||||
|
_wbSpawnAdapter.OnLandblockLoaded(_loaded[landblock.LandblockId]);
|
||||||
RebuildFlatView();
|
RebuildFlatView();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -181,6 +191,9 @@ public sealed class GpuWorldState
|
||||||
|
|
||||||
public void RemoveLandblock(uint landblockId)
|
public void RemoveLandblock(uint landblockId)
|
||||||
{
|
{
|
||||||
|
if (WbFoundationFlag.IsEnabled && _wbSpawnAdapter is not null)
|
||||||
|
_wbSpawnAdapter.OnLandblockUnloaded(landblockId);
|
||||||
|
|
||||||
// Rescue persistent entities before removal. These get appended
|
// Rescue persistent entities before removal. These get appended
|
||||||
// to the _persistentRescued list; the caller is responsible for
|
// to the _persistentRescued list; the caller is responsible for
|
||||||
// re-injecting them (via AppendLiveEntity) into whatever landblock
|
// re-injecting them (via AppendLiveEntity) into whatever landblock
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue