BankProject/Common/FixedQueue.cs
GabrielTofvesson 856e16b3f2 * Added support for artificial key event triggers
* Added OnClose event to view: triggered when controller is removing view from render queue
* Added more localization
* Added bank transfer
* Fixed account balance reset
* Fixed user copying issues in database: now it does a full deep copy, as opposed to a shallow copy
* Fixed serverside sysinsert checks
* Fixed serverside Account_Get info endpoint
* Other minor things
2018-05-15 18:57:49 +02:00

76 lines
2.5 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Tofvesson.Common
{
// A custom queue implementation with a fixed size
// Almost directly copied from https://gist.github.com/GabrielTofvesson/1cfbb659e7b2f7cfb6549c799b0864f3
public class FixedQueue<T> : IEnumerable<T>
{
protected readonly T[] queue;
protected int queueCount = 0;
protected int queueStart;
public int Count { get => queueCount; }
public FixedQueue(int maxSize)
{
queue = new T[maxSize];
queueStart = 0;
}
// Add an item to the queue
public bool Enqueue(T t)
{
queue[(queueStart + queueCount) % queue.Length] = t;
if (++queueCount > queue.Length)
{
--queueCount;
return true;
}
return false;
}
// Remove an item from the queue
public T Dequeue()
{
if (--queueCount == -1) throw new IndexOutOfRangeException("Cannot dequeue empty queue!");
T res = queue[queueStart];
queue[queueStart] = default(T); // Remove reference to item
queueStart = (queueStart + 1) % queue.Length;
return res;
}
// Indexing for the queue
public T ElementAt(int index) => queue[(queueStart + index) % queue.Length];
public virtual void Clear()
{
while (Count > 0) Dequeue();
}
// Enumeration
public virtual IEnumerator<T> GetEnumerator() => new QueueEnumerator<T>(this);
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
// Enumerator for this queue
public sealed class QueueEnumerator<K> : IEnumerator<K>
{
private int offset = -1;
private readonly FixedQueue<K> queue;
internal QueueEnumerator(FixedQueue<K> queue) => this.queue = queue;
object IEnumerator.Current => this.Current;
public K Current => offset == -1 ? default(K) : queue.ElementAt(offset); // Get current item or (null) if MoveNext() hasn't been called
public void Dispose() { } // NOP
public bool MoveNext() => offset < queue.Count && ++offset < queue.Count; // Increment index tracker (offset)
public void Reset() => offset = -1;
}
}
}