7 hours ago, Thomas Izzo said:Your API seems clean and simple which I like. However, I'm curious how you efficiently handle modifying the index when new entities are added/removed.
More specifically, how do you efficiently update the returned index whenever a new entity/component is added? It seems like it would be inefficient to have to iterate over every entity to generate the new EntityIndex array whenever a single entity is added or removed.
I realize this is an implementation detail that I could optimize in the future.
Actually, for my purposes that turned out rather easy but it is definitely a behind the scenes type of thing. First, everything in that API is actually deferred and does not run immediately. This is a painful thing to implement and still keep the nice API, but it is doable. Now that everything is deferred it means that because my engine is fully threaded, I do a lot of lazy cleanup. So, with entities and components being added/removed in bulk, performing a little sort on the data and then updating the indexes is quite efficient. I'm not sure if there is a proper name for my method of insert/delete, but it is generally a couple memcpy's. I start at the highest thing to be inserted and binary search for the location it should be in the index. I memcpy everything at that location to the end up in memory by the total number of items to be inserted. Copy the new index and pop it, repeat till done but only moving the portion of memory to the point right before the insertion. Eventually the gap you made fills in and you've only moved any given element once.
Overall it is a reasonable approach, I think I have some ideas to make it work faster but haven't bothered since in the ridiculous stress test I run the insert/delete hasn't shown up in the top 100 hot spots yet. The test adds/removes on average five thousand components and three thousand entities every second, so it is being beaten on significantly.