aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/service/am/button_poller.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/service/am/button_poller.cpp')
-rw-r--r--src/core/hle/service/am/button_poller.cpp71
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