A game about forced loneliness, made by TACStudios
1using System;
2using NUnit.Framework;
3using Unity.Collections;
4using Unity.Collections.LowLevel.Unsafe;
5using Unity.Jobs;
6using Unity.Jobs.LowLevel.Unsafe;
7using Unity.Jobs.Tests.ManagedJobs;
8
9internal class NativeListDeferredArrayTests : JobTestsFixtureBasic
10{
11 private bool JobsDebuggerWasEnabled;
12 struct AliasJob : IJob
13 {
14 public NativeArray<int> array;
15 public NativeList<int> list;
16
17 public void Execute()
18 {
19 }
20 }
21
22 struct SetListLengthJob : IJob
23 {
24 public int ResizeLength;
25 public NativeList<int> list;
26
27 public void Execute()
28 {
29 list.Resize(ResizeLength, NativeArrayOptions.UninitializedMemory);
30 }
31 }
32
33 struct SetArrayValuesJobParallel : IJobParallelForDefer
34 {
35 public NativeArray<int> array;
36
37 public void Execute(int index)
38 {
39 array[index] = array.Length;
40 }
41 }
42
43 struct GetArrayValuesJobParallel : IJobParallelForDefer
44 {
45 [ReadOnly]
46 public NativeArray<int> array;
47
48 public void Execute(int index)
49 {
50 }
51 }
52
53
54 struct ParallelForWithoutList : IJobParallelForDefer
55 {
56 public void Execute(int index)
57 {
58 }
59 }
60
61 [SetUp]
62 public void NativeListDeferredArrayTestsSetup()
63 {
64 // Many ECS tests will only pass if the Jobs Debugger enabled;
65 // force it enabled for all tests, and restore the original value at teardown.
66 JobsDebuggerWasEnabled = JobsUtility.JobDebuggerEnabled;
67#if ENABLE_UNITY_COLLECTIONS_CHECKS
68 JobsUtility.JobDebuggerEnabled = true;
69#endif
70 }
71
72 [Test]
73 public void ResizedListToDeferredJobArray([Values(0, 1, 2, 3, 4, 5, 6, 42, 97, 1023)] int length)
74 {
75 var list = new NativeList<int>(RwdAllocator.ToAllocator);
76
77 var setLengthJob = new SetListLengthJob { list = list, ResizeLength = length };
78 var jobHandle = setLengthJob.Schedule();
79
80 var setValuesJob = new SetArrayValuesJobParallel { array = list.AsDeferredJobArray() };
81 setValuesJob.Schedule(list, 3, jobHandle).Complete();
82
83 Assert.AreEqual(length, list.Length);
84 for (int i = 0; i != list.Length; i++)
85 Assert.AreEqual(length, list[i]);
86 }
87
88 [Test]
89 public unsafe void DeferredParallelForFromIntPtr()
90 {
91 int length = 10;
92
93 var lengthValue = CollectionHelper.CreateNativeArray<int>(1, RwdAllocator.ToAllocator);
94 lengthValue[0] = length;
95 var array = CollectionHelper.CreateNativeArray<int>(length, RwdAllocator.ToAllocator);
96
97 var setValuesJob = new SetArrayValuesJobParallel { array = array };
98 setValuesJob.Schedule((int*)lengthValue.GetUnsafePtr(), 3).Complete();
99
100 for (int i = 0; i != array.Length; i++)
101 Assert.AreEqual(length, array[i]);
102 }
103
104 [Test]
105 public void ResizeListBeforeSchedule([Values(5)] int length)
106 {
107 var list = new NativeList<int>(RwdAllocator.ToAllocator);
108
109 var setLengthJob = new SetListLengthJob { list = list, ResizeLength = length }.Schedule();
110 var setValuesJob = new SetArrayValuesJobParallel { array = list.AsDeferredJobArray() };
111 setLengthJob.Complete();
112
113 setValuesJob.Schedule(list, 3).Complete();
114
115 Assert.AreEqual(length, list.Length);
116 for (int i = 0; i != list.Length; i++)
117 Assert.AreEqual(length, list[i]);
118 }
119
120#if ENABLE_UNITY_COLLECTIONS_CHECKS
121 [Test]
122 public void ResizedListToDeferredJobArray()
123 {
124 var list = new NativeList<int>(RwdAllocator.ToAllocator);
125 list.Add(1);
126
127 var array = list.AsDeferredJobArray();
128#pragma warning disable 0219 // assigned but its value is never used
129 Assert.Throws<IndexOutOfRangeException>(() => { var value = array[0]; });
130#pragma warning restore 0219
131 Assert.AreEqual(0, array.Length);
132 }
133
134 [Test]
135 public void ResizeListWhileJobIsRunning()
136 {
137 var list = new NativeList<int>(RwdAllocator.ToAllocator);
138 list.Resize(42, NativeArrayOptions.UninitializedMemory);
139
140 var setValuesJob = new GetArrayValuesJobParallel { array = list.AsDeferredJobArray() };
141 var jobHandle = setValuesJob.Schedule(list, 3);
142
143 Assert.Throws<InvalidOperationException>(() => list.Resize(1, NativeArrayOptions.UninitializedMemory));
144
145 jobHandle.Complete();
146 }
147
148 [Test]
149 public void AliasArrayThrows()
150 {
151 var list = new NativeList<int>(RwdAllocator.ToAllocator);
152
153 var aliasJob = new AliasJob { list = list, array = list.AsDeferredJobArray() };
154 Assert.Throws<InvalidOperationException>(() => aliasJob.Schedule());
155 }
156
157 [Test]
158 public void DeferredListMustExistInJobData()
159 {
160 var list = new NativeList<int>(RwdAllocator.ToAllocator);
161
162 var job = new ParallelForWithoutList();
163 Assert.Throws<InvalidOperationException>(() => job.Schedule(list, 64));
164 }
165
166 [Test]
167 public void DeferredListCantBeDeletedWhileJobIsRunning()
168 {
169 var list = new NativeList<int>(RwdAllocator.ToAllocator);
170 list.Resize(42, NativeArrayOptions.UninitializedMemory);
171
172 var setValuesJob = new GetArrayValuesJobParallel { array = list.AsDeferredJobArray() };
173 var jobHandle = setValuesJob.Schedule(list, 3);
174
175 Assert.Throws<InvalidOperationException>(() => list.Dispose());
176
177 jobHandle.Complete();
178 }
179
180 [Test]
181 public void DeferredArrayCantBeAccessedOnMainthread()
182 {
183 var list = new NativeList<int>(RwdAllocator.ToAllocator);
184 list.Add(1);
185
186 var defer = list.AsDeferredJobArray();
187
188 Assert.AreEqual(0, defer.Length);
189 Assert.Throws<IndexOutOfRangeException>(() => defer[0] = 5);
190 }
191#endif
192
193 [TearDown]
194 public void TearDown()
195 {
196#if ENABLE_UNITY_COLLECTIONS_CHECKS
197 JobsUtility.JobDebuggerEnabled = JobsDebuggerWasEnabled;
198#endif
199 }
200}