126 lines
3.2 KiB
C#
126 lines
3.2 KiB
C#
// #define RESET_REMOVED_ELEMENTS
|
|
|
|
using System;
|
|
|
|
namespace IngameDebugConsole
|
|
{
|
|
public class CircularBuffer<T>
|
|
{
|
|
private readonly T[] arr;
|
|
private int startIndex;
|
|
|
|
public CircularBuffer(int capacity)
|
|
{
|
|
arr = new T[capacity];
|
|
}
|
|
|
|
public int Count { get; private set; }
|
|
public T this[int index] => arr[(startIndex + index) % arr.Length];
|
|
|
|
// Old elements are overwritten when capacity is reached
|
|
public void Add(T value)
|
|
{
|
|
if (Count < arr.Length)
|
|
{
|
|
arr[Count++] = value;
|
|
}
|
|
else
|
|
{
|
|
arr[startIndex] = value;
|
|
if (++startIndex >= arr.Length)
|
|
startIndex = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
public class DynamicCircularBuffer<T>
|
|
{
|
|
private T[] arr;
|
|
private int startIndex;
|
|
|
|
public DynamicCircularBuffer(int initialCapacity = 2)
|
|
{
|
|
arr = new T[initialCapacity];
|
|
}
|
|
|
|
public int Count { get; private set; }
|
|
public int Capacity => arr.Length;
|
|
|
|
public T this[int index]
|
|
{
|
|
get => arr[(startIndex + index) % arr.Length];
|
|
set => arr[(startIndex + index) % arr.Length] = value;
|
|
}
|
|
|
|
public void Add(T value)
|
|
{
|
|
if (Count >= arr.Length)
|
|
{
|
|
var prevSize = arr.Length;
|
|
var newSize =
|
|
prevSize > 0
|
|
? prevSize * 2
|
|
: 2; // Size must be doubled (at least), or the shift operation below must consider IndexOutOfRange situations
|
|
|
|
Array.Resize(ref arr, newSize);
|
|
|
|
if (startIndex > 0)
|
|
{
|
|
if (startIndex <= (prevSize - 1) / 2)
|
|
{
|
|
// Move elements [0,startIndex) to the end
|
|
for (var i = 0; i < startIndex; i++)
|
|
{
|
|
arr[i + prevSize] = arr[i];
|
|
#if RESET_REMOVED_ELEMENTS
|
|
arr[i] = default( T );
|
|
#endif
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// Move elements [startIndex,prevSize) to the end
|
|
var delta = newSize - prevSize;
|
|
for (var i = prevSize - 1; i >= startIndex; i--)
|
|
{
|
|
arr[i + delta] = arr[i];
|
|
#if RESET_REMOVED_ELEMENTS
|
|
arr[i] = default( T );
|
|
#endif
|
|
}
|
|
|
|
startIndex += delta;
|
|
}
|
|
}
|
|
}
|
|
|
|
this[Count++] = value;
|
|
}
|
|
|
|
public T RemoveFirst()
|
|
{
|
|
var element = arr[startIndex];
|
|
#if RESET_REMOVED_ELEMENTS
|
|
arr[startIndex] = default( T );
|
|
#endif
|
|
|
|
if (++startIndex >= arr.Length)
|
|
startIndex = 0;
|
|
|
|
Count--;
|
|
return element;
|
|
}
|
|
|
|
public T RemoveLast()
|
|
{
|
|
var index = (startIndex + Count - 1) % arr.Length;
|
|
var element = arr[index];
|
|
#if RESET_REMOVED_ELEMENTS
|
|
arr[index] = default( T );
|
|
#endif
|
|
|
|
Count--;
|
|
return element;
|
|
}
|
|
}
|
|
} |