ParadoxSaveParser/ParadoxSaveParser.Lib/BufferedEnumerator.cs

83 lines
2.2 KiB
C#

using System.Collections;
namespace ParadoxSaveParser.Lib;
/// <summary>
/// Enumerator wrapper that stores <c>N/2</c> items before and <c>N/2-1</c> after <c>Current</c> item.
/// </summary>
/// <code language="cs">
/// IEnumerator&lt;int&gt; Enumerator()
/// {
/// for(int i = 0; i &lt; 6; i++)
/// yield return i;
/// }
///
/// var en = Enumerator();
/// var bufen = new BufferedEnumerator&lt;int&gt;(en, 5);
///
/// while(bufen.MoveNext())
/// {
/// var cur = bufen.Current;
/// for (var prev = cur.List?.First; prev != cur; prev = prev?.Next)
/// Console.Write($"{prev?.Value} ");
///
/// Console.Write($"| {cur.Value} |");
///
/// for (var next = cur.Next; next is not null; next = next.Next)
/// Console.Write($" {next.Value}");
/// Console.WriteLine();
/// }
/// </code>
/// Output:
/// <code>
/// | 0 | 1 2 3 4
/// 0 | 1 | 2 3 4
/// 0 1 | 2 | 3 4
/// 1 2 | 3 | 4 5
/// 2 3 | 4 | 5
/// 3 4 | 5 |
/// </code>
public class BufferedEnumerator<T> : IEnumerator<LinkedListNode<T>>
{
private IEnumerator<T> _enumerator;
private int _bufferSize;
LinkedList<T> _llist = new();
private LinkedListNode<T>? _currentNode;
private int _currentNodeIndex = -1;
public BufferedEnumerator(IEnumerator<T> enumerator, int bufferSize)
{
_enumerator = enumerator;
_bufferSize = bufferSize;
}
public bool MoveNext()
{
if(_currentNodeIndex >= _bufferSize / 2)
_llist.RemoveFirst();
while (_llist.Count < _bufferSize && _enumerator.MoveNext())
{
_llist.AddLast(_enumerator.Current);
}
if (_llist.Count == 0)
return false;
_currentNodeIndex++;
_currentNode = _currentNode is null ? _llist.First : _currentNode.Next;
return _currentNode is not null;
}
public void Reset()
{
throw new NotImplementedException();
}
public LinkedListNode<T> Current => _currentNode!;
object IEnumerator.Current => Current;
public void Dispose()
{
}
}