CircularBuffer.cs 2.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // #define RESET_REMOVED_ELEMENTS
  2. namespace IngameDebugConsole
  3. {
  4. public class CircularBuffer<T>
  5. {
  6. private T[] arr;
  7. private int startIndex;
  8. public int Count { get; private set; }
  9. public T this[int index] { get { return arr[( startIndex + index ) % arr.Length]; } }
  10. public CircularBuffer( int capacity )
  11. {
  12. arr = new T[capacity];
  13. }
  14. // Old elements are overwritten when capacity is reached
  15. public void Add( T value )
  16. {
  17. if( Count < arr.Length )
  18. arr[Count++] = value;
  19. else
  20. {
  21. arr[startIndex] = value;
  22. if( ++startIndex >= arr.Length )
  23. startIndex = 0;
  24. }
  25. }
  26. }
  27. public class DynamicCircularBuffer<T>
  28. {
  29. private T[] arr;
  30. private int startIndex;
  31. public int Count { get; private set; }
  32. public int Capacity { get { return arr.Length; } }
  33. public T this[int index]
  34. {
  35. get { return arr[( startIndex + index ) % arr.Length]; }
  36. set { arr[( startIndex + index ) % arr.Length] = value; }
  37. }
  38. public DynamicCircularBuffer( int initialCapacity = 2 )
  39. {
  40. arr = new T[initialCapacity];
  41. }
  42. public void Add( T value )
  43. {
  44. if( Count >= arr.Length )
  45. {
  46. int prevSize = arr.Length;
  47. int newSize = prevSize > 0 ? prevSize * 2 : 2; // Size must be doubled (at least), or the shift operation below must consider IndexOutOfRange situations
  48. System.Array.Resize( ref arr, newSize );
  49. if( startIndex > 0 )
  50. {
  51. if( startIndex <= ( prevSize - 1 ) / 2 )
  52. {
  53. // Move elements [0,startIndex) to the end
  54. for( int i = 0; i < startIndex; i++ )
  55. {
  56. arr[i + prevSize] = arr[i];
  57. #if RESET_REMOVED_ELEMENTS
  58. arr[i] = default( T );
  59. #endif
  60. }
  61. }
  62. else
  63. {
  64. // Move elements [startIndex,prevSize) to the end
  65. int delta = newSize - prevSize;
  66. for( int i = prevSize - 1; i >= startIndex; i-- )
  67. {
  68. arr[i + delta] = arr[i];
  69. #if RESET_REMOVED_ELEMENTS
  70. arr[i] = default( T );
  71. #endif
  72. }
  73. startIndex += delta;
  74. }
  75. }
  76. }
  77. this[Count++] = value;
  78. }
  79. public T RemoveFirst()
  80. {
  81. T element = arr[startIndex];
  82. #if RESET_REMOVED_ELEMENTS
  83. arr[startIndex] = default( T );
  84. #endif
  85. if( ++startIndex >= arr.Length )
  86. startIndex = 0;
  87. Count--;
  88. return element;
  89. }
  90. public T RemoveLast()
  91. {
  92. T element = arr[Count - 1];
  93. #if RESET_REMOVED_ELEMENTS
  94. arr[Count - 1] = default( T );
  95. #endif
  96. Count--;
  97. return element;
  98. }
  99. }
  100. }