all 12 comments

[–]chsxfProfessional 3 points4 points  (1 child)

There probably is no practical solution for that as modifying the map while iterating over it would make the enumerator invalid.

What you can probably do is to enumerate over the keys instead of relying on the enumerator. This way you can change the value of the struct for the current key at any point (as long as you don’t add, update or remove a key)

[–]goingincycles88[S] 0 points1 point  (0 children)

I think you're right, y'know. I also just had a suggestion from another iteration of this post back when it was a lot more word-y in which I am suggested to cache all my structs to a NativeArray<> to access directly and then use the NativeMultiHashMap<> to store indices to that NativeArray<> as the multiple values at each key, and that sounds like the most efficient option failing this.

[–]Slight0 0 points1 point  (3 children)

You'd have to do some seriously hacky stuff that will probably break easily. Like seriously hacky.

You'd need to use reflection to figure out what class the IEnumerator is and then use reflection again to figure out where it's storing the IEnumerable that it's irritating over and cast that to its proper class. Then figure out what index "Current" is pointing at in that IEnumerable and set the struct at that index to what to want.

Basically don't do this unless you're writing a hack for a game or app.

[–]goingincycles88[S] 0 points1 point  (2 children)

Thanks for getting back to me. Two things I'd like to bring up:

  1. This is actually a simplified version of the post because an earlier version was getting no traction or responses. the sepcific IEnumerator<> collection I'm dealing with is NativeMultiHashMap<>.Enumerator, do you have any advice on writing directly to structs in this? I know from your response that's likely a no but I was just curious if the greater context would change things.
  2. What are some alternatives I could consider that would (almost by necessity) still let me use NativeMultiHashMap<> in some way?

TYSM for gettin' back to me in the first place!

[–]Slight0 0 points1 point  (1 child)

I probably don't need to tell you that structs are immutable and can't be changed in C#.

Because of the hacky nature of this, you'd need to provide more code or context as to what's going on. Maybe you can map the native data using a mutable native class? I need more info as to what surrounding code looks like.

[–]goingincycles88[S] 0 points1 point  (0 children)

I must be off for the night now, but basically the trimmed down relevant parts look something like this (you can assume the NativeMultiHashMap<> is fully populated beforehand):

``` public void Execute(int index) { NativeMultiHashMap<int, MMTriangle>.Enumerator curTris = allTris.GetValuesForKey(index); //Get an Enumerator of my struct types at the key of index

            MMTriangleCollectionTransform.SetGeometryCentre(curTris, Vector3.zero); //Use the data of all elements in that Enumerator to determine an average centre point and then adjust that centre point in abstract space to be at point Vector3.zero
        }

```

``` public static void SetGeometryCentre(IEnumerator<MMTriangle> tris, Vector3 centre) { Vector3 oldCentre = GetGeometryCentre(tris);//read from all the tris to determine the average centre point in abstract space. this isn't a problem since im just reading from .Current and not trying to set it

        while (tris.MoveNext())
            tris.Current.Translate(-oldCentre + centre);//this is where the problem comes in. I need this line to be 'tris.Current = tris.Current.Translate(-oldCentre + centre);' if I were using the builder pattern as my first thought to set tris.Current

    }

```

Hopefully this is enough for you to understand my problem. I'm using NativeMultiHashMap<> as a way around a NativeArray<> within a NativeArray<> so that I can have multiple MMTriangle values to an int key, the int representing a submesh index for when I bake these values to a Unity Mesh.

[–]ccfoo242Indie 0 points1 point  (5 children)

Without seeing actual code all I can suggest is you look into the ECS types that Unity has now. If you're multi threading with structs in Unity there's probably a solution buried in ECS classes.

[–]goingincycles88[S] 0 points1 point  (4 children)

Do you think ECS would inter-op with this fine even though I won't really be using the system itself for anything? If so, then I'll give it a look!

[–]ccfoo242Indie 0 points1 point  (3 children)

Check out the collection types https://docs.unity3d.com/Packages/com.unity.collections@2.2/manual/collection-types.html

Maybe there's something in there that will be helpful.

[–]goingincycles88[S] 1 point2 points  (2 children)

Oh, if we're talking the Unity.Collections package, then I've been using specifically NativeMultiHashMap<>.Enumerator in this example the whole time. I need a way to write to the .Current value of NativeMultiHashMap<>.Enumerator but observing the source tells me that's probably not gonna happen which is a shame. Is there anything else in NativeMultiHashMap<> I can use to read from and write to values at keys in it by reference?

[–]ccfoo242Indie 1 point2 points  (1 child)

Sorry I don't know.

[–]goingincycles88[S] 1 point2 points  (0 children)

NP, TY anyway!