From 1ec60c5613fac308e63323afb35c0e06c5b5976a Mon Sep 17 00:00:00 2001 From: lizzie Date: Sat, 6 Sep 2025 08:01:34 +0000 Subject: [PATCH] [qt] use std::jthread instead of playing around with std::thread Signed-off-by: lizzie --- .../calibration_configuration_job.cpp | 15 ++-- src/yuzu/applets/qt_software_keyboard.cpp | 71 ++++++++---------- src/yuzu/applets/qt_software_keyboard.h | 10 +-- src/yuzu/applets/qt_web_browser.cpp | 72 ++++++++----------- src/yuzu/applets/qt_web_browser.h | 21 ++---- src/yuzu/util/overlay_dialog.cpp | 38 ++++------ src/yuzu/util/overlay_dialog.h | 11 +-- 7 files changed, 89 insertions(+), 149 deletions(-) diff --git a/src/tests/input_common/calibration_configuration_job.cpp b/src/tests/input_common/calibration_configuration_job.cpp index 8f5466253c..02ffa880aa 100644 --- a/src/tests/input_common/calibration_configuration_job.cpp +++ b/src/tests/input_common/calibration_configuration_job.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -18,13 +21,9 @@ public: : socket(io_context, boost::asio::ip::udp::endpoint(boost::asio::ip::udp::v4(), 0)) {} ~FakeCemuhookServer() { - is_running = false; boost::system::error_code error_code; socket.shutdown(boost::asio::socket_base::shutdown_both, error_code); socket.close(); - if (handler.joinable()) { - handler.join(); - } } u16 GetPort() { @@ -41,10 +40,9 @@ public: sizeof(InputCommon::CemuhookUDP::Message); REQUIRE(touch_movement_path.size() > 0); - is_running = true; - handler = std::thread([touch_movement_path, this]() { + handler = std::jthread([touch_movement_path, this](std::stop_token stoken) { auto current_touch_position = touch_movement_path.begin(); - while (is_running) { + while (!stoken.stop_requested()) { boost::asio::ip::udp::endpoint sender_endpoint; boost::system::error_code error_code; auto received_size = socket.receive_from(boost::asio::buffer(receive_buffer), @@ -87,8 +85,7 @@ private: boost::asio::ip::udp::socket socket; std::array send_buffer; std::array receive_buffer; - bool is_running = false; - std::thread handler; + std::jthread handler; }; TEST_CASE("CalibrationConfigurationJob completed", "[input_common]") { diff --git a/src/yuzu/applets/qt_software_keyboard.cpp b/src/yuzu/applets/qt_software_keyboard.cpp index 2749e6ed31..ddaf1fb9ba 100644 --- a/src/yuzu/applets/qt_software_keyboard.cpp +++ b/src/yuzu/applets/qt_software_keyboard.cpp @@ -1,3 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -1492,53 +1494,36 @@ void QtSoftwareKeyboardDialog::MoveTextCursorDirection(Direction direction) { } void QtSoftwareKeyboardDialog::StartInputThread() { - if (input_thread_running) { - return; - } - - input_thread_running = true; - - input_thread = std::thread(&QtSoftwareKeyboardDialog::InputThread, this); + input_thread = std::jthread([&](std::stop_token stoken) { + while (!stoken.stop_requested()) { + input_interpreter->PollInput(); + HandleButtonPressedOnce< + Core::HID::NpadButton::A, Core::HID::NpadButton::B, Core::HID::NpadButton::X, + Core::HID::NpadButton::Y, Core::HID::NpadButton::StickL, Core::HID::NpadButton::StickR, + Core::HID::NpadButton::L, Core::HID::NpadButton::R, Core::HID::NpadButton::Plus, + Core::HID::NpadButton::Left, Core::HID::NpadButton::Up, Core::HID::NpadButton::Right, + Core::HID::NpadButton::Down, Core::HID::NpadButton::StickLLeft, + Core::HID::NpadButton::StickLUp, Core::HID::NpadButton::StickLRight, + Core::HID::NpadButton::StickLDown, Core::HID::NpadButton::StickRLeft, + Core::HID::NpadButton::StickRUp, Core::HID::NpadButton::StickRRight, + Core::HID::NpadButton::StickRDown>(); + HandleButtonHold(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + }); } void QtSoftwareKeyboardDialog::StopInputThread() { - input_thread_running = false; - - if (input_thread.joinable()) { - input_thread.join(); - } - - if (input_interpreter) { + input_thread.request_stop(); + if (input_interpreter) input_interpreter->ResetButtonStates(); - } -} - -void QtSoftwareKeyboardDialog::InputThread() { - while (input_thread_running) { - input_interpreter->PollInput(); - - HandleButtonPressedOnce< - Core::HID::NpadButton::A, Core::HID::NpadButton::B, Core::HID::NpadButton::X, - Core::HID::NpadButton::Y, Core::HID::NpadButton::StickL, Core::HID::NpadButton::StickR, - Core::HID::NpadButton::L, Core::HID::NpadButton::R, Core::HID::NpadButton::Plus, - Core::HID::NpadButton::Left, Core::HID::NpadButton::Up, Core::HID::NpadButton::Right, - Core::HID::NpadButton::Down, Core::HID::NpadButton::StickLLeft, - Core::HID::NpadButton::StickLUp, Core::HID::NpadButton::StickLRight, - Core::HID::NpadButton::StickLDown, Core::HID::NpadButton::StickRLeft, - Core::HID::NpadButton::StickRUp, Core::HID::NpadButton::StickRRight, - Core::HID::NpadButton::StickRDown>(); - - HandleButtonHold(); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } } QtSoftwareKeyboard::QtSoftwareKeyboard(GMainWindow& main_window) { diff --git a/src/yuzu/applets/qt_software_keyboard.h b/src/yuzu/applets/qt_software_keyboard.h index 7e2fdf09ea..217d305ffc 100644 --- a/src/yuzu/applets/qt_software_keyboard.h +++ b/src/yuzu/applets/qt_software_keyboard.h @@ -1,3 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -182,9 +184,6 @@ private: void StartInputThread(); void StopInputThread(); - /// The thread where input is being polled and processed. - void InputThread(); - std::unique_ptr ui; Core::System& system; @@ -220,10 +219,7 @@ private: std::atomic caps_lock_enabled{false}; std::unique_ptr input_interpreter; - - std::thread input_thread; - - std::atomic input_thread_running{}; + std::jthread input_thread; }; class QtSoftwareKeyboard final : public QObject, public Core::Frontend::SoftwareKeyboardApplet { diff --git a/src/yuzu/applets/qt_web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp index a287ea16df..3a01b0bc17 100644 --- a/src/yuzu/applets/qt_web_browser.cpp +++ b/src/yuzu/applets/qt_web_browser.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -282,54 +285,41 @@ void QtNXWebEngineView::SendKeyPressEvent(int key) { } void QtNXWebEngineView::StartInputThread() { - if (input_thread_running) { - return; - } + input_thread = std::jthread([&](std::stop_token stoken) { + // Wait for 1 second before allowing any inputs to be processed. + std::this_thread::sleep_for(std::chrono::seconds(1)); + if (is_local) { + QWidget::grabKeyboard(); + } + while (!stoken.stop_requested()) { + input_interpreter->PollInput(); - input_thread_running = true; - input_thread = std::thread(&QtNXWebEngineView::InputThread, this); + HandleWindowFooterButtonPressedOnce(); + + HandleWindowKeyButtonPressedOnce< + Core::HID::NpadButton::Left, Core::HID::NpadButton::Up, Core::HID::NpadButton::Right, + Core::HID::NpadButton::Down, Core::HID::NpadButton::StickLLeft, + Core::HID::NpadButton::StickLUp, Core::HID::NpadButton::StickLRight, + Core::HID::NpadButton::StickLDown>(); + + HandleWindowKeyButtonHold< + Core::HID::NpadButton::Left, Core::HID::NpadButton::Up, Core::HID::NpadButton::Right, + Core::HID::NpadButton::Down, Core::HID::NpadButton::StickLLeft, + Core::HID::NpadButton::StickLUp, Core::HID::NpadButton::StickLRight, + Core::HID::NpadButton::StickLDown>(); + + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + }); } void QtNXWebEngineView::StopInputThread() { if (is_local) { QWidget::releaseKeyboard(); } - - input_thread_running = false; - if (input_thread.joinable()) { - input_thread.join(); - } -} - -void QtNXWebEngineView::InputThread() { - // Wait for 1 second before allowing any inputs to be processed. - std::this_thread::sleep_for(std::chrono::seconds(1)); - - if (is_local) { - QWidget::grabKeyboard(); - } - - while (input_thread_running) { - input_interpreter->PollInput(); - - HandleWindowFooterButtonPressedOnce(); - - HandleWindowKeyButtonPressedOnce< - Core::HID::NpadButton::Left, Core::HID::NpadButton::Up, Core::HID::NpadButton::Right, - Core::HID::NpadButton::Down, Core::HID::NpadButton::StickLLeft, - Core::HID::NpadButton::StickLUp, Core::HID::NpadButton::StickLRight, - Core::HID::NpadButton::StickLDown>(); - - HandleWindowKeyButtonHold< - Core::HID::NpadButton::Left, Core::HID::NpadButton::Up, Core::HID::NpadButton::Right, - Core::HID::NpadButton::Down, Core::HID::NpadButton::StickLLeft, - Core::HID::NpadButton::StickLUp, Core::HID::NpadButton::StickLRight, - Core::HID::NpadButton::StickLDown>(); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } + input_thread.request_stop(); } void QtNXWebEngineView::LoadExtractedFonts() { diff --git a/src/yuzu/applets/qt_web_browser.h b/src/yuzu/applets/qt_web_browser.h index e8a0b6931b..773726f1ac 100644 --- a/src/yuzu/applets/qt_web_browser.h +++ b/src/yuzu/applets/qt_web_browser.h @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -155,9 +158,6 @@ private: void StartInputThread(); void StopInputThread(); - /// The thread where input is being polled and processed. - void InputThread(); - /// Loads the extracted fonts using JavaScript. void LoadExtractedFonts(); @@ -165,24 +165,13 @@ private: void FocusFirstLinkElement(); InputCommon::InputSubsystem* input_subsystem; - std::unique_ptr url_interceptor; - std::unique_ptr input_interpreter; - - std::thread input_thread; - - std::atomic input_thread_running{}; - + std::jthread input_thread; std::atomic finished{}; - - Service::AM::Frontend::WebExitReason exit_reason{ - Service::AM::Frontend::WebExitReason::EndButtonPressed}; - + Service::AM::Frontend::WebExitReason exit_reason{Service::AM::Frontend::WebExitReason::EndButtonPressed}; std::string last_url{"http://localhost/"}; - bool is_local{}; - QWebEngineProfile* default_profile; QWebEngineSettings* global_settings; }; diff --git a/src/yuzu/util/overlay_dialog.cpp b/src/yuzu/util/overlay_dialog.cpp index 466bbe7b25..01b894f744 100644 --- a/src/yuzu/util/overlay_dialog.cpp +++ b/src/yuzu/util/overlay_dialog.cpp @@ -1,3 +1,5 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -231,34 +233,20 @@ void OverlayDialog::TranslateButtonPress(Core::HID::NpadButton button) { } void OverlayDialog::StartInputThread() { - if (input_thread_running) { - return; - } - - input_thread_running = true; - - input_thread = std::thread(&OverlayDialog::InputThread, this); + input_thread = std::jthread([&](std::stop_token stoken) { + while (!stoken.stop_requested()) { + input_interpreter->PollInput(); + HandleButtonPressedOnce(); + std::this_thread::sleep_for(std::chrono::milliseconds(50)); + } + }); } void OverlayDialog::StopInputThread() { - input_thread_running = false; - - if (input_thread.joinable()) { - input_thread.join(); - } -} - -void OverlayDialog::InputThread() { - while (input_thread_running) { - input_interpreter->PollInput(); - - HandleButtonPressedOnce(); - - std::this_thread::sleep_for(std::chrono::milliseconds(50)); - } + input_thread.request_stop(); } void OverlayDialog::keyPressEvent(QKeyEvent* e) { diff --git a/src/yuzu/util/overlay_dialog.h b/src/yuzu/util/overlay_dialog.h index 62f9da311d..36c9b52339 100644 --- a/src/yuzu/util/overlay_dialog.h +++ b/src/yuzu/util/overlay_dialog.h @@ -1,9 +1,10 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#include #include #include @@ -91,9 +92,6 @@ private: void StartInputThread(); void StopInputThread(); - - /// The thread where input is being polled and processed. - void InputThread(); void keyPressEvent(QKeyEvent* e) override; std::unique_ptr ui; @@ -101,8 +99,5 @@ private: bool use_rich_text; std::unique_ptr input_interpreter; - - std::thread input_thread; - - std::atomic input_thread_running{}; + std::jthread input_thread; };