diff options
Diffstat (limited to 'src/core/hle/service/am/button_poller.cpp')
| -rw-r--r-- | src/core/hle/service/am/button_poller.cpp | 71 |
1 files changed, 34 insertions, 37 deletions
diff --git a/src/core/hle/service/am/button_poller.cpp b/src/core/hle/service/am/button_poller.cpp index 069a1934d4..6999acfa12 100644 --- a/src/core/hle/service/am/button_poller.cpp +++ b/src/core/hle/service/am/button_poller.cpp @@ -1,9 +1,11 @@ -// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-License-Identifier: GPL-3.0-or-later // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include <thread> +#include "common/thread.h" #include "core/core.h" #include "core/hle/service/am/am_types.h" #include "core/hle/service/am/button_poller.h" @@ -34,16 +36,15 @@ ButtonPressDuration ClassifyPressDuration(std::chrono::steady_clock::time_point } // namespace -ButtonPoller::ButtonPoller(Core::System& system, WindowSystem& window_system) - : m_window_system(window_system) { +ButtonPoller::ButtonPoller(Core::System& system, WindowSystem& window_system) { // TODO: am reads this from the home button state in hid, which is controller-agnostic. Core::HID::ControllerUpdateCallback engine_callback{ - .on_change = - [this](Core::HID::ControllerTriggerType type) { - if (type == Core::HID::ControllerTriggerType::Button) { - this->OnButtonStateChanged(); - } - }, + .on_change = [this, &window_system](Core::HID::ControllerTriggerType type) { + if (type == Core::HID::ControllerTriggerType::Button) { + std::unique_lock lk{m_mutex}; + OnButtonStateChanged(window_system); + } + }, .is_npad_service = true, }; @@ -52,25 +53,35 @@ ButtonPoller::ButtonPoller(Core::System& system, WindowSystem& window_system) m_player1 = system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1); m_player1_key = m_player1->SetCallback(engine_callback); - m_thread = std::thread([this] { this->ThreadLoop(); }); + m_thread = std::jthread([this, &window_system](std::stop_token stop_token) { + Common::SetCurrentThreadName("ButtonPoller"); + while (!stop_token.stop_requested()) { + using namespace std::chrono_literals; + std::unique_lock lk{m_mutex}; + m_cv.wait_for(lk, 50ms); + if (stop_token.stop_requested()) + break; + OnButtonStateChanged(window_system); + std::this_thread::sleep_for(5ms); + } + }); } ButtonPoller::~ButtonPoller() { m_handheld->DeleteCallback(m_handheld_key); m_player1->DeleteCallback(m_player1_key); - m_stop = true; m_cv.notify_all(); if (m_thread.joinable()) { + m_thread.request_stop(); m_thread.join(); } } -void ButtonPoller::OnButtonStateChanged() { - std::lock_guard lk{m_mutex}; - const bool home_button = - m_handheld->GetHomeButtons().home.Value() || m_player1->GetHomeButtons().home.Value(); - const bool capture_button = m_handheld->GetCaptureButtons().capture.Value() || - m_player1->GetCaptureButtons().capture.Value(); +void ButtonPoller::OnButtonStateChanged(WindowSystem& window_system) { + auto const home_button = m_handheld->GetHomeButtons().home.Value() + || m_player1->GetHomeButtons().home.Value(); + auto const capture_button = m_handheld->GetCaptureButtons().capture.Value() + || m_player1->GetCaptureButtons().capture.Value(); // Buttons pressed which were not previously pressed if (home_button && !m_home_button_press_start) { @@ -90,7 +101,7 @@ void ButtonPoller::OnButtonStateChanged() { if (home_button && m_home_button_press_start && !m_home_button_long_sent) { const auto duration = ClassifyPressDuration(*m_home_button_press_start); if (duration != ButtonPressDuration::ShortPressing) { - m_window_system.OnSystemButtonPress(SystemButtonType::HomeButtonLongPressing); + window_system.OnSystemButtonPress(SystemButtonType::HomeButtonLongPressing); m_home_button_long_sent = true; } } @@ -98,7 +109,7 @@ void ButtonPoller::OnButtonStateChanged() { if (capture_button && m_capture_button_press_start && !m_capture_button_long_sent) { const auto duration = ClassifyPressDuration(*m_capture_button_press_start); if (duration != ButtonPressDuration::ShortPressing) { - m_window_system.OnSystemButtonPress(SystemButtonType::CaptureButtonLongPressing); + window_system.OnSystemButtonPress(SystemButtonType::CaptureButtonLongPressing); m_capture_button_long_sent = true; } } @@ -107,9 +118,8 @@ void ButtonPoller::OnButtonStateChanged() { if (!home_button && m_home_button_press_start) { if(!m_home_button_long_sent) { const auto duration = ClassifyPressDuration(*m_home_button_press_start); - m_window_system.OnSystemButtonPress( - duration == ButtonPressDuration::ShortPressing ? SystemButtonType::HomeButtonShortPressing - : SystemButtonType::HomeButtonLongPressing); + window_system.OnSystemButtonPress(duration == ButtonPressDuration::ShortPressing + ? SystemButtonType::HomeButtonShortPressing : SystemButtonType::HomeButtonLongPressing); } m_home_button_press_start = std::nullopt; m_home_button_long_sent = false; @@ -117,9 +127,8 @@ void ButtonPoller::OnButtonStateChanged() { if (!capture_button && m_capture_button_press_start) { if (!m_capture_button_long_sent) { const auto duration = ClassifyPressDuration(*m_capture_button_press_start); - m_window_system.OnSystemButtonPress( - duration == ButtonPressDuration::ShortPressing ? SystemButtonType::CaptureButtonShortPressing - : SystemButtonType::CaptureButtonLongPressing); + window_system.OnSystemButtonPress(duration == ButtonPressDuration::ShortPressing + ? SystemButtonType::CaptureButtonShortPressing : SystemButtonType::CaptureButtonLongPressing); } m_capture_button_press_start = std::nullopt; m_capture_button_long_sent = false; @@ -130,16 +139,4 @@ void ButtonPoller::OnButtonStateChanged() { // } } -void ButtonPoller::ThreadLoop() { - using namespace std::chrono_literals; - std::unique_lock lk{m_mutex}; - while (!m_stop) { - m_cv.wait_for(lk, 50ms); - if (m_stop) break; - lk.unlock(); - OnButtonStateChanged(); - lk.lock(); - } -} - } // namespace Service::AM |
