mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-04-20 11:36:13 +00:00
Emu: Implement BlockingCallFromMainThread
Reduces some copy-paste clutter throughout the project
This commit is contained in:
parent
7842812e24
commit
9cf7a63c77
13 changed files with 95 additions and 223 deletions
|
@ -1627,19 +1627,11 @@ void camera_context::operator()()
|
|||
else
|
||||
{
|
||||
std::lock_guard lock(mutex);
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&]()
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
send_frame_update_event = handler ? on_handler_state(handler->get_state()) : true;
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1704,9 +1696,8 @@ void camera_context::operator()()
|
|||
bool camera_context::open_camera()
|
||||
{
|
||||
bool result = true;
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, &result, this]()
|
||||
Emu.BlockingCallFromMainThread([&result, this]()
|
||||
{
|
||||
handler.reset();
|
||||
handler = Emu.GetCallbacks().get_camera_handler();
|
||||
|
@ -1715,15 +1706,8 @@ bool camera_context::open_camera()
|
|||
handler->open_camera();
|
||||
result = on_handler_state(handler->get_state());
|
||||
}
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1738,20 +1722,11 @@ bool camera_context::start_camera()
|
|||
handler->set_resolution(info.width, info.height);
|
||||
handler->set_format(info.format, info.bytesize);
|
||||
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, &result, this]()
|
||||
Emu.BlockingCallFromMainThread([&result, this]()
|
||||
{
|
||||
handler->start_camera();
|
||||
result = on_handler_state(handler->get_state());
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1763,19 +1738,10 @@ bool camera_context::get_camera_frame(u8* dst, u32& width, u32& height, u64& fra
|
|||
|
||||
if (handler)
|
||||
{
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&]()
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
result = on_handler_state(handler->get_image(dst, info.bytesize, width, height, frame_number, bytes_read));
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -1785,19 +1751,10 @@ void camera_context::stop_camera()
|
|||
{
|
||||
if (handler)
|
||||
{
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
handler->stop_camera();
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1805,19 +1762,10 @@ void camera_context::close_camera()
|
|||
{
|
||||
if (handler)
|
||||
{
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
handler->close_camera();
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -214,8 +214,6 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
|
|||
}
|
||||
}
|
||||
|
||||
atomic_t<bool> result = false;
|
||||
|
||||
osk->on_osk_close = [wptr = std::weak_ptr<OskDialogBase>(osk)](s32 status)
|
||||
{
|
||||
cellOskDialog.notice("on_osk_close(status=%d)", status);
|
||||
|
@ -531,26 +529,19 @@ error_code cellOskDialogLoadAsync(u32 container, vm::ptr<CellOskDialogParam> dia
|
|||
|
||||
input::SetIntercepted(osk->pad_input_enabled, osk->keyboard_input_enabled, osk->mouse_input_enabled);
|
||||
|
||||
Emu.CallFromMainThread([=, &result, &info]()
|
||||
Emu.BlockingCallFromMainThread([=, &info]()
|
||||
{
|
||||
osk->Create(get_localized_string(localized_string_id::CELL_OSK_DIALOG_TITLE), message, osk->osk_text, maxLength, prohibitFlgs, allowOskPanelFlg, firstViewPanel, info.base_color.load(), info.dimmer_enabled.load(), false);
|
||||
result = true;
|
||||
result.notify_one();
|
||||
|
||||
if (g_fxo->get<osk_info>().osk_continuous_mode.load() == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
|
||||
{
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED, CELL_OSKDIALOG_DISPLAY_STATUS_SHOW);
|
||||
}
|
||||
});
|
||||
|
||||
if (info.osk_continuous_mode == CELL_OSKDIALOG_CONTINUOUS_MODE_HIDE)
|
||||
{
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_DISPLAY_CHANGED, CELL_OSKDIALOG_DISPLAY_STATUS_SHOW);
|
||||
}
|
||||
|
||||
g_fxo->get<osk_info>().last_dialog_state = CELL_SYSUTIL_OSKDIALOG_LOADED;
|
||||
sysutil_send_system_cmd(CELL_SYSUTIL_OSKDIALOG_LOADED, 0);
|
||||
|
||||
while (!result && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(result, false);
|
||||
}
|
||||
|
||||
return CELL_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -983,23 +983,15 @@ error_code sceNpBasicSendMessageGui(vm::cptr<SceNpBasicMessageDetails> msg, sys_
|
|||
msg_data.data.assign(msg->data.get_ptr(), msg->data.get_ptr() + msg->size);
|
||||
}
|
||||
|
||||
atomic_t<bool> wake_up = false;
|
||||
bool result = false;
|
||||
bool result = false;
|
||||
|
||||
input::SetIntercepted(true);
|
||||
|
||||
Emu.CallFromMainThread([=, &wake_up, &result, msg_data = std::move(msg_data), npids = std::move(npids)]() mutable
|
||||
{
|
||||
auto send_dlg = Emu.GetCallbacks().get_sendmessage_dialog();
|
||||
result = send_dlg->Exec(msg_data, npids);
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
Emu.BlockingCallFromMainThread([=, &result, msg_data = std::move(msg_data), npids = std::move(npids)]() mutable
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
auto send_dlg = Emu.GetCallbacks().get_sendmessage_dialog();
|
||||
result = send_dlg->Exec(msg_data, npids);
|
||||
});
|
||||
|
||||
input::SetIntercepted(false);
|
||||
|
||||
|
@ -1154,26 +1146,18 @@ error_code sceNpBasicRecvMessageCustom(u16 mainType, u32 recvOptions, sys_memory
|
|||
return SCE_NP_BASIC_ERROR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
||||
atomic_t<bool> wake_up = false;
|
||||
bool result = false;
|
||||
bool result = false;
|
||||
|
||||
input::SetIntercepted(true);
|
||||
|
||||
SceNpBasicMessageRecvAction recv_result;
|
||||
u64 chosen_msg_id;
|
||||
SceNpBasicMessageRecvAction recv_result{};
|
||||
u64 chosen_msg_id{};
|
||||
|
||||
Emu.CallFromMainThread([=, &wake_up, &result, &recv_result, &chosen_msg_id]()
|
||||
{
|
||||
auto recv_dlg = Emu.GetCallbacks().get_recvmessage_dialog();
|
||||
result = recv_dlg->Exec(static_cast<SceNpBasicMessageMainType>(mainType), static_cast<SceNpBasicMessageRecvOptions>(recvOptions), recv_result, chosen_msg_id);
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
Emu.BlockingCallFromMainThread([=, &result, &recv_result, &chosen_msg_id]()
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
auto recv_dlg = Emu.GetCallbacks().get_recvmessage_dialog();
|
||||
result = recv_dlg->Exec(static_cast<SceNpBasicMessageMainType>(mainType), static_cast<SceNpBasicMessageRecvOptions>(recvOptions), recv_result, chosen_msg_id);
|
||||
});
|
||||
|
||||
input::SetIntercepted(false);
|
||||
|
||||
|
|
|
@ -130,6 +130,37 @@ void fmt_class_string<cfg_mode>::format(std::string& out, u64 arg)
|
|||
});
|
||||
}
|
||||
|
||||
void Emulator::CallFromMainThread(std::function<void()>&& func, atomic_t<bool>* wake_up, bool track_emu_state, u64 stop_ctr) const
|
||||
{
|
||||
if (!track_emu_state)
|
||||
{
|
||||
m_cb.call_from_main_thread(std::move(func), wake_up);
|
||||
return;
|
||||
}
|
||||
|
||||
std::function<void()> final_func = [this, before = IsStopped(), count = (stop_ctr == umax ? +m_stop_ctr : stop_ctr), func = std::move(func)]
|
||||
{
|
||||
if (count == m_stop_ctr && before == IsStopped())
|
||||
{
|
||||
func();
|
||||
}
|
||||
};
|
||||
|
||||
m_cb.call_from_main_thread(std::move(final_func), wake_up);
|
||||
}
|
||||
|
||||
void Emulator::BlockingCallFromMainThread(std::function<void()>&& func) const
|
||||
{
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
CallFromMainThread(std::move(func), &wake_up);
|
||||
|
||||
while (!wake_up && !IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
|
||||
void Emulator::Init(bool add_only)
|
||||
{
|
||||
jit_runtime::initialize();
|
||||
|
|
|
@ -56,7 +56,7 @@ enum class cfg_mode
|
|||
|
||||
struct EmuCallbacks
|
||||
{
|
||||
std::function<void(std::function<void()>)> call_from_main_thread;
|
||||
std::function<void(std::function<void()>, atomic_t<bool>*)> call_from_main_thread;
|
||||
std::function<void(bool)> on_run; // (start_playtime) continuing or going ingame, so start the clock
|
||||
std::function<void()> on_pause;
|
||||
std::function<void()> on_resume;
|
||||
|
@ -136,23 +136,10 @@ public:
|
|||
}
|
||||
|
||||
// Call from the GUI thread
|
||||
void CallFromMainThread(std::function<void()>&& func, bool track_emu_state = true, u64 stop_ctr = umax) const
|
||||
{
|
||||
if (!track_emu_state)
|
||||
{
|
||||
return m_cb.call_from_main_thread(std::move(func));
|
||||
}
|
||||
void CallFromMainThread(std::function<void()>&& func, atomic_t<bool>* wake_up = nullptr, bool track_emu_state = true, u64 stop_ctr = umax) const;
|
||||
|
||||
std::function<void()> final_func = [this, before = IsStopped(), count = (stop_ctr == umax ? +m_stop_ctr : stop_ctr), func = std::move(func)]
|
||||
{
|
||||
if (count == m_stop_ctr && before == IsStopped())
|
||||
{
|
||||
func();
|
||||
}
|
||||
};
|
||||
|
||||
return m_cb.call_from_main_thread(std::move(final_func));
|
||||
}
|
||||
// Blocking call from the GUI thread
|
||||
void BlockingCallFromMainThread(std::function<void()>&& func) const;
|
||||
|
||||
enum class stop_counter_t : u64{};
|
||||
|
||||
|
@ -163,7 +150,7 @@ public:
|
|||
|
||||
void CallFromMainThread(std::function<void()>&& func, stop_counter_t counter) const
|
||||
{
|
||||
CallFromMainThread(std::move(func), true, static_cast<u64>(counter));
|
||||
CallFromMainThread(std::move(func), nullptr, true, static_cast<u64>(counter));
|
||||
}
|
||||
|
||||
/** Set emulator mode to running unconditionnaly.
|
||||
|
|
|
@ -58,9 +58,9 @@ void headless_application::InitializeCallbacks()
|
|||
|
||||
return false;
|
||||
};
|
||||
callbacks.call_from_main_thread = [this](std::function<void()> func)
|
||||
callbacks.call_from_main_thread = [this](std::function<void()> func, atomic_t<bool>* wake_up)
|
||||
{
|
||||
RequestCallFromMainThread(std::move(func));
|
||||
RequestCallFromMainThread(std::move(func), wake_up);
|
||||
};
|
||||
|
||||
callbacks.init_gs_render = []()
|
||||
|
@ -156,7 +156,13 @@ void headless_application::InitializeCallbacks()
|
|||
/**
|
||||
* Using connects avoids timers being unable to be used in a non-qt thread. So, even if this looks stupid to just call func, it's succinct.
|
||||
*/
|
||||
void headless_application::CallFromMainThread(const std::function<void()>& func)
|
||||
void headless_application::CallFromMainThread(const std::function<void()>& func, atomic_t<bool>* wake_up)
|
||||
{
|
||||
func();
|
||||
|
||||
if (wake_up)
|
||||
{
|
||||
*wake_up = true;
|
||||
wake_up->notify_one();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include <QCoreApplication>
|
||||
|
||||
#include "main_application.h"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
#include <functional>
|
||||
|
||||
|
@ -29,8 +30,8 @@ private:
|
|||
}
|
||||
|
||||
Q_SIGNALS:
|
||||
void RequestCallFromMainThread(std::function<void()> func);
|
||||
void RequestCallFromMainThread(std::function<void()> func, atomic_t<bool>* wake_up);
|
||||
|
||||
private Q_SLOTS:
|
||||
static void CallFromMainThread(const std::function<void()>& func);
|
||||
static void CallFromMainThread(const std::function<void()>& func, atomic_t<bool>* wake_up);
|
||||
};
|
||||
|
|
|
@ -338,9 +338,9 @@ void gui_application::InitializeCallbacks()
|
|||
|
||||
return false;
|
||||
};
|
||||
callbacks.call_from_main_thread = [this](std::function<void()> func)
|
||||
callbacks.call_from_main_thread = [this](std::function<void()> func, atomic_t<bool>* wake_up)
|
||||
{
|
||||
RequestCallFromMainThread(std::move(func));
|
||||
RequestCallFromMainThread(std::move(func), wake_up);
|
||||
};
|
||||
|
||||
callbacks.init_gs_render = []()
|
||||
|
@ -669,7 +669,13 @@ void gui_application::OnEmuSettingsChange()
|
|||
/**
|
||||
* Using connects avoids timers being unable to be used in a non-qt thread. So, even if this looks stupid to just call func, it's succinct.
|
||||
*/
|
||||
void gui_application::CallFromMainThread(const std::function<void()>& func)
|
||||
void gui_application::CallFromMainThread(const std::function<void()>& func, atomic_t<bool>* wake_up)
|
||||
{
|
||||
func();
|
||||
|
||||
if (wake_up)
|
||||
{
|
||||
*wake_up = true;
|
||||
wake_up->notify_one();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "util/types.hpp"
|
||||
#include "util/atomic.hpp"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QElapsedTimer>
|
||||
|
@ -95,8 +96,8 @@ Q_SIGNALS:
|
|||
void OnEnableDiscEject(bool enabled);
|
||||
void OnEnableDiscInsert(bool enabled);
|
||||
|
||||
void RequestCallFromMainThread(const std::function<void()>& func);
|
||||
void RequestCallFromMainThread(std::function<void()> func, atomic_t<bool>* wake_up);
|
||||
|
||||
private Q_SLOTS:
|
||||
static void CallFromMainThread(const std::function<void()>& func);
|
||||
static void CallFromMainThread(const std::function<void()>& func, atomic_t<bool>* wake_up);
|
||||
};
|
||||
|
|
|
@ -1056,7 +1056,7 @@ void main_window::HandlePupInstallation(const QString& file_path, const QString&
|
|||
Emu.CallFromMainThread([this, str = std::move(str)]()
|
||||
{
|
||||
QMessageBox::critical(this, tr("Firmware Installation Failed"), str);
|
||||
}, false);
|
||||
}, nullptr, false);
|
||||
};
|
||||
|
||||
if (file_path.isEmpty())
|
||||
|
|
|
@ -23,23 +23,13 @@ qt_camera_handler::qt_camera_handler() : camera_handler_base()
|
|||
|
||||
qt_camera_handler::~qt_camera_handler()
|
||||
{
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&]()
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
close_camera();
|
||||
m_surface.reset();
|
||||
m_camera.reset();
|
||||
m_error_handler.reset();
|
||||
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up)
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
|
||||
void qt_camera_handler::set_camera(const QCameraInfo& camera_info)
|
||||
|
|
|
@ -20,30 +20,20 @@ qt_music_handler::qt_music_handler()
|
|||
|
||||
qt_music_handler::~qt_music_handler()
|
||||
{
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
music_log.notice("Destroying Qt music handler...");
|
||||
m_media_player->stop();
|
||||
m_media_player.reset();
|
||||
m_error_handler.reset();
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
|
||||
void qt_music_handler::play(const std::string& path)
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, &path, this]()
|
||||
Emu.BlockingCallFromMainThread([&path, this]()
|
||||
{
|
||||
if (m_state == CELL_MUSIC_PB_STATUS_PAUSE)
|
||||
{
|
||||
|
@ -57,141 +47,86 @@ void qt_music_handler::play(const std::string& path)
|
|||
}
|
||||
|
||||
m_media_player->play();
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
|
||||
m_state = CELL_MUSIC_PB_STATUS_PLAY;
|
||||
}
|
||||
|
||||
void qt_music_handler::stop()
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
music_log.notice("Stopping music...");
|
||||
m_media_player->stop();
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
|
||||
m_state = CELL_MUSIC_PB_STATUS_STOP;
|
||||
}
|
||||
|
||||
void qt_music_handler::pause()
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
music_log.notice("Pausing music...");
|
||||
m_media_player->pause();
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
|
||||
m_state = CELL_MUSIC_PB_STATUS_PAUSE;
|
||||
}
|
||||
|
||||
void qt_music_handler::fast_forward()
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
music_log.notice("Fast-forwarding music...");
|
||||
m_media_player->setPlaybackRate(2.0);
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
|
||||
m_state = CELL_MUSIC_PB_STATUS_FASTFORWARD;
|
||||
}
|
||||
|
||||
void qt_music_handler::fast_reverse()
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, this]()
|
||||
Emu.BlockingCallFromMainThread([this]()
|
||||
{
|
||||
music_log.notice("Fast-reversing music...");
|
||||
m_media_player->setPlaybackRate(-2.0);
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
|
||||
m_state = CELL_MUSIC_PB_STATUS_FASTREVERSE;
|
||||
}
|
||||
|
||||
void qt_music_handler::set_volume(f32 volume)
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
atomic_t<bool> wake_up = false;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, &volume, this]()
|
||||
Emu.BlockingCallFromMainThread([&volume, this]()
|
||||
{
|
||||
const int new_volume = std::max<int>(0, std::min<int>(volume * 100, 100));
|
||||
music_log.notice("Setting volume to %d%%", new_volume);
|
||||
m_media_player->setVolume(new_volume);
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
}
|
||||
|
||||
f32 qt_music_handler::get_volume() const
|
||||
{
|
||||
std::lock_guard lock(m_mutex);
|
||||
atomic_t<bool> wake_up = false;
|
||||
f32 volume = 0.0f;
|
||||
|
||||
Emu.CallFromMainThread([&wake_up, &volume, this]()
|
||||
Emu.BlockingCallFromMainThread([&volume, this]()
|
||||
{
|
||||
const int current_volume = std::max(0, std::min(m_media_player->volume(), 100));
|
||||
music_log.notice("Getting volume: %d%%", current_volume);
|
||||
volume = current_volume / 100.0f;
|
||||
wake_up = true;
|
||||
wake_up.notify_one();
|
||||
});
|
||||
|
||||
while (!wake_up && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(wake_up, false);
|
||||
}
|
||||
|
||||
return volume;
|
||||
}
|
||||
|
|
|
@ -40,25 +40,17 @@ s32 save_data_dialog::ShowSaveDataList(std::vector<SaveDataEntry>& save_entries,
|
|||
}
|
||||
|
||||
// Fall back to front-end GUI
|
||||
atomic_t<bool> dlg_result(false);
|
||||
atomic_t<s32> selection = 0;
|
||||
|
||||
input::SetIntercepted(true);
|
||||
|
||||
Emu.CallFromMainThread([&]()
|
||||
Emu.BlockingCallFromMainThread([&]()
|
||||
{
|
||||
save_data_list_dialog sdid(save_entries, focused, op, listSet);
|
||||
sdid.exec();
|
||||
selection = sdid.GetSelection();
|
||||
dlg_result = true;
|
||||
dlg_result.notify_one();
|
||||
});
|
||||
|
||||
while (!dlg_result && !Emu.IsStopped())
|
||||
{
|
||||
thread_ctrl::wait_on(dlg_result, false);
|
||||
}
|
||||
|
||||
input::SetIntercepted(false);
|
||||
|
||||
if (use_end) sysutil_send_system_cmd(CELL_SYSUTIL_DRAWING_END, 0);
|
||||
|
|
Loading…
Add table
Reference in a new issue