perf(streaming): quiesce retired generations and budget teardown
Publish the retail blocking-for-cells edge before deferred recenter work, freeze old-world presentation/simulation/audio, and advance full-window retirement from exact metered entity and owner cursors. This removes synchronous portal teardown without allowing retained owners to remain observable.
This commit is contained in:
parent
b8f6317fe1
commit
bb16f74fd4
38 changed files with 1691 additions and 170 deletions
|
|
@ -56,6 +56,7 @@ public sealed class GpuWorldState : ILiveEntitySpatialQuery
|
|||
{
|
||||
private readonly LandblockSpawnAdapter? _wbSpawnAdapter;
|
||||
private readonly EntityScriptActivator? _entityScriptActivator;
|
||||
private readonly IWorldGenerationAvailability _availability;
|
||||
|
||||
/// <summary>
|
||||
/// Phase Post-A.5 #53 (Task 12): optional callback fired before
|
||||
|
|
@ -72,11 +73,13 @@ public sealed class GpuWorldState : ILiveEntitySpatialQuery
|
|||
public GpuWorldState(
|
||||
LandblockSpawnAdapter? wbSpawnAdapter = null,
|
||||
System.Action<uint>? onLandblockUnloaded = null,
|
||||
EntityScriptActivator? entityScriptActivator = null)
|
||||
EntityScriptActivator? entityScriptActivator = null,
|
||||
IWorldGenerationAvailability? availability = null)
|
||||
{
|
||||
_wbSpawnAdapter = wbSpawnAdapter;
|
||||
_onLandblockUnloaded = onLandblockUnloaded;
|
||||
_entityScriptActivator = entityScriptActivator;
|
||||
_availability = availability ?? AlwaysAvailableWorldGeneration.Instance;
|
||||
}
|
||||
|
||||
private readonly Dictionary<uint, LoadedLandblock> _loaded = new();
|
||||
|
|
@ -151,7 +154,9 @@ public sealed class GpuWorldState : ILiveEntitySpatialQuery
|
|||
_loaded.ContainsKey(landblockId)
|
||||
&& (_wbSpawnAdapter?.IsLandblockRenderReady(landblockId) ?? true);
|
||||
public bool IsLiveEntityVisible(uint serverGuid) =>
|
||||
serverGuid != 0 && _visibleLiveProjectionCounts.ContainsKey(serverGuid);
|
||||
_availability.IsWorldAvailable
|
||||
&& serverGuid != 0
|
||||
&& _visibleLiveProjectionCounts.ContainsKey(serverGuid);
|
||||
|
||||
/// <summary>
|
||||
/// Try to grab the loaded record for a landblock — useful for callers
|
||||
|
|
@ -217,6 +222,9 @@ public sealed class GpuWorldState : ILiveEntitySpatialQuery
|
|||
{
|
||||
get
|
||||
{
|
||||
if (!_availability.IsWorldAvailable)
|
||||
yield break;
|
||||
|
||||
foreach (var kvp in _loaded)
|
||||
{
|
||||
if (_aabbs.TryGetValue(kvp.Key, out var aabb))
|
||||
|
|
@ -232,6 +240,9 @@ public sealed class GpuWorldState : ILiveEntitySpatialQuery
|
|||
IReadOnlyDictionary<uint, WorldEntity>? AnimatedById)> EnumerateLandblockEntries(
|
||||
bool includeAnimatedIndex)
|
||||
{
|
||||
if (!_availability.IsWorldAvailable)
|
||||
yield break;
|
||||
|
||||
foreach (var kvp in _loaded)
|
||||
{
|
||||
IReadOnlyDictionary<uint, WorldEntity>? byId = null;
|
||||
|
|
@ -299,6 +310,8 @@ public sealed class GpuWorldState : ILiveEntitySpatialQuery
|
|||
ArgumentNullException.ThrowIfNull(destination);
|
||||
ArgumentOutOfRangeException.ThrowIfNegative(landblockRadius);
|
||||
destination.Clear();
|
||||
if (!_availability.IsWorldAvailable)
|
||||
return;
|
||||
|
||||
int centerX = (int)((centerCellOrLandblockId >> 24) & 0xFFu);
|
||||
int centerY = (int)((centerCellOrLandblockId >> 16) & 0xFFu);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue