SparseArrays.cs 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. using System;
  2. using System.Collections;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. namespace SharpGLTF.Memory
  6. {
  7. /// <summary>
  8. /// Special accessor to wrap over a base accessor and a sparse accessor
  9. /// </summary>
  10. /// <typeparam name="T">An unmanage structure type.</typeparam>
  11. [System.Diagnostics.DebuggerDisplay("Sparse {typeof(T).Name} Accessor {Count}")]
  12. public struct SparseArray<T> : IList<T>, IReadOnlyList<T>
  13. where T : unmanaged
  14. {
  15. #region lifecycle
  16. public SparseArray(IList<T> bottom, IList<T> top, IntegerArray topMapping)
  17. {
  18. _BottomItems = bottom;
  19. _TopItems = top;
  20. _Mapping = new Dictionary<int, int>();
  21. for (int val = 0; val < topMapping.Count; ++val)
  22. {
  23. var key = (int)topMapping[val];
  24. _Mapping[key] = val;
  25. }
  26. }
  27. #endregion
  28. #region data
  29. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
  30. private readonly IList<T> _BottomItems;
  31. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
  32. private readonly IList<T> _TopItems;
  33. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
  34. private readonly Dictionary<int, int> _Mapping;
  35. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.RootHidden)]
  36. private T[] _DebugItems => this.ToArray();
  37. #endregion
  38. #region API
  39. [System.Diagnostics.DebuggerBrowsable(System.Diagnostics.DebuggerBrowsableState.Never)]
  40. public int Count => _BottomItems.Count;
  41. public bool IsReadOnly => true;
  42. public T this[int index]
  43. {
  44. get => _Mapping.TryGetValue(index, out int topIndex) ? _TopItems[topIndex] : _BottomItems[index];
  45. set => throw new NotSupportedException("Collection is read only.");
  46. }
  47. public IEnumerator<T> GetEnumerator() { return new EncodedArrayEnumerator<T>(this); }
  48. IEnumerator IEnumerable.GetEnumerator() { return new EncodedArrayEnumerator<T>(this); }
  49. public bool Contains(T item) { return IndexOf(item) >= 0; }
  50. public int IndexOf(T item) { return this._FirstIndexOf(item); }
  51. public void CopyTo(T[] array, int arrayIndex) { this._CopyTo(array, arrayIndex); }
  52. void IList<T>.Insert(int index, T item) { throw new NotSupportedException(); }
  53. void IList<T>.RemoveAt(int index) { throw new NotSupportedException(); }
  54. void ICollection<T>.Add(T item) { throw new NotSupportedException(); }
  55. void ICollection<T>.Clear() { throw new NotSupportedException(); }
  56. bool ICollection<T>.Remove(T item) { throw new NotSupportedException(); }
  57. #endregion
  58. }
  59. }