A game about forced loneliness, made by TACStudios
at master 211 lines 6.6 kB view raw
1using NUnit.Framework; 2using System.Collections.Generic; 3using Unity.Jobs; 4using Unity.Burst; 5using Unity.Collections; 6using Unity.Collections.Tests; 7using Assert = FastAssert; 8using System; 9 10internal class NativeQueueTests_InJobs : CollectionsTestCommonBase 11{ 12 struct NestedContainerJob : IJob 13 { 14 public NativeQueue<NativeQueue<int>> nestedContainer; 15 16 public void Execute() 17 { 18 nestedContainer.Clear(); 19 } 20 } 21 22 [Test] 23 [TestRequiresCollectionChecks] 24 public void NativeQueue_NestedJob_Error() 25 { 26 var container = new NativeQueue<NativeQueue<int>>(CommonRwdAllocator.Handle); 27 28 var nestedJob = new NestedContainerJob 29 { 30 nestedContainer = container 31 }; 32 33 JobHandle job = default; 34 Assert.Throws<System.InvalidOperationException>(() => { job = nestedJob.Schedule(); }); 35 job.Complete(); 36 37 container.Dispose(); 38 } 39 40 [BurstCompile(CompileSynchronously = true)] 41 struct ConcurrentEnqueue : IJobParallelFor 42 { 43 public NativeQueue<int>.ParallelWriter queue; 44 45 [NativeDisableParallelForRestriction] 46 public NativeArray<int> result; 47 48 public int StartIndex; 49 50 public void Execute(int index) 51 { 52 index += StartIndex; 53 result[index] = 1; 54 queue.Enqueue(index); 55 } 56 } 57 58 [Test] 59 public void Enqueue() 60 { 61 const int queueSize = 100 * 1024; 62 var queue = new NativeQueue<int>(CommonRwdAllocator.Handle); 63 var writeStatus = CollectionHelper.CreateNativeArray<int>(queueSize, CommonRwdAllocator.Handle); 64 65 var enqueueJob = new ConcurrentEnqueue() 66 { 67 queue = queue.AsParallelWriter(), 68 result = writeStatus, 69 StartIndex = 0, 70 }; 71 72 var enqueue = enqueueJob.Schedule(queueSize, 1); 73 enqueue.Complete(); 74 75 Assert.AreEqual(queueSize, queue.Count, "Job enqueued the wrong number of values"); 76 var allValues = new NativeParallelHashSet<int>(queueSize, Allocator.Persistent); 77 for (int i = 0; i < queueSize; ++i) 78 { 79 Assert.AreEqual(1, writeStatus[i], "Job failed to enqueue value"); 80 int enqueued = queue.Dequeue(); 81 Assert.IsTrue(enqueued >= 0 && enqueued < queueSize, "Job enqueued invalid value"); 82 Assert.IsTrue(allValues.Add(enqueued), "Job enqueued same value multiple times"); 83 } 84 85 var disposeJob = queue.Dispose(enqueue); 86 disposeJob.Complete(); 87 88 writeStatus.Dispose(); 89 allValues.Dispose(); 90 } 91 92 [BurstCompile(CompileSynchronously = true)] 93 struct EnqueueDequeueJob : IJob 94 { 95 public NativeQueue<int> queue; 96 [ReadOnly] public NativeArray<int> arr; 97 public int val; 98 99 public void Execute() 100 { 101 for (int i = 0; i < 10000; ++i) 102 { 103 queue.Enqueue(0); 104 val += arr[queue.Dequeue()]; 105 } 106 } 107 } 108 109 [Test] 110 public void EnqueueDequeueMultipleQueuesInMultipleJobs() 111 { 112 var handles = new NativeArray<JobHandle>(4, Allocator.Temp); 113 for (int i = 0; i < 10; ++i) 114 { 115 var q1 = new NativeQueue<int>(CommonRwdAllocator.Handle); 116 var q2 = new NativeQueue<int>(CommonRwdAllocator.Handle); 117 var q3 = new NativeQueue<int>(CommonRwdAllocator.Handle); 118 var q4 = new NativeQueue<int>(CommonRwdAllocator.Handle); 119 var rangeCheck = CollectionHelper.CreateNativeArray<int>(1, CommonRwdAllocator.Handle); 120 var j1 = new EnqueueDequeueJob {queue = q1, arr = rangeCheck, val = 0}; 121 var j2 = new EnqueueDequeueJob {queue = q2, arr = rangeCheck, val = 0}; 122 var j3 = new EnqueueDequeueJob {queue = q3, arr = rangeCheck, val = 0}; 123 var j4 = new EnqueueDequeueJob {queue = q4, arr = rangeCheck, val = 0}; 124 handles[0] = j1.Schedule(); 125 handles[1] = j2.Schedule(); 126 handles[2] = j3.Schedule(); 127 handles[3] = j4.Schedule(); 128 JobHandle.ScheduleBatchedJobs(); 129 130 JobHandle.CombineDependencies(handles).Complete(); 131 132 q1.Dispose(); 133 q2.Dispose(); 134 q3.Dispose(); 135 q4.Dispose(); 136 rangeCheck.Dispose(); 137 } 138 handles.Dispose(); 139 } 140 141 struct EnqueueJob : IJobParallelFor 142 { 143 public NativeQueue<int>.ParallelWriter Queue; 144 public void Execute(int index) 145 { 146 Queue.Enqueue(index); 147 } 148 } 149 150 [Test] 151 public void ToArray_WorksFromJobs() 152 { 153 using (var queue = new NativeQueue<int>(CommonRwdAllocator.Handle)) 154 { 155 new EnqueueJob 156 { 157 Queue = queue.AsParallelWriter() 158 }.Schedule(100, 10).Complete(); 159 Assert.AreEqual(100, queue.Count); 160 using (var arr = queue.ToArray(Allocator.Temp)) 161 { 162 Assert.AreEqual(100, arr.Length); 163 arr.Sort(); 164 for (int i = 0; i < arr.Length; i++) 165 Assert.AreEqual(i, arr[i]); 166 } 167 } 168 } 169 170 [Test] 171 public void NativeQueue_ParallelWriter() 172 { 173 const int queueSize = 100 * 1024; 174 var queue = new NativeQueue<int>(CommonRwdAllocator.Handle); 175 var writeStatus = CollectionHelper.CreateNativeArray<int>(queueSize, CommonRwdAllocator.Handle); 176 177 var jobHandle = new ConcurrentEnqueue() 178 { 179 queue = queue.AsParallelWriter(), 180 result = writeStatus, 181 StartIndex = 0, 182 183 }.Schedule(queueSize / 2, 1); 184 185 jobHandle = new ConcurrentEnqueue() 186 { 187 queue = queue.AsParallelWriter(), 188 result = writeStatus, 189 StartIndex = queueSize / 2, 190 191 }.Schedule(queueSize / 2, 1, jobHandle); 192 193 jobHandle.Complete(); 194 195 Assert.AreEqual(queueSize, queue.Count, "Job enqueued the wrong number of values"); 196 var allValues = new NativeParallelHashSet<int>(queueSize, Allocator.Persistent); 197 for (int i = 0; i < queueSize; ++i) 198 { 199 Assert.AreEqual(1, writeStatus[i], "Job failed to enqueue value"); 200 int enqueued = queue.Dequeue(); 201 Assert.IsTrue(enqueued >= 0 && enqueued < queueSize, "Job enqueued invalid value"); 202 Assert.IsTrue(allValues.Add(enqueued), "Job enqueued same value multiple times"); 203 } 204 205 var disposeJob = queue.Dispose(jobHandle); 206 disposeJob.Complete(); 207 208 writeStatus.Dispose(); 209 allValues.Dispose(); 210 } 211}