Example #1
0
        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());
        }
Example #2
0
        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);
        }
Example #3
0
        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());
        }
Example #4
0
        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();
            });
        }
Example #5
0
        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"));
        }
Example #6
0
        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));
        }
Example #7
0
        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
            }
        }
Example #8
0
        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");
            }
        }
Example #9
0
        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);
        }
Example #10
0
        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"));
            }
        }
Example #11
0
        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;
        }