using System.Buffers; namespace AcDream.Core.Physics; /// /// Pooled, mutation-stable snapshot of a cell's live shadow entries. /// Nested collision resolution can update the registry while the outer /// transition is still walking the cell, so the captured count and entries /// must remain fixed for the lifetime of that walk. /// internal ref struct ShadowEntrySnapshot { private ShadowEntry[]? _buffer; private readonly int _count; private ShadowEntrySnapshot(ShadowEntry[] buffer, int count) { _buffer = buffer; _count = count; } public readonly ReadOnlySpan Entries => _buffer.AsSpan(0, _count); public static ShadowEntrySnapshot Capture(IReadOnlyList source) { int count = source.Count; ShadowEntry[] buffer = ArrayPool.Shared.Rent(count); try { for (int i = 0; i < count; i++) buffer[i] = source[i]; return new ShadowEntrySnapshot(buffer, count); } catch { ArrayPool.Shared.Return(buffer, clearArray: false); throw; } } public void Dispose() { ShadowEntry[]? buffer = _buffer; _buffer = null; if (buffer is not null) { // ShadowEntry is a value-only record struct, so the pooled buffer // cannot retain references to live entities or renderer state. ArrayPool.Shared.Return(buffer, clearArray: false); } } }