Search Unity

IJobParallelFor runtime error

Discussion in 'Data Oriented Technology Stack' started by DarthRayban, Dec 16, 2018.

  1. DarthRayban

    DarthRayban

    Joined:
    Apr 5, 2016
    Posts:
    7
    Hi, i'm new to ECS. I'm trying to write a pathfinding system; at first i used a IJobProcessComponentData and it worked but i noticed that that job didn't run in parallel. So i switched to IJobParallelFor, however i get this runtime error message:

    Code (CSharp):
    1. InvalidOperationException: Handle is not initialized.
    2. System.Runtime.InteropServices.GCHandle.Free () (at <ac823e2bb42b41bda67924a45a0173c3>:0)
    Here the code:

    Code (CSharp):
    1. public class AStarSystem : JobComponentSystem
    2. {  
    3.     //[BurstCompile]
    4.     private struct AStarJob : IJobParallelFor//IJobProcessComponentDataWithEntity<Agent, Target>
    5.     {
    6.         [ReadOnly] public EntityCommandBuffer Commands;
    7.         [ReadOnly] public ComponentDataFromEntity<Position> Positions;
    8.         [ReadOnly] public ComponentDataFromEntity<Walkable> Walkables;
    9.         [ReadOnly] private const int maxLength = 2500;
    10.         [ReadOnly] private const int maxX = 50;
    11.         public EntityArray NodeEntityArray;
    12.         public AgentGroup AgentGroup;
    13.  
    14.         public void Execute(int index)
    15.         {
    16.             int2 start = GridGenerator.ClosestNode(AgentGroup.Position[index].Value);
    17.             int2 goal = GridGenerator.ClosestNode(AgentGroup.Target[index].Value);
    18.             int2 goal2 = new int2(6,6);
    19.             AStarSolver(start, goal2);
    20.         }
    21.        
    22. //        public void Execute(Entity agent, int index, ref Agent data, ref Target target)
    23. //        {
    24. //            //Commands.RemoveComponent<Target>(agent);
    25. //            int2 start = GridGenerator.ClosestNode(Positions[agent].Value);
    26. //            int2 goal = GridGenerator.ClosestNode(target.Value);
    27. //            AStarSolver(new int2(0,0), new int2(5,5));
    28. //        }
    29.  
    30.         private void AStarSolver(int2 start, int2 goal)
    31.         {
    32.  
    33.             var openSet = new NativeMinHeap(maxLength, Allocator.TempJob);
    34.             var closedSet = new NativeArray<MinHeapNode>(maxLength, Allocator.TempJob);
    35.             var G_Costs = new NativeArray<int>(maxLength, Allocator.TempJob);
    36.             var neighbours = new NativeList<int2>(Allocator.TempJob);
    37.            
    38.             var startNode = new MinHeapNode(GridGenerator.grid[start.x,start.y], start.x, start.y);
    39.             openSet.Push(startNode);
    40.        
    41.             while (openSet.HasNext())
    42.             {
    43.                 //c++;
    44.                 var currentNode = openSet.Pop();
    45.  
    46.                 currentNode.IsClosed = 1;
    47.                 closedSet[GetIndex(currentNode.Position)] = currentNode;
    48.            
    49.                 //em.SetSharedComponentData(currentNode.NodeEntity, closedLook);
    50.  
    51.                 if (currentNode.Position.x == goal.x && currentNode.Position.y == goal.y)
    52.                 {
    53.                     var current = currentNode;
    54.                     while(current.ParentPosition.x != -1)
    55.                     {
    56.                         Commands.SetSharedComponent(current.NodeEntity, Bootstrap.pathLook);
    57.                         current = closedSet[GetIndex(current.ParentPosition)];
    58.                         //CreatePathStep(agent, i, path[i]);
    59.                     }
    60.                     Commands.SetSharedComponent(current.NodeEntity, Bootstrap.pathLook);
    61.                     break;
    62.                 }
    63.  
    64.                 GetNeighbours(currentNode.Position, ref neighbours);
    65.  
    66.                 for (int i = 0; i < neighbours.Length; i++)
    67.                 {
    68.                     if (closedSet[GetIndex(neighbours[i])].IsClosed == 1)
    69.                         continue;
    70.                
    71.                     int costSoFar = G_Costs[GetIndex(currentNode.Position)] + Heuristics.OctileDistance(currentNode.Position, neighbours[i]);
    72.  
    73.                     //em.SetSharedComponentData(GridGenerator.grid[neighbours[i].x,neighbours[i].y], openLook);
    74.  
    75.                     if (G_Costs[GetIndex(neighbours[i])] == 0 || costSoFar < G_Costs[GetIndex(neighbours[i])])
    76.                     {
    77.                         // update costs
    78.                    
    79.                         int g = costSoFar;
    80.                         int h = Heuristics.OctileDistance(neighbours[i], goal);
    81.                         int f = g + h;
    82.                    
    83.                         G_Costs[GetIndex(neighbours[i])] = g;
    84.                         var node = new MinHeapNode(GridGenerator.grid[neighbours[i].x,neighbours[i].y], neighbours[i], currentNode.Position, f, h);
    85.                         openSet.Push(node);
    86.                     }
    87.                 }  
    88.             }
    89.             openSet.Dispose();
    90.             closedSet.Dispose();
    91.             G_Costs.Dispose();
    92.             neighbours.Dispose();
    93.         }
    94.  
    95.         private void CreatePathStep(Entity agent, int index, float3 stepPos)
    96.         {
    97.             Commands.CreateEntity(Bootstrap._pathStepArchetype);
    98.             Commands.SetSharedComponent(new ParentAgent{Value = agent});
    99.             Commands.SetComponent(new PathIndex{Value = index});
    100.             Commands.SetComponent(new PathStep{Value = stepPos});
    101.         }
    102.  
    103.         private void GetNeighbours(int2 coords, ref NativeList<int2> neighbours)
    104.         {  
    105.             neighbours.Clear();
    106.             for (int x = -1; x <= 1; x++)
    107.             {
    108.                 var checkX = coords.x + x;
    109.                 for (int y = -1; y <= 1; y++)
    110.                 {
    111.                     if(x == 0 && y == 0)
    112.                         continue;
    113.  
    114.                     var checkY = coords.y + y;
    115.                     if (checkX >= 0 && checkX < GridGenerator.grid.GetLength(0) && checkY >= 0 && checkY < GridGenerator.grid.GetLength(1))
    116.                     {
    117.                         Entity checkNode = GridGenerator.grid[coords.x + x, coords.y + y];
    118.                         if(Walkables[checkNode].Value)
    119.                         {
    120.                             neighbours.Add(new int2(checkX,checkY));
    121.                         }                  
    122.                     }                  
    123.                 }
    124.             }          
    125.         }
    126.        
    127.         [MethodImpl(MethodImplOptions.AggressiveInlining)]
    128.         private int GetIndex(int2 i)
    129.         {
    130.             return (i.y * maxX) + i.x;
    131.         }
    132.     }
    133.  
    134.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    135.     {
    136. //        return new AStarJob()
    137. //        {
    138. //            NodeEntityArray = _gridGroup.NodeEntity,
    139. //            Positions = _position,
    140. //            Walkables = _walkable,
    141. //            Commands = _aStarBarrier.CreateCommandBuffer()
    142. //        }.Schedule(this, inputDeps);
    143.  
    144.         JobHandle jh = new AStarJob()
    145.         {
    146.             NodeEntityArray = _gridGroup.NodeEntity,
    147.             Positions = _position,
    148.             Walkables = _walkable,
    149.             Commands = _aStarBarrier.CreateCommandBuffer(),
    150.             AgentGroup = _agentGroup
    151.         }.Schedule(_agentGroup.Length, 2, inputDeps);
    152.         jh.Complete();
    153.         return jh;
    154.     }
    155.  
    156.     private class AStarBarrier : BarrierSystem {}
    157.  
    158.     [Inject] private AStarBarrier _aStarBarrier;
    159.    
    160.     private struct GridGroup
    161.     {
    162.         [ReadOnly] public ComponentDataArray<Position> Position;
    163.         [ReadOnly] public ComponentDataArray<Node> Node;
    164.         [ReadOnly] public ComponentDataArray<Cost> Cost;
    165.         [ReadOnly] public ComponentDataArray<Walkable> Walkable;
    166.         [ReadOnly] public EntityArray NodeEntity;
    167.         public readonly int Length;
    168.     }
    169.    
    170.     private struct AgentGroup
    171.     {
    172.         [ReadOnly] public ComponentDataArray<Position> Position;
    173.         [ReadOnly] public ComponentDataArray<Agent> Agent;
    174.         [ReadOnly] public ComponentDataArray<Target> Target;
    175.         [ReadOnly] public EntityArray NodeEntity;
    176.         public readonly int Length;
    177.     }
    178.  
    179.     [Inject] private GridGroup _gridGroup;
    180.     [Inject] private AgentGroup _agentGroup;
    181.     [Inject] private ComponentDataFromEntity<Position> _position;
    182.     [Inject] private ComponentDataFromEntity<Walkable> _walkable;
    183. }
    What i possibly did wrong? Many thanks
     
  2. DarthRayban

    DarthRayban

    Joined:
    Apr 5, 2016
    Posts:
    7
    After several tries I found my mistake: using EntityCommandBuffer.Concurrent instead of EntityCommandBuffer solve the issue.