static void CopyBitsTest(ref UnsafeBitArray dstBitArray, int dstPos, ref UnsafeBitArray srcBitArray, int srcPos, int numBits) { for (int pos = 0; pos < dstBitArray.Length; pos += 64) { dstBitArray.SetBits(pos, 0xaaaaaaaaaaaaaaaaul, 64); } srcBitArray.SetBits(srcPos, true, numBits); dstBitArray.Copy(dstPos, ref srcBitArray, srcPos, numBits); Assert.AreEqual(true, dstBitArray.TestAll(dstPos, numBits)); for (int pos = 0; pos < dstBitArray.Length; ++pos) { if ((pos >= dstPos && pos < dstPos + numBits) || (pos >= srcPos && pos < srcPos + numBits)) { Assert.AreEqual(true, dstBitArray.IsSet(pos)); } else { Assert.AreEqual((0 != (pos & 1)), dstBitArray.IsSet(pos)); } } dstBitArray.Clear(); }
static void CopyBitsTest(ref UnsafeBitArray 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 UnsafeBitArray_CopyBetweenBitArrays() { var numBits = 512; var test0 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); var test1 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); var test2 = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); for (int pos = 0; pos < test0.Length; pos += 64) { test0.SetBits(pos, 0xaaaaaaaaaaaaaaaaul, 64); test1.SetBits(pos, 0x5555555555555555ul, 64); } var numCopyBits = 255; test0.SetBits(13, true, numCopyBits); test1.Copy(1, ref test0, 13, numCopyBits); Assert.AreEqual(true, test1.TestAll(1, numCopyBits)); test2.Copy(43, ref test1, 1, numCopyBits); Assert.AreEqual(true, test2.TestAll(43, numCopyBits)); test0.Dispose(); test1.Dispose(); test2.Dispose(); }
public void UnsafeBitArray_FindWithPattern() { var test = new UnsafeBitArray(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 unsafe void UnsafeBitArray_Find_With_Begin_End() { var numBits = 512; using (var test = new UnsafeBitArray(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}"); } } } }
static void GetBitsTest(ref UnsafeBitArray 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(); }
// Simple grassfire to calculate shortest distance along path to target position for every position. // - i.e. breadth-first expansion from target position. static void CalculateShortestWalkableDistancesToTarget(int rowCount, int colCount, byte *gridWalls, CartesianGridCoordinates targetPosition, NativeArray <int> targetDistances) { var cellCount = rowCount * colCount; var closed = new UnsafeBitArray(cellCount, Allocator.Temp, NativeArrayOptions.ClearMemory); var pending = new UnsafeBitArray(cellCount, Allocator.Temp, NativeArrayOptions.ClearMemory); var open = new UnsafeRingQueue <int>(cellCount, Allocator.Temp); var targetCellIndex = (targetPosition.y * colCount) + targetPosition.x; var cellIndexNorth = targetCellIndex + colCount; var cellIndexSouth = targetCellIndex - colCount; var cellIndexWest = targetCellIndex - 1; var cellIndexEast = targetCellIndex + 1; for (int i = 0; i < targetDistances.Length; i++) { targetDistances[i] = -1; } targetDistances[targetCellIndex] = 0; pending.Set(targetCellIndex, true); closed.Set(targetCellIndex, true); var validDirections = CartesianGridMovement.ValidDirections(targetPosition, rowCount, colCount, gridWalls); var validNorth = ((validDirections & (byte)CartesianGridDirectionBit.North) != 0); var validSouth = ((validDirections & (byte)CartesianGridDirectionBit.South) != 0); var validWest = ((validDirections & (byte)CartesianGridDirectionBit.West) != 0); var validEast = ((validDirections & (byte)CartesianGridDirectionBit.East) != 0); if (validNorth) { open.Enqueue(cellIndexNorth); pending.Set(cellIndexNorth, true); } if (validSouth) { open.Enqueue(cellIndexSouth); pending.Set(cellIndexSouth, true); } if (validWest) { open.Enqueue(cellIndexWest); pending.Set(cellIndexWest, true); } if (validEast) { open.Enqueue(cellIndexEast); pending.Set(cellIndexEast, true); } CalculateShortestWalkableDistancesToTargetInner(rowCount, colCount, gridWalls, targetDistances, pending, closed, open); closed.Dispose(); pending.Dispose(); open.Dispose(); }
public void UnsafeBitArray_FindLastUnsetBit([NUnit.Framework.Range(1, 64)] int numBits) { using (var bits = new UnsafeBitArray(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 unsafe void UnsafeBitArray_Find_Throws() { var numBits = 512; using (var test = new UnsafeBitArray(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 } }
NativeBitArray(int numBits, Allocator allocator, NativeArrayOptions options, int disposeSentinelStackDepth) { CheckAllocator(allocator); #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, disposeSentinelStackDepth, allocator); if (s_staticSafetyId.Data == 0) { CreateStaticSafetyId(); } AtomicSafetyHandle.SetStaticSafetyId(ref m_Safety, s_staticSafetyId.Data); #endif m_BitArray = new UnsafeBitArray(numBits, allocator, options); }
public void UnsafeBitArray_GetBits() { var numBits = 256; var test = new UnsafeBitArray(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); test.Dispose(); }
public unsafe void UnsafeBitArray_Throws() { var numBits = 256; var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); Assert.DoesNotThrow(() => { test.TestAll(0, numBits); }); Assert.Throws <ArgumentException>(() => { test.IsSet(-1); }); Assert.Throws <ArgumentException>(() => { test.IsSet(numBits); }); Assert.Throws <ArgumentException>(() => { new UnsafeBitArray(null, 7); /* check sizeInBytes must be multiple of 8-bytes. */ }); test.Dispose(); }
public void UnsafeBitArray_FindInTinyBitArray() { var test = new UnsafeBitArray(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 unsafe void UnsafeBitArray_Throws() { var numBits = 256; using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory)) { Assert.DoesNotThrow(() => { test.TestAll(0, numBits); }); Assert.Throws <ArgumentException>(() => { test.IsSet(-1); }); Assert.Throws <ArgumentException>(() => { test.IsSet(numBits); }); // 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); }); Assert.Throws <ArgumentException>(() => { new UnsafeBitArray(null, 7); /* check sizeInBytes must be multiple of 8-bytes. */ }); } }
void findWithPattern(ref UnsafeBitArray 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)); }
NativeBitArray(int numBits, Allocator allocator, NativeArrayOptions options, int disposeSentinelStackDepth) { if (allocator <= Allocator.None) { throw new ArgumentException("Allocator must be Temp, TempJob or Persistent", nameof(allocator)); } #if ENABLE_UNITY_COLLECTIONS_CHECKS DisposeSentinel.Create(out m_Safety, out m_DisposeSentinel, disposeSentinelStackDepth, allocator); #if UNITY_2020_1_OR_NEWER if (s_staticSafetyId.Data == 0) { CreateStaticSafetyId(); } AtomicSafetyHandle.SetStaticSafetyId(ref m_Safety, s_staticSafetyId.Data); #endif #endif m_BitArray = new UnsafeBitArray(numBits, allocator, options); }
public unsafe void UnsafeBitArray_Copy_Throws() { var numBits = 512; var test = new UnsafeBitArray(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(); }
private void Start() { //module.Init(); //var replace = module.Replace("ιδΈθ3r3r"); //Debug.Log(replace); //this.TestCollectionHelp(); var bitArray = new UnsafeBitArray(129, Allocator.Temp); bitArray.Set(0, true); bitArray.Set(1, true); bitArray.Set(5, true); Debug.Log("Length:" + bitArray.Length); for (int i = 0; i < bitArray.Length; i++) { var value = bitArray.GetBits(i); Debug.Log("index:" + i); var value2 = bitArray.TestAll(i); Debug.Log(value2); } }
public void UnsafeBitArray_Get_Set() { var numBits = 256; var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); Assert.False(test.IsSet(123)); test.Set(123, true); Assert.True(test.IsSet(123)); Assert.False(test.TestAll(0, numBits)); Assert.False(test.TestNone(0, numBits)); Assert.True(test.TestAny(0, numBits)); Assert.AreEqual(1, test.CountBits(0, numBits)); Assert.False(test.TestAll(0, 122)); Assert.True(test.TestNone(0, 122)); Assert.False(test.TestAny(0, 122)); test.Clear(); Assert.False(test.IsSet(123)); Assert.AreEqual(0, test.CountBits(0, numBits)); test.SetBits(40, true, 4); Assert.AreEqual(4, test.CountBits(0, numBits)); test.SetBits(0, true, numBits); Assert.False(test.TestNone(0, numBits)); Assert.True(test.TestAll(0, numBits)); test.SetBits(0, false, numBits); Assert.True(test.TestNone(0, numBits)); Assert.False(test.TestAll(0, numBits)); test.SetBits(123, true, 7); Assert.True(test.TestAll(123, 7)); test.Dispose(); }
public void UnsafeBitArray_Copy() { var numBits = 512; var test = new UnsafeBitArray(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(); }
public unsafe void UnsafeBitArray_Find() { var numBits = 512; using (var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory)) { test.SetBits(0, true, 11); for (var i = 0; i < 256; ++i) { Assert.AreEqual(11, test.Find(0, i + 1)); } for (var j = 0; j < 64; ++j) { for (var i = 0; i < 256; ++i) { var numBitsToFind = 7 + i; var pos = 37 + j; test.SetBits(0, true, test.Length); test.SetBits(pos, false, numBitsToFind); Assert.AreEqual(pos, test.Find(0, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}"); Assert.AreEqual(pos, test.Find(pos, numBitsToFind), $"{j}/{i}:pos {pos}, numBitsToFind {numBitsToFind}"); Assert.AreEqual(pos, test.Find(0, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}"); Assert.AreEqual(pos, test.Find(pos, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}"); Assert.IsTrue(test.TestNone(test.Find(0, numBitsToFind), numBitsToFind)); Assert.AreEqual(int.MaxValue, test.Find(pos + 1, numBitsToFind), $"{j}/{i}: pos {pos}, numBitsToFind {numBitsToFind}"); } } } }
public void UnsafeBitArray_Get_Set_Short() { var numBits = 31; var test = new UnsafeBitArray(numBits, Allocator.Persistent, NativeArrayOptions.ClearMemory); Assert.False(test.IsSet(13)); test.Set(13, true); Assert.True(test.IsSet(13)); Assert.False(test.TestAll(0, numBits)); Assert.False(test.TestNone(0, numBits)); Assert.True(test.TestAny(0, numBits)); Assert.AreEqual(1, test.CountBits(0, numBits)); Assert.False(test.TestAll(0, 12)); Assert.True(test.TestNone(0, 12)); Assert.False(test.TestAny(0, 12)); test.Clear(); Assert.False(test.IsSet(13)); Assert.AreEqual(0, test.CountBits(0, numBits)); test.SetBits(4, true, 4); Assert.AreEqual(4, test.CountBits(0, numBits)); test.SetBits(0, true, numBits); Assert.False(test.TestNone(0, numBits)); Assert.True(test.TestAll(0, numBits)); test.SetBits(0, false, numBits); Assert.True(test.TestNone(0, numBits)); Assert.False(test.TestAll(0, numBits)); test.SetBits(13, true, 7); Assert.True(test.TestAll(13, 7)); test.Clear(); test.SetBits(4, true, 4); Assert.AreEqual(false, test.IsSet(3)); Assert.AreEqual(true, test.TestAll(4, 4)); Assert.AreEqual(false, test.IsSet(18)); Assert.AreEqual(4, test.CountBits(4, 4)); Assert.AreEqual(4, test.CountBits(0, numBits)); test.Clear(); test.SetBits(5, true, 2); Assert.AreEqual(false, test.IsSet(4)); Assert.AreEqual(true, test.TestAll(5, 2)); Assert.AreEqual(false, test.IsSet(17)); Assert.AreEqual(2, test.CountBits(4, 4)); Assert.AreEqual(2, test.CountBits(0, numBits)); test.Clear(); test.SetBits(6, true, 4); Assert.AreEqual(false, test.IsSet(5)); Assert.AreEqual(true, test.TestAll(6, 4)); Assert.AreEqual(false, test.IsSet(10)); Assert.AreEqual(4, test.CountBits(6, 4)); Assert.AreEqual(4, test.CountBits(0, numBits)); test.Dispose(); }
static void CalculateShortestWalkableDistancesToTargetInner(NativeArray <int> targetDistances, int rowCount, byte *gridWalls, float4x4 *faceLocalToLocal, UnsafeBitArray pending, UnsafeBitArray closed, UnsafeRingQueue <int> open) { var cellCount = rowCount * rowCount; var maxPathLength = 6 * (cellCount + 1); while (open.Length > 0) { var cellIndex = open.Dequeue(); var cellPosition = CartesianGridOnCubeUtility.CellFaceCoordinates(cellIndex, rowCount); var faceIndex = CartesianGridOnCubeUtility.CellFaceIndex(cellIndex, rowCount); var rowStride = (rowCount + 1) / 2; var faceStride = rowCount * rowStride; var faceGridWallsOffset = faceIndex * faceStride; var validDirections = CartesianGridMovement.ValidDirections(cellPosition, rowCount, rowCount, gridWalls + faceGridWallsOffset); var validNorth = ((validDirections & (byte)CartesianGridDirectionBit.North) != 0); var validSouth = ((validDirections & (byte)CartesianGridDirectionBit.South) != 0); var validWest = ((validDirections & (byte)CartesianGridDirectionBit.West) != 0); var validEast = ((validDirections & (byte)CartesianGridDirectionBit.East) != 0); var cellIndexNorth = CartesianGridOnCubeUtility.CellIndexNorth(cellIndex, rowCount, faceLocalToLocal); var cellIndexSouth = CartesianGridOnCubeUtility.CellIndexSouth(cellIndex, rowCount, faceLocalToLocal); var cellIndexWest = CartesianGridOnCubeUtility.CellIndexWest(cellIndex, rowCount, faceLocalToLocal); var cellIndexEast = CartesianGridOnCubeUtility.CellIndexEast(cellIndex, rowCount, faceLocalToLocal); var distanceNorth = maxPathLength; var distanceSouth = maxPathLength; var distanceEast = maxPathLength; var distanceWest = maxPathLength; var closedNorth = false; var closedSouth = false; var closedWest = false; var closedEast = false; if (validNorth) { if (closed.IsSet(cellIndexNorth)) { distanceNorth = targetDistances[cellIndexNorth]; closedNorth = true; } else if (!pending.IsSet(cellIndexNorth)) { open.Enqueue(cellIndexNorth); pending.Set(cellIndexNorth, true); } } if (validSouth) { if (closed.IsSet(cellIndexSouth)) { distanceSouth = targetDistances[cellIndexSouth]; closedSouth = true; } else if (!pending.IsSet(cellIndexSouth)) { open.Enqueue(cellIndexSouth); pending.Set(cellIndexSouth, true); } } if (validWest) { if (closed.IsSet(cellIndexWest)) { distanceWest = targetDistances[cellIndexWest]; closedWest = true; } else if (!pending.IsSet(cellIndexWest)) { open.Enqueue(cellIndexWest); pending.Set(cellIndexWest, true); } } if (validEast) { if (closed.IsSet(cellIndexEast)) { distanceEast = targetDistances[cellIndexEast]; closedEast = true; } else if (!pending.IsSet(cellIndexEast)) { open.Enqueue(cellIndexEast); pending.Set(cellIndexEast, true); } } var closedNeighbor = closedNorth || closedSouth || closedWest || closedEast; Assert.IsTrue(closedNeighbor); var bestDist = math.cmin(new int4(distanceNorth, distanceSouth, distanceEast, distanceWest)) + 1; Assert.IsFalse(bestDist > (maxPathLength + 1)); targetDistances[cellIndex] = bestDist; closed.Set(cellIndex, true); } }
static void CalculateShortestWalkableDistancesToTargetInner(int rowCount, int colCount, byte *gridWalls, NativeArray <int> targetDistances, UnsafeBitArray pending, UnsafeBitArray closed, UnsafeRingQueue <int> open) { var cellCount = rowCount * colCount; while (open.Count > 0) { var cellIndex = open.Dequeue(); var y = cellIndex / colCount; var x = cellIndex - (y * colCount); var cellPosition = new CartesianGridCoordinates { x = (short)x, y = (short)y }; var validDirections = CartesianGridMovement.ValidDirections(cellPosition, rowCount, colCount, gridWalls); var validNorth = ((validDirections & (byte)CartesianGridDirectionBit.North) != 0); var validSouth = ((validDirections & (byte)CartesianGridDirectionBit.South) != 0); var validWest = ((validDirections & (byte)CartesianGridDirectionBit.West) != 0); var validEast = ((validDirections & (byte)CartesianGridDirectionBit.East) != 0); var cellIndexNorth = cellIndex + colCount; var cellIndexSouth = cellIndex - colCount; var cellIndexWest = cellIndex - 1; var cellIndexEast = cellIndex + 1; var distanceNorth = cellCount + 1; var distanceSouth = cellCount + 1; var distanceEast = cellCount + 1; var distanceWest = cellCount + 1; if (validNorth) { if (closed.IsSet(cellIndexNorth)) { distanceNorth = targetDistances[cellIndexNorth]; } else if (!pending.IsSet(cellIndexNorth)) { open.Enqueue(cellIndexNorth); pending.Set(cellIndexNorth, true); } } if (validSouth) { if (closed.IsSet(cellIndexSouth)) { distanceSouth = targetDistances[cellIndexSouth]; } else if (!pending.IsSet(cellIndexSouth)) { open.Enqueue(cellIndexSouth); pending.Set(cellIndexSouth, true); } } if (validWest) { if (closed.IsSet(cellIndexWest)) { distanceWest = targetDistances[cellIndexWest]; } else if (!pending.IsSet(cellIndexWest)) { open.Enqueue(cellIndexWest); pending.Set(cellIndexWest, true); } } if (validEast) { if (closed.IsSet(cellIndexEast)) { distanceEast = targetDistances[cellIndexEast]; } else if (!pending.IsSet(cellIndexEast)) { open.Enqueue(cellIndexEast); pending.Set(cellIndexEast, true); } } var bestDist = math.cmin(new int4(distanceNorth, distanceSouth, distanceEast, distanceWest)) + 1; targetDistances[cellIndex] = bestDist; closed.Set(cellIndex, true); } }
// Simple grassfire to calculate shortest distance along path to target position for every position. // - i.e. breadth-first expansion from target position. static void CalculateShortestWalkableDistancesToTarget(NativeArray <int> targetDistances, int rowCount, byte *gridWalls, CartesianGridCoordinates targetPosition, CartesianGridOnCubeFace cubeFace, float4x4 *faceLocalToLocal) { var cellCount = rowCount * rowCount; var closed = new UnsafeBitArray(6 * cellCount, Allocator.Temp, NativeArrayOptions.ClearMemory); var pending = new UnsafeBitArray(6 * cellCount, Allocator.Temp, NativeArrayOptions.ClearMemory); var open = new UnsafeRingQueue <int>(6 * cellCount, Allocator.Temp); var faceIndex = cubeFace.Value; var faceTargetCellIndex = (targetPosition.y * rowCount) + targetPosition.x; for (int i = 0; i < targetDistances.Length; i++) { targetDistances[i] = -1; } var targetCellIndex = (faceIndex * cellCount) + faceTargetCellIndex; targetDistances[targetCellIndex] = 0; pending.Set(targetCellIndex, true); closed.Set(targetCellIndex, true); var cellIndexNorth = CartesianGridOnCubeUtility.CellIndexNorth(targetCellIndex, rowCount, faceLocalToLocal); var cellIndexSouth = CartesianGridOnCubeUtility.CellIndexSouth(targetCellIndex, rowCount, faceLocalToLocal); var cellIndexWest = CartesianGridOnCubeUtility.CellIndexWest(targetCellIndex, rowCount, faceLocalToLocal); var cellIndexEast = CartesianGridOnCubeUtility.CellIndexEast(targetCellIndex, rowCount, faceLocalToLocal); var rowStride = (rowCount + 1) / 2; var faceStride = rowCount * rowStride; var faceGridWallsOffset = faceIndex * faceStride; var validDirections = CartesianGridMovement.ValidDirections(targetPosition, rowCount, rowCount, gridWalls + faceGridWallsOffset); var validNorth = ((validDirections & (byte)CartesianGridDirectionBit.North) != 0); var validSouth = ((validDirections & (byte)CartesianGridDirectionBit.South) != 0); var validWest = ((validDirections & (byte)CartesianGridDirectionBit.West) != 0); var validEast = ((validDirections & (byte)CartesianGridDirectionBit.East) != 0); if (validNorth) { open.Enqueue(cellIndexNorth); pending.Set(cellIndexNorth, true); } if (validSouth) { open.Enqueue(cellIndexSouth); pending.Set(cellIndexSouth, true); } if (validWest) { open.Enqueue(cellIndexWest); pending.Set(cellIndexWest, true); } if (validEast) { open.Enqueue(cellIndexEast); pending.Set(cellIndexEast, true); } CalculateShortestWalkableDistancesToTargetInner(targetDistances, rowCount, gridWalls, faceLocalToLocal, pending, closed, open); closed.Dispose(); pending.Dispose(); open.Dispose(); }
static void SetBitsTest(ref UnsafeBitArray test, int pos, ulong value, int numBits) { test.SetBits(pos, value, numBits); Assert.AreEqual(value, test.GetBits(pos, numBits)); test.Clear(); }
static void CopyBitsTest(ref UnsafeBitArray test, int dstPos, int srcPos, int numBits) { CopyBitsTest(ref test, dstPos, ref test, srcPos, numBits); }
public void CheckInternalConsistency(object[] managedComponentData) { Assert.IsTrue(ManagedChangesTracker.Empty); var managedComponentIndices = new UnsafeBitArray(m_ManagedComponentIndex, Allocator.Temp); Assert.IsTrue(managedComponentData.Length >= m_ManagedComponentIndex); for (int i = m_ManagedComponentIndex; i < managedComponentData.Length; ++i) { Assert.IsNull(managedComponentData[i]); } // Iterate by archetype var entityCountByArchetype = 0; for (var i = 0; i < m_Archetypes.Length; ++i) { var archetype = m_Archetypes.Ptr[i]; int managedTypeBegin = archetype->FirstManagedComponent; int managedTypeEnd = archetype->ManagedComponentsEnd; var countInArchetype = 0; for (var j = 0; j < archetype->Chunks.Count; ++j) { var chunk = archetype->Chunks.p[j]; Assert.IsTrue(chunk->Archetype == archetype); Assert.IsTrue(chunk->Capacity >= chunk->Count); Assert.AreEqual(chunk->Count, archetype->Chunks.GetChunkEntityCount(j)); var chunkEntities = (Entity *)chunk->Buffer; AssertEntitiesExist(chunkEntities, chunk->Count); if (!chunk->Locked) { if (chunk->Count < chunk->Capacity) { if (archetype->NumSharedComponents == 0) { Assert.IsTrue(chunk->ListWithEmptySlotsIndex >= 0 && chunk->ListWithEmptySlotsIndex < archetype->ChunksWithEmptySlots.Length); Assert.IsTrue( chunk == archetype->ChunksWithEmptySlots.Ptr[chunk->ListWithEmptySlotsIndex]); } else { Assert.IsTrue(archetype->FreeChunksBySharedComponents.Contains(chunk)); } } } countInArchetype += chunk->Count; if (chunk->Archetype->HasChunkHeader) // Chunk entities with chunk components are not supported { Assert.IsFalse(chunk->Archetype->HasChunkComponents); } Assert.AreEqual(chunk->Archetype->HasChunkComponents, chunk->metaChunkEntity != Entity.Null); if (chunk->metaChunkEntity != Entity.Null) { var chunkHeaderTypeIndex = TypeManager.GetTypeIndex <ChunkHeader>(); AssertEntitiesExist(&chunk->metaChunkEntity, 1); AssertEntityHasComponent(chunk->metaChunkEntity, chunkHeaderTypeIndex); var chunkHeader = *(ChunkHeader *)GetComponentDataWithTypeRO(chunk->metaChunkEntity, chunkHeaderTypeIndex); Assert.IsTrue(chunk == chunkHeader.ArchetypeChunk.m_Chunk); var metaChunk = GetChunk(chunk->metaChunkEntity); Assert.IsTrue(metaChunk->Archetype == chunk->Archetype->MetaChunkArchetype); } for (int iType = managedTypeBegin; iType < managedTypeEnd; ++iType) { var managedIndicesInChunk = (int *)(chunk->Buffer + archetype->Offsets[iType]); for (int ie = 0; ie < chunk->Count; ++ie) { var index = managedIndicesInChunk[ie]; if (index == 0) { continue; } Assert.IsTrue(index < m_ManagedComponentIndex, "Managed component index in chunk is out of range."); Assert.IsFalse(managedComponentIndices.IsSet(index), "Managed component index is used multiple times."); managedComponentIndices.Set(index, true); } } } Assert.AreEqual(countInArchetype, archetype->EntityCount); entityCountByArchetype += countInArchetype; } for (int i = 0; i < m_ManagedComponentIndex; ++i) { Assert.AreEqual(managedComponentData[i] != null, managedComponentIndices.IsSet(i)); } var freeManagedIndices = (int *)m_ManagedComponentFreeIndex.Ptr; var freeManagedCount = m_ManagedComponentFreeIndex.Length / sizeof(int); for (int i = 0; i < freeManagedCount; ++i) { var index = freeManagedIndices[i]; Assert.IsTrue(0 < index && index < m_ManagedComponentIndex, "Managed component index in free list is out of range."); Assert.IsFalse(managedComponentIndices.IsSet(index), "Managed component was marked as free but is used in chunk."); managedComponentIndices.Set(index, true); } Assert.IsTrue(m_ManagedComponentIndex - 1 == 0 || managedComponentIndices.TestAll(1, m_ManagedComponentIndex - 1), "Managed component index has leaked."); managedComponentIndices.Dispose(); // Iterate by free list Assert.IsTrue(m_EntityInChunkByEntity[m_NextFreeEntityIndex].Chunk == null); var entityCountByFreeList = EntitiesCapacity; int freeIndex = m_NextFreeEntityIndex; while (freeIndex != -1) { Assert.IsTrue(m_EntityInChunkByEntity[freeIndex].Chunk == null); Assert.IsTrue(freeIndex < EntitiesCapacity); freeIndex = m_EntityInChunkByEntity[freeIndex].IndexInChunk; entityCountByFreeList--; } // iterate by entities var entityCountByEntities = 0; var entityType = TypeManager.GetTypeIndex <Entity>(); for (var i = 0; i != EntitiesCapacity; i++) { var chunk = m_EntityInChunkByEntity[i].Chunk; if (chunk == null) { continue; } entityCountByEntities++; var archetype = m_ArchetypeByEntity[i]; Assert.AreEqual((IntPtr)archetype, (IntPtr)chunk->Archetype); Assert.AreEqual(entityType, archetype->Types[0].TypeIndex); Assert.IsTrue(m_EntityInChunkByEntity[i].IndexInChunk < m_EntityInChunkByEntity[i].Chunk->Count); var entity = *(Entity *)ChunkDataUtility.GetComponentDataRO(m_EntityInChunkByEntity[i].Chunk, m_EntityInChunkByEntity[i].IndexInChunk, 0); Assert.AreEqual(i, entity.Index); Assert.AreEqual(m_VersionByEntity[i], entity.Version); Assert.IsTrue(Exists(entity)); } Assert.AreEqual(entityCountByEntities, entityCountByArchetype); // Enabling this fails SerializeEntitiesWorksWithBlobAssetReferences. // There is some special entity 0 usage in the serialization code. // @TODO: Review with simon looks like a potential leak? //Assert.AreEqual(entityCountByEntities, entityCountByFreeList); }
public UnsafeBitArrayDebugView(UnsafeBitArray data) { Data = data; }