tweak(gamemessage): Reduce number of MSG_DESTROY_SELECTED_GROUP messages#2668
tweak(gamemessage): Reduce number of MSG_DESTROY_SELECTED_GROUP messages#2668Caball009 wants to merge 7 commits into
Conversation
|
| Filename | Overview |
|---|---|
| GeneralsMD/Code/GameEngine/Source/GameClient/InGameUI.cpp | Core change: deselectAllDrawables now captures whether any drawables were selected before clearing them, and only posts MSG_DESTROY_SELECTED_GROUP when updateGameLogic=true AND objects were previously selected. Logic is correct; the snapshot precedes the deselection loop. |
| Core/GameEngine/Source/GameClient/MessageStream/SelectionXlat.cpp | Introduces m_pendingDeselection to defer the deselect message from RAW_MOUSE_LEFT_BUTTON_UP until after MOUSE_LEFT_CLICK resolves, preventing double MSG_DESTROY_SELECTED_GROUP on new-object selection. Removes the now-redundant deselectAll() static helper. Double-deselection bug in onMetaAddTeam is also fixed with a deselectedAllDrawables flag. |
| Core/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp | All deselectAllDrawables() call-sites that immediately precede MSG_CREATE_SELECTED_GROUP are updated to pass FALSE, suppressing the redundant MSG_DESTROY_SELECTED_GROUP in those paths. One change is inside a block comment and has no runtime effect. |
| GeneralsMD/Code/GameEngine/Include/GameClient/InGameUI.h | Parameter rename only: postMsg → updateGameLogic for better clarity. No functional change. |
| Core/GameEngine/Include/GameClient/SelectionXlat.h | Adds the m_pendingDeselection Bool member to SelectionTranslator. Straightforward declaration change. |
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/ControlBar/ControlBarCommandProcessing.cpp | Single call-site update: deselectAllDrawables(FALSE) before MSG_CREATE_SELECTED_GROUP, suppressing the redundant destroy message. |
| Core/GameEngine/Source/GameLogic/System/GameLogicDispatch.cpp | Single call-site update in replay observer path: deselectAllDrawables(FALSE) before reselecting objects for the replay camera, suppressing the destroy message during replay sync. |
Sequence Diagram
%%{init: {'theme': 'neutral'}}%%
sequenceDiagram
participant Mouse
participant SelectionXlat
participant InGameUI
participant MessageStream
Note over Mouse,MessageStream: Alternate mouse mode – click on empty space (deselect)
Mouse->>SelectionXlat: RAW_MOUSE_LEFT_BUTTON_UP
SelectionXlat->>SelectionXlat: "m_pendingDeselection = TRUE"
Mouse->>SelectionXlat: MOUSE_LEFT_CLICK
SelectionXlat->>SelectionXlat: onMouseLeftClick() – no object found
Note over SelectionXlat: m_pendingDeselection still TRUE
SelectionXlat->>InGameUI: "deselectAllDrawables(updateGameLogic=true)"
InGameUI-->>InGameUI: hadSelectedDrawables?
alt had selected drawables
InGameUI->>MessageStream: MSG_DESTROY_SELECTED_GROUP
end
Note over Mouse,MessageStream: Alternate mouse mode – click on new object
Mouse->>SelectionXlat: RAW_MOUSE_LEFT_BUTTON_UP
SelectionXlat->>SelectionXlat: "m_pendingDeselection = TRUE"
Mouse->>SelectionXlat: MOUSE_LEFT_CLICK
SelectionXlat->>SelectionXlat: onMouseLeftClick() – object found
SelectionXlat->>SelectionXlat: "m_pendingDeselection = FALSE"
SelectionXlat->>InGameUI: "deselectAllDrawables(updateGameLogic=false)"
Note over SelectionXlat: No MSG_DESTROY_SELECTED_GROUP (skipped)
SelectionXlat->>MessageStream: MSG_CREATE_SELECTED_GROUP
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
sequenceDiagram
participant Mouse
participant SelectionXlat
participant InGameUI
participant MessageStream
Note over Mouse,MessageStream: Alternate mouse mode – click on empty space (deselect)
Mouse->>SelectionXlat: RAW_MOUSE_LEFT_BUTTON_UP
SelectionXlat->>SelectionXlat: "m_pendingDeselection = TRUE"
Mouse->>SelectionXlat: MOUSE_LEFT_CLICK
SelectionXlat->>SelectionXlat: onMouseLeftClick() – no object found
Note over SelectionXlat: m_pendingDeselection still TRUE
SelectionXlat->>InGameUI: "deselectAllDrawables(updateGameLogic=true)"
InGameUI-->>InGameUI: hadSelectedDrawables?
alt had selected drawables
InGameUI->>MessageStream: MSG_DESTROY_SELECTED_GROUP
end
Note over Mouse,MessageStream: Alternate mouse mode – click on new object
Mouse->>SelectionXlat: RAW_MOUSE_LEFT_BUTTON_UP
SelectionXlat->>SelectionXlat: "m_pendingDeselection = TRUE"
Mouse->>SelectionXlat: MOUSE_LEFT_CLICK
SelectionXlat->>SelectionXlat: onMouseLeftClick() – object found
SelectionXlat->>SelectionXlat: "m_pendingDeselection = FALSE"
SelectionXlat->>InGameUI: "deselectAllDrawables(updateGameLogic=false)"
Note over SelectionXlat: No MSG_DESTROY_SELECTED_GROUP (skipped)
SelectionXlat->>MessageStream: MSG_CREATE_SELECTED_GROUP
Reviews (6): Last reviewed commit: "Misc fixes." | Re-trigger Greptile
2a1e6c7 to
fcb6ef1
Compare
xezon
left a comment
There was a problem hiding this comment.
How confident are we that this will cause no gameplay issues?
|
|
||
| // TheSuperHackers @tweak Avoid double deselection when selecting a new object with another object selected, | ||
| // originally triggered by RAW_MOUSE_LEFT_BUTTON_UP and MOUSE_LEFT_CLICK, respectively. | ||
| if (msg->getType() == GameMessage::MSG_MOUSE_LEFT_CLICK && m_pendingDeselection) |
| if( !TheInGameUI->getPreventLeftClickDeselectionInAlternateMouseModeForOneClick() ) | ||
| { | ||
| deselectAll(); | ||
| m_pendingDeselection = TRUE; |
There was a problem hiding this comment.
Why is this necessary? Can't we just call deselectAllDrawables here? A second call to deselectAllDrawables will not send a second message then.
There was a problem hiding this comment.
(My comment assumes alternate mouse mode is enabled).
The selection of an object generates two messages, RAW_MOUSE_LEFT_BUTTON_DOWN and MOUSE_LEFT_CLICK. Originally, both would deselect everything, even in the case of a new group creation, which doesn't require prior deselection.
Why is this necessary? Can't we just call
deselectAllDrawableshere? A second call todeselectAllDrawableswill not send a second message then.
It would be ok to call deselectAllDrawables here, except it's extremely likely that the next message is MOUSE_LEFT_CLICK creating a new group in which case there's no Logic deselection required at all. If you can think of a cleaner way to do this, I'd like that.
There was a problem hiding this comment.
So MSG_MOUSE_LEFT_CLICK is synonymous for a single MSG_RAW_MOUSE_LEFT_BUTTON_UP.
If object deselect cannot be fully determined at RAW_MOUSE_LEFT_BUTTON_DOWN, then why not just determine it at only MSG_MOUSE_LEFT_CLICK?
There was a problem hiding this comment.
Perhaps for consistency with RAW_MOUSE_RIGHT_BUTTON_DOWN, and because MSG_MOUSE_LEFT_CLICK has 7 early breaks before it gets to the code that does the group creation.
65a34a7 to
74b9ff4
Compare
8baab11 to
219fa73
Compare
The client considers primary mouse clicks in the game world as a deselection, and will also update the game logic. This means that
GameMessage::MSG_DESTROY_SELECTED_GROUPmessages are sent frequently, even if no objects are currently selected. There's actually an old EA comment on this issue. It's also unnecessary to send this message prior to the creation of a new group. This PR changes that by checking first if the local player has objects selected, which reduces the number of messages significantly.I've tested with two local clients in multiplayer (VS22 debug builds); one had this feature and one didn't, and everything worked fine.
See commits for cleaner diffs.
Results for Golden Replay 1:
MSG_NETWORK_MESSAGES: 58770MSG_LOGIC_CRC: 13386MSG_DO_MOVETO: 6888MSG_AREA_SELECTION_DEPRECATED: 4476MSG_QUEUE_UNIT_CREATE: 2225MSG_DESTROY_SELECTED_GROUP: 17366MSG_CREATE_SELECTED_GROUP_NO_SOUND: 317, new group: 88MSG_CREATE_SELECTED_GROUP: 8299, new group: 8114MSG_DESTROY_SELECTED_GROUPbefore new group creation: 8901Just avoiding the
MSG_DESTROY_SELECTED_GROUPbefore the creation of a new group accounts for 15% of all network messages in this replay. That doesn't even take into account how many times this message was sent when no units were selected.TODO: