public void stress_test() { var subject = new PathIndex <ByteString>(); subject.Add("start", "start value"); long totalBytes = 0; for (int i = 0; i < 1000; i++) { var newKey = Convert.ToBase64String(Guid.NewGuid().ToByteArray()); var newValue = Convert.ToBase64String(Guid.NewGuid().ToByteArray()); totalBytes += newKey.Length; totalBytes += newValue.Length; subject.Add(newKey, newValue); } subject.Add("end", "end value"); Assert.That((string)subject.Get("start"), Is.EqualTo("start value")); Assert.That((string)subject.Get("end"), Is.EqualTo("end value")); using (var ms = new MemoryStream()) { subject.WriteTo(ms); Console.WriteLine($"Produced {totalBytes} bytes"); Console.WriteLine($"Stored {ms.Length} bytes"); } Console.WriteLine(subject.DiagnosticString()); }
public void can_remove_values_from_keys() { // Note -- we don't actually remove the key, just the value // This is the same as setting the value to null. var subject = new PathIndex <ByteString>(); subject.Add("my/path/1", "value1"); subject.Add("my/path/2", "value2"); subject.Add("my/other/path", "value3"); subject.Add("my/other/path/longer", "value4"); var r1 = subject.Get("my/path/2"); Assert.That((string)r1, Is.EqualTo("value2")); subject.Delete("my/path/2"); var r2 = subject.Get("my/other/path"); var r3 = subject.Get("my/path/1"); var r4 = subject.Get("my/path/2"); Assert.That((string)r2, Is.EqualTo("value3")); Assert.That((string)r3, Is.EqualTo("value1")); Assert.That((string)r4, Is.Null); }
public void can_add_keys_to_tree() { var subject = new PathIndex <ByteString>(); subject.Add("my/path/1", "value1"); subject.Add("my/other/path", "value2"); Console.WriteLine(subject.DiagnosticString()); }
public PaperRendererRegistry() { pathIndex = new PathIndex(); pathTemplateIndex = new Map <string, PaperRendererInfo>(); paperTypeIndex = new Map <Type, List <PaperRendererInfo> >(); // atrasando a inicialização do índex para liberar a inicialização do sistema Task.Run(async() => { await Task.Delay(500); InitializeIndex(); }); }
public void can_query_keys_using_a_partial_key() { var subject = new PathIndex <ByteString>(); subject.Add("my/path/1", "value1"); subject.Add("my/path/2", "value2"); subject.Add("my/other/path", "value3"); subject.Add("my/other/path/longer", "value4"); var result = subject.Search("my/pa"); Assert.That(string.Join(",", result), Is.EqualTo("my/path/1,my/path/2")); }
public void indexing_guid_values() { var source = new PathIndex <SerialGuid>(); var guid1 = Guid.NewGuid(); var guid2 = Guid.NewGuid(); source.Add("/etc/init.d/01-system.sh", guid1); source.Add("/etc/init.d/02-user.sh", guid2); Assert.That((Guid)source.Get("/etc/init.d/01-system.sh"), Is.EqualTo(guid1)); Assert.That((Guid)source.Get("/etc/init.d/02-user.sh"), Is.EqualTo(guid2)); Assert.That(source.Get("/etc/init.d/03-custom.sh"), Is.EqualTo(null)); }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { var entities = chunk.GetNativeArray(EntityType); var pathfindingParamsArray = chunk.GetNativeArray(PathfindingParamsType); var pathIndexArray = chunk.GetNativeArray(PathIndexType); var pathPositionBuffers = chunk.GetBufferAccessor(PathPositionType); for (int i = 0; i < chunk.Count; i++) { var pathfindingParams = pathfindingParamsArray[i]; var endNodeIndex = CalculateIndex(pathfindingParams.EndPosition.x, pathfindingParams.EndPosition.y, GridSize.x); var startNode = PathNodeArray[CalculateIndex(pathfindingParams.StartPosition.x, pathfindingParams.StartPosition.y, GridSize.x)]; startNode.GCost = 0; startNode.HCost = CalculateDistanceCost(new int2(startNode.X, startNode.Y), pathfindingParams.EndPosition); startNode.CalculateFCost(); startNode.CameFromNodeIndex = -1; PathNodeArray[startNode.Index] = startNode; NativeList <int> openList = new NativeList <int>(128, Allocator.Temp); NativeList <int> closedList = new NativeList <int>(128, Allocator.Temp); openList.Add(startNode.Index); int currentNodeIndex = GetLowestCostFNodeIndex(openList, PathNodeArray); var recursionCounter = 0; var flags = RecursivePathFinding(currentNodeIndex, endNodeIndex, openList, closedList, recursionCounter); DynamicBuffer <PathPosition> pathPositionBuffer = pathPositionBuffers[i]; pathPositionBuffer.Clear(); if (flags == 0)//Found Path { PathNode endNode = PathNodeArray[endNodeIndex]; CalculatePath(PathNodeArray, endNode, pathPositionBuffer); pathIndexArray[i] = new PathIndex { Value = pathPositionBuffer.Length - 1 }; } else { pathIndexArray[i] = new PathIndex { Value = -1 }; } openList.Dispose(); closedList.Dispose(); CommandBuffer.RemoveComponent <PathfindingParams>(chunkIndex, entities[i]); //removing the components removes the entity from our entity query } }
public void can_output_to_a_stream() { var subject = new PathIndex <ByteString>(); subject.Add("my/path/1", "value1"); subject.Add("my/path/2", "value2"); subject.Add("my/other/path", "value3"); subject.Add("my/other/path/longer", "value4"); using (var ms = new MemoryStream()) { subject.WriteTo(ms); Assert.That(ms.Length, Is.GreaterThan(10)); Console.WriteLine($"Wrote {ms.Length} bytes"); } }
public void can_query_keys_for_values() { var subject = new PathIndex <ByteString>(); subject.Add("my/path/1", "value1"); subject.Add("my/path/2", "value2"); subject.Add("my/other/path", "value3"); subject.Add("my/other/path/longer", "value4"); var r1 = subject.Get("my/path/2"); var r2 = subject.Get("my/other/path"); var r3 = subject.Get("not/here"); Assert.That((string)r1, Is.EqualTo("value2")); Assert.That((string)r2, Is.EqualTo("value3")); Assert.That(r3, Is.Null); }
public void can_read_from_a_stream() { var source = new PathIndex <ByteString>(); source.Add("my/path/1", "value1"); source.Add("my/path/2", "value2"); source.Add("my/other/path", "value3"); source.Add("my/other/path/longer", "value4"); using (var ms = new MemoryStream()) { source.WriteTo(ms); ms.Seek(0, SeekOrigin.Begin); var target = PathIndex <ByteString> .ReadFrom(ms); Assert.That((string)target.Get("my/path/1"), Is.EqualTo("value1")); Assert.That((string)target.Get("my/path/2"), Is.EqualTo("value2")); Assert.That((string)target.Get("my/other/path"), Is.EqualTo("value3")); Assert.That((string)target.Get("my/other/path/longer"), Is.EqualTo("value4")); } }
public void Execute(ArchetypeChunk chunk, int chunkIndex, int firstEntityIndex) { NativeArray <PathFindingRequest> chunkPathFindingRequest = chunk.GetNativeArray(pathFindingRequestType); BufferAccessor <PathPositions> chunkPathPositions = chunk.GetBufferAccessor(pathPositionType); NativeArray <PathIndex> chunkPathIndex = chunk.GetNativeArray(pathIndexType); NativeArray <int> cameFrom = new NativeArray <int>(waypoints.Length, Allocator.Temp); NativeArray <float> totalCost = new NativeArray <float>(waypoints.Length, Allocator.Temp); //TODO Change container to have something more optimized NativeList <int> openList = new NativeList <int>(Allocator.Temp); NativeList <int> closedList = new NativeList <int>(Allocator.Temp); for (int entityIdx = 0; entityIdx < chunk.ChunkEntityCount; entityIdx++) { for (int i = 0; i < waypoints.Length; i++) { cameFrom[i] = 0; } for (int i = 0; i < totalCost.Length; i++) { totalCost[i] = float.MaxValue; } openList.Clear(); closedList.Clear(); //Get start and end index int startIndex = GetClosestNodeIndex(chunkPathFindingRequest[entityIdx].startPos, waypoints); int endIndex = GetClosestNodeIndex(chunkPathFindingRequest[entityIdx].endPos, waypoints); //Security if startIndex == endIndex if (startIndex == endIndex) { //Create new path chunkPathPositions[entityIdx].Clear(); chunkPathPositions[entityIdx].Add(new PathPositions() { Value = chunkPathFindingRequest[entityIdx].endPos }); chunkPathPositions[entityIdx].Add(new PathPositions() { Value = waypoints[startIndex].position }); //Assign index chunkPathIndex[entityIdx] = new PathIndex { Value = chunkPathPositions[entityIdx].Length - 1 }; return; } totalCost[startIndex] = 0; openList.Add(startIndex); while (openList.Length > 0) { int currentIndex = 0; //Get lowest cost node float lowestCost = totalCost[openList[0]]; int indexToRemove = 0; for (int i = 1; i < openList.Length; i++) { if (!(totalCost[openList[i]] < lowestCost)) { continue; } lowestCost = totalCost[openList[i]]; indexToRemove = i; } currentIndex = openList[indexToRemove]; openList.RemoveAt(indexToRemove); //Add to closed list closedList.Add(currentIndex); //If the current node is the end node then the algorithm is finished if (currentIndex == endIndex) { break; } //Check neighbors for (int i = 0; i < waypoints[currentIndex].neigborCount; i++) { int neighborLinkIndex = i + waypoints[currentIndex].firstNeighbors; int neighborIndex = Neighbors[neighborLinkIndex].neighborsIndex; //Compute new cost float newCost = totalCost[currentIndex] + //Total cost Neighbors[neighborLinkIndex].moveCost + //Move cost math.distance(waypoints[neighborIndex].position, waypoints[endIndex].position); //Heuristic cost if (!(newCost < totalCost[neighborIndex])) { continue; } totalCost[neighborIndex] = newCost; cameFrom[neighborIndex] = currentIndex; if (!openList.Contains(neighborIndex)) { openList.Add(neighborIndex); } } } //Calculate path chunkPathPositions[entityIdx].Clear(); CreatePath(chunkPathPositions[entityIdx], cameFrom, endIndex, startIndex, chunkPathFindingRequest[entityIdx].endPos, waypoints); chunkPathIndex[entityIdx] = new PathIndex { Value = chunkPathPositions[entityIdx].Length - 1 }; } //Dispose every temporary allocated container cameFrom.Dispose(); totalCost.Dispose(); openList.Dispose(); closedList.Dispose(); }
public void Execute(int jobIndex) { #region SETUP // Get the current entity Entity entity = entities[jobIndex]; pathPositionBuffer[entity].Clear(); pathIndexComponentData[entity] = new PathIndex { index = -1 }; // Get grid positions from world positions (float2 -> int2) float2 startGridPositionAsFloat = new float2( startWorldPositions[jobIndex].x / graphCellSize, startWorldPositions[jobIndex].y / graphCellSize); float2 endGridPositionAsFloat = new float2( endWorldPositions[jobIndex].x / graphCellSize, endWorldPositions[jobIndex].y / graphCellSize); int2 startGridPosition = new int2( ( int )math.round(startGridPositionAsFloat.x), ( int )math.round(startGridPositionAsFloat.y)); int2 endGridPosition = new int2( ( int )math.round(endGridPositionAsFloat.x), ( int )math.round(endGridPositionAsFloat.y)); // Get the cluster positions from the grid positions int2 startClusterPosition = new int2( startGridPosition.x / graphClusterLength, startGridPosition.y / graphClusterLength); int2 endClusterPosition = new int2( endGridPosition.x / graphClusterLength, endGridPosition.y / graphClusterLength); #endregion #region MEAT // If the start and end positions are in different clusters if (!startClusterPosition.Equals(endClusterPosition)) { // Get the start and end node indexes from their grid cluster positions int clusterIndex = startClusterPosition.x + startClusterPosition.y * graphNumClusters; int2 clusterEdgesKey = graphClusterEdgesLists[clusterIndex]; // Check every edge in the cluster to see if we can reach it, and add it to the list if we can NativeList <int> startEdges = new NativeList <int>(Allocator.Temp); for (int edgeIndex = clusterEdgesKey.x; edgeIndex < clusterEdgesKey.y; edgeIndex++) { startEdges.Add(graphIntraEdges[edgeIndex]); } // If there are no paths from start position to any of the edges in current cluster, break out if (startEdges.Length != 0) { NativeList <int3> abstractPath = FindAbstractPath(startEdges, startGridPosition, endGridPosition); if (abstractPath.Length > 0) { NativeList <int2> concretePath = FindConcretePath(abstractPath); // Write final path to entity buffer float2 pathPosition = new float2(0, 0); for (int i = 0; i < concretePath.Length; i++) { pathPosition = new float2( concretePath[i].x * graphCellSize, concretePath[i].y * graphCellSize); pathPositionBuffer[entity].Add( new PathPosition { position = pathPosition }); } pathIndexComponentData[entity] = new PathIndex { index = pathPositionBuffer[entity].Length - 1 }; concretePath.Dispose(); abstractPath.Dispose(); startEdges.Dispose(); return; } else { pathIndexComponentData[entity] = new PathIndex { index = -1 }; startEdges.Dispose(); abstractPath.Dispose(); return; } } else { pathIndexComponentData[entity] = new PathIndex { index = -1 }; startEdges.Dispose(); return; } } else // OTHERWISE, the start and end positions are in the same cluster, so just do a quick low-level a* search { NativeList <int2> path = FindLowLevelPathInCluster(startGridPosition, endGridPosition, startClusterPosition); if (path.Length > 0) { float2 pathPosition = new float2(0, 0); for (int i = 0; i < path.Length; i++) { pathPosition = new float2( path[i].x * graphCellSize, path[i].y * graphCellSize); pathPositionBuffer[entity].Add( new PathPosition { position = pathPosition }); } pathIndexComponentData[entity] = new PathIndex { index = pathPositionBuffer[entity].Length - 1 }; } else { pathIndexComponentData[entity] = new PathIndex { index = -1 }; } path.Dispose(); return; } #endregion }
public void Execute(int jobIndex) { Entity entity = entities[jobIndex]; float2 startGridPositionAsFloat = startWorldPositions[jobIndex] / graphCellSize; float2 endGridPositionAsFloat = endWorldPositions[jobIndex] / graphCellSize; int2 startGridPosition = ( int2 )math.round(startGridPositionAsFloat); int2 endGridPosition = ( int2 )math.round(endGridPositionAsFloat); int2 startClusterPosition = startGridPosition / graphClusterSize; int2 endClusterPosition = endGridPosition / graphClusterSize; pathfindingStateComponentData[entity] = new FormationPathFindingState { Value = PathfindingState.free }; // If the start and end positions are in different clusters if (!startClusterPosition.Equals(endClusterPosition)) { int clusterIndex = startClusterPosition.x + startClusterPosition.y * graphNumClusters; int2 clusterEdgesKey = graphClusterEdgesLists[clusterIndex]; // If there are no paths from start position to any of the edges in current cluster, break out if (clusterEdgesKey.y - clusterEdgesKey.x > 0) { NativeList <AbstractNode> abstractPath = FindAbstractPathInGraph(clusterEdgesKey, startGridPosition, endGridPosition); if (abstractPath.Length > 0) { pathPositionBufferEntity[entity].Clear(); pathPositionBufferEntity[entity].Add(new PathPosition { Value = endWorldPositions[jobIndex] }); NativeList <int2> concretePath = FindConcretePathFromAbstract(abstractPath); for (int i = 1; i < concretePath.Length; i++) { float2 pathPosition = concretePath[i] * graphCellSize; pathPositionBufferEntity[entity].Add(new PathPosition { Value = pathPosition }); } pathIndexComponentData[entity] = new PathIndex { Value = pathPositionBufferEntity[entity].Length - 1 }; concretePath.Dispose(); abstractPath.Dispose(); return; } abstractPath.Dispose(); } } else // OTHERWISE, the start and end positions are in the same cluster, so just do a quick low-level a* search { FixedList4096 <int2> path = FindLowLevelPathInCluster(startGridPosition, endGridPosition, startClusterPosition); if (path.Length > 0) { pathPositionBufferEntity[entity].Clear(); pathPositionBufferEntity[entity].Add(new PathPosition { Value = endWorldPositions[jobIndex] }); for (int i = 1; i < path.Length; i++) { float2 pathPosition = path[i] * graphCellSize; pathPositionBufferEntity[entity].Add(new PathPosition { Value = pathPosition }); } pathIndexComponentData[entity] = new PathIndex { Value = pathPositionBufferEntity[entity].Length - 1 }; return; } } // If no path was found we will reach here return; }