using System; using System.Collections; using System.Collections.Generic; using System.Linq; namespace SharpGLTF.Memory { /// /// Special accessor to wrap over a base accessor and a sparse accessor /// /// An unmanage structure type. [System.Diagnostics.DebuggerDisplay("Sparse {typeof(T).Name} Accessor {Count}")] public struct SparseArray : IList, IReadOnlyList where T : unmanaged { #region lifecycle public SparseArray(IList bottom, IList top, IntegerArray topMapping) { _BottomItems = bottom; _TopItems = top; _Mapping = new Dictionary(); for (int val = 0; val < topMapping.Count; ++val) { var key = (int)topMapping[val]; _Mapping[key] = val; } } #endregion #region data [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] private readonly IList _BottomItems; [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] private readonly IList _TopItems; [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] private readonly Dictionary _Mapping; [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)] private T[] _DebugItems => this.ToArray(); #endregion #region API [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)] public int Count => _BottomItems.Count; public bool IsReadOnly => true; public T this[int index] { get => _Mapping.TryGetValue(index, out int topIndex) ? _TopItems[topIndex] : _BottomItems[index]; set => throw new NotSupportedException("Collection is read only."); } public IEnumerator GetEnumerator() { return new EncodedArrayEnumerator(this); } IEnumerator IEnumerable.GetEnumerator() { return new EncodedArrayEnumerator(this); } public bool Contains(T item) { return IndexOf(item) >= 0; } public int IndexOf(T item) { return this._FirstIndexOf(item); } public void CopyTo(T[] array, int arrayIndex) { this._CopyTo(array, arrayIndex); } void IList.Insert(int index, T item) { throw new NotSupportedException(); } void IList.RemoveAt(int index) { throw new NotSupportedException(); } void ICollection.Add(T item) { throw new NotSupportedException(); } void ICollection.Clear() { throw new NotSupportedException(); } bool ICollection.Remove(T item) { throw new NotSupportedException(); } #endregion } }