< Summary

Information
Class: SwiftCollections.Observable.SwiftObservableArray<T>
Assembly: SwiftCollections
File(s): /home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Observable/SwiftObservableArray.cs
Line coverage
91%
Covered lines: 81
Uncovered lines: 8
Coverable lines: 89
Total lines: 205
Line coverage: 91%
Branch coverage
90%
Covered branches: 20
Total branches: 22
Branch coverage: 90.9%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
get_Index()100%11100%
get_NewValue()100%11100%
.ctor(...)100%11100%
.ctor(...)100%22100%
.ctor(...)0%3230%
.ctor(...)100%11100%
get_Capacity()100%11100%
get_Item(...)100%11100%
set_Item(...)100%22100%
get_State()100%22100%
set_State(...)100%22100%
ToArray()100%22100%
ValidateIndex(...)100%44100%
OnItemChanged(...)100%44100%
OnPropertyChanged(...)100%22100%

File(s)

/home/runner/work/SwiftCollections/SwiftCollections/src/SwiftCollections/Observable/SwiftObservableArray.cs

#LineLine coverage
 1using MemoryPack;
 2using System;
 3using System.ComponentModel;
 4using System.Text.Json.Serialization;
 5
 6namespace SwiftCollections.Observable;
 7
 8/// <summary>
 9/// Represents an array of observable properties, raising events whenever an element is updated.
 10/// Designed for performance-critical scenarios in Unity game development.
 11/// </summary>
 12/// <typeparam name="TValue">The type of elements in the array.</typeparam>
 13[Serializable]
 14[JsonConverter(typeof(SwiftStateJsonConverterFactory))]
 15[MemoryPackable]
 16public partial class SwiftObservableArray<TValue> : INotifyPropertyChanged
 17{
 18    #region Fields
 19
 20    protected SwiftObservableProperty<TValue>[] _items;
 21
 22    protected PropertyChangedEventHandler _itemChangedHandler;
 23
 24    #endregion
 25
 26    #region Events
 27
 28    /// <summary>
 29    /// Raised when any element in the array changes, providing the index and the new value.
 30    /// </summary>
 31    public event EventHandler<ElementChangedEventArgs<TValue>> ElementChanged;
 32
 33    /// <summary>
 34    /// Raised when the array's state changes.
 35    /// </summary>
 36    public event PropertyChangedEventHandler PropertyChanged;
 37
 38    #endregion
 39
 40    #region Nested Types
 41
 42    /// <summary>
 43    /// Provides details about a changed element, including its index and new value.
 44    /// </summary>
 45    public class ElementChangedEventArgs<T> : EventArgs
 46    {
 47        /// <summary>
 48        /// The index of the changed element.
 49        /// </summary>
 650        public int Index { get; }
 51
 52        /// <summary>
 53        /// The new value of the changed element.
 54        /// </summary>
 255        public T NewValue { get; }
 56
 100757        public ElementChangedEventArgs(int index, T newValue)
 100758        {
 100759            Index = index;
 100760            NewValue = newValue;
 100761        }
 62    }
 63
 64    #endregion
 65
 66    #region Constructors
 67
 2068    public SwiftObservableArray(int capacity)
 2069    {
 2070        SwiftThrowHelper.ThrowIfNegativeOrZero(capacity, nameof(capacity));
 71
 2072        _items = new SwiftObservableProperty<TValue>[capacity];
 104573        _itemChangedHandler = (sender, e) => OnItemChanged(sender);
 74
 20214675        for (int i = 0; i < capacity; i++)
 10105376        {
 10105377            _items[i] = new SwiftObservableProperty<TValue>
 10105378            {
 10105379                Index = i
 10105380            };
 10105381            _items[i].PropertyChanged += _itemChangedHandler;
 10105382        }
 2083    }
 84
 185    public SwiftObservableArray(SwiftObservableProperty<TValue>[] observableProperties)
 186    {
 187        SwiftThrowHelper.ThrowIfNull(observableProperties, nameof(observableProperties));
 88
 089        _items = observableProperties;
 090        _itemChangedHandler = (sender, e) => OnItemChanged(sender);
 91
 092        for (int i = 0; i < _items.Length; i++)
 093        {
 094            _items[i].Index = i;
 095            _items[i].PropertyChanged += _itemChangedHandler;
 096        }
 097    }
 98
 99    ///  <summary>
 100    ///  Initializes a new instance of the <see cref="SwiftObservableArray{TValue}"/> class with the specified <see cref
 101    ///  </summary>
 102    ///  <param name="state">The state containing the internal array, count, offset, and version for initialization.</pa
 103    [MemoryPackConstructor]
 7104    public SwiftObservableArray(SwiftArrayState<TValue> state)
 7105    {
 7106        State = state;
 7107    }
 108
 109    #endregion
 110
 111    #region Properties
 112
 113    [JsonIgnore]
 114    [MemoryPackIgnore]
 2115    public int Capacity => _items.Length;
 116
 117    [JsonIgnore]
 118    [MemoryPackIgnore]
 119    public TValue this[int index]
 120    {
 121        get
 10122        {
 10123            ValidateIndex(index);
 8124            return _items[index].Value;
 8125        }
 126        set
 1029127        {
 1029128            ValidateIndex(index);
 1029129            if (!Equals(_items[index].Value, value))
 1027130                _items[index].Value = value;
 1029131        }
 132    }
 133
 134    [JsonInclude]
 135    [MemoryPackInclude]
 136    public SwiftArrayState<TValue> State
 137    {
 138        get
 8139        {
 8140            var values = new TValue[_items.Length];
 141
 54142            for (int i = 0; i < _items.Length; i++)
 19143                values[i] = _items[i].Value;
 144
 8145            return new SwiftArrayState<TValue>(values);
 8146        }
 147        internal set
 7148        {
 7149            var values = value.Items;
 150
 9151            _itemChangedHandler = (sender, e) => OnItemChanged(sender);
 152
 7153            _items = new SwiftObservableProperty<TValue>[values.Length];
 154
 48155            for (int i = 0; i < values.Length; i++)
 17156            {
 17157                _items[i] = new SwiftObservableProperty<TValue>(values[i])
 17158                {
 17159                    Index = i
 17160                };
 17161                _items[i].PropertyChanged += _itemChangedHandler;
 17162            }
 7163        }
 164    }
 165
 166    #endregion
 167
 168    #region Methods
 169
 170    public TValue[] ToArray()
 6171    {
 6172        var array = new TValue[_items.Length];
 202040173        for (int i = 0; i < _items.Length; i++)
 101014174            array[i] = _items[i].Value;
 6175        return array;
 6176    }
 177
 178    private void ValidateIndex(int index)
 1039179    {
 1039180        if (index < 0 || index >= _items.Length)
 2181            throw new IndexOutOfRangeException($"Index {index} is out of bounds for this array.");
 1037182    }
 183
 184    private void OnItemChanged(object sender)
 1027185    {
 1027186        if (sender is SwiftObservableProperty<TValue> property)
 1027187        {
 1027188            int index = property.Index;
 189
 1027190            ElementChanged?.Invoke(
 1027191                this,
 1027192                new ElementChangedEventArgs<TValue>(index, property.Value)
 1027193            );
 194
 1027195            OnPropertyChanged("Items[]");
 1027196        }
 1027197    }
 198
 199    private void OnPropertyChanged(string propertyName)
 1027200    {
 1027201        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
 1027202    }
 203
 204    #endregion
 205}