A game about forced loneliness, made by TACStudios
1using System;
2using NUnit.Framework;
3using Unity.Burst;
4using Unity.Collections;
5using Unity.Collections.Tests;
6using Unity.Jobs;
7using Unity.Collections.LowLevel.Unsafe;
8
9internal class NativeArrayTests : CollectionsTestFixture
10{
11 [Test]
12 public unsafe void NativeArray_IndexOf_Int()
13 {
14 var container = new NativeArray<int>(10, Allocator.Persistent);
15 container[0] = 123;
16 container[1] = 789;
17
18 bool r0 = false, r1 = false, r2 = false;
19
20 GCAllocRecorder.ValidateNoGCAllocs(() =>
21 {
22 r0 = -1 != container.IndexOf(456);
23 r1 = container.Contains(123);
24 r2 = container.Contains(789);
25 });
26
27 Assert.False(r0);
28 Assert.False(-1 != NativeArrayExtensions.IndexOf<int, int>(container.GetUnsafePtr(), container.Length, 456));
29
30 Assert.True(r1);
31 Assert.True(NativeArrayExtensions.Contains<int, int>(container.GetUnsafePtr(), container.Length, 123));
32
33 Assert.True(r2);
34 Assert.True(NativeArrayExtensions.Contains<int, int>(container.GetUnsafePtr(), container.Length, 789));
35
36 container.Dispose();
37 }
38
39 [Test]
40 public unsafe void NativeArray_IndexOf_FixedString128()
41 {
42 var container = new NativeArray<FixedString128Bytes>(10, Allocator.Persistent);
43 container[0] = new FixedString128Bytes("123");
44 container[1] = new FixedString128Bytes("789");
45
46 bool r0 = false, r1 = false, r2 = false;
47
48 GCAllocRecorder.ValidateNoGCAllocs(() =>
49 {
50 r0 = -1 != container.IndexOf(new FixedString128Bytes("456"));
51 r1 = container.Contains(new FixedString128Bytes("123"));
52 r2 = container.Contains(new FixedString128Bytes("789"));
53 });
54
55 Assert.False(r0);
56 Assert.False(-1 != NativeArrayExtensions.IndexOf<FixedString128Bytes, FixedString128Bytes>(container.GetUnsafePtr(), container.Length, new FixedString128Bytes("456")));
57
58 Assert.True(r1);
59 Assert.True(NativeArrayExtensions.Contains<FixedString128Bytes, FixedString128Bytes>(container.GetUnsafePtr(), container.Length, new FixedString128Bytes("123")));
60
61 Assert.True(r2);
62 Assert.True(NativeArrayExtensions.Contains<FixedString128Bytes, FixedString128Bytes>(container.GetUnsafePtr(), container.Length, new FixedString128Bytes("789")));
63
64 container.Dispose();
65 }
66
67 [Test]
68 public void NativeArray_DisposeJob()
69 {
70 var container = new NativeArray<int>(1, Allocator.Persistent);
71 Assert.True(container.IsCreated);
72 Assert.DoesNotThrow(() => { container[0] = 1; });
73
74 var disposeJob = container.Dispose(default);
75 Assert.False(container.IsCreated);
76#if ENABLE_UNITY_COLLECTIONS_CHECKS
77 Assert.Throws<ObjectDisposedException>(
78 () => { container[0] = 2; });
79#endif
80
81 disposeJob.Complete();
82 }
83
84 [BurstCompile(CompileSynchronously = true)]
85 struct NativeArrayPokeJob : IJob
86 {
87 NativeArray<int> array;
88
89 public NativeArrayPokeJob(NativeArray<int> array) { this.array = array; }
90
91 public void Execute()
92 {
93 array[0] = 1;
94 }
95 }
96
97 [Test]
98 [TestRequiresCollectionChecks]
99 public void NativeArray_DisposeJobWithMissingDependencyThrows()
100 {
101 var array = new NativeArray<int>(1, Allocator.Persistent);
102 var deps = new NativeArrayPokeJob(array).Schedule();
103 Assert.Throws<InvalidOperationException>(() => { array.Dispose(default); });
104 deps.Complete();
105 array.Dispose();
106 }
107
108 [Test]
109 [TestRequiresCollectionChecks]
110 public void NativeArray_DisposeJobCantBeScheduled()
111 {
112 var array = new NativeArray<int>(1, Allocator.Persistent);
113 var deps = array.Dispose(default);
114 Assert.Throws<InvalidOperationException>(() => { new NativeArrayPokeJob(array).Schedule(deps); });
115 deps.Complete();
116 }
117
118 [Test]
119 unsafe public void NativeArray_ConvertExistingDataToNativeArray()
120 {
121 AllocatorManager.Initialize();
122 var allocatorHelper = new AllocatorHelper<RewindableAllocator>(AllocatorManager.Persistent);
123 allocatorHelper.Allocator.Initialize(64 * 1024);
124
125 var nativeList = new NativeList<int>(allocatorHelper.Allocator.Handle);
126 for(int i = 0; i < 20; i++)
127 {
128 nativeList.Add(i);
129 }
130
131 var nativeArray = CollectionHelper.ConvertExistingDataToNativeArray<int>(nativeList.GetUnsafePtr(), nativeList.Length, allocatorHelper.Allocator.Handle);
132
133#if ENABLE_UNITY_COLLECTIONS_CHECKS
134 var listSafety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref nativeList);
135 NativeArrayUnsafeUtility.SetAtomicSafetyHandle<int>(ref nativeArray, listSafety);
136#endif
137
138 for (int i = 0; i < 20; i++)
139 {
140 Assert.AreEqual(nativeArray[i], i);
141 }
142
143 nativeArray.Dispose();
144
145 allocatorHelper.Allocator.Dispose();
146 allocatorHelper.Dispose();
147 AllocatorManager.Shutdown();
148 }
149
150 [Test]
151 unsafe public void NativeArray_ConvertExistingDataToNativeArray_SetTempMemoryHandle()
152 {
153 var nativeList = new NativeList<int>(Allocator.Temp);
154 for (int i = 0; i < 20; i++)
155 {
156 nativeList.Add(i);
157 }
158
159 var nativeArray = CollectionHelper.ConvertExistingDataToNativeArray<int>(nativeList.GetUnsafePtr(), nativeList.Length, Allocator.Temp, true);
160
161 for (int i = 0; i < 20; i++)
162 {
163 Assert.AreEqual(nativeArray[i], i);
164 }
165
166 nativeArray.Dispose();
167 }
168
169 [Test]
170 unsafe public void NativeArray_ConvertExistingNativeListToNativeArray()
171 {
172 AllocatorManager.Initialize();
173 var allocatorHelper = new AllocatorHelper<RewindableAllocator>(AllocatorManager.Persistent);
174 allocatorHelper.Allocator.Initialize(64 * 1024);
175
176 var nativeList = new NativeList<int>(allocatorHelper.Allocator.Handle);
177 for (int i = 0; i < 20; i++)
178 {
179 nativeList.Add(i);
180 }
181
182 var nativeArray = CollectionHelper.ConvertExistingNativeListToNativeArray<int>(ref nativeList, nativeList.Length, allocatorHelper.Allocator.Handle);
183
184 for (int i = 0; i < 20; i++)
185 {
186 Assert.AreEqual(nativeArray[i], i);
187 }
188
189#if ENABLE_UNITY_COLLECTIONS_CHECKS
190 var listSafety = NativeListUnsafeUtility.GetAtomicSafetyHandle(ref nativeList);
191 var arraySafety = CollectionHelper.GetNativeArraySafetyHandle(ref nativeArray);
192 Assert.AreEqual(listSafety, arraySafety);
193#endif
194
195 nativeArray.Dispose();
196
197 allocatorHelper.Allocator.Dispose();
198 allocatorHelper.Dispose();
199 AllocatorManager.Shutdown();
200 }
201
202 [Ignore("Wait for DOTS-7576 trunk PR in")]
203 [Test]
204 public void NativeArray_CustomAllocator_DisposeException()
205 {
206 AllocatorManager.Initialize();
207 var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
208 ref var allocator = ref allocatorHelper.Allocator;
209 allocator.Initialize();
210
211 var nativeArray = CollectionHelper.CreateNativeArray<int>(100, allocator.ToAllocator, NativeArrayOptions.UninitializedMemory);
212 nativeArray[0] = 0xFE;
213
214 var nativeList = new NativeList<int>(allocator.ToAllocator);
215 for (int i = 0; i < 50; i++)
216 {
217 nativeList.Add(i);
218 }
219
220 Assert.IsTrue(allocator.WasUsed);
221
222 Assert.Throws<InvalidOperationException>(() => nativeArray.Dispose());
223
224 CollectionHelper.Dispose(nativeArray);
225 nativeList.Dispose();
226 allocator.Dispose();
227 allocatorHelper.Dispose();
228 AllocatorManager.Shutdown();
229 }
230
231 public struct SimpleTestJob : IJob
232 {
233 public int ElementValue;
234
235 [WriteOnly]
236 public NativeArray<int> Result;
237
238 public void Execute()
239 {
240 for (int i = 0; i < Result.Length; ++i)
241 Result[i] = ElementValue;
242 }
243 }
244
245 [Ignore("Wait for DOTS-7576 trunk PR in")]
246 [Test]
247 public void NativeArray_CustomAllocator_DisposeHandleException()
248 {
249 AllocatorManager.Initialize();
250 var allocatorHelper = new AllocatorHelper<CustomAllocatorTests.CountingAllocator>(AllocatorManager.Persistent);
251 ref var allocator = ref allocatorHelper.Allocator;
252 allocator.Initialize();
253
254 var nativeArray = CollectionHelper.CreateNativeArray<int>(100, allocator.ToAllocator, NativeArrayOptions.UninitializedMemory);
255
256 SimpleTestJob job = new SimpleTestJob()
257 {
258 ElementValue = 0xFE,
259 Result = nativeArray
260 };
261
262 var jobHandle = job.Schedule();
263 jobHandle.Complete();
264 Assert.IsTrue(allocator.WasUsed);
265 Assert.Throws<InvalidOperationException>(() => nativeArray.Dispose(jobHandle));
266
267 CollectionHelper.Dispose(nativeArray);
268 allocator.Dispose();
269 allocatorHelper.Dispose();
270 AllocatorManager.Shutdown();
271 }
272}