A game about forced loneliness, made by TACStudios
1using System; 2using Unity.Collections; 3using System.Diagnostics; 4using System.Runtime.InteropServices; 5using Unity.Collections.LowLevel.Unsafe; 6using System.Collections.Generic; 7using Unity.Burst; 8 9namespace UnityEngine.U2D.Common.UTess 10{ 11 12 /// <summary> 13 /// Array. Used within UTess and constrained to 14 /// 1. Auto-resizes upto the Max count with a smaller initial count. 15 /// 2. Only be used within the created thread. Read 1. 16 /// 3. Read/Write access are all fast-paths. 17 /// 4. Mostly used with Temp Alloc within UTess ontext. 18 /// </summary> 19 /// <typeparam name="T"></typeparam> 20 [StructLayout(LayoutKind.Sequential)] 21 [DebuggerDisplay("Length = {Length}")] 22 [DebuggerTypeProxy(typeof(ArrayDebugView<>))] 23 internal unsafe struct Array<T> : IDisposable where T : struct 24 { 25 internal NativeArray<T> m_Array; 26 internal int m_MaxSize; 27 internal Allocator m_AllocLabel; 28 internal NativeArrayOptions m_Options; 29 30 public Array(int length, int maxSize, Allocator allocMode, NativeArrayOptions options) 31 { 32 m_Array = new NativeArray<T>(length, allocMode, options); 33 m_AllocLabel = allocMode; 34 m_Options = options; 35 m_MaxSize = maxSize; 36 } 37 38 39 private void ResizeIfRequired(int index) 40 { 41 if (index >= m_MaxSize || index < 0) 42 throw new IndexOutOfRangeException( 43 $"Trying to access beyond allowed size. {index} is out of range of '{m_MaxSize}' MaxSize."); 44 if (index < m_Array.Length) 45 return; 46 47 int requiredSize = Length; 48 while (requiredSize <= index) 49 requiredSize = requiredSize * 2; 50 51 requiredSize = requiredSize > m_MaxSize ? m_MaxSize : requiredSize; 52 var copyArray = new NativeArray<T>(requiredSize, m_AllocLabel, m_Options); 53 54 NativeArray<T>.Copy(m_Array, copyArray, Length); 55 m_Array.Dispose(); 56 m_Array = copyArray; 57 } 58 59 public unsafe T this[int index] 60 { 61 get 62 { 63 return m_Array[index]; 64 } 65 66 set 67 { 68 ResizeIfRequired(index); 69 m_Array[index] = value; 70 } 71 } 72 73 public bool IsCreated => m_Array.IsCreated; 74 75 public int Length => (m_MaxSize != 0) ? m_Array.Length : 0; 76 77 public int MaxSize => m_MaxSize; 78 79 public void Dispose() 80 { 81 m_Array.Dispose(); 82 m_MaxSize = 0; 83 } 84 85 public void* UnsafePtr 86 { 87 get 88 { 89 return m_Array.GetUnsafePtr(); 90 } 91 } 92 93 public void* UnsafeReadOnlyPtr 94 { 95 get 96 { 97 return m_Array.GetUnsafeReadOnlyPtr(); 98 } 99 } 100 101 // Should only ever be used for Debugging. 102 public void CopyTo(T[] array) 103 { 104 m_Array.CopyTo(array); 105 } 106 } 107 108 /// <summary> 109 /// DebuggerTypeProxy for <see cref="Array{T}"/> 110 /// </summary> 111 internal sealed class ArrayDebugView<T> where T : struct 112 { 113 private Array<T> array; 114 115 public ArrayDebugView(Array<T> array) 116 { 117 this.array = array; 118 } 119 120 public T[] Items 121 { 122 get 123 { 124 var ret = new T[array.Length]; 125 array.CopyTo(ret); 126 return ret; 127 } 128 } 129 } 130 131}