diag(render): #105 round 3 — finalize-replace + late-register tripwires on EnvCellRenderer
Live evidence narrowed #105 to the pending->committed instance hand-off: walls missing from BOTH inside and outside views while the same cells'' props draw and collision works = the wall-shell INSTANCES never reach the committed draw set. FinalizeLandblock uses REPLACE semantics (lb.Instances = lb.PendingInstances), and with two-tier streaming a landblock can finalize while a promote job is still registering its cells on the worker thread — the partial pending set commits, the remainder lands in a fresh pending list, and the next finalize REPLACES the committed set with only the remainder. Whoever registered first is silently lost: per-session-random (drain timing), per-building-persistent, from session start. - [finalize-replace] a finalize that DISCARDS already-committed instances - [late-register] a RegisterCell landing after its landblock finalized Both print only on the suspect interleavings. Next occurrence proves or kills the theory; the fix (merge semantics + registration/finalize atomicity) follows the evidence. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
parent
cbba71f8a9
commit
0a38d934fd
1 changed files with 13 additions and 0 deletions
|
|
@ -349,6 +349,12 @@ public sealed unsafe class EnvCellRenderer : IDisposable
|
|||
|
||||
lock (lb.Lock)
|
||||
{
|
||||
// TEMP diagnostic #105 (strip with fix): a registration landing AFTER
|
||||
// this landblock was already finalized starts a fresh pending list that
|
||||
// only commits if ANOTHER finalize arrives — and that one will REPLACE
|
||||
// (not merge) the committed set. One-shot per landblock per pending list.
|
||||
if (lb.InstancesReady && lb.PendingInstances is null)
|
||||
Console.WriteLine($"[late-register] lb=0x{landblockId:X8} cell=0x{envCellId:X8} registered AFTER finalize — starting a new pending list ({(lb.Instances?.Count ?? 0)} already committed)");
|
||||
lb.PendingInstances ??= new List<EnvCellSceneryInstance>(capacity: 32);
|
||||
lb.PendingInstances.Add(cellInstance);
|
||||
lb.PendingEnvCellBounds ??= new Dictionary<uint, WbBoundingBox>();
|
||||
|
|
@ -403,6 +409,13 @@ public sealed unsafe class EnvCellRenderer : IDisposable
|
|||
{
|
||||
if (lb.PendingInstances is not null)
|
||||
{
|
||||
// TEMP diagnostic #105 (strip with fix): REPLACE semantics — if a
|
||||
// previous finalize already committed instances for this landblock,
|
||||
// this swap DISCARDS them in favor of the new pending set. A partial
|
||||
// pending set (finalize racing a still-registering promote job)
|
||||
// silently loses buildings.
|
||||
if (lb.Instances is { Count: > 0 })
|
||||
Console.WriteLine($"[finalize-replace] lb=0x{landblockId:X8} DISCARDING {lb.Instances.Count} committed instances, replacing with {lb.PendingInstances.Count} pending");
|
||||
lb.Instances = lb.PendingInstances;
|
||||
lb.PendingInstances = null;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue