I have scoured the fora for something showing how to update values in a NativeMultiHashMap, but all I can find are rather elaborate Rube Goldberg-like contraptions that I wonder would be best hidden behind a simpler API-call… (IMHO would be what makes it a game engine). It would also be nice to have a single page explaining all the how-tos with regards to use of this with simple examples, and also as recent as possible, as also one other issue is that the results I find are now getting old and I fear also outdated.
My usecase is as follows:
An array of lists because I know the length of the array but not the length of each element of the array and they can have a lot of variation. In standard .NET all I do is List[ ] and I can shut my brain off comfortably and focusing on getting results, however this does not seem as straight forward unfortunately with the data management of NativeCollections. I wish I could just have it as one long 1D-array but as stated I do not know the length of each element of the array, and I just want some simple flexibility here so I can move on.
I don’t think there is one liner solution. You probably need to grab unique keys and iterating through their values.
There were some work around, to use lists in hashmap, if I remember correctly. But they wasn’t safe, nor without boiler plate.
Btw, you can run all in one bursted job. No need for separate jobs as per example. That reduces boilerplate significantly.
A little bit late to be responding this thread, but anyways. MultiNativeHashMap(TKey, TValue) maps each key to an array of TValue. IMHO, MultiNativeHashMap is good when you don’t want to update the values, I.E. you don’t want to change one particular value of the map, you’re either adding values without removing the old ones or you’re reading all the values in a key. It’s great when you want to Input or Output data from a Job, as it’s likely where you’ll only read or only write. Additionally, there is a thing called ParallelWritter (MultiNativeHashMap.AsParallelWriter) that allows you to write values to the MultiNativeHashMap in multiple parallel jobs simulteneously, so you’re using MultiNativeHashMap ideally it’s in a situation where you don’t care what order things are added in as long as they’re added to the rigth key. As for reading, you use Enumerator, if that’s no good, lemme help cut the boilerplate.
public static class WavelikeNativeMultiHashMapExtension
{
public static NativeArray<State<T>> GetValuesForKeyAsNativeArray<TKey, T>(this NativeMultiHashMap<TKey, State<T>> nmhm, TKey key, Allocator allocator)
where TKey : struct, IEquatable<TKey>
where T : unmanaged, IEquatable<T>
{
NativeArray<State<T>> states = new NativeArray<State<T>>(nmhm.CountValuesForKey(key), allocator, NativeArrayOptions.UninitializedMemory);
var nmhmEnum = nmhm.GetValuesForKey(key);
int i = 0;
nmhmEnum.Reset();
while (nmhmEnum.MoveNext())
{
states[i] = nmhmEnum.Current;
i++;
}
return states;
}
}
So, that’s the deal with MultiNativeHashMap. On the other hand, if you want a substitute for multidimensional arrays that isn’t as easily iterated through, but can be easily used the same way your usual T[ ][ ] can, then go for NativeHashMap<{int2 or int3 or int4}, T>, and access it with nhm[new int2(i, j)] or nhm[new int3(i, j, k)].
On both cases, since you’re dealing with Data Oriented, you want to know how many entries there will be, or guess a number on the high end and reallocate if it passes. Another way of doing this is through ValueTuple. Make a wrapper class with a NativeList<(int2, T)> (which I think reallocates automatically, please correct me if I’m wrong) and a public T this[int i, int j] and hope it doesn’t cost too much performance.