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);
}
}
}