rP18399 moved the developer overlay from session.xml to developer_overlay.xml.
In rP22370/D1928, the developer overlay was refactored to use prototype syntax, remove XML duplication and move definitions to JS.
This patch revisits that commit in the course of #5387, addresses the following points:
- The checkbox definition is a function getCommands that returns an array of objects where each object returns a checkbox. This approach is problematic in multiple ways. (A) Mods can't extend the array if its the result of a function! (B) Objects are limited to the few hardcoded functions. Class instances can add custom functions, subscribe them to events refs rP23076/D2378. (C) It doesn't provide a this reference, so it is impossible to store a state variable. By using an actual class instance per checkbox, we can store class helper variables per checkbox, such as the TimeWarp class or EntityState class.
- The benefit of using classes is to increase cohesion and separation of concerns. Actually take this benefit by splitting things that are logically unrelated. That is
- the EntityState panel that shows the simstate of the selected entity. That has nothing to do with the checkboxes and shouldn't dilute the class concerned with that.
- TimeWarp mode is only relevant for one of the option, but the class in rP22370/D1928 now needs to be aware of that since its not split.
- Splitting the class to handle one checkbox from the class to manage the panel. This allows making the checkbox states more simple, extensible and moddable.
- Filenames match their classname.
- Code uses class keyword.
- The TimeWarp code is moved from input.js from rP8803 to the TimeWarp setting using the hotkey release event from rP19028, refs #3194.
- Removes the global references to g_DeveloperOverlay and getters by accessing the players simstate.
- Moves EntityState to own XML file.
New classes:
class DeveloperOverlay class DeveloperOverlayCheckbox class DeveloperOverlayCheckboxes class DeveloperOverlayEntityState class TimeWarp DeveloperOverlayCheckboxes.prototype.ControlAll = class DeveloperOverlayCheckboxes.prototype.ChangePerspective = class DeveloperOverlayCheckboxes.prototype.SelectionEntityState = class DeveloperOverlayCheckboxes.prototype.PathfinderOverlay = class DeveloperOverlayCheckboxes.prototype.HierarchicalPathfinderOverlay = class DeveloperOverlayCheckboxes.prototype.ObstructionOverlay = class DeveloperOverlayCheckboxes.prototype.UnitMotionOverlay = class DeveloperOverlayCheckboxes.prototype.RangeOverlay = class DeveloperOverlayCheckboxes.prototype.BoundingBoxOverlay = class DeveloperOverlayCheckboxes.prototype.RestrictCamera = class DeveloperOverlayCheckboxes.prototype.RevealMap = class DeveloperOverlayCheckboxes.prototype.EnableTimeWarp = class DeveloperOverlayCheckboxes.prototype.PromoteSelectedUnits = class DeveloperOverlayCheckboxes.prototype.EnableCulling = class DeveloperOverlayCheckboxes.prototype.LockCullCamera = class DeveloperOverlayCheckboxes.prototype.DisplayCameraFrustum = class
A performance optimization added in this patch is to extend the system from 23076/D2378 to support unsubscription from events.
This means we can save about 200 microsecnds each turn if the developer overlay is closed by unscubsribing from onSimulationUpdate if its closed!
(That's signficant, because the turn length may be 100ms eventually, so a no-op shouldnt consume 0.2% of each turn length.)
Measurement method:
diff --git a/binaries/data/mods/public/gui/session/developer_overlay.js b/binaries/data/mods/public/gui/session/developer_overlay.js index 57e9736fd8..6b1329ae93 100644 --- a/binaries/data/mods/public/gui/session/developer_overlay.js +++ b/binaries/data/mods/public/gui/session/developer_overlay.js @@ -210,11 +210,13 @@ DeveloperOverlay.prototype.toggle = function() DeveloperOverlay.prototype.update = function() { + let foo = Engine.GetMicroseconds(); let playerState = g_SimState.players[g_ViewedPlayer]; this.controlAll = playerState ? playerState.controlsAll : false; this.updateValues(); this.updateEntityState(); + warn(Engine.GetMicroseconds() - foo); } DeveloperOverlay.prototype.updateEntityState = function()
Measuremnet result (the 600microsecond numbers occur when showing the entity selection state):
WARNING: 376 WARNING: 211 WARNING: 205 WARNING: 201 WARNING: 202 WARNING: 212 WARNING: 228 WARNING: 265 WARNING: 207 WARNING: 216 WARNING: 664 WARNING: 175 WARNING: 162 WARNING: 170 WARNING: 181 WARNING: 186 WARNING: 153 WARNING: 158 WARNING: 186 WARNING: 540 WARNING: 291 WARNING: 150 WARNING: 150 WARNING: 153 WARNING: 145 WARNING: 161 WARNING: 386 WARNING: 179 WARNING: 158 WARNING: 141 WARNING: 146 WARNING: 261 WARNING: 136 WARNING: 132 WARNING: 130 WARNING: 138 WARNING: 134 WARNING: 129 WARNING: 141 WARNING: 139 WARNING: 145 WARNING: 280 WARNING: 139 WARNING: 132 WARNING: 145 WARNING: 152 WARNING: 141 WARNING: 215 WARNING: 139 WARNING: 161 WARNING: 139 WARNING: 151 WARNING: 169 WARNING: 138 WARNING: 133 WARNING: 129 WARNING: 140 WARNING: 141 WARNING: 125 WARNING: 137 WARNING: 111 WARNING: 133 WARNING: 132 WARNING: 168 WARNING: 146 WARNING: 135 WARNING: 124 WARNING: 125 WARNING: 125 WARNING: 114 WARNING: 141 WARNING: 126 WARNING: 128 WARNING: 173 WARNING: 126 WARNING: 110 WARNING: 177 WARNING: 151 WARNING: 130 WARNING: 159 WARNING: 148 WARNING: 130 WARNING: 168 WARNING: 146 WARNING: 154 WARNING: 135 WARNING: 196 WARNING: 130 WARNING: 136 WARNING: 165 WARNING: 138 WARNING: 141 WARNING: 137 WARNING: 139 WARNING: 146 WARNING: 131 WARNING: 163 WARNING: 145 WARNING: 131 WARNING: 130 WARNING: 142 WARNING: 156 WARNING: 161 WARNING: 150 WARNING: 138 WARNING: 141 WARNING: 131 WARNING: 156 WARNING: 138 WARNING: 133 WARNING: 129 WARNING: 130 WARNING: 132 WARNING: 135 WARNING: 145 WARNING: 881 WARNING: 645 WARNING: 629 WARNING: 652 WARNING: 641 WARNING: 657 WARNING: 696 WARNING: 628 WARNING: 609 WARNING: 632 WARNING: 641 WARNING: 618 WARNING: 638 WARNING: 628 WARNING: 618 WARNING: 787 WARNING: 638 WARNING: 612 WARNING: 622 WARNING: 889 WARNING: 622 WARNING: 642 WARNING: 661 WARNING: 644 WARNING: 928 WARNING: 854 WARNING: 958 WARNING: 845 WARNING: 829 WARNING: 869 WARNING: 858 WARNING: 823 WARNING: 832 WARNING: 921 WARNING: 1031 WARNING: 844 WARNING: 696 WARNING: 640 WARNING: 751 WARNING: 842 WARNING: 662 WARNING: 672 WARNING: 652 WARNING: 670 WARNING: 653 WARNING: 636 WARNING: 897 WARNING: 212 WARNING: 143 WARNING: 140 WARNING: 139 WARNING: 132 WARNING: 141 WARNING: 151 WARNING: 159 WARNING: 208 WARNING: 137
At last, the patch changes the developer overlay to be openable in case of loading a multiplayer savegame that was played without cheats and replays in observermode before saving, as discovered in the course of F1100948 / #5624, see rP19558, rP19651.