Implement cellMsgDialog closing thread

Fixing deprecation warning.
This commit is contained in:
Nekotekina 2020-02-22 14:46:49 +03:00
parent 3001701059
commit 96be40bf30

View File

@ -13,6 +13,8 @@
LOG_CHANNEL(cellSysutil); LOG_CHANNEL(cellSysutil);
extern u64 get_guest_system_time();
template<> template<>
void fmt_class_string<CellMsgDialogError>::format(std::string& out, u64 arg) void fmt_class_string<CellMsgDialogError>::format(std::string& out, u64 arg)
{ {
@ -79,6 +81,59 @@ struct msg_info
} }
}; };
struct msg_dlg_thread_info
{
atomic_t<u64> wait_until = 0;
void operator()()
{
while (thread_ctrl::state() != thread_state::aborting)
{
const u64 new_value = wait_until.load();
if (new_value == 0)
{
wait_until.wait(0);
continue;
}
while (get_guest_system_time() < new_value)
{
if (wait_until.load() != new_value)
break;
std::this_thread::sleep_for(10ms);
}
if (auto manager = g_fxo->get<rsx::overlays::display_manager>())
{
if (auto dlg = manager->get<rsx::overlays::message_dialog>())
{
if (!wait_until.compare_and_swap_test(new_value, 0))
{
continue;
}
dlg->close();
}
}
else if (const auto dlg = g_fxo->get<msg_info>()->get())
{
if (!wait_until.compare_and_swap_test(new_value, 0))
{
continue;
}
dlg->on_close(CELL_MSGDIALOG_BUTTON_NONE);
}
}
}
static constexpr auto thread_name = "MsgDialog Close Thread"sv;
};
using msg_dlg_thread = named_thread<msg_dlg_thread_info>;
// variable used to immediately get the response from auxiliary message dialogs (callbacks would be async) // variable used to immediately get the response from auxiliary message dialogs (callbacks would be async)
atomic_t<s32> g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE; atomic_t<s32> g_last_user_response = CELL_MSGDIALOG_BUTTON_NONE;
@ -140,6 +195,7 @@ error_code open_msg_dialog(bool is_blocking, u32 type, vm::cptr<char> msgString,
}); });
} }
g_fxo->get<msg_dlg_thread>()->wait_until = 0;
g_fxo->get<msg_info>()->remove(); g_fxo->get<msg_info>()->remove();
} }
@ -368,31 +424,19 @@ error_code cellMsgDialogClose(f32 delay)
{ {
cellSysutil.warning("cellMsgDialogClose(delay=%f)", delay); cellSysutil.warning("cellMsgDialogClose(delay=%f)", delay);
extern u64 get_guest_system_time();
const u64 wait_until = get_guest_system_time() + static_cast<s64>(std::max<float>(delay, 0.0f) * 1000); const u64 wait_until = get_guest_system_time() + static_cast<s64>(std::max<float>(delay, 0.0f) * 1000);
if (auto manager = g_fxo->get<rsx::overlays::display_manager>()) if (auto manager = g_fxo->get<rsx::overlays::display_manager>())
{ {
if (auto dlg = manager->get<rsx::overlays::message_dialog>()) if (auto dlg = manager->get<rsx::overlays::message_dialog>())
{ {
thread_ctrl::spawn("cellMsgDialogClose() Thread", [=] const auto thr = g_fxo->get<msg_dlg_thread>();
{ thr->wait_until = wait_until;
while (get_guest_system_time() < wait_until) thr->wait_until.notify_one();
{
if (Emu.IsStopped())
return;
if (manager->get<rsx::overlays::message_dialog>() != dlg)
return;
std::this_thread::sleep_for(1ms);
}
dlg->close();
});
return CELL_OK; return CELL_OK;
} }
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
} }
const auto dlg = g_fxo->get<msg_info>()->get(); const auto dlg = g_fxo->get<msg_info>()->get();
@ -402,18 +446,9 @@ error_code cellMsgDialogClose(f32 delay)
return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED; return CELL_MSGDIALOG_ERROR_DIALOG_NOT_OPENED;
} }
thread_ctrl::spawn("cellMsgDialogClose() Thread", [=]() const auto thr = g_fxo->get<msg_dlg_thread>();
{ thr->wait_until = wait_until;
while (dlg->state == MsgDialogState::Open && get_guest_system_time() < wait_until) thr->wait_until.notify_one();
{
if (Emu.IsStopped()) return;
std::this_thread::sleep_for(1ms);
}
dlg->on_close(CELL_MSGDIALOG_BUTTON_NONE);
});
return CELL_OK; return CELL_OK;
} }
@ -425,6 +460,7 @@ error_code cellMsgDialogAbort()
{ {
if (auto dlg = manager->get<rsx::overlays::message_dialog>()) if (auto dlg = manager->get<rsx::overlays::message_dialog>())
{ {
g_fxo->get<msg_dlg_thread>()->wait_until = 0;
dlg->close(false); dlg->close(false);
return CELL_OK; return CELL_OK;
} }
@ -442,6 +478,7 @@ error_code cellMsgDialogAbort()
return CELL_SYSUTIL_ERROR_BUSY; return CELL_SYSUTIL_ERROR_BUSY;
} }
g_fxo->get<msg_dlg_thread>()->wait_until = 0;
g_fxo->get<msg_info>()->remove(); // this shouldn't call on_close g_fxo->get<msg_info>()->remove(); // this shouldn't call on_close
pad::SetIntercepted(false); // so we need to reenable the pads here pad::SetIntercepted(false); // so we need to reenable the pads here