feature(gamelogic): Implement ALT + F4 and Window X button to close game#2336
feature(gamelogic): Implement ALT + F4 and Window X button to close game#2336githubawn wants to merge 4 commits intoTheSuperHackers:mainfrom
Conversation
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp | Centralizes quit logic into GameLogic::quit() method and adds exception-based abort for loading process |
| Generals/Code/GameEngine/Source/GameClient/GameClient.cpp | Adds isMovieAbortRequested() helper to check for ESC, Alt+F4, and window close during video playback |
| Generals/Code/GameEngine/Source/GameClient/MessageStream/CommandXlat.cpp | Simplifies instant quit handler to use centralized quit logic and marks message as system message |
| Core/GameEngine/Source/GameClient/GUI/LoadScreen.cpp | Refactors movie abort checks to use isMovieAbortRequested() and adds abort support during loading |
| Generals/Code/GameEngine/Include/GameLogic/GameLogic.h | Adds public m_quitToDesktopAfterMatch flag and quit() method declaration |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[User Action: Alt+F4 / Window X / ESC] --> B{Context?}
B -->|In Game| C[GameLogic::quit called]
B -->|During Movie| D[isMovieAbortRequested]
B -->|During Loading| E[updateLoadProgress checks flags]
C --> F{In Multiplayer?}
F -->|Yes, not Skirmish| G[Send MSG_SELF_DESTRUCT]
F -->|No| H[Skip self-destruct]
G --> I{Recording?}
H --> I
I -->|Yes| J[Stop recording]
I -->|No| K[Skip stop recording]
J --> L[Unpause & unfreeze game]
K --> L
L --> M{toDesktop flag?}
M -->|Yes & Multiplayer| N[Set m_quitToDesktopAfterMatch]
M -->|Yes & Not Multiplayer| O[clearGameData]
M -->|No| P[exitGame]
N --> Q[exitGame]
O --> R[setQuitting TRUE]
P --> S[setClientQuiet]
Q --> S
R --> S
D --> T{Quit flag set?}
E --> U{Quit flag set?}
T -->|Yes| V[Abort movie playback]
U -->|Yes| W[Throw QuitGameException]
W --> X[Caught in startNewGame]
X --> Y[Clean abort]
V --> Y
Last reviewed commit: 036ed84
| TheGameEngine->serviceWindowsOS(); | ||
| if (TheGameEngine->getQuitting()) | ||
| TheMessageStream->propagateMessages(); | ||
| if (TheGameEngine->getQuitting() || TheGameLogic->m_quitToDesktopAfterMatch) |
There was a problem hiding this comment.
Missing null check for TheGameLogic before accessing m_quitToDesktopAfterMatch. GameClient.cpp:820 includes this check. Add the same guard here to prevent potential null pointer dereference.
| if (TheGameEngine->getQuitting() || TheGameLogic->m_quitToDesktopAfterMatch) | |
| if (TheGameEngine->getQuitting() || (TheGameLogic && TheGameLogic->m_quitToDesktopAfterMatch)) |
Prompt To Fix With AI
This is a comment left during a code review.
Path: GeneralsMD/Code/GameEngine/Source/GameClient/GUI/LoadScreen.cpp
Line: 166
Comment:
Missing null check for `TheGameLogic` before accessing `m_quitToDesktopAfterMatch`. `GameClient.cpp:820` includes this check. Add the same guard here to prevent potential null pointer dereference.
```suggestion
if (TheGameEngine->getQuitting() || (TheGameLogic && TheGameLogic->m_quitToDesktopAfterMatch))
```
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
I gave this a thumbs up, but on second thought TheGameLogic is initialized as part of the game engine initialization, so it doesn't seem necessary. (3 several times in this PR)
There was a problem hiding this comment.
keeping it as free insurance, no cost to having it, open to removing if there's a concrete reason
|
Needs rebase. My initial thought on this, without looking at code, is that it will make it easier for players to disconnect from a Multiplayer match - by accident or intentional - so this feature must not work during a Multiplayer Match. |
|
Will rebase soon. The multiplayer behavior was designed based on your comment from #1356 (comment). It also adds safe abort logic so Alt+F4 works consistently everywhere addressing helmutbuhler's #1356 (comment) concern about the button only working in some situations. |
|
Thank you for implementing this. I did a few quick tests and the current implementation appears to work well. |
843b370 to
4fda496
Compare
GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp
Outdated
Show resolved
Hide resolved
GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp
Outdated
Show resolved
Hide resolved
2d896d5 to
036ed84
Compare
Fixes #1356
Split up in 2 commits.
Previously, the quit logic was duplicated and inconsistent across several places (the quit menu, the "quit to desktop" button, and the Alt+F4 handler). This commit centralizes all of that into a single GameLogic::quit(Bool toDesktop) method. It properly handles edge cases like stopping an active recording, sending a self-destruct message in multiplayer (using a new m_quitToDesktopAfterMatch flag), unpausing/unfreezing the game before exiting. All the old scattered quit code is replaced with a simple call to TheGameLogic->quit(true/false).
This follow-up extends the graceful exit to two more situations where the game previously couldn't be closed cleanly:
During the loading screen: The load progress update now checks if a quit has been requested and throws a QuitGameException, which is caught in startNewGame() to cleanly abort the loading process mid-way.
During movies: The inline ESC-key checking that was copy-pasted in multiple video playback loops is refactored into a new GameClient::isMovieAbortRequested() method. This method now also checks for window close / Alt+F4 events (not just ESC), so closing the window during a movie no longer gets stuck. The MSG_META_DEMO_INSTANT_QUIT message is also registered as a system message so it propagates correctly even during loading.