[SOLVED] setComponent(), getComponent() and applyChanges()

I wonder what if in one same update() I set some component and then want to use it with new data, if I just call getComponent(e.getId(), myComponent.class) - will it be updated already, or do I have to wait till next frame? Will calling applyChanges() affect this (I assume calling it within ‘for’ cycle for entities isn’t a good idea though)? Or is it better to store/calc locally within one frame and update Component just once? From the game logic’s point of view next frame is ok, it will just affect checking conditions…

applyChanges() only affects the local view of Entities.

setComponent()/getComponent() on the real EntityData is always live.

got it, thanks!

Also note: Entity views are local. If you have two different EntitySets, calling applyChanges() one does not update the Entity views of the other.

These local snapshots are what make these loops inherently thread safe.

I work within one this time, but I’ll remember that. Most important thing for now is that getComponent/setComponent can be combined as many times as needed within same set.

Yes, that’s a live view of the real underlying “database” so to speak.

So also note that it may be showing you newer values than Entity.get() would be.

I just searched through my project, looks like I use it in ‘semi-static’ code only, like, if I know that once constructed this entity’s parameter (say, visual model, or bounding diameter etc etc) won’t change during its lifetime. I didn’t do much performance optimizations yet though, since performance is still affordable for the tests I run…

Hmm looks like I have problem with local views again. I have the following in update() cycle:

...
System.out.println("TargetersControl: " + targetId + " targeted by " + e.toString() );
fighters.applyChanges();
if ( fighters.containsId(targetId) )
{ // target is fighter
    System.out.println("TargetersControl: FIGHTER targeted by " + e.toString() );
...

where fighters initialized as

fighters = ed.getEntities(PhysicalObject.class, FighterAI.class);

Second println() is never called, however according to 1st println() entityId is correct and entity itself behaves like it should having PhysicalObject (shown on screen) and FighterAI (behavior).
What should I check?

That indicates that the entity referred to by targetId does not have PhysicalObject and FighterAI components. It can’t really be otherwise.

Reduce your code to a simple test case and you will find your issue. Else, you can log where you are actually setting those components on the entity and compare the IDs in your output. One of them is different.

Thanks, Paul, found it. I started to think that EntityData could become inconsistent and such things while my mistake was really stupid one. Backside of keeping everything decoupled in ES - everything might continue working even when you do really dumb things such as messing component class with a system one lol.