Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

IJobParallelFor runtime error

Discussion in 'Entity Component System' 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.