cellSaveData: improve ppu schedule during dialogs

This commit is contained in:
Megamouse 2019-12-29 13:08:37 +01:00
parent c4b4ce46b8
commit 45dc5d9b02
1 changed files with 75 additions and 44 deletions

View File

@ -164,23 +164,24 @@ static error_code select_and_delete(ppu_thread& ppu)
while (true)
{
// Yield
// Yield before a blocking dialog is being spawned
lv2_obj::sleep(ppu);
// Display Save Data List asynchronously in the GUI thread.
// Display a blocking Save Data List asynchronously in the GUI thread.
if (auto save_dialog = Emu.GetCallbacks().get_save_dialog())
{
selected = save_dialog->ShowSaveDataList(save_entries, focused, SAVEDATA_OP_LIST_DELETE, vm::null);
}
// Reschedule after a blocking dialog returns
if (ppu.check_state())
{
return 0;
}
// Abort if dialog was canceled or selection is invalid in this context
if (selected < 0)
{
// Reschedule
if (ppu.check_state())
{
return 0;
}
return CELL_CANCEL;
}
@ -191,11 +192,16 @@ static error_code select_and_delete(ppu_thread& ppu)
SaveDataEntry entry = save_entries[selected];
const std::string info = entry.title + "\n" + entry.subtitle + "\n" + entry.details;
// Get user confirmation
// Reusable display message string
std::string msg = "Do you really want to delete this entry?\n\n" + info;
// Yield before a blocking dialog is being spawned
lv2_obj::sleep(ppu);
// Get user confirmation by opening a blocking dialog
error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(msg));
// Reschedule
// Reschedule after a blocking dialog returns
if (ppu.check_state())
{
return 0;
@ -222,23 +228,35 @@ static error_code select_and_delete(ppu_thread& ppu)
focused = -1;
}
// Display success message (return value should be irrelevant here)
// Update display message
msg = "Successfully removed entry!\n\n" + info;
cellSaveData.success("%s", msg);
// Yield before blocking dialog is being spawned
lv2_obj::sleep(ppu);
// Display success message by opening a blocking dialog (return value should be irrelevant here)
res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, vm::make_str(msg));
// Reschedule after blocking dialog returns
if (ppu.check_state())
{
return 0;
}
}
}
return CELL_CANCEL;
}
// Displays a savedata error message. error_code is not returned since the caller errored already.
static void display_error_message(vm::ptr<CellSaveDataCBResult> result)
// Displays a CellSaveDataCBResult error message.
static error_code display_callback_result_error_message(ppu_thread& ppu, vm::ptr<CellSaveDataCBResult> result)
{
if (!result)
return;
return CELL_SAVEDATA_ERROR_CBRESULT;
std::string msg;
bool use_invalid_message = false;
switch (result->result)
{
@ -256,13 +274,25 @@ static void display_error_message(vm::ptr<CellSaveDataCBResult> result)
break;
case CELL_SAVEDATA_CBRESULT_ERR_INVALID:
if (result->invalidMsg)
error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, result->invalidMsg);
return;
use_invalid_message = true;
break;
default:
return;
return CELL_SAVEDATA_ERROR_CBRESULT;
}
error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, vm::make_str(msg));
// Yield before a blocking dialog is being spawned
lv2_obj::sleep(ppu);
// Get user confirmation by opening a blocking dialog (return value should be irrelevant here)
error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_OK, use_invalid_message ? result->invalidMsg : vm::make_str(msg));
// Reschedule after a blocking dialog returns
if (ppu.check_state())
{
return 0;
}
return CELL_SAVEDATA_ERROR_CBRESULT;
}
static std::string get_confirmation_message(u32 operation)
@ -654,10 +684,9 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
if (result->result < 0)
{
display_error_message(result);
cellSaveData.warning("savedata_op(): funcList returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT;
return display_callback_result_error_message(ppu, result);
}
// if the callback has returned ok, lets return OK.
@ -797,10 +826,10 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
while (funcList)
{
// Yield
// Yield before a blocking dialog is being spawned
lv2_obj::sleep(ppu);
// Display Save Data List asynchronously in the GUI thread.
// Display a blocking Save Data List asynchronously in the GUI thread.
if (auto save_dialog = Emu.GetCallbacks().get_save_dialog())
{
selected = save_dialog->ShowSaveDataList(save_entries, focused, operation, listSet);
@ -810,14 +839,15 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
selected = -2;
}
// Reschedule after a blocking dialog returns
if (ppu.check_state())
{
return 0;
}
// Cancel selected in UI
if (selected == -2)
{
// Reschedule
if (ppu.check_state())
{
return 0;
}
return CELL_CANCEL;
}
@ -837,10 +867,13 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
message = get_confirmation_message(operation) + "\n\n" + entry.title + "\n" + entry.subtitle + "\n" + entry.details;
}
// Get user confirmation
// Yield before a blocking dialog is being spawned
lv2_obj::sleep(ppu);
// Get user confirmation by opening a blocking dialog
error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(message));
// Reschedule
// Reschedule after a blocking dialog returns
if (ppu.check_state())
{
return 0;
@ -862,10 +895,9 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
if (result->result < 0)
{
display_error_message(result);
cellSaveData.warning("savedata_op(): funcDone returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT;
return display_callback_result_error_message(ppu, result);
}
if (result->result == CELL_SAVEDATA_CBRESULT_OK_LAST || result->result == CELL_SAVEDATA_CBRESULT_OK_LAST_NOCONFIRM)
@ -905,10 +937,9 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
if (result->result < 0)
{
display_error_message(result);
cellSaveData.warning("savedata_op(): funcFixed returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT;
return display_callback_result_error_message(ppu, result);
}
if (!fixedSet->dirName)
@ -944,10 +975,13 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
message = get_confirmation_message(operation) + "\n\n" + entry.title + "\n" + entry.subtitle + "\n" + entry.details;
}
// Get user confirmation
// Yield before a blocking dialog is being spawned
lv2_obj::sleep(ppu);
// Get user confirmation by opening a blocking dialog
error_code res = open_msg_dialog(true, CELL_MSGDIALOG_TYPE_SE_TYPE_NORMAL | CELL_MSGDIALOG_TYPE_BUTTON_TYPE_YESNO, vm::make_str(message));
// Reschedule
// Reschedule after a blocking dialog returns
if (ppu.check_state())
{
return 0;
@ -976,10 +1010,9 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
if (result->result < 0)
{
display_error_message(result);
cellSaveData.warning("savedata_op(): funcDone_ returned result=%d.", result->result);
return CELL_SAVEDATA_ERROR_CBRESULT;
return display_callback_result_error_message(ppu, result);
}
return CELL_OK;
@ -1158,9 +1191,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
if (result->result < CELL_SAVEDATA_CBRESULT_OK_NEXT)
{
display_error_message(result);
return CELL_SAVEDATA_ERROR_CBRESULT;
return display_callback_result_error_message(ppu, result);
}
// Skip and return without error
@ -1561,7 +1592,7 @@ static NEVER_INLINE error_code savedata_op(ppu_thread& ppu, u32 operation, u32 v
if (savedata_result == CELL_SAVEDATA_ERROR_CBRESULT)
{
display_error_message(result);
return display_callback_result_error_message(ppu, result);
}
return savedata_result;