sebas77/Svelto.ECS

QueryEntityViewsAsArray null reference becase its size is changing during iteration.

Darelbi opened this issue · 7 comments

Ok I found a really minor bug, but maybe it can be useful, maybe it was just a undocumented behaviour

Reproducing the bug:

        int count;
        var views = entityViewsDB.QueryEntityViewsAsArray< GeometrySourceView>(out count);

        for( int i=0; i< count; i++)
        {
            entitiesSink.RemoveEntity( views[i].id.ID); // null reference at some point
        }

When iterating a array of entities taken from the entityViewsDB if I remove them in a loop I get a null reference exception. I didn't investigated yed but I assume the array is resized as long as entities are removed. I expected this kind of stuff to happen only during "SubmitEntityViews" phase.

How I fixed it (basically copying the array locally)

        var views = entityViewsDB.QueryEntityViews< GeometrySourceView>().ToArray(); // linq copy

        for( int i=0; i< views.Count(); i++)
        {
            entitiesSink.RemoveEntity( views[i].id.ID);
        }

Also what's the difference between QueryEntityViews and QueryEntityViewsAsArray? when I should prefer one to the other?

In both cases the array is resized dynamically. Now, using "AsArray" allowed me to find the bug early because of null reference (but in the second code snippet, if I remove the ".ToArray()" I will stop getting the error (of course because "view.Count" changed accordingly) and noticing the bug become harder.

The array version is to be used for performance critical code where you wouldn't remove the entity very likely :)

Also you don't need the ToArray

To avoid these problems I could remove the entities the next frame like I do for the adding

Without the ToArray not all entities are removed. Because even though the "Count" is updated, the index "i" will miss some entities. (just tested it)

do you think this is still an issue @Darelbi ?