123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256 |
- using System;
- using UnityEngine;
- namespace Leap.Unity.Graphing
- {
- public class RingBuffer<T>
- {
- 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;
- }
- }
|