< Summary

Class:GDX.Collections.Generic.Array2D[T]
Assembly:GDX
File(s):./Packages/com.dotbunny.gdx/GDX/Collections/Generic/Array2D.cs
Covered lines:101
Uncovered lines:8
Coverable lines:109
Total lines:264
Line coverage:92.6% (101 of 109)
Covered branches:0
Total branches:0
Covered methods:12
Total methods:14
Method coverage:85.7% (12 of 14)

Coverage History

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity NPath complexity Sequence coverage
Array2D(...)0%110100%
Array2D(...)0%2100%
Dispose()0%2100%
AddRows(...)0%110100%
AddColumns(...)0%330100%
GetColumnIndex(...)0%110100%
GetRowIndex(...)0%110100%
ReverseColumns()0%330100%
ReverseRows()0%220100%
RotateClockwise()0%330100%
RotateCounterClockwise()0%330100%
ToMultiDimensionalArray()0%330100%

File(s)

./Packages/com.dotbunny.gdx/GDX/Collections/Generic/Array2D.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 2-dimensional array backed by a flat array.
 12    /// </summary>
 13    /// <remarks>Mimics multi-dimensional array format.</remarks>
 14    /// <typeparam name="T">Type of objects.</typeparam>
 15    [VisualScriptingCompatible(1)]
 16    public struct Array2D<T> : IDisposable
 17    {
 18        /// <summary>
 19        ///     The backing flat array.
 20        /// </summary>
 21        public T[] Array;
 22
 23        /// <summary>
 24        ///     The length of each pseudo-array in the dataset.
 25        /// </summary>
 26        /// <remarks>CAUTION! Changing this will alter the understanding of the data.</remarks>
 27        public int ColumnCount;
 28
 29        /// <summary>
 30        ///     The number of pseudo-arrays created to support the dimensionality.
 31        /// </summary>
 32        /// <remarks>CAUTION! Changing this will alter the understanding of the data.</remarks>
 33        public int RowCount;
 34
 35        /// <summary>
 36        ///     Create a <see cref="Array2D{T}" />.
 37        /// </summary>
 38        /// <param name="rowCount">The number of rows (X).</param>
 39        /// <param name="columnCount">The number of columns (Y).</param>
 40        public Array2D(int rowCount, int columnCount)
 1341        {
 1342            ColumnCount = columnCount;
 1343            RowCount = rowCount;
 1344            Array = new T[rowCount * columnCount];
 1345        }
 46
 47        /// <summary>
 48        ///     Create a <see cref="Array2D{T}" /> providing an existing <paramref name="arrayToUse" />.
 49        /// </summary>
 50        /// <param name="rowCount">The number of rows (X).</param>
 51        /// <param name="columnCount">The number of columns (Y).</param>
 52        /// <param name="arrayToUse">An existing array to use in the <see cref="Array2D{T}" />.</param>
 53        public Array2D(int rowCount, int columnCount, T[] arrayToUse)
 054        {
 055            ColumnCount = columnCount;
 056            RowCount = rowCount;
 057            Array = arrayToUse;
 058        }
 59
 60        /// <summary>
 61        ///     Get a typed object at a specific 2-dimensional index in <see cref="Array" />.
 62        /// </summary>
 63        /// <param name="x">The row/line number (vertical axis).</param>
 64        /// <param name="y">The column number (horizontal axis).</param>
 65        public T this[int x, int y]
 66        {
 67            [MethodImpl(MethodImplOptions.AggressiveInlining)]
 8868            get => Array[x * ColumnCount + y];
 69            [MethodImpl(MethodImplOptions.AggressiveInlining)]
 6870            set => Array[x * ColumnCount + y] = value;
 71        }
 72
 73        /// <summary>
 74        ///     Properly dispose of the <see cref="Array2D{T}" />.
 75        /// </summary>
 76        public void Dispose()
 077        {
 078            Array = default;
 079        }
 80
 81        /// <summary>
 82        ///     Add additional rows to the dataset.
 83        /// </summary>
 84        /// <param name="numberOfNewRows">The number of rows/arrays to add.</param>
 85        public void AddRows(int numberOfNewRows)
 186        {
 187            int newArrayCount = RowCount + numberOfNewRows;
 188            System.Array.Resize(ref Array, newArrayCount * ColumnCount);
 189            RowCount = newArrayCount;
 190        }
 91
 92        /// <summary>
 93        ///     Add additional columns to the dataset.
 94        /// </summary>
 95        /// <param name="numberOfNewColumns">The number of columns add.</param>
 96        public void AddColumns(int numberOfNewColumns)
 197        {
 198            int currentLengthOfArrays = ColumnCount;
 199            int newLengthOfArrays = currentLengthOfArrays + numberOfNewColumns;
 1100            T[] newArray = new T[RowCount * newLengthOfArrays];
 101
 6102            for (int i = 0; i < RowCount; i++)
 16103            for (int j = 0; j < currentLengthOfArrays; j++)
 6104            {
 6105                newArray[i * newLengthOfArrays + j] = Array[i * currentLengthOfArrays + j];
 6106            }
 107
 1108            Array = newArray;
 1109            ColumnCount = newLengthOfArrays;
 1110        }
 111
 112        /// <summary>
 113        ///     Get the column index of the provided <paramref name="index" />.
 114        /// </summary>
 115        /// <param name="index">A valid index contained within <see cref="Array" />.</param>
 116        /// <returns>The column index.</returns>
 117        public int GetColumnIndex(int index)
 1118        {
 1119            int leftOvers = index % ColumnCount;
 1120            return leftOvers;
 1121        }
 122
 123        /// <summary>
 124        ///     Get the row index of the provided <paramref name="index" />.
 125        /// </summary>
 126        /// <param name="index">A valid index contained within <see cref="Array" />.</param>
 127        /// <returns>The row index.</returns>
 128        public int GetRowIndex(int index)
 1129        {
 1130            int leftOvers = index % ColumnCount;
 1131            return (index - leftOvers) / ColumnCount;
 1132        }
 133
 134        /// <summary>
 135        ///     Reverse the order of the columns in the backing <see cref="Array" />.
 136        /// </summary>
 137        public void ReverseColumns()
 2138        {
 139            // ReSharper disable once TooWideLocalVariableScope
 140            T temporaryStorage;
 141
 2142            int lastIndex = ColumnCount - 1;
 2143            int middleIndex = ColumnCount / 2;
 144
 12145            for (int rowIndex = 0; rowIndex < RowCount; rowIndex++)
 4146            {
 24147                for (int columnIndex = 0; columnIndex < middleIndex; columnIndex++)
 8148                {
 149                    // Cache our indexes
 8150                    int currentElementIndex = rowIndex * ColumnCount + columnIndex;
 8151                    int swapElementIndex = rowIndex * ColumnCount + (lastIndex - columnIndex);
 152
 153                    // Store the swap value
 8154                    temporaryStorage = Array[currentElementIndex];
 155
 156                    // Swap values
 8157                    Array[currentElementIndex] = Array[swapElementIndex];
 8158                    Array[swapElementIndex] = temporaryStorage;
 8159                }
 4160            }
 2161        }
 162
 163        /// <summary>
 164        ///     Reverse the order of the rows in the backing <see cref="Array" />.
 165        /// </summary>
 166        public void ReverseRows()
 2167        {
 2168            T[] temporaryStorage = new T[ColumnCount];
 169
 2170            int lastIndex = RowCount - 1;
 2171            int middleIndex = RowCount / 2;
 172
 14173            for (int rowIndex = 0; rowIndex < middleIndex; rowIndex++)
 5174            {
 175                // Save existing line
 5176                System.Array.Copy(Array, rowIndex * ColumnCount, temporaryStorage, 0, ColumnCount);
 177
 178                // Get line on other side of the flip and put in place
 5179                System.Array.Copy(Array, (lastIndex - rowIndex) * ColumnCount, Array, rowIndex * ColumnCount,
 180                    ColumnCount);
 181
 182                // Write other side content
 5183                System.Array.Copy(temporaryStorage, 0, Array, (lastIndex - rowIndex) * ColumnCount, ColumnCount);
 5184            }
 2185        }
 186
 187        /// <summary>
 188        ///     Rotate internal dataset clockwise.
 189        /// </summary>
 190        public void RotateClockwise()
 1191        {
 192            // TODO: There should be a way to do this without making a transient array.
 193
 194            // Make our new array
 1195            T[] newArray = new T[Array.Length];
 196
 1197            int newColumnCount = RowCount;
 1198            int runningIndex = 0;
 199
 200            // Transpose values to new array
 6201            for (int column = 0; column < ColumnCount; column++)
 2202            {
 24203                for (int row = RowCount - 1; row >= 0; row--)
 10204                {
 10205                    newArray[runningIndex] = Array[row * ColumnCount + column];
 10206                    runningIndex++;
 10207                }
 2208            }
 209
 210            // Assign Data
 1211            RowCount = ColumnCount;
 1212            ColumnCount = newColumnCount;
 1213            Array = newArray;
 1214        }
 215
 216        /// <summary>
 217        ///     Rotate internal dataset counter-clockwise.
 218        /// </summary>
 219        public void RotateCounterClockwise()
 1220        {
 221            // TODO: There should be a way to do this without making a transient array.
 222
 223            // Make our new array
 1224            T[] newArray = new T[Array.Length];
 225
 1226            int newColumnCount = RowCount;
 1227            int runningIndex = 0;
 228
 229            // Transpose values to new array
 6230            for (int column = ColumnCount - 1; column >= 0; column--)
 2231            {
 24232                for (int row = 0; row < RowCount; row++)
 10233                {
 10234                    newArray[runningIndex] = Array[row * ColumnCount + column];
 10235                    runningIndex++;
 10236                }
 2237            }
 238
 239            // Assign Data
 1240            RowCount = ColumnCount;
 1241            ColumnCount = newColumnCount;
 1242            Array = newArray;
 1243        }
 244
 245        /// <summary>
 246        ///     Creates a copy of the internal array as a traditional multi-dimensional array.
 247        /// </summary>
 248        /// <remarks>Useful for scenarios where fills need to be done with [,] structured multi-dimensional arrays.</rem
 249        /// <returns>A new copy of the backing <see cref="Array" /> in multi-dimensional form.</returns>
 250        public T[,] ToMultiDimensionalArray()
 1251        {
 1252            T[,] returnArray = new T[RowCount, ColumnCount];
 6253            for (int x = 0; x < RowCount; x++)
 2254            {
 12255                for (int y = 0; y < ColumnCount; y++)
 4256                {
 4257                    returnArray[x, y] = Array[x * ColumnCount + y];
 4258                }
 2259            }
 260
 1261            return returnArray;
 1262        }
 263    }
 264}

Coverage by test methods














Methods/Properties

Array2D(System.Int32, System.Int32)
Array2D(System.Int32, System.Int32, )
Item(System.Int32, System.Int32)
Item(System.Int32, System.Int32, T)
Dispose()
AddRows(System.Int32)
AddColumns(System.Int32)
GetColumnIndex(System.Int32)
GetRowIndex(System.Int32)
ReverseColumns()
ReverseRows()
RotateClockwise()
RotateCounterClockwise()
ToMultiDimensionalArray()