You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
A: Internally, queries store a reference to any archetype that matches the current query. When we enter a system, we iterate over each archetype and then iterate over each entity in that archetype. The problem with this is that we if were to add or remove components from entities, the entity could no longer match the given query. We would end up mutating an array that we are iterating over, which is a recipe for disaster!
There are different ways around this, but instead, we opted for the "most simple" approach. Rather than updating the archetype immediately, we simply queue up the changes to be applied at a later time.
Whenever world.flush() is called, we apply all of these changes at once. If you are using the in-built scheduler, this will be called automatically at the end of each system for you, so you do not typically need to worry about it. The only time you should need to call it manually is if you decide to manage anything that interacts with the world outside of the scheduler.
Q: Is creating a new entity deferred?
A: No. This is because components are not added to entities immediately. An entity can exist immediately because it will not be able to match any queries until it has at least one component. This is not true for entity removal, this operation is deferred.
Q: Is state changed in the world deferred?
A: No. If a system processes one entity and changes the component data, this change will be reflected in the world immediately. This is because the world is not a snapshot of the current state of the world, but rather a reference to the current state of the world. This is for performance reasons.
Although the ability to defer operations adds less complexity for the user, many queries will never make modifications to their own underlying archetypes. It would likely be beneficial to allow the user to defer operations to the end of a query, only when they are actually needed to be!
The proposed idea would be to add a defer function, where only the operations within the defer would be called (a bit like task.defer() but contained within the ecs system. world.flush() woud still be used to clear these changes.
This means that by default, all operations will not be deferred, reducing the overhead, while also ensuring that the overhead is only seen when the user explicitly wishes to defer an operation.
The text was updated successfully, but these errors were encountered:
Agreed completely, it's not very responsive if I have to wait for all of my changes to be applied, and feels like it's very easily going to just cause hard to fix bugs if someone forgets that. An emulation of the task.defered pattern seems best.
HOWEVER, I think we need debug-environment-only checks to warn users if/when they modify components that are currently being targeted by the query. I'm not going to raise an issue on that, it's a down the line thing, but I think it should be considered.
Original Motivation:
Although the ability to defer operations adds less complexity for the user, many queries will never make modifications to their own underlying archetypes. It would likely be beneficial to allow the user to defer operations to the end of a query, only when they are actually needed to be!
The proposed idea would be to add a
defer function
, where only the operations within the defer would be called (a bit liketask.defer()
but contained within the ecs system.world.flush()
woud still be used to clear these changes.This means that by default, all operations will not be deferred, reducing the overhead, while also ensuring that the overhead is only seen when the user explicitly wishes to defer an operation.
The text was updated successfully, but these errors were encountered: