Page MenuHomeWildfire Games

Cleanup of GetEntityState
ClosedPublic

Authored by mimo on Jan 14 2018, 4:51 PM.

Details

Reviewers
elexis
Commits
rP20875: Cleanup of GetEntityState
Trac Tickets
#4322
Summary

As now GetExtendedEntityState is always used, there is no more use of the distinction between GetEntityState and GetExtendedEntityState which only adds complexity and degrades performances. Then as GetEntityState is now always called for all entities of the selection, it is better to query all of them once in an array.
In addition, obstructions info is never used in the gui, and thus removed from GetEntityState.

With these changes, the "gui sim interface" performance is improved by 15 to 20% when selectiong 200 units (test on combat demo huge).

Test Plan

Check the performance improvement and that the gui responds as before.

Diff Detail

Repository
rP 0 A.D. Public Repository
Lint
Automatic diff as part of commit; lint not applicable.
Unit
Automatic diff as part of commit; unit tests not applicable.

Event Timeline

mimo created this revision.Jan 14 2018, 4:51 PM
Owners added a subscriber: Restricted Owners Package.Jan 14 2018, 4:51 PM

Reducing the complexity and (currently subideal) performance when selecting units sounds good.

The most crucial question is if there are performancerelevant use cases for the simple GetEntityState when we don't also have the extended state at hand.

The only cases where we currently request a state without the unit being selected is in

  • input.js (just before the selection),
  • unit action targets (repair, attack, rallypoint)
  • additional highlight (status bars I suppose)
  • panel entities and groups (heroes, relics, < 20)
  • garrison health bar (< 30)
  • observermode (selects the units)

So it seems there is no case where we can expect a relevant performance regression.

The new function must remain compatible to globalscripts/Templates.js, but since it's just unifying two functions that already are compatible, that requirement should be satisfied.
Leaving a ping for @Imarok for awareness. There was this one ticket which should probably become fixed by this patch.

binaries/data/mods/public/gui/session/session.js
195 ↗(On Diff #5283)

Should return something according to the name

733 ↗(On Diff #5283)

Sure we should fill the cache in advance and not just in time?

binaries/data/mods/public/simulation/components/GuiInterface.js
574 ↗(On Diff #5283)

GetEntityStates

580 ↗(On Diff #5283)

Could be a return ents.map(ent => ({ prop1: val1, \n prop2: val2 }));

mimo added a comment.Jan 14 2018, 5:56 PM
In D1223#49578, @elexis wrote:

Reducing the complexity and (currently subideal) performance when selecting units sounds good.

The most crucial question is if there are performancerelevant use cases for the simple GetEntityState when we don't also have the extended state at hand.

The only cases where we currently request a state without the unit being selected is in

  • input.js (just before the selection),
  • unit action targets (repair, attack, rallypoint)
  • additional highlight (status bars I suppose)
  • panel entities and groups (heroes, relics, < 20)
  • garrison health bar (< 30)
  • observermode (selects the units)
With only one unit, that's negligible as GetEntityState is still used when one unit. Thus the difference is only the extra time added by the merging of EntityState and ExtendedEntityState on one unit.

So it seems there is no case where we can expect a relevant performance regression.

The new function must remain compatible to globalscripts/Templates.js, but since it's just unifying two functions that already are compatible, that requirement should be satisfied.
Leaving a ping for @Imarok for awareness. There was this one ticket which should probably become fixed by this patch.

binaries/data/mods/public/gui/session/session.js
195 ↗(On Diff #5283)

Yes, i hesitated to call it LoadMultiEntityStates for that purpose, but then keep the GetMultiEntityStates by symetry with the other function. I can a return (which is not currently used) or change the name, as preferred.

733 ↗(On Diff #5283)

We can also do nothing (entityStates will be called when needed). As this is used only when the selection changes, that's does not affect performances. So we can remove that line here.

binaries/data/mods/public/simulation/components/GuiInterface.js
574 ↗(On Diff #5283)

As the function GetEntityState still exists, that would be too confusing. So I'd rather keep the multi here, or rename the function to LoadEntityStates (as discussed in previous comment).

580 ↗(On Diff #5283)

ok

input.js also requests the entity state when doing a mouse selection on multiple units. But that's also negligible I assume because the same units are selected when releasing the mousebutton.
We observe that we can add a cheap getter for remaining edge cases like input.js where we might only want to get the Identity classes for instance.

If you made sure that the patch is complete and tested for typos again, I'd say give it a go.

binaries/data/mods/public/gui/session/session.js
195 ↗(On Diff #5283)

I'd prefer a Get*EntityState* name and add a return. There might be a use-case in the future, symmetry is nice and there is no real cost (only returns a reference to the object)

733 ↗(On Diff #5283)

Hm, actually the call should help with performance as the just-in-time loading does one call per entity rather than one call for all entities. So keep it, it's good.

788 ↗(On Diff #5283)

(same)

binaries/data/mods/public/simulation/components/GuiInterface.js
574 ↗(On Diff #5283)

+ple? :-)

mimo updated this revision to Diff 5284.Jan 14 2018, 6:31 PM

updated patch

Imarok updated the Trac tickets for this revision.Jan 15 2018, 10:40 AM

Looks good in general (only read the diff and a small part of the code.
Here are some comments:

binaries/data/mods/public/gui/session/hotkeys/misc.xml
63 ↗(On Diff #5284)

Why not GetMultipleEntityStates?

binaries/data/mods/public/gui/session/selection_details.js
466 ↗(On Diff #5284)

Why not GetMultipleEntityStatesand then remove the null ones?

binaries/data/mods/public/simulation/components/GuiInterface.js
580 ↗(On Diff #5283)

I thought a for loop is faster than map?
(Maybe it doesn't matter that much here...)

Imarok added inline comments.Jan 15 2018, 10:52 AM
binaries/data/mods/public/gui/session/session.js
734 ↗(On Diff #5284)

Maybe add a comment, why we do this here?

elexis added inline comments.Jan 15 2018, 2:24 PM
binaries/data/mods/public/gui/session/hotkeys/misc.xml
63 ↗(On Diff #5284)

Thought about it too, but doesn't really shorten.

binaries/data/mods/public/simulation/components/GuiInterface.js
580 ↗(On Diff #5283)

And a counted loop is much faster than a for...of loop. https://code.wildfiregames.com/rP20706#26324
The question is if the relation of the performance of the loop to the performance of the rest.

mimo added inline comments.Jan 15 2018, 7:22 PM
binaries/data/mods/public/gui/session/hotkeys/misc.xml
63 ↗(On Diff #5284)

My guess is that, at that point, GetEntityState(ent) has already been called for all entities of the selection and we (nearly always) only need to check that it was not null (i.e. that the entity has not been already destroyed).
If calling GetMultipleEntityStates, we'd need first to check that GetEntityState(ent) is not already filled (i.e. a filter like when the selection changes) and then check the GetEntityState is not null for each ent. So not shorter.

binaries/data/mods/public/gui/session/selection_details.js
466 ↗(On Diff #5284)

As before, when you are here, GetMultipleEntityStates has already been called, so all entityStates are already in g_EntityStates. You only need to remove those which are null, not to do the Engine;GuiInterfaceCall which is the role of GetMultipleEntityStates.

binaries/data/mods/public/gui/session/session.js
734 ↗(On Diff #5284)

you mean the filter? just because the new selection can contain a subset of the previous one, and we don't want to re-transfer all the common entityStates. I can add a comment if not clear enough.

binaries/data/mods/public/simulation/components/GuiInterface.js
580 ↗(On Diff #5283)

yes, this loop on ents here is negligible compared to the time to collect all the entities info, and more importantly to pass that info from js to c++ then js back. So i've favored code shorteness here.

elexis accepted this revision.Jan 15 2018, 8:46 PM

I'm afraid I'm violating the rules by accepting without testing this and it's easy to smuggle an oversight in this diff. I can test it if you want, but I wouldn't mind doing something else too.

Patch appears complete as the two functions are merged.
I suggest to scroll through all civs in the tech tree and hover many items, start an SP game, try the "gift from the gods" cheat and build many things, repair a foundation and maybe a damaged building, reading a healer tooltip in the session and so forth if we want to find the obligatory oversight.

binaries/data/mods/public/simulation/components/GuiInterface.js
269 ↗(On Diff #5284)

I wonder if we can delete the entire null casino

372 ↗(On Diff #5284)

would be nice to move this into a common object sooner or later, but presumably requires changes out of scope

589 ↗(On Diff #5284)

good

603 ↗(On Diff #5284)

blame rP19387 for this pointlessness

This revision is now accepted and ready to land.Jan 15 2018, 8:46 PM
This revision was automatically updated to reflect the committed changes.