71 lines
1.8 KiB
C#
71 lines
1.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace ClipForge
|
|
{
|
|
public class RingBuffer<T>
|
|
{
|
|
private readonly T[] _buffer;
|
|
private readonly int _capacity;
|
|
private int _head; // where the next write goes
|
|
private int _count; // how many slots are filled
|
|
private readonly object _lock = new object();
|
|
|
|
public RingBuffer(int capacity)
|
|
{
|
|
_capacity = capacity;
|
|
_buffer = new T[capacity];
|
|
_head = 0;
|
|
_count = 0;
|
|
}
|
|
|
|
// Write a new item into the buffer
|
|
public void Write(T item)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_buffer[_head] = item;
|
|
_head = (_head + 1) % _capacity;
|
|
if (_count < _capacity)
|
|
_count++;
|
|
}
|
|
}
|
|
|
|
// Read the last N items in chronological order
|
|
public List<T> ReadLast(int count)
|
|
{
|
|
lock (_lock)
|
|
{
|
|
// Can't read more than we have
|
|
int available = Math.Min(count, _count);
|
|
var result = new List<T>(available);
|
|
|
|
// Work backwards from the most recent write
|
|
int start = (_head - available + _capacity) % _capacity;
|
|
|
|
for (int i = 0; i < available; i++)
|
|
{
|
|
result.Add(_buffer[(start + i) % _capacity]);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
}
|
|
|
|
// How many items are currently stored
|
|
public int Count
|
|
{
|
|
get { lock (_lock) { return _count; } }
|
|
}
|
|
|
|
// Empty the buffer
|
|
public void Clear()
|
|
{
|
|
lock (_lock)
|
|
{
|
|
_head = 0;
|
|
_count = 0;
|
|
}
|
|
}
|
|
}
|
|
} |