using System; using UnityEngine; namespace Leap.Unity.Graphing { public class RingBuffer { public RingBuffer(int minCapacity = 8) { if (minCapacity <= 0) { throw new ArgumentException("Capacity must be positive and nonzero."); } int num = Mathf.ClosestPowerOfTwo(minCapacity); if (num < minCapacity) { num *= 2; } this._array = new T[num]; this.recalculateIndexMask(); this._front = 0U; this._count = 0U; } public int Count { get { return (int)this._count; } } public void Clear() { if (this._count != 0U) { Array.Clear(this._array, 0, this._array.Length); this._front = 0U; this._count = 0U; } } public void PushBack(T t) { this.doubleCapacityIfFull(); this._count += 1U; this._array[(int)((UIntPtr)this.getBackIndex())] = t; } public void PushFront(T t) { this.doubleCapacityIfFull(); this._count += 1U; this._front = (this._front - 1U & this._indexMask); this._array[(int)((UIntPtr)this._front)] = t; } public void PopBack() { this.checkForEmpty("pop back"); this._array[(int)((UIntPtr)this.getBackIndex())] = default(T); this._count -= 1U; } public void PopFront() { this.checkForEmpty("pop front"); this._array[(int)((UIntPtr)this._front)] = default(T); this._count -= 1U; this._front = (this._front + 1U & this._indexMask); } public void PopBack(out T back) { this.checkForEmpty("pop back"); uint backIndex = this.getBackIndex(); back = this._array[(int)((UIntPtr)backIndex)]; this._array[(int)((UIntPtr)backIndex)] = default(T); this._count -= 1U; } public void PopFront(out T front) { this.checkForEmpty("pop front"); front = this._array[(int)((UIntPtr)this._front)]; this._array[(int)((UIntPtr)this._front)] = default(T); this._front = (this._front + 1U & this._indexMask); this._count -= 1U; } public T Front { get { this.checkForEmpty("get front"); return this._array[(int)((UIntPtr)this._front)]; } set { this.checkForEmpty("set front"); this._array[(int)((UIntPtr)this._front)] = value; } } public T Back { get { this.checkForEmpty("get back"); return this._array[(int)((UIntPtr)this.getBackIndex())]; } set { this.checkForEmpty("set back"); this._array[(int)((UIntPtr)this.getBackIndex())] = value; } } public T this[int index] { get { this.checkForValidIndex((uint)index); return this._array[(int)((UIntPtr)this.getIndex((uint)index))]; } set { this.checkForValidIndex((uint)index); this._array[(int)((UIntPtr)this.getIndex((uint)index))] = value; } } public string ToDebugString() { string str = "["; uint backIndex = this.getBackIndex(); uint num = 0U; while ((ulong)num < (ulong)((long)this._array.Length)) { bool flag; if (this._count == 0U) { flag = true; } else if (this._count == 1U) { flag = (num != this._front); } else if (this._front < backIndex) { flag = (num < this._front || num > backIndex); } else { flag = (num < this._front && num > backIndex); } string text = string.Empty; if (num == this._front) { text = "{"; } else { text = " "; } if (flag) { text += "."; } else { text += this._array[(int)((UIntPtr)num)].ToString(); } if (num == backIndex) { text += "}"; } else { text += " "; } str += text; num += 1U; } return str + "]"; } private uint getBackIndex() { return this._front + this._count - 1U & this._indexMask; } private uint getIndex(uint index) { return this._front + index & this._indexMask; } private void doubleCapacityIfFull() { if ((ulong)this._count >= (ulong)((long)this._array.Length)) { T[] array = new T[this._array.Length * 2]; uint backIndex = this.getBackIndex(); if (this._front <= backIndex) { Array.Copy(this._array, (long)((ulong)this._front), array, 0L, (long)((ulong)this._count)); } else { uint num = (uint)(this._array.Length - (int)this._front); Array.Copy(this._array, (long)((ulong)this._front), array, 0L, (long)((ulong)num)); Array.Copy(this._array, 0L, array, (long)((ulong)num), (long)((ulong)(this._count - num))); } this._front = 0U; this._array = array; this.recalculateIndexMask(); } } private void recalculateIndexMask() { this._indexMask = (uint)(this._array.Length - 1); } private void checkForValidIndex(uint index) { if (index >= this._count) { throw new IndexOutOfRangeException(string.Concat(new object[] { "The index ", index, " was out of range for the RingBuffer with size ", this._count, "." })); } } private void checkForEmpty(string actionName) { if (this._count == 0U) { throw new InvalidOperationException("Cannot " + actionName + " because the RingBuffer is empty."); } } private T[] _array; private uint _front; private uint _count; private uint _indexMask; } }