< Summary

Class:GDX.Collections.Generic.CircularBuffer[T]
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/Collections/Generic/CircularBuffer.cs
Covered lines:84
Uncovered lines:49
Coverable lines:133
Total lines:311
Line coverage:63.1% (84 of 133)
Covered branches:0
Total branches:0
Covered methods:14
Total methods:15
Method coverage:93.3% (14 of 15)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
CircularBuffer(...)0%4.134080%
CircularBuffer(...)0%42600%
Add(...)0%110100%
Clear()0%220100%
GetBack()0%330100%
GetFront()0%110100%
IsEmpty()0%110100%
IsFull()0%110100%
PopBack()0%2.152066.67%
PopFront()0%2.212062.5%
PushBack(...)0%4.064084.21%
PushFront(...)0%6.984042.86%
ToArray()0%4.964060.87%

File(s)

./Packages/com.dotbunny.gdx/GDX/Collections/Generic/CircularBuffer.cs

#LineLine coverage
 1// Copyright (c) 2020-2024 dotBunny Inc.
 2// dotBunny licenses this file to you under the BSL-1.0 license.
 3// See the LICENSE file in the project root for more information.
 4
 5using System;
 6using System.Runtime.CompilerServices;
 7
 8namespace GDX.Collections.Generic
 9{
 10    /// <summary>
 11    ///     A sized buffer which loops back over itself as elements are used.
 12    /// </summary>
 13    /// <typeparam name="T">The type of <see cref="object" />s contained within.</typeparam>
 14    [VisualScriptingCompatible(1)]
 15    public struct CircularBuffer<T>
 16    {
 17        /// <summary>
 18        ///     Internal array of backed data for the <see cref="CircularBuffer{T}" />.
 19        /// </summary>
 20        public readonly T[] Array;
 21
 22        /// <summary>
 23        ///     The cached array length for <see cref="Array" />.
 24        /// </summary>
 25        public readonly int Capacity;
 26
 27        /// <summary>
 28        ///     The current size of occupied elements in the <see cref="CircularBuffer{T}" />.
 29        /// </summary>
 30        /// <remarks>CAUTION! Changing this will alter the understanding of the data.</remarks>
 31        public int Count;
 32
 33        /// <summary>
 34        ///     The index of the last item in <see cref="Array" />.
 35        /// </summary>
 36        /// <remarks>CAUTION! Changing this will alter the understanding of the data.</remarks>
 37        public int EndIndex;
 38
 39        /// <summary>
 40        ///     The index of the first item in <see cref="Array" />.
 41        /// </summary>
 42        /// <remarks>CAUTION! Changing this will alter the understanding of the data.</remarks>
 43        public int StartIndex;
 44
 45        /// <summary>
 46        ///     Create a <see cref="CircularBuffer{T}" /> with a <paramref name="capacity" />.
 47        /// </summary>
 48        /// <param name="capacity">The maximum number of items allowed in the <see cref="CircularBuffer{T}" /></param>
 49        public CircularBuffer(int capacity)
 2450        {
 2451            if (capacity < 1)
 052            {
 053                throw new ArgumentException("Circular buffer cannot have negative or zero capacity.", nameof(capacity));
 54            }
 55
 2456            Array = new T[capacity];
 2457            Capacity = capacity;
 58
 2459            Count = 0;
 60
 2461            StartIndex = 0;
 2462            EndIndex = Count == capacity ? 0 : Count;
 2463        }
 64
 65        /// <summary>
 66        ///     Create a <see cref="CircularBuffer{T}" /> with a <paramref name="capacity" />, filling with
 67        ///     <paramref name="targetItems" />.
 68        /// </summary>
 69        /// <param name="capacity">The maximum number of items allowed in the <see cref="CircularBuffer{T}" /></param>
 70        /// <param name="targetItems">An array of values to fill the <see cref="CircularBuffer{T}" /> with.</param>
 71        /// <exception cref="ArgumentException">
 72        ///     Invalid number of entries provided to the <see cref="CircularBuffer{T}" />
 73        ///     constructor.
 74        /// </exception>
 75        /// <exception cref="ArgumentNullException">No items were provided to the <see cref="CircularBuffer{T}" /> const
 76        public CircularBuffer(int capacity, T[] targetItems)
 077        {
 078            if (capacity < 1)
 079            {
 080                throw new ArgumentException("Circular buffer cannot have negative or zero capacity.", nameof(capacity));
 81            }
 82
 083            if (targetItems == null)
 084            {
 085                throw new ArgumentNullException(nameof(targetItems));
 86            }
 87
 088            if (targetItems.Length > capacity)
 089            {
 090                throw new ArgumentException("Too many items to fit circular buffer", nameof(targetItems));
 91            }
 92
 093            Array = new T[capacity];
 094            Capacity = capacity;
 95
 096            System.Array.Copy(targetItems, Array, targetItems.Length);
 097            Count = targetItems.Length;
 98
 099            StartIndex = 0;
 0100            EndIndex = Count == capacity ? 0 : Count;
 0101        }
 102
 103        /// <summary>
 104        ///     Access item at <paramref name="pseudoIndex" />.
 105        /// </summary>
 106        /// <param name="pseudoIndex"></param>
 107        /// <exception cref="IndexOutOfRangeException">Provided index is out of buffers range.</exception>
 108        public T this[int pseudoIndex]
 109        {
 110            get =>
 11111                Array[
 112                    StartIndex +
 113                    (pseudoIndex < Capacity - StartIndex ? pseudoIndex : pseudoIndex - Capacity)];
 114            set =>
 3115                Array[
 116                    StartIndex +
 117                    (pseudoIndex < Capacity - StartIndex ? pseudoIndex : pseudoIndex - Capacity)] = value;
 118        }
 119
 120        /// <summary>
 121        ///     Add an <paramref name="item" /> to the <see cref="Array" />.
 122        /// </summary>
 123        /// <param name="item">The typed <see cref="object" /> to add.</param>
 124        public void Add(T item)
 95125        {
 95126            PushBack(item);
 95127        }
 128
 129        /// <summary>
 130        ///     Clear all values of the <see cref="Array" />.
 131        /// </summary>
 132        public void Clear()
 2133        {
 20134            for (int i = 0; i < Array.Length; i++)
 8135            {
 8136                Array[i] = default;
 8137            }
 138
 2139            Count = 0;
 2140            StartIndex = 0;
 2141            EndIndex = 0;
 2142        }
 143
 144        /// <summary>
 145        ///     Get the last item in the <see cref="Array" />.
 146        /// </summary>
 147        /// <returns>The last typed object in <see cref="Array" />.</returns>
 148        public T GetBack()
 1149        {
 1150            return Array[(EndIndex != 0 ? EndIndex : Capacity) - 1];
 1151        }
 152
 153        /// <summary>
 154        ///     Get the first item in the <see cref="Array" />.
 155        /// </summary>
 156        /// <returns>The first typed object in <see cref="Array" />.</returns>
 157        public T GetFront()
 1158        {
 1159            return Array[StartIndex];
 1160        }
 161
 162
 163        /// <summary>
 164        ///     Does the <see cref="Array" /> have any items in it?
 165        /// </summary>
 166        /// <returns>true/false</returns>
 167        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 168        public bool IsEmpty()
 3169        {
 3170            return Count == 0;
 3171        }
 172
 173        /// <summary>
 174        ///     Is the <see cref="Array" /> at capacity?
 175        /// </summary>
 176        /// <returns>true/false</returns>
 177        [MethodImpl(MethodImplOptions.AggressiveInlining)]
 178        public bool IsFull()
 2179        {
 2180            return Count == Capacity;
 2181        }
 182
 183        /// <summary>
 184        ///     Remove an item from the end of the <see cref="Array" />.
 185        /// </summary>
 186        public void PopBack()
 1187        {
 1188            if (EndIndex == 0)
 0189            {
 0190                EndIndex = Capacity;
 0191            }
 192
 1193            EndIndex--;
 1194            Array[EndIndex] = default;
 1195            --Count;
 1196        }
 197
 198        /// <summary>
 199        ///     Remove an item from the start of the <see cref="Array" />.
 200        /// </summary>
 201        public void PopFront()
 1202        {
 1203            Array[StartIndex] = default;
 1204            if (++StartIndex == Capacity)
 0205            {
 0206                StartIndex = 0;
 0207            }
 208
 1209            --Count;
 1210        }
 211
 212        /// <summary>
 213        ///     Add an item to the end of the <see cref="Array" />.
 214        /// </summary>
 215        /// <param name="targetItem">The item to add to the end of <see cref="Array" />.</param>
 216        public void PushBack(T targetItem)
 96217        {
 96218            if (Count == Capacity)
 13219            {
 13220                Array[EndIndex] = targetItem;
 13221                if (++EndIndex == Capacity)
 0222                {
 0223                    EndIndex = 0;
 0224                }
 225
 13226                StartIndex = EndIndex;
 13227            }
 228            else
 83229            {
 83230                Array[EndIndex] = targetItem;
 83231                if (++EndIndex == Capacity)
 20232                {
 20233                    EndIndex = 0;
 20234                }
 235
 83236                ++Count;
 83237            }
 96238        }
 239
 240        /// <summary>
 241        ///     Add an item to the start of the <see cref="Array" />.
 242        /// </summary>
 243        /// <param name="targetItem">The item to add to the start of <see cref="Array" />.</param>
 244        public void PushFront(T targetItem)
 1245        {
 1246            if (Count == Capacity)
 1247            {
 1248                if (StartIndex == 0)
 0249                {
 0250                    StartIndex = Capacity;
 0251                }
 252
 1253                StartIndex--;
 1254                EndIndex = StartIndex;
 1255                Array[StartIndex] = targetItem;
 1256            }
 257            else
 0258            {
 0259                if (StartIndex == 0)
 0260                {
 0261                    StartIndex = Capacity;
 0262                }
 263
 0264                StartIndex--;
 0265                Array[StartIndex] = targetItem;
 0266                ++Count;
 0267            }
 1268        }
 269
 270        /// <summary>
 271        ///     Copy <see cref="Array" /> to an array of the same type.
 272        /// </summary>
 273        /// <returns>A copied version of the <see cref="Array" /> as an array.</returns>
 274        public T[] ToArray()
 2275        {
 2276            T[] newArray = new T[Count];
 277
 278            // We dont need to fill anything as its empty.
 2279            if (Count <= 0)
 0280            {
 0281                return newArray;
 282            }
 283
 284            int length;
 285
 286            // First Part
 2287            if (StartIndex < EndIndex)
 0288            {
 0289                length = EndIndex - StartIndex;
 0290                System.Array.Copy(Array, StartIndex, newArray, 0, length);
 0291            }
 292            else
 2293            {
 2294                length = Array.Length - StartIndex;
 2295                System.Array.Copy(Array, StartIndex, newArray, 0, length);
 2296            }
 297
 298            // Second Part
 2299            if (StartIndex > EndIndex)
 0300            {
 0301                System.Array.Copy(Array, EndIndex, newArray, length, 0);
 0302            }
 303            else
 2304            {
 2305                System.Array.Copy(Array, 0, newArray, length, EndIndex);
 2306            }
 307
 2308            return newArray;
 2309        }
 310    }
 311}

Coverage by test methods
























Methods/Properties

CircularBuffer(System.Int32)
CircularBuffer(System.Int32, )
Item(System.Int32)
Item(System.Int32, T)
Add(T)
Clear()
GetBack()
GetFront()
IsEmpty()
IsFull()
PopBack()
PopFront()
PushBack(T)
PushFront(T)
ToArray()