refactor(saveload): Decouple result handling from game state - #3000
refactor(saveload): Decouple result handling from game state#3000bobtista wants to merge 6 commits into
Conversation
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Source/Common/System/SaveGame/GameState.cpp | Removes direct UI presentation from persistence methods and returns structured save/load results with optional resolved filenames. |
| Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/SaveLoadFeedback.cpp | Centralizes the existing GUI messages and dialogs associated with save/load result codes. |
| Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/PopupSaveLoad.cpp | Captures save/load results and delegates their presentation to the new GUI helper. |
| Generals/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/Menus/ScoreScreen.cpp | Presents mission-save results from the score-screen caller. |
| GeneralsMD/Code/GameEngine/Source/Common/System/SaveGame/GameState.cpp | Mirrors the decoupled persistence result handling for Zero Hour. |
| GeneralsMD/Code/GameEngine/Source/GameClient/GUI/GUICallbacks/SaveLoadFeedback.cpp | Mirrors the centralized save/load GUI feedback implementation for Zero Hour. |
Reviews (2): Last reviewed commit: "refactor(saveload): Decouple result hand..." | Re-trigger Greptile
| // engine resets | ||
| // | ||
| if (TheGameState->loadGame( *selectedGameInfo ) != SC_OK) | ||
| AsciiString filename = selectedGameInfo->filename; |
There was a problem hiding this comment.
filename is a const copy rather than a const ref because loadGame() resets the engine and frees the listbox item data that selectedGameInfo points at, so the value has to outlive the call right?
There was a problem hiding this comment.
Ok if that is the case and selectedGameInfo will be dangling afterwards, then reduce the scope of selectedGameInfo.
There was a problem hiding this comment.
How about we copy the struct up front instead? eg
const AvailableGameInfo gameInfo = *getSelectedSaveFileInfo( listboxGames );
const SaveCode result = TheGameState->loadGame( gameInfo );
presentLoadResult( result, gameInfo.filename );
There was a problem hiding this comment.
Looks a bit much. And there are pointers inside which may be dangling then as well.
By reducing the scope of selectedGameInfo, it implicitly documents that the lifetime is capped and the compiler will error if it is dereferenced after the scope end. Alternative is to set selectedGameInfo to null, but then the compiler would still happily compile a dereference afterwards.
8fa0016 to
7347dd0
Compare
|
There are 2 test cases left in the TODO description. Does it work? |
Yes, I checked them |
Fixes #2998
GameState::saveGame and GameState::loadGame present their results directly through TheInGameUI and MessageBoxOk. This couples save serialization to interactive client UI and prevents non-interactive callers from handling results themselves.
Now save and load functions only return SaveCode results, while GUI callers present the existing success and error messages. Save functions can also return the resolved filename when one is generated automatically.
Todo: