void GetBitsTest(ref NativeBitArray test, int pos, int numBits) { test.SetBits(pos, true, numBits); Assert.AreEqual(numBits, test.CountBits(0, test.Length)); Assert.AreEqual(0xfffffffffffffffful >> (64 - numBits), test.GetBits(pos, numBits)); test.Clear(); }
public unsafe void NativeBitArray_Find_With_Begin_End() { var numBits = 512; using (var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory)) { Assert.AreEqual(0, test.Find(0, 2, 1)); Assert.AreEqual(1, test.Find(1, 2, 1)); test.SetBits(0, true, 6); Assert.AreEqual(int.MaxValue, test.Find(0, 2, 1)); for (var j = 0; j < 64; ++j) { for (var i = 0; i < 256; ++i) { var numBitsToFind = 7 + i; var padding = 11; var begin = 37 + j; var end = begin + padding + numBitsToFind; var count = end - begin; test.Clear(); test.SetBits(begin, true, count); test.SetBits(begin + padding + 1, false, numBitsToFind - 1); Assert.AreEqual(begin + padding + 1, test.Find(begin, count, numBitsToFind - 1)); //, $"{j}/{i}: begin {begin}, end {end}, count {count}, numBitsToFind {numBitsToFind}"); Assert.AreEqual(int.MaxValue, test.Find(begin, count, numBitsToFind)); //, $"{j}/{i}: begin {begin}, end {end}, count {count}, numBitsToFind {numBitsToFind}"); } } } }
public void NativeBitArray_AtomicSafetyHandle_AllocatorTemp_UniqueStaticSafetyIds() { var numBits = 256; var test = new NativeBitArray(numBits, Allocator.Temp, NativeArrayOptions.ClearMemory); // All collections that use Allocator.Temp share the same core AtomicSafetyHandle. // This test verifies that containers can proceed to assign unique static safety IDs to each // AtomicSafetyHandle value, which will not be shared by other containers using Allocator.Temp. var test0 = new NativeBitArray(numBits, Allocator.Temp, NativeArrayOptions.ClearMemory); var test1 = new NativeBitArray(numBits, Allocator.Temp, NativeArrayOptions.ClearMemory); SetBitsTest(ref test0, 0, 16, 5); test0.Dispose(); Assert.That(() => test0.IsSet(0), #if UNITY_2020_2_OR_NEWER Throws.Exception.With.TypeOf <ObjectDisposedException>() #else Throws.InvalidOperationException #endif .With.Message.Contains($"The {test0.GetType()} has been deallocated")); SetBitsTest(ref test1, 0, 16, 5); test1.Dispose(); Assert.That(() => test1.IsSet(0), #if UNITY_2020_2_OR_NEWER Throws.Exception.With.TypeOf <ObjectDisposedException>() #else Throws.InvalidOperationException #endif .With.Message.Contains($"The {test1.GetType()} has been deallocated")); }
static void CopyBitsTest(ref NativeBitArray test, int dstPos, int srcPos, int numBits) { for (int pos = 0; pos < test.Length; pos += 64) { test.SetBits(pos, 0xaaaaaaaaaaaaaaaaul, 64); } test.SetBits(srcPos, true, numBits); test.Copy(dstPos, srcPos, numBits); Assert.AreEqual(true, test.TestAll(dstPos, numBits)); for (int pos = 0; pos < test.Length; ++pos) { if ((pos >= dstPos && pos < dstPos + numBits) || (pos >= srcPos && pos < srcPos + numBits)) { Assert.AreEqual(true, test.IsSet(pos)); } else { Assert.AreEqual((0 != (pos & 1)), test.IsSet(pos)); } } test.Clear(); }
public void NativeBitArray_FindWithPattern() { var test = new NativeBitArray(512, Allocator.Persistent, NativeArrayOptions.ClearMemory); // Separated test for some more interesting patterns findWithPattern(ref test, 0x81, 1); findWithPattern(ref test, 0x81, 2); findWithPattern(ref test, 0x81, 3); findWithPattern(ref test, 0x81, 6); findWithPattern(ref test, 0x88, 3); findWithPattern(ref test, 0x99, 2); findWithPattern(ref test, 0xaa, 1); findWithPattern(ref test, 0xc3, 1); findWithPattern(ref test, 0xc3, 2); findWithPattern(ref test, 0xc3, 4); findWithPattern(ref test, 0xe7, 1); findWithPattern(ref test, 0xe7, 2); // Test all patterns for (int i = 0; i < 256; i++) { findWithPattern(ref test, (byte)i, 1); } test.Dispose(); }
public void NativeBitArray_AsNativeArray_Byte() { var numBits = 64; var test0 = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); var test1 = test0.AsNativeArray <byte>(); Assert.AreEqual(numBits / 8, test1.Length); test1[0] = 0x10; test1[1] = 0x32; test1[2] = 0x54; test1[3] = 0x76; test1[4] = 0x98; test1[5] = 0xba; test1[6] = 0xdc; test1[7] = 0xfe; for (var i = 0; i < 16; ++i) { Assert.AreEqual(i, test0.GetBits(i * 4, 4)); } test0.Dispose(); #if UNITY_2020_2_OR_NEWER test1.Dispose(); #endif }
static void SetBitsTest(ref NativeBitArray test, int pos, ulong value, int numBits) { test.SetBits(pos, value, numBits); if (value != test.GetBits(pos, numBits)) { throw new Exception("Assert.Equals(value, test.GetBits(pos, numBits)) failed"); } test.Clear(); }
public void NativeBitArray_AsNativeArray_ThrowsOnSizeMismatch() { var numBits = 64; var test0 = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); Assert.Throws <InvalidOperationException>(() => { test0.AsNativeArray <SizeMismatch128>(); }); Assert.Throws <InvalidOperationException>(() => { test0.AsNativeArray <SizeMismatch56>(); }); test0.Dispose(); }
public void Execute() { var numBits = 256; var test = new NativeBitArray(numBits, Allocator.Temp, NativeArrayOptions.ClearMemory); SetBitsTest(ref test, 0, 16, 5); test.Dispose(); SetBitsTest(ref test, 0, 16, 5); }
public void NativeBitArray_UseAfterFree_UsesCustomOwnerTypeName() { var numBits = 256; var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); SetBitsTest(ref test, 0, 16, 5); test.Dispose(); Assert.That(() => test.IsSet(0), Throws.InvalidOperationException.With.Message.Contains($"The {test.GetType()} has been deallocated")); }
public unsafe void NativeBitArray_Find_Throws() { var numBits = 512; using (var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory)) { Assert.Throws <ArgumentException>(() => { test.Find(0, 0, 1); }); // empty range Assert.Throws <ArgumentException>(() => { test.Find(0, 1, 0); }); // zero bits Assert.Throws <ArgumentException>(() => { test.Find(0, 1, 2); }); // numBits is larger than range Assert.Throws <ArgumentException>(() => { test.Find(10, 0, 0); }); // empty range, numBits is less than 1 Assert.Throws <ArgumentException>(() => { test.Find(1, 10, -2); }); // numBits can't be negative } }
public void NativeBitArray_FindLastUnsetBit([NUnit.Framework.Range(1, 64)] int numBits) { using (var bits = new NativeBitArray(numBits, Allocator.Persistent)) { // Set all bits to one then unset a single bit to find. for (int i = 0; i < numBits; ++i) { bits.SetBits(0, true, numBits); bits.Set(i, false); Assert.AreEqual(i, bits.Find(0, 1)); } } }
public void RunImmediate() { if (isLayerLayer) { var hitArrayA = new NativeBitArray(layerA.Count, Allocator.Temp, NativeArrayOptions.ClearMemory); var hitArrayB = new NativeBitArray(layerB.Count, Allocator.Temp, NativeArrayOptions.ClearMemory); var processor = new DebugFindPairsLayerLayerProcessor { hitArrayA = hitArrayA, hitArrayB = hitArrayB }; Physics.FindPairs(layerA, layerB, processor).RunImmediate(); var job = new DebugFindPairsDrawJob { layer = layerA, hitArray = hitArrayA, hitColor = hitColor, missColor = missColor, drawMisses = drawMisses }; for (int i = 0; i < layerA.Count; i++) { job.Execute(i); } job.hitArray = hitArrayB; job.layer = layerB; for (int i = 0; i < layerB.Count; i++) { job.Execute(i); } } else { var hitArray = new NativeBitArray(layerA.Count, Allocator.Temp, NativeArrayOptions.ClearMemory); var processor = new DebugFindPairsLayerSelfProcessor { hitArray = hitArray }; Physics.FindPairs(layerA, processor).RunImmediate(); var job = new DebugFindPairsDrawJob { layer = layerA, hitArray = hitArray, hitColor = hitColor, missColor = missColor, drawMisses = drawMisses }; for (int i = 0; i < layerA.Count; i++) { job.Execute(i); } } }
public static void EnsureMinimumSizeAndClear(ref NativeBitArray array, int minimumSize, Allocator allocator = Allocator.Temp) { if (!array.IsCreated || array.Length < minimumSize) { if (array.IsCreated) { array.Dispose(); } array = new NativeBitArray(minimumSize, Allocator.Temp); } else { array.Clear(); } }
public void NativeBitArray_SetBits() { var numBits = 256; var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); SetBitsTest(ref test, 0, 16, 5); SetBitsTest(ref test, 1, 7, 3); SetBitsTest(ref test, 1, 32, 64); SetBitsTest(ref test, 62, 6, 5); SetBitsTest(ref test, 127, 1, 3); SetBitsTest(ref test, 60, 0xaa, 8); test.Dispose(); }
public void NativeBitArray_ParallelReader() { var numBits = 256; var reader = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); reader.Set(7, true); var readerJob = new NativeBitArrayTestParallelReader { reader = reader }.Schedule(); reader.Dispose(readerJob); readerJob.Complete(); }
public void NativeBitArray_GetBits() { var numBits = 256; var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); GetBitsTest(ref test, 0, 5); GetBitsTest(ref test, 1, 3); GetBitsTest(ref test, 1, 64); GetBitsTest(ref test, 62, 5); GetBitsTest(ref test, 127, 3); GetBitsTest(ref test, 250, 6); GetBitsTest(ref test, 254, 2); test.Dispose(); }
public static void EnsureMinimumSizeAndClear(ref NativeBitArray array, int minimumSize, Allocator allocator = Allocator.Temp) { if (!array.IsCreated || array.Length < minimumSize) { if (array.IsCreated) { array.Dispose(); } array = new NativeBitArray(minimumSize, allocator); } else { array.SetBits(0, false, array.Length); //array.Clear(); // <= does not clear bits as you'd expect, is it broken? } }
public void NativeBitArray_FindInTinyBitArray() { var test = new NativeBitArray(3, Allocator.Persistent, NativeArrayOptions.ClearMemory); Assert.AreEqual(3, test.Length); test.SetBits(0, 0x55, test.Length); Assert.AreEqual(1, test.Find(0, 1)); Assert.AreEqual(1, test.Find(0, test.Length, 1)); test.SetBits(1, true, 1); Assert.True(test.TestAll(0, test.Length)); Assert.AreEqual(int.MaxValue, test.Find(0, test.Length, 1)); test.Dispose(); }
public void NativeBitArray_AsNativeArray_Ulong() { var numBits = 64; var test0 = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); var test1 = test0.AsNativeArray <ulong>(); Assert.AreEqual(numBits / 64, test1.Length); test1[0] = 0xfedcba9876543210; for (var i = 0; i < 16; ++i) { Assert.AreEqual(i, test0.GetBits(i * 4, 4)); } test0.Dispose(); test1.Dispose(); }
public void Run() { if (isLayerLayer) { var hitArrayA = new NativeBitArray(layerA.Count, Allocator.TempJob, NativeArrayOptions.ClearMemory); var hitArrayB = new NativeBitArray(layerB.Count, Allocator.TempJob, NativeArrayOptions.ClearMemory); var processor = new DebugFindPairsLayerLayerProcessor { hitArrayA = hitArrayA, hitArrayB = hitArrayB }; Physics.FindPairs(layerA, layerB, processor).Run(); var job = new DebugFindPairsDrawJob { layer = layerA, hitArray = hitArrayA, hitColor = hitColor, missColor = missColor, drawMisses = drawMisses }; job.Run(layerA.Count); job.hitArray = hitArrayB; job.layer = layerB; job.Run(layerB.Count); hitArrayA.Dispose(); hitArrayB.Dispose(); } else { var hitArray = new NativeBitArray(layerA.Count, Allocator.TempJob, NativeArrayOptions.ClearMemory); var processor = new DebugFindPairsLayerSelfProcessor { hitArray = hitArray }; Physics.FindPairs(layerA, processor).Run(); new DebugFindPairsDrawJob { layer = layerA, hitArray = hitArray, hitColor = hitColor, missColor = missColor, drawMisses = drawMisses }.Run(layerA.Count); hitArray.Dispose(); } }
public JobHandle ScheduleParallel(JobHandle inputDeps = default) { if (isLayerLayer) { var hitArrayA = new NativeBitArray(layerA.Count, Allocator.TempJob, NativeArrayOptions.ClearMemory); var hitArrayB = new NativeBitArray(layerB.Count, Allocator.TempJob, NativeArrayOptions.ClearMemory); var processor = new DebugFindPairsLayerLayerProcessor { hitArrayA = hitArrayA, hitArrayB = hitArrayB }; var jh = Physics.FindPairs(layerA, layerB, processor).ScheduleSingle(inputDeps); var job = new DebugFindPairsDrawJob { layer = layerA, hitArray = hitArrayA, hitColor = hitColor, missColor = missColor, drawMisses = drawMisses }; jh = job.ScheduleParallel(layerA.Count, 64, jh); job.hitArray = hitArrayB; job.layer = layerB; jh = job.ScheduleParallel(layerB.Count, 64, jh); jh = hitArrayA.Dispose(jh); return(hitArrayB.Dispose(jh)); } else { var hitArray = new NativeBitArray(layerA.Count, Allocator.TempJob, NativeArrayOptions.ClearMemory); var processor = new DebugFindPairsLayerSelfProcessor { hitArray = hitArray }; var jh = Physics.FindPairs(layerA, processor).ScheduleSingle(inputDeps); jh = new DebugFindPairsDrawJob { layer = layerA, hitArray = hitArray, hitColor = hitColor, missColor = missColor, drawMisses = drawMisses }.ScheduleParallel(layerA.Count, 64, jh); return(hitArray.Dispose(jh)); } }
void findWithPattern(ref NativeBitArray test, byte pattern, int numBits) { for (int pos = 0; pos < test.Length; pos += 8) { test.SetBits(pos, pattern, 8); } var bitCount = math.countbits((int)pattern); var numEmptyBits = test.Length - (test.Length / 8 * bitCount); for (int i = 0; i < numEmptyBits; i += numBits) { var pos = test.Find(0, numBits); Assert.AreNotEqual(int.MaxValue, pos, $"{i}"); test.SetBits(pos, true, numBits); } Assert.True(test.TestAll(0, test.Length)); }
public void NativeBitArray_ParallelReader() { var numBits = 256; var reader = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); reader.Set(7, true); var readerJob = new NativeBitArrayTestParallelReader { reader = reader }.Schedule(); var from = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); Assert.Throws <InvalidOperationException>(() => { reader.Copy(7, ref from, 30, 10); } /* attempt to write into reader after job is scheduled */); from.Dispose(); reader.Dispose(readerJob); readerJob.Complete(); }
public unsafe void NativeBitArray_Copy_Throws() { var numBits = 512; var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); Assert.Throws <ArgumentException>(() => { CopyBitsTest(ref test, 0, numBits - 1, 16); }); // short up to 64-bits copy out of bounds Assert.Throws <ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 0, 16); }); // short up to 64-bits copy out of bounds Assert.Throws <ArgumentException>(() => { CopyBitsTest(ref test, 0, numBits - 1, 80); }); // short up to 128-bits copy out of bounds Assert.Throws <ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 0, 80); }); // short up to 128-bits copy out of bounds Assert.Throws <ArgumentException>(() => { CopyBitsTest(ref test, 1, numBits - 7, 127); }); // long copy aligned Assert.Throws <ArgumentException>(() => { CopyBitsTest(ref test, numBits - 7, 1, 127); }); // long copy aligned Assert.Throws <ArgumentException>(() => { CopyBitsTest(ref test, 2, numBits - 1, 127); }); // long copy unaligned Assert.Throws <ArgumentException>(() => { CopyBitsTest(ref test, numBits - 1, 2, 127); }); // long copy unaligned test.Dispose(); }
public void NativeBitArray_CreateAndUseAfterFreeInBurstJob_UsesCustomOwnerTypeName() { // Make sure this isn't the first container of this type ever created, so that valid static safety data exists var numBits = 256; var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); test.Dispose(); var job = new NativeBitArrayCreateAndUseAfterFreeBurst { }; // Two things: // 1. This exception is logged, not thrown; thus, we use LogAssert to detect it. // 2. Calling write operation after container.Dispose() emits an unintuitive error message. For now, all this test cares about is whether it contains the // expected type name. job.Run(); LogAssert.Expect(LogType.Exception, new Regex($"InvalidOperationException: The {Regex.Escape(test.GetType().ToString())} has been declared as \\[ReadOnly\\] in the job, but you are writing to it")); }
public void NativeBitArray_AsNativeArray_Uint() { var numBits = 64; var test0 = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); var test1 = test0.AsNativeArray <uint>(); Assert.AreEqual(numBits / 32, test1.Length); test1[0] = 0x76543210; test1[1] = 0xfedcba98; for (var i = 0; i < 16; ++i) { Assert.AreEqual(i, test0.GetBits(i * 4, 4)); } test0.Dispose(); #if UNITY_2020_2_OR_NEWER test1.Dispose(); #endif }
public unsafe void NativeBitArray_CopyBetweenBitArrays() { var numBits = 512; var str = new FixedString128("aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"); AtomicSafetyHandle ash; DisposeSentinel ds; DisposeSentinel.Create(out ash, out ds, 1, Allocator.Temp); var test0 = NativeBitArrayUnsafeUtility.ConvertExistingDataToNativeBitArray(&str.bytes.offset0000, 64, Allocator.None); NativeBitArrayUnsafeUtility.SetAtomicSafetyHandle(ref test0, ash); var test1 = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); var test2 = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); for (int pos = 0; pos < test0.Length; pos += 64) { test1.SetBits(pos, 0x5555555555555555ul, 64); test2.SetBits(pos, 0xaaaaaaaaaaaaaaaaul, 64); } test1.Copy(1, ref test0, 205, 211); test1.Copy(214, ref test0, 0, 205); test2.Copy(205, ref test1, 1, 211); test2.Copy(0, ref test1, 214, 205); test0.Copy(0, ref test2, 0, 512); Assert.AreEqual(str, "aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ"); test0.Dispose(); test1.Dispose(); test2.Dispose(); }
public unsafe void NativeBitArray_Throws() { var numBits = 256; Assert.Throws <ArgumentException>(() => { new NativeBitArray(numBits, Allocator.None); }); using (var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory)) { Assert.DoesNotThrow(() => { test.TestAll(0, numBits); }); Assert.DoesNotThrow(() => { test.TestAny(numBits - 1, numBits); }); Assert.Throws <ArgumentException>(() => { test.IsSet(-1); }); Assert.Throws <ArgumentException>(() => { test.IsSet(numBits); }); Assert.Throws <ArgumentException>(() => { test.TestAny(0, 0); }); Assert.Throws <ArgumentException>(() => { test.TestAny(numBits, 1); }); Assert.Throws <ArgumentException>(() => { test.TestAny(numBits - 1, 0); }); // GetBits numBits must be 1-64. Assert.Throws <ArgumentException>(() => { test.GetBits(0, 0); }); Assert.Throws <ArgumentException>(() => { test.GetBits(0, 65); }); Assert.DoesNotThrow(() => { test.GetBits(63, 2); }); } }
public void NativeBitArray_Copy() { var numBits = 512; var test = new NativeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); CopyBitsTest(ref test, 1, 16, 12); // short up to 64-bits copy CopyBitsTest(ref test, 1, 80, 63); // short up to 64-bits copy CopyBitsTest(ref test, 1, 11, 12); // short up to 64-bits copy overlapped CopyBitsTest(ref test, 11, 1, 12); // short up to 64-bits copy overlapped CopyBitsTest(ref test, 1, 16, 76); // short up to 128-bits copy CopyBitsTest(ref test, 1, 80, 127); // short up to 128-bits copy CopyBitsTest(ref test, 1, 11, 76); // short up to 128-bits copy overlapped CopyBitsTest(ref test, 11, 1, 76); // short up to 128-bits copy overlapped CopyBitsTest(ref test, 1, 81, 255); // long copy aligned CopyBitsTest(ref test, 8, 0, 255); // long copy overlapped aligned CopyBitsTest(ref test, 1, 80, 255); // long copy unaligned CopyBitsTest(ref test, 80, 1, 255); // long copy overlapped unaligned test.Dispose(); }