-
Notifications
You must be signed in to change notification settings - Fork 145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding component is async sometimes #186
Comments
+1 is there a way to either force-add or check if it's scheduled? It seems to be add immediately if entity is "fresh" (not added yet to engine) |
The wiki states that, if you add a component to an entity during engine What strategy do you suggest we adopt, it's not such a simple problem. Maybe you can change your approach, why do you need to modify a component during the same frame it got added to the entity? Maybe you should be doing that in a system that processes entities with such component, you will only get the update for that entity once it has the component. |
In my experience, it's a pretty common use case - mostly when bootstrapping entities. In the current project (ECS, but not ashley) - if the user needs to modify/query an entity further, any pending operations for the entity in question are flushed. It could just as well be added to the current operation batch, but this was the easier solution. Lifecycle dependent state propagation/inconsistencies are non-obvious to everyone except those intimately familiar with the inner workings. |
I'm implementing actions for Ashley. I want to keep the possibility and syntax of adding parallel events to entities just like its done with gdx actor events where you can write things like actor.addAction(action1); and they will work together as parallel actions. Actions.moveTo(entity, x, y, duration); The static method adds the logic to the ActionComponent, but before doing it, it checks if the entity already has the ActionComponent and ads one if it hasn't. So turns out if I add 2 actions to an entity in a row, the second one won't know that the previous one already scheduled the ActionComponent creation and instead of adding only logic to the scheduled component, it will schedule a new component creation and overwrite previous one. |
One solution we can implement when adding a component to an entity is (pseudocode):
This would break another use case: remove PhysicsComponent from entity during update, the PhysicsSystem updates later but that entity doesn't actually have the component anymore... BOOM. We don't want people to have to check for null ALL the time. Again, any ideas to fix this for all use cases? How does artemis do it @junkdog? |
I see. I guess the best solution in this case would be if the engine or the entity had the getSceduledToAddComponents() , so I could get the component either from the entity's components list or the "scheduled" list and modify it regardless of it being "actually added". |
Oh crap this is harder then I first thought. We can do lot's of outside code to schedule adding in our semi-singleton kind of places, but that has ton of other problems either. The best thing that could be done in Ashley is if getComponent can somehow return component that is yet scheduled. What kind of problem does that have? This component is "somewhere" right? so it should be possible to retrieve it? |
What about the opposite? What do we do when trying to retrieve a component that was scheduled for removal? That seems rather inconsistent. |
Well if it is scheduled for removal that is no problem, we get it, we modify it, and then it get's removed. (or we do not get it) whichever it is, it is not an issue. I looked at the codes, it seems rather hard to get the scheduled component though right? |
Oh right but that's still a problem, sorry. If I remove component, then I will try to add action to it, and then I will lose it.. true.. Dabate is still going here in our room. :D And we are curious on what @junkdog will say. |
High level, a bit old, but more or less correct: http://i.imgur.com/ARNefV6.png It's not entirely consistent, but for the most part:
And, about the lifecycle dependent state propagation/inconsistencies: when deleting a full entity, it's still possible to retrieve its components when listeners are informed. For the most part, this doesn't cause too much trouble, but it can throw users off guard when components are already deleted due a component delete vs it's there in the case of entity delete (it makes sense on some level however). (I might expand a bit after work) |
We do process all pending operations in between system updates (see here). So this approach might work. Looking forward some more details. |
@junkdog how does it handle when:
Do we call |
Alright, I'm implemented what we discussed and adding a few unit tests... Will submit a PR to get it reviewed by some of you guys and make sure it's nothing crazy. We don't want to keep breaking things. |
Entity state changes are governed by EntitySubscriptions, and these are only triggered in-between systems; adding+immediately removing a component, the entity would end up with the same compositionId -> no EntitySubscriptions updated, |
…r system update. Fixes issue libgdx#186
…r system update. Fixes issue libgdx#186
…r system update. Fixes issue libgdx#186
Taking a look right now. |
I chose to make insertion operations immediate and removal operations deferred in retinazer, to make it possible to retrieve components in entity listeners. Entity lists are updated in between system updates, after which components are removed (this comes with the side effect of making it cumbersome to replace components). See the What's implemented in #187 should be fine, as long as entity lists do not change while a system is updating. |
Thanks guys for taking a look, I think I will merge now. |
So I noticed that when you add a component to an entity that's already in the engine, it adds asynchronously. Which means that it's not retrievable immediately after adding. As I assume it becomes available only after next frame.
My case is: I need to modify a component. But before modifying it, I have to check if it's present in the entity or not. If not, then I'm going to add a new component of needed type and then modify it. But I can't do it, because after i call entity.add(), it's not present in the entity's components array. The problem becomes really bad when you have to call the modifying/checking function multiple times. Every time the "is component present check" returns null on a given entity. So I'd like to know if there's a workaround for this problem. Thanks in advance.
The text was updated successfully, but these errors were encountered: