Savestate: The callback is already an std::function, so no cbUserdata value is needed.

This commit is contained in:
Henrik Rydgård
2025-05-16 00:27:32 +02:00
parent 8e206d891f
commit a698486f9c
7 changed files with 52 additions and 62 deletions
+31 -38
View File
@@ -80,14 +80,13 @@ double g_lastSaveTime = -1.0;
struct Operation {
// The slot number is for visual purposes only. Set to -1 for operations where we don't display a message for example.
Operation(OperationType t, const Path &f, int slot_, Callback cb, void *cbUserData_)
: type(t), filename(f), callback(cb), slot(slot_), cbUserData(cbUserData_) {}
Operation(OperationType t, const Path &f, int slot_, Callback cb)
: type(t), filename(f), callback(cb), slot(slot_) {}
OperationType type;
Path filename;
Callback callback;
int slot;
void *cbUserData;
};
CChunkFileReader::Error SaveToRam(std::vector<u8> &data) {
@@ -427,8 +426,7 @@ double g_lastSaveTime = -1.0;
needsProcess = true;
}
void Load(const Path &filename, int slot, Callback callback, void *cbUserData)
{
void Load(const Path &filename, int slot, Callback callback) {
if (!NetworkAllowSaveState()) {
return;
}
@@ -436,11 +434,10 @@ double g_lastSaveTime = -1.0;
rewindStates.NotifyState();
if (coreState == CoreState::CORE_RUNTIME_ERROR)
Core_Break(BreakReason::SavestateLoad, 0);
Enqueue(Operation(SAVESTATE_LOAD, filename, slot, callback, cbUserData));
Enqueue(Operation(SAVESTATE_LOAD, filename, slot, callback));
}
void Save(const Path &filename, int slot, Callback callback, void *cbUserData)
{
void Save(const Path &filename, int slot, Callback callback) {
if (!NetworkAllowSaveState()) {
return;
}
@@ -448,27 +445,25 @@ double g_lastSaveTime = -1.0;
rewindStates.NotifyState();
if (coreState == CoreState::CORE_RUNTIME_ERROR)
Core_Break(BreakReason::SavestateSave, 0);
Enqueue(Operation(SAVESTATE_SAVE, filename, slot, callback, cbUserData));
Enqueue(Operation(SAVESTATE_SAVE, filename, slot, callback));
}
void Verify(Callback callback, void *cbUserData)
{
Enqueue(Operation(SAVESTATE_VERIFY, Path(), -1, callback, cbUserData));
void Verify(Callback callback) {
Enqueue(Operation(SAVESTATE_VERIFY, Path(), -1, callback));
}
void Rewind(Callback callback, void *cbUserData)
{
void Rewind(Callback callback) {
if (g_netInited) {
return;
}
if (coreState == CoreState::CORE_RUNTIME_ERROR)
Core_Break(BreakReason::SavestateRewind, 0);
Enqueue(Operation(SAVESTATE_REWIND, Path(), -1, callback, cbUserData));
Enqueue(Operation(SAVESTATE_REWIND, Path(), -1, callback));
}
static void SaveScreenshot(const Path &filename) {
screenshotFailures = 0;
Enqueue(Operation(SAVESTATE_SAVE_SCREENSHOT, filename, -1, nullptr, nullptr));
Enqueue(Operation(SAVESTATE_SAVE_SCREENSHOT, filename, -1, nullptr));
}
bool CanRewind() {
@@ -588,7 +583,7 @@ double g_lastSaveTime = -1.0;
}
}
void LoadSlot(const Path &gameFilename, int slot, Callback callback, void *cbUserData)
void LoadSlot(const Path &gameFilename, int slot, Callback callback)
{
if (!NetworkAllowSaveState()) {
return;
@@ -600,7 +595,7 @@ double g_lastSaveTime = -1.0;
if (g_Config.bEnableStateUndo) {
Path backup = GetSysDirectory(DIRECTORY_SAVESTATE) / LOAD_UNDO_NAME;
auto saveCallback = [=](Status status, std::string_view message, void *data) {
auto saveCallback = [=](Status status, std::string_view message) {
if (status != Status::FAILURE) {
DeleteIfExists(backup);
File::Rename(backup.WithExtraExtension(".tmp"), backup);
@@ -609,28 +604,27 @@ double g_lastSaveTime = -1.0;
} else {
ERROR_LOG(Log::SaveState, "Saving load undo state failed: %.*s", (int)message.size(), message.data());
}
Load(fn, slot, callback, cbUserData);
Load(fn, slot, callback);
};
if (!backup.empty()) {
Save(backup.WithExtraExtension(".tmp"), LOAD_UNDO_SLOT, saveCallback, cbUserData);
Save(backup.WithExtraExtension(".tmp"), LOAD_UNDO_SLOT, saveCallback);
} else {
ERROR_LOG(Log::SaveState, "Saving load undo state failed. Error in the file system.");
Load(fn, slot, callback, cbUserData);
Load(fn, slot, callback);
}
} else {
Load(fn, slot, callback, cbUserData);
Load(fn, slot, callback);
}
} else {
if (callback) {
auto sy = GetI18NCategory(I18NCat::SYSTEM);
callback(Status::FAILURE, sy->T("Failed to load state. Error in the file system."), cbUserData);
callback(Status::FAILURE, sy->T("Failed to load state. Error in the file system."));
}
}
}
bool UndoLoad(const Path &gameFilename, Callback callback, void *cbUserData)
{
bool UndoLoad(const Path &gameFilename, Callback callback) {
if (!NetworkAllowSaveState()) {
return false;
}
@@ -638,26 +632,25 @@ double g_lastSaveTime = -1.0;
if (g_Config.sStateLoadUndoGame != GenerateFullDiscId(gameFilename)) {
if (callback) {
auto sy = GetI18NCategory(I18NCat::SYSTEM);
callback(Status::FAILURE, sy->T("Error: load undo state is from a different game"), cbUserData);
callback(Status::FAILURE, sy->T("Error: load undo state is from a different game"));
}
return false;
}
Path fn = GetSysDirectory(DIRECTORY_SAVESTATE) / LOAD_UNDO_NAME;
if (!fn.empty()) {
Load(fn, LOAD_UNDO_SLOT, callback, cbUserData);
Load(fn, LOAD_UNDO_SLOT, callback);
return true;
} else {
if (callback) {
auto sy = GetI18NCategory(I18NCat::SYSTEM);
callback(Status::FAILURE, sy->T("Failed to load state for load undo. Error in the file system."), cbUserData);
callback(Status::FAILURE, sy->T("Failed to load state for load undo. Error in the file system."));
}
return false;
}
}
void SaveSlot(const Path &gameFilename, int slot, Callback callback, void *cbUserData)
{
void SaveSlot(const Path &gameFilename, int slot, Callback callback) {
if (!NetworkAllowSaveState()) {
return;
}
@@ -666,7 +659,7 @@ double g_lastSaveTime = -1.0;
Path fnUndo = GenerateSaveSlotFilename(gameFilename, slot, UNDO_STATE_EXTENSION);
if (!fn.empty()) {
Path shot = GenerateSaveSlotFilename(gameFilename, slot, SCREENSHOT_EXTENSION);
auto renameCallback = [=](Status status, std::string_view message, void *data) {
auto renameCallback = [=](Status status, std::string_view message) {
if (status != Status::FAILURE) {
if (g_Config.bEnableStateUndo) {
DeleteIfExists(fnUndo);
@@ -680,7 +673,7 @@ double g_lastSaveTime = -1.0;
File::Rename(fn.WithExtraExtension(".tmp"), fn);
}
if (callback) {
callback(status, message, data);
callback(status, message);
}
};
// Let's also create a screenshot.
@@ -690,11 +683,11 @@ double g_lastSaveTime = -1.0;
RenameIfExists(shot, shotUndo);
}
SaveScreenshot(shot);
Save(fn.WithExtraExtension(".tmp"), slot, renameCallback, cbUserData);
Save(fn.WithExtraExtension(".tmp"), slot, renameCallback);
} else {
if (callback) {
auto sy = GetI18NCategory(I18NCat::SYSTEM);
callback(Status::FAILURE, sy->T("Failed to save state. Error in the file system."), cbUserData);
callback(Status::FAILURE, sy->T("Failed to save state. Error in the file system."));
}
}
}
@@ -720,7 +713,6 @@ double g_lastSaveTime = -1.0;
return false;
}
bool UndoLastSave(const Path &gameFilename) {
if (!NetworkAllowSaveState()) {
return false;
@@ -732,7 +724,7 @@ double g_lastSaveTime = -1.0;
return UndoSaveSlot(gameFilename, g_Config.iStateUndoLastSaveSlot);
}
bool HasSaveInSlot(const Path &gameFilename, int slot)
bool HasSaveInSlot(const Path &gameFilename, int slot)
{
Path fn = GenerateSaveSlotFilename(gameFilename, slot, STATE_EXTENSION);
return File::Exists(fn);
@@ -1130,8 +1122,9 @@ double g_lastSaveTime = -1.0;
break;
}
if (op.callback)
op.callback(callbackResult, callbackMessage, op.cbUserData);
if (op.callback) {
op.callback(callbackResult, callbackMessage);
}
}
if (operations.size()) {
// Avoid triggering frame skipping due to slowdown
+8 -8
View File
@@ -31,7 +31,7 @@ namespace SaveState {
WARNING,
SUCCESS,
};
typedef std::function<void(Status status, std::string_view message, void *cbUserData)> Callback;
typedef std::function<void(Status status, std::string_view message)> Callback;
static const int NUM_SLOTS = 5;
static const char * const STATE_EXTENSION = "ppst";
@@ -47,11 +47,11 @@ namespace SaveState {
// Cycle through the 5 savestate slots
void PrevSlot();
void NextSlot();
void SaveSlot(const Path &gameFilename, int slot, Callback callback, void *cbUserData = 0);
void LoadSlot(const Path &gameFilename, int slot, Callback callback, void *cbUserData = 0);
void SaveSlot(const Path &gameFilename, int slot, Callback callback);
void LoadSlot(const Path &gameFilename, int slot, Callback callback);
bool UndoSaveSlot(const Path &gameFilename, int slot);
bool UndoLastSave(const Path &gameFilename);
bool UndoLoad(const Path &gameFilename, Callback callback, void *cbUserData = 0);
bool UndoLoad(const Path &gameFilename, Callback callback);
// Checks whether there's an existing save in the specified slot.
bool HasSaveInSlot(const Path &gameFilename, int slot);
bool HasUndoSaveInSlot(const Path &gameFilename, int slot);
@@ -73,22 +73,22 @@ namespace SaveState {
// Load the specified file into the current state (async.)
// Warning: callback will be called on a different thread.
void Load(const Path &filename, int slot, Callback callback = Callback(), void *cbUserData = 0);
void Load(const Path &filename, int slot, Callback callback = Callback());
// Save the current state to the specified file (async.)
// Warning: callback will be called on a different thread.
void Save(const Path &filename, int slot, Callback callback = Callback(), void *cbUserData = 0);
void Save(const Path &filename, int slot, Callback callback = Callback());
CChunkFileReader::Error SaveToRam(std::vector<u8> &state);
CChunkFileReader::Error LoadFromRam(std::vector<u8> &state, std::string *errorString);
// For testing / automated tests. Runs a save state verification pass (async.)
// Warning: callback will be called on a different thread.
void Verify(Callback callback = Callback(), void *cbUserData = 0);
void Verify(Callback callback = Callback());
// To go back to a previous snapshot (only if enabled.)
// Warning: callback will be called on a different thread.
void Rewind(Callback callback = Callback(), void *cbUserData = 0);
void Rewind(Callback callback = Callback());
// Returns true if there are rewind snapshots available.
bool CanRewind();
+5 -5
View File
@@ -149,7 +149,7 @@ void MainWindow::openmsAct()
QDesktopServices::openUrl(QUrl(memorystick));
}
static void SaveStateActionFinished(SaveState::Status status, std::string_view message, void *userdata)
static void SaveStateActionFinished(SaveState::Status status, std::string_view message)
{
// TODO: Improve messaging?
if (status == SaveState::Status::FAILURE)
@@ -165,13 +165,13 @@ static void SaveStateActionFinished(SaveState::Status status, std::string_view m
void MainWindow::qlstateAct()
{
Path gamePath = PSP_CoreParameter().fileToStart;
SaveState::LoadSlot(gamePath, 0, SaveStateActionFinished, this);
SaveState::LoadSlot(gamePath, 0, SaveStateActionFinished);
}
void MainWindow::qsstateAct()
{
Path gamePath = PSP_CoreParameter().fileToStart;
SaveState::SaveSlot(gamePath, 0, SaveStateActionFinished, this);
SaveState::SaveSlot(gamePath, 0, SaveStateActionFinished);
}
void MainWindow::lstateAct()
@@ -185,7 +185,7 @@ void MainWindow::lstateAct()
if (dialog.exec())
{
QStringList fileNames = dialog.selectedFiles();
SaveState::Load(Path(fileNames[0].toStdString()), -1, SaveStateActionFinished, this);
SaveState::Load(Path(fileNames[0].toStdString()), -1, SaveStateActionFinished);
}
}
@@ -200,7 +200,7 @@ void MainWindow::sstateAct()
if (dialog.exec())
{
QStringList fileNames = dialog.selectedFiles();
SaveState::Save(Path(fileNames[0].toStdString()), -1, SaveStateActionFinished, this);
SaveState::Save(Path(fileNames[0].toStdString()), -1, SaveStateActionFinished);
}
}
+5 -8
View File
@@ -493,18 +493,12 @@ void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) {
lastImguiEnabled_ = false;
}
static void AfterSaveStateAction(SaveState::Status status, std::string_view message, void *) {
static void AfterSaveStateAction(SaveState::Status status, std::string_view message) {
if (!message.empty() && (!g_Config.bDumpFrames || !g_Config.bDumpVideoOutput)) {
g_OSD.Show(status == SaveState::Status::SUCCESS ? OSDType::MESSAGE_SUCCESS : OSDType::MESSAGE_ERROR, message, status == SaveState::Status::SUCCESS ? 2.0 : 5.0);
}
}
static void AfterStateBoot(SaveState::Status status, std::string_view message, void *ignored) {
AfterSaveStateAction(status, message, ignored);
Core_Resume();
System_Notify(SystemNotification::DISASSEMBLY);
}
void EmuScreen::focusChanged(ScreenFocusChange focusChange) {
Screen::focusChanged(focusChange);
@@ -567,7 +561,10 @@ void EmuScreen::sendMessage(UIMessage message, const char *value) {
}
const char *ext = strrchr(value, '.');
if (ext != nullptr && !strcmp(ext, ".ppst")) {
SaveState::Load(Path(value), -1, &AfterStateBoot);
SaveState::Load(Path(value), -1, [](SaveState::Status status, std::string_view message) {
Core_Resume();
System_Notify(SystemNotification::DISASSEMBLY);
});
} else {
PSP_Shutdown(true);
Achievements::UnloadGame();
+1 -1
View File
@@ -725,7 +725,7 @@ void NativeInit(int argc, const char *argv[], const char *savegame_dir, const ch
g_BackgroundAudio.SFX().Init();
if (!boot_filename.empty() && stateToLoad.Valid()) {
SaveState::Load(stateToLoad, -1, [](SaveState::Status status, std::string_view message, void *) {
SaveState::Load(stateToLoad, -1, [](SaveState::Status status, std::string_view message) {
if (!message.empty() && (!g_Config.bDumpFrames || !g_Config.bDumpVideoOutput)) {
g_OSD.Show(status == SaveState::Status::SUCCESS ? OSDType::MESSAGE_SUCCESS : OSDType::MESSAGE_ERROR,
message, status == SaveState::Status::SUCCESS ? 2.0 : 5.0);
+1 -1
View File
@@ -64,7 +64,7 @@
#include "UI/RetroAchievementScreens.h"
#include "UI/BackgroundAudio.h"
static void AfterSaveStateAction(SaveState::Status status, std::string_view message, void *) {
static void AfterSaveStateAction(SaveState::Status status, std::string_view message) {
if (!message.empty() && (!g_Config.bDumpFrames || !g_Config.bDumpVideoOutput)) {
g_OSD.Show(status == SaveState::Status::SUCCESS ? OSDType::MESSAGE_SUCCESS : OSDType::MESSAGE_ERROR,
message, status == SaveState::Status::SUCCESS ? 2.0 : 5.0);
+1 -1
View File
@@ -375,7 +375,7 @@ namespace MainWindow {
});
}
static void SaveStateActionFinished(SaveState::Status status, std::string_view message, void *userdata) {
static void SaveStateActionFinished(SaveState::Status status, std::string_view message) {
if (!message.empty() && (!g_Config.bDumpFrames || !g_Config.bDumpVideoOutput)) {
g_OSD.Show(status == SaveState::Status::SUCCESS ? OSDType::MESSAGE_SUCCESS : OSDType::MESSAGE_ERROR, message, status == SaveState::Status::SUCCESS ? 2.0 : 5.0);
}