Search Unity

Iteration over values in NativeHashMap or NativeMultiHashMap?

Discussion in 'Entity Component System' started by fholm, Nov 12, 2018.

  1. fholm

    fholm

    Joined:
    Aug 20, 2011
    Posts:
    2,052
    Is it in any way possible to iterate over the values in any of these collections? If the answer to this question is no.. then are there any workarounds?
     
  2. meanmonkey

    meanmonkey

    Joined:
    Nov 13, 2014
    Posts:
    148
  3. meanmonkey

    meanmonkey

    Joined:
    Nov 13, 2014
    Posts:
    148
    I have a similar case where I need key/value data in my job, so I a wrote a little workaround using Parallel.For.

    I need it to manipulate data in jobs by a given ID.

    This should work with IJobParallelForTransform (for classic use with transforms) and IJobProcessComponentData (pure ecs use) too, but not tested yet.

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. using Unity.Jobs;
    6. using UnityEngine.Jobs;
    7. using Unity.Collections;
    8.  
    9. using System.Threading.Tasks;
    10.  
    11. // =================================================================== //
    12. public class Test : MonoBehaviour {
    13.  
    14.     NativeHashMap<int, Vector3> testNativeHashMap;
    15.     NativeArray<Vector3> testNativeArray;
    16.     int size;
    17.  
    18.     // ------------------------------------------------------------------- //
    19.     void Start () {
    20.  
    21.         size = 100;
    22.  
    23.         testNativeHashMap = new NativeHashMap<int, Vector3>(size, Allocator.Persistent);
    24.         testNativeArray = new NativeArray<Vector3>(size, Allocator.Persistent);
    25.  
    26.         // Run a parallel task job from Systems.Threading.Tasks. Unity seems to be fine with multithreading on their NativeHashMap
    27.         Parallel.For(0, testNativeHashMap.Capacity, i => // Note that testNativeHashMap.Length is 0 at this point
    28.         {
    29.             testNativeHashMap.TryAdd(i, new Vector3(i, i, i));
    30.         });
    31.  
    32.         // Mainthread waits automatically for Parallel.For to complete
    33.    
    34.         // Setup and schedule job, wait for complition
    35.         TestJob testJob = new TestJob()
    36.         {
    37.             _testNativeHashMap = testNativeHashMap,
    38.             _testNativeArray = testNativeArray
    39.         };
    40.         JobHandle testJobHandle = testJob.Schedule(size, 64); // 64 batches per execute is ok as the job is doing very little work
    41.         testJobHandle.Complete();
    42.  
    43.         // Debug output new values in mainthread
    44.         for (int i = 0; i < testNativeArray.Length; i++)
    45.         {
    46.             UnityEngine.Debug.Log("testNativeArray Vector3 value for index " + i + ": " + testNativeArray[i].x + "," + testNativeArray[i].y + "," + testNativeArray[i].z);
    47.         }
    48.     }
    49.  
    50.     // ------------------------------------------------------------------- //
    51.     private void OnDestroy()
    52.     {
    53.         testNativeHashMap.Dispose();
    54.         testNativeArray.Dispose();
    55.     }
    56.  
    57.     // =================================================================== //
    58.     struct TestJob : IJobParallelFor
    59.     {
    60.         [ReadOnly] // Mark the nativeHashMap as readonly so we are allowed to use it
    61.         public NativeHashMap<int, Vector3> _testNativeHashMap;
    62.         public NativeArray<Vector3> _testNativeArray;
    63.  
    64.         public void Execute(int i)
    65.         {
    66.             Vector3 value;
    67.             _testNativeHashMap.TryGetValue(i, out value);
    68.             _testNativeArray[i] = value;
    69.         }
    70.     }
    71. }
    72.  
     
    Last edited: Nov 12, 2018
  4. tertle

    tertle

    Joined:
    Jan 25, 2011
    Posts:
    3,761
    One kind of workaround is that since NativeMultiHashMap<int,int> can be iterated using the IJobNativeMultiHashMapMergedSharedKeyIndices, you can store your values in separately in NativeArray/NativeList and then store the indices in NativeMultiHashMap<int,int> and do a lookup/iteration like that.