< Summary

Information
Class: SwiftCollections.Dimensions.SwiftArray3D<T>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Dimension/SwiftArray3D.cs
Line coverage
97%
Covered lines: 114
Uncovered lines: 3
Coverable lines: 117
Total lines: 275
Line coverage: 97.4%
Branch coverage
100%
Covered branches: 40
Total branches: 40
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor()100%210%
.ctor(...)100%11100%
.ctor(...)100%11100%
.ctor(...)100%11100%
get_Width()100%11100%
get_Height()100%11100%
get_Depth()100%11100%
get_Size()100%210%
get_Length()100%11100%
get_Item(...)100%11100%
set_Item(...)100%11100%
get_State()100%11100%
set_State(...)100%11100%
Initialize(...)100%11100%
Resize(...)100%66100%
Shift(...)100%1414100%
Clear()100%11100%
Fill(...)100%22100%
GetIndex(...)100%11100%
ValidateIndex(...)100%22100%
IsValidIndex(...)100%1010100%
GetEnumerator()100%66100%
System.Collections.IEnumerable.GetEnumerator()100%210%

File(s)

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Dimension/SwiftArray3D.cs

#LineLine coverage
 1using MemoryPack;
 2using System;
 3using System.Collections;
 4using System.Collections.Generic;
 5using System.Text.Json.Serialization;
 6
 7namespace SwiftCollections.Dimensions;
 8
 9/// <summary>
 10/// Represents a generic, flattened 3D array with efficient indexing and resizing capabilities.
 11/// Optimized for use in performance-critical applications like game grids.
 12/// </summary>
 13/// <typeparam name="T">The type of elements in the 3D array.</typeparam>
 14[Serializable]
 15[JsonConverter(typeof(SwiftStateJsonConverterFactory))]
 16[MemoryPackable]
 17public partial class SwiftArray3D<T> : IEnumerable<T>, IEnumerable
 18{
 19    #region Fields
 20
 21    private T[] _innerArray;
 22
 23    private int _width;
 24
 25    private int _height;
 26
 27    private int _depth;
 28
 29    #endregion
 30
 31    #region Constructors
 32
 033    public SwiftArray3D() : this(0, 0, 0) { }
 34
 1935    public SwiftArray3D(int width, int height, int length)
 1936    {
 1937        Initialize(width, height, length);
 1938    }
 39
 140    public SwiftArray3D(int width, int height, int length, T defaultValue) : this(width, height, length)
 141    {
 142        Fill(defaultValue);
 143    }
 44
 45    [MemoryPackConstructor]
 246    public SwiftArray3D(Array3DState<T> state)
 247    {
 248        State = state;
 249    }
 50
 51    #endregion
 52
 53    #region Properties
 54
 55
 56    [JsonIgnore]
 57    [MemoryPackIgnore]
 237811458    public int Width => _width;
 59
 60    [JsonIgnore]
 61    [MemoryPackIgnore]
 475603462    public int Height => _height;
 63
 64    [JsonIgnore]
 65    [MemoryPackIgnore]
 713426666    public int Depth => _depth;
 67
 68    /// <summary>
 69    /// Total size of the array.
 70    /// </summary>
 71    [JsonIgnore]
 72    [MemoryPackIgnore]
 073    public int Size => _width * _height * _depth;
 74
 75    /// <inheritdoc cref="Array.Length" />
 76    [JsonIgnore]
 77    [MemoryPackIgnore]
 278    public int Length => _innerArray.Length;
 79
 80    [JsonIgnore]
 81    [MemoryPackIgnore]
 82    public T this[int x, int y, int z]
 83    {
 84        get
 125112385        {
 125112386            ValidateIndex(x, y, z);
 125111987            return _innerArray[GetIndex(x, y, z)];
 125111988        }
 89        set
 112601490        {
 112601491            ValidateIndex(x, y, z);
 112601492            _innerArray[GetIndex(x, y, z)] = value;
 112601493        }
 94    }
 95
 96    [JsonInclude]
 97    [MemoryPackInclude]
 98    public Array3DState<T> State
 99    {
 100        get
 2101        {
 2102            var data = new T[_innerArray.Length];
 2103            Array.Copy(_innerArray, data, data.Length);
 104
 2105            return new Array3DState<T>(
 2106                _width,
 2107                _height,
 2108                _depth,
 2109                data
 2110            );
 2111        }
 112
 113        internal set
 2114        {
 2115            _width = value.Width;
 2116            _height = value.Height;
 2117            _depth = value.Depth;
 118
 2119            _innerArray = new T[value.Data.Length];
 2120            Array.Copy(value.Data, _innerArray, value.Data.Length);
 2121        }
 122    }
 123
 124    #endregion
 125
 126    #region Methods
 127
 128    /// <summary>
 129    /// Initializes the 3D array with the specified dimensions.
 130    /// </summary>
 131    private void Initialize(int width, int height, int depth)
 19132    {
 19133        _width = width;
 19134        _height = height;
 19135        _depth = depth;
 19136        _innerArray = new T[width * height * depth];
 19137    }
 138
 139    /// <summary>
 140    /// Resizes the 3D array to the specified dimensions.
 141    /// Retains existing data where possible.
 142    /// </summary>
 143    public void Resize(int newWidth, int newHeight, int newDepth)
 5144    {
 5145        var newArray = new T[newWidth * newHeight * newDepth];
 146
 5147        int minWidth = Math.Min(Width, newWidth);
 5148        int minHeight = Math.Min(Height, newHeight);
 5149        int minDepth = Math.Min(Depth, newDepth);
 150
 32151        for (int x = 0; x < minWidth; x++)
 11152        {
 88153            for (int y = 0; y < minHeight; y++)
 33154            {
 280155                for (int z = 0; z < minDepth; z++)
 107156                {
 107157                    int srcIndex = GetIndex(x, y, z);
 107158                    int dstIndex = x * (newHeight * newDepth) + y * newDepth + z;
 107159                    newArray[dstIndex] = _innerArray[srcIndex];
 107160                }
 33161            }
 11162        }
 163
 5164        _innerArray = newArray;
 5165        _width = newWidth;
 5166        _height = newHeight;
 5167        _depth = newDepth;
 5168    }
 169
 170    /// <summary>
 171    /// Shifts the elements in the array by the specified offsets along each axis.
 172    /// </summary>
 173    /// <param name="xOffset">The offset to apply along the X-axis.</param>
 174    /// <param name="yOffset">The offset to apply along the Y-axis.</param>
 175    /// <param name="zOffset">The offset to apply along the Z-axis.</param>
 176    /// <param name="wrap">
 177    /// Specifies whether to wrap elements that exceed the array's boundaries.
 178    /// If <c>true</c>, values wrap around to the other side of the array.
 179    /// If <c>false</c>, values that exceed boundaries are discarded.
 180    /// </param>
 181    /// <remarks>
 182    /// - Wrapping behavior ensures that no data is lost during shifts.
 183    /// - Non-wrapping behavior discards elements that move out of bounds.
 184    /// </remarks>
 185    public void Shift(int xOffset, int yOffset, int zOffset, bool wrap = true)
 5186    {
 5187        var newArray = new T[Width * Height * Depth];
 188
 46189        for (int x = 0; x < Width; x++)
 18190        {
 180191            for (int y = 0; y < Height; y++)
 72192            {
 792193                for (int z = 0; z < Depth; z++)
 324194                {
 324195                    int newX = wrap ? (x + xOffset + Width) % Width : x + xOffset;
 324196                    int newY = wrap ? (y + yOffset + Height) % Height : y + yOffset;
 324197                    int newZ = wrap ? (z + zOffset + Depth) % Depth : z + zOffset;
 198
 324199                    if (IsValidIndex(newX, newY, newZ))
 301200                    {
 301201                        int srcIndex = GetIndex(x, y, z);
 301202                        int dstIndex = GetIndex(newX, newY, newZ);
 301203                        newArray[dstIndex] = _innerArray[srcIndex];
 301204                    }
 324205                }
 72206            }
 18207        }
 208
 5209        _innerArray = newArray;
 5210    }
 211
 212    /// <summary>
 213    /// Clears all elements in the array.
 214    /// </summary>
 1215    public void Clear() => Array.Clear(_innerArray, 0, _innerArray.Length);
 216
 217    /// <summary>
 218    /// Fills the entire array with the specified value.
 219    /// </summary>
 220    public void Fill(T value)
 4221    {
 224222        for (int i = 0; i < _innerArray.Length; i++)
 108223            _innerArray[i] = value;
 4224    }
 225
 226    public virtual int GetIndex(int x, int y, int z)
 2377842227    {
 2377842228        return x * (Height * Depth) + y * Depth + z;
 2377842229    }
 230
 231    /// <summary>
 232    /// Validates the specified indices.
 233    /// Throws an exception if the indices are out of bounds.
 234    /// </summary>
 235    public virtual void ValidateIndex(int x, int y, int z)
 2377137236    {
 2377137237        if (!IsValidIndex(x, y, z))
 4238            throw new IndexOutOfRangeException($"Invalid index ({x}, {y}, {z}) for dimensions ({Width}, {Height}, {Depth
 2377133239    }
 240
 241    /// <summary>
 242    /// Checks if the specified indices are within bounds.
 243    /// </summary>
 244    public virtual bool IsValidIndex(int x, int y, int z) =>
 2377464245        x >= 0 && x < Width && y >= 0 && y < Height && z >= 0 && z < Depth;
 246
 247    #endregion
 248
 249    #region IEnumerator Implementation
 250
 251    /// <summary>
 252    /// Returns an enumerator that iterates through all elements in the 3D array.
 253    /// </summary>
 254    /// <returns>An enumerator for the 3D array.</returns>
 255    public IEnumerator<T> GetEnumerator()
 5256    {
 36257        for (int x = 0; x < Width; x++)
 13258        {
 96259            for (int y = 0; y < Height; y++)
 35260            {
 264261                for (int z = 0; z < Depth; z++)
 97262                    yield return this[x, y, z];
 35263            }
 13264        }
 5265    }
 266
 267    /// <summary>
 268    /// Returns an enumerator that iterates through all elements in the 3D array (non-generic).
 269    /// </summary>
 270    /// <returns>An enumerator for the 3D array.</returns>
 0271    IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
 272
 273
 274    #endregion
 275}