fix(portal): synchronize destination presentation state

This commit is contained in:
Erik 2026-07-16 21:17:13 +02:00
parent 4b1bceefbb
commit e95f55f25b
42 changed files with 2815 additions and 288 deletions

View file

@ -143,23 +143,26 @@ public sealed class LandblockStreamer : IDisposable
/// <see cref="LandblockStreamResult.Loaded"/> (or
/// <see cref="LandblockStreamResult.Failed"/>) to the outbox.
/// </summary>
public void EnqueueLoad(uint landblockId, LandblockStreamJobKind kind = LandblockStreamJobKind.LoadNear)
public void EnqueueLoad(
uint landblockId,
LandblockStreamJobKind kind = LandblockStreamJobKind.LoadNear,
ulong generation = 0)
{
if (System.Threading.Volatile.Read(ref _disposed) != 0)
throw new ObjectDisposedException(nameof(LandblockStreamer));
AcDream.Core.Physics.PhysicsDiagnostics.LogTeleport("ENQ", landblockId, $"kind={kind}");
_inbox.Writer.TryWrite(new LandblockStreamJob.Load(landblockId, kind));
_inbox.Writer.TryWrite(new LandblockStreamJob.Load(landblockId, kind, generation));
}
/// <summary>
/// Non-blocking enqueue. The worker posts a
/// <see cref="LandblockStreamResult.Unloaded"/> to the outbox.
/// </summary>
public void EnqueueUnload(uint landblockId)
public void EnqueueUnload(uint landblockId, ulong generation = 0)
{
if (System.Threading.Volatile.Read(ref _disposed) != 0)
throw new ObjectDisposedException(nameof(LandblockStreamer));
_inbox.Writer.TryWrite(new LandblockStreamJob.Unload(landblockId));
_inbox.Writer.TryWrite(new LandblockStreamJob.Unload(landblockId, generation));
}
/// <summary>
@ -335,7 +338,7 @@ public sealed class LandblockStreamer : IDisposable
if (build is null)
{
_outbox.Writer.TryWrite(new LandblockStreamResult.Failed(
load.LandblockId, "LandblockLoader.Load returned null"));
load.LandblockId, "LandblockLoader.Load returned null", load.Generation));
break;
}
var lb = build.Landblock;
@ -345,18 +348,18 @@ public sealed class LandblockStreamer : IDisposable
if (promotedMesh is null)
{
_outbox.Writer.TryWrite(new LandblockStreamResult.Failed(
load.LandblockId, "buildMeshOrNull returned null"));
load.LandblockId, "buildMeshOrNull returned null", load.Generation));
break;
}
_outbox.Writer.TryWrite(new LandblockStreamResult.Promoted(
load.LandblockId, build, promotedMesh));
load.LandblockId, build, promotedMesh, load.Generation));
break;
}
var mesh = _buildMeshOrNull(load.LandblockId, lb);
if (mesh is null)
{
_outbox.Writer.TryWrite(new LandblockStreamResult.Failed(
load.LandblockId, "buildMeshOrNull returned null"));
load.LandblockId, "buildMeshOrNull returned null", load.Generation));
break;
}
var tier = load.Kind == LandblockStreamJobKind.LoadFar
@ -375,17 +378,19 @@ public sealed class LandblockStreamer : IDisposable
build = new LandblockBuild(lb);
}
_outbox.Writer.TryWrite(new LandblockStreamResult.Loaded(
load.LandblockId, tier, build, mesh));
load.LandblockId, tier, build, mesh, load.Generation));
}
catch (Exception ex)
{
_outbox.Writer.TryWrite(new LandblockStreamResult.Failed(
load.LandblockId, ex.ToString()));
load.LandblockId, ex.ToString(), load.Generation));
}
break;
case LandblockStreamJob.Unload unload:
_outbox.Writer.TryWrite(new LandblockStreamResult.Unloaded(unload.LandblockId));
_outbox.Writer.TryWrite(new LandblockStreamResult.Unloaded(
unload.LandblockId,
unload.Generation));
break;
}
}