yuanshen/Yuanshen.Kcp/KcpAcknowledgeList.cs
wisedev fc2ac1050f First working version of the server
KCP gameserver with packet dispatch, scene streaming, combat, gacha and the
shop, plus a small HTTP server for the login flow and the wish history page.

Game data under assets is pulled out of the client instead of being typed by
hand. The excel tables come from the packed bin container and the spawn points
from the compiled scene scripts.
2026-09-04 02:10:50 +03:00

104 lines
2.7 KiB
C#

using System.Runtime.CompilerServices;
namespace Yuanshen.Kcp
{
internal sealed class KcpAcknowledgeList
{
private readonly KcpSendQueue _sendQueue;
private (uint SerialNumber, uint Timestamp)[] _array;
private int _count;
private SpinLock _lock;
public KcpAcknowledgeList(KcpSendQueue sendQueue, int windowSize)
{
_array = new (uint SerialNumber, uint Timestamp)[windowSize];
_count = 0;
_lock = new SpinLock();
_sendQueue = sendQueue;
}
public bool TryGetAt(int index, out uint serialNumber, out uint timestamp)
{
bool lockTaken = false;
try
{
_lock.Enter(ref lockTaken);
if ((uint)index >= (uint)_count)
{
serialNumber = default;
timestamp = default;
return false;
}
(serialNumber, timestamp) = _array[index];
return true;
}
finally
{
if (lockTaken)
{
_lock.Exit();
}
}
}
public void Clear()
{
bool lockTaken = false;
try
{
_lock.Enter(ref lockTaken);
_count = 0;
}
finally
{
if (lockTaken)
{
_lock.Exit();
}
}
_sendQueue.NotifyAckListChanged(false);
}
public void Add(uint serialNumber, uint timestamp)
{
bool lockTaken = false;
try
{
_lock.Enter(ref lockTaken);
EnsureCapacity();
_array[_count++] = (serialNumber, timestamp);
}
finally
{
if (lockTaken)
{
_lock.Exit();
}
}
_sendQueue.NotifyAckListChanged(true);
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void EnsureCapacity()
{
if (_count == _array.Length)
{
Expand();
}
}
[MethodImpl(MethodImplOptions.NoInlining)]
private void Expand()
{
int capacity = _count + 1;
capacity = Math.Max(capacity + capacity / 2, 16);
var newArray = new (uint SerialNumber, uint Timestamp)[capacity];
_array.AsSpan(0, _count).CopyTo(newArray);
_array = newArray;
}
}
}