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}