sebas77/Svelto.ECS

Fix the Swap and Remove entity logic

Closed this issue · 4 comments

Hi,

A problem recently arose regarding the use of the Swap and Remove entity related functions. Since I give the possibility to work directly with arrays to get maximum performance, these functions cannot currently be used inside an iteration because they immediately alter the arrays that store the entities. This means that an array will change while iterating, which would lead to unexpected behaviors. Leaving the responsibility of managing this situation to the user is too much, therefore we need to find a solution and your help would be appreciated.
My current idea is to copy the entity to the new group during a swap, but never remove immediately in any case. I will just mark the item as not valid anymore.
I am not sure which datastructure to use to mark it yet, as it depends if I want to give you some tools to check if an entity is valid or not. These tool would be under the form of different ways of iteration, i.e.: use ExecuteOnEntity would always skip not valid cells.
The real remove then would happen in the next frame, like it happens when submit entities.
The concept of frame is a weird one tho, but that's why you can customize when the entities are submitted overloading the Submission Scheduler behaviour.
In a not too far feature, I want to give the chance to create hierarchical Enginesroot, so that you can encapsulate the code even more and also customize the way entities are submitted.
This could be very helpful in a 100% multithreaded environment.

Why do you think your solution is better though? I thought about the I disposable solution, but it would change the pattern of usage quite a lot. Moreover as a user, I have to remember to use the using function because, if I got it right, I would free the array only once disposed. In doing so I could apply the move and remove when the array is freed in this way, not sure if it's better. What is again your reasoning about multithreading? Didn't understand the benefits you wanted to show me. I will need to think more about it so give me more thoughts please .

Edit: about wrapping the use of the array. This is already possible through the ExecuteOnEntities function. I could also give the possibility to use an enumerator and therefore use foreach.
Both option are slower than using directly the buffer, at least until I move Svelto to c# 7. It's possible that once I move everything to c# 7 I may remove the QueryEntities<> functions and solve the problem once for ever.

@Darelbi why don't you join us on Discord? https://discord.gg/3qAdjDb

This is now fixed with Svelto.ECS 2.7. Currently all the operations are deferred, in future I may introduce more options.
swap and remove are now always safe.