< Summary

Class:GDX.Collections.Generic.Array2D[T]
Assembly:GDX
File(s):D:/BuildAgent/work/GDX-Documentation/Projects/GDX_Development/Packages/com.dotbunny.gdx/GDX/Collections/Generic/Array2D.cs
Covered lines:106
Uncovered lines:8
Coverable lines:114
Total lines:270
Line coverage:92.9% (106 of 114)
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%220100%
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)

D:/BuildAgent/work/GDX-Documentation/Projects/GDX_Development/Packages/com.dotbunny.gdx/GDX/Collections/Generic/Array2D.cs

#LineLine coverage
 1// Copyright (c) 2020-2022 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            T[] newArray = new T[newArrayCount * ColumnCount];
 1889            for (int i = 0; i < Array.Length; i++)
 890            {
 891                newArray[i] = Array[i];
 892            }
 93
 194            Array = newArray;
 195            RowCount = newArrayCount;
 196        }
 97
 98        /// <summary>
 99        ///     Add additional columns to the dataset.
 100        /// </summary>
 101        /// <param name="numberOfNewColumns">The number of columns add.</param>
 102        public void AddColumns(int numberOfNewColumns)
 1103        {
 1104            int currentLengthOfArrays = ColumnCount;
 1105            int newLengthOfArrays = currentLengthOfArrays + numberOfNewColumns;
 1106            T[] newArray = new T[RowCount * newLengthOfArrays];
 107
 6108            for (int i = 0; i < RowCount; i++)
 16109            for (int j = 0; j < currentLengthOfArrays; j++)
 6110            {
 6111                newArray[i * newLengthOfArrays + j] = Array[i * currentLengthOfArrays + j];
 6112            }
 113
 1114            Array = newArray;
 1115            ColumnCount = newLengthOfArrays;
 1116        }
 117
 118        /// <summary>
 119        /// Get the column index of the provided <paramref name="index"/>.
 120        /// </summary>
 121        /// <param name="index">A valid index contained within <see cref="Array"/>.</param>
 122        /// <returns>The column index.</returns>
 123        public int GetColumnIndex(int index)
 1124        {
 1125            int leftOvers = index % ColumnCount;
 1126            return leftOvers;
 1127        }
 128
 129        /// <summary>
 130        /// Get the row index of the provided <paramref name="index"/>.
 131        /// </summary>
 132        /// <param name="index">A valid index contained within <see cref="Array"/>.</param>
 133        /// <returns>The row index.</returns>
 134        public int GetRowIndex(int index)
 1135        {
 1136            int leftOvers = index % ColumnCount;
 1137            return (index - leftOvers) / ColumnCount;
 1138        }
 139
 140        /// <summary>
 141        ///     Reverse the order of the columns in the backing <see cref="Array" />.
 142        /// </summary>
 143        public void ReverseColumns()
 2144        {
 145            // ReSharper disable once TooWideLocalVariableScope
 146            T temporaryStorage;
 147
 2148            int lastIndex = ColumnCount - 1;
 2149            int middleIndex = ColumnCount / 2;
 150
 12151            for (int rowIndex = 0; rowIndex < RowCount; rowIndex++)
 4152            {
 24153                for (int columnIndex = 0; columnIndex < middleIndex; columnIndex++)
 8154                {
 155                    // Cache our indexes
 8156                    int currentElementIndex = rowIndex * ColumnCount + columnIndex;
 8157                    int swapElementIndex = rowIndex * ColumnCount + (lastIndex - columnIndex);
 158
 159                    // Store the swap value
 8160                    temporaryStorage = Array[currentElementIndex];
 161
 162                    // Swap values
 8163                    Array[currentElementIndex] = Array[swapElementIndex];
 8164                    Array[swapElementIndex] = temporaryStorage;
 8165                }
 4166            }
 2167        }
 168
 169        /// <summary>
 170        ///     Reverse the order of the rows in the backing <see cref="Array" />.
 171        /// </summary>
 172        public void ReverseRows()
 2173        {
 2174            T[] temporaryStorage = new T[ColumnCount];
 175
 2176            int lastIndex = RowCount - 1;
 2177            int middleIndex = RowCount / 2;
 178
 14179            for (int rowIndex = 0; rowIndex < middleIndex; rowIndex++)
 5180            {
 181                // Save existing line
 5182                System.Array.Copy(Array, rowIndex * ColumnCount, temporaryStorage, 0, ColumnCount);
 183
 184                // Get line on other side of the flip and put in place
 5185                System.Array.Copy(Array, (lastIndex - rowIndex) * ColumnCount, Array, rowIndex * ColumnCount,
 186                    ColumnCount);
 187
 188                // Write other side content
 5189                System.Array.Copy(temporaryStorage, 0, Array, (lastIndex - rowIndex) * ColumnCount, ColumnCount);
 5190            }
 2191        }
 192
 193        /// <summary>
 194        /// Rotate internal dataset clockwise.
 195        /// </summary>
 196        public void RotateClockwise()
 1197        {
 198            // TODO: There should be a way to do this without making a transient array.
 199
 200            // Make our new array
 1201            T[] newArray = new T[Array.Length];
 202
 1203            int newColumnCount = RowCount;
 1204            int runningIndex = 0;
 205
 206            // Transpose values to new array
 6207            for (int column = 0; column < ColumnCount; column++)
 2208            {
 24209                for (int row = RowCount - 1; row >= 0; row--)
 10210                {
 10211                    newArray[runningIndex] = Array[row * ColumnCount + column];
 10212                    runningIndex++;
 10213                }
 2214            }
 215
 216            // Assign Data
 1217            RowCount = ColumnCount;
 1218            ColumnCount = newColumnCount;
 1219            Array = newArray;
 1220        }
 221
 222        /// <summary>
 223        /// Rotate internal dataset counter-clockwise.
 224        /// </summary>
 225        public void RotateCounterClockwise()
 1226        {
 227            // TODO: There should be a way to do this without making a transient array.
 228
 229            // Make our new array
 1230            T[] newArray = new T[Array.Length];
 231
 1232            int newColumnCount = RowCount;
 1233            int runningIndex = 0;
 234
 235            // Transpose values to new array
 6236            for (int column = ColumnCount - 1; column >= 0; column--)
 2237            {
 24238                for (int row = 0; row < RowCount; row++)
 10239                {
 10240                    newArray[runningIndex] = Array[row * ColumnCount + column];
 10241                    runningIndex++;
 10242                }
 2243            }
 244
 245            // Assign Data
 1246            RowCount = ColumnCount;
 1247            ColumnCount = newColumnCount;
 1248            Array = newArray;
 1249        }
 250
 251        /// <summary>
 252        ///     Creates a copy of the internal array as a traditional multi-dimensional array.
 253        /// </summary>
 254        /// <remarks>Useful for scenarios where fills need to be done with [,] structured multi-dimensional arrays.</rem
 255        /// <returns>A new copy of the backing <see cref="Array" /> in multi-dimensional form.</returns>
 256        public T[,] ToMultiDimensionalArray()
 1257        {
 1258            T[,] returnArray = new T[RowCount, ColumnCount];
 6259            for (int x = 0; x < RowCount; x++)
 2260            {
 12261                for (int y = 0; y < ColumnCount; y++)
 4262                {
 4263                    returnArray[x, y] = Array[x * ColumnCount + y];
 4264                }
 2265            }
 266
 1267            return returnArray;
 1268        }
 269    }
 270}