From 871ef2cdfeb9b74a85f44f4acd9af31a116e9a4a Mon Sep 17 00:00:00 2001 From: Megamouse Date: Fri, 21 Oct 2022 22:55:31 +0200 Subject: [PATCH] Input: return pad connection in get_next_button_press This fix some minor race condition in the UI that had no real consequences just by chance. --- rpcs3/Emu/Io/PadHandler.cpp | 20 +++++++------ rpcs3/Emu/Io/PadHandler.h | 17 +++++------ rpcs3/Input/evdev_joystick_handler.cpp | 14 +++++---- rpcs3/Input/evdev_joystick_handler.h | 2 +- rpcs3/Input/keyboard_pad_handler.h | 2 +- rpcs3/Input/mm_joystick_handler.cpp | 40 ++++++++++++++------------ rpcs3/Input/mm_joystick_handler.h | 2 +- rpcs3/rpcs3qt/pad_settings_dialog.cpp | 40 ++++++++++++-------------- rpcs3/rpcs3qt/pad_settings_dialog.h | 3 +- 9 files changed, 73 insertions(+), 67 deletions(-) diff --git a/rpcs3/Emu/Io/PadHandler.cpp b/rpcs3/Emu/Io/PadHandler.cpp index 0d7ab2cf71..9b1b1ff2c5 100644 --- a/rpcs3/Emu/Io/PadHandler.cpp +++ b/rpcs3/Emu/Io/PadHandler.cpp @@ -323,7 +323,7 @@ void PadHandlerBase::init_configs() } } -void PadHandlerBase::get_next_button_press(const std::string& pad_id, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector& /*buttons*/) +PadHandlerBase::connection PadHandlerBase::get_next_button_press(const std::string& pad_id, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector& /*buttons*/) { if (get_blacklist) blacklist.clear(); @@ -335,12 +335,12 @@ void PadHandlerBase::get_next_button_press(const std::string& pad_id, const pad_ { if (fail_callback) fail_callback(pad_id); - return; + return status; } if (status == connection::no_data) { - return; + return status; } // Get the current button values @@ -384,19 +384,21 @@ void PadHandlerBase::get_next_button_press(const std::string& pad_id, const pad_ { if (blacklist.empty()) input_log.success("%s Calibration: Blacklist is clear. No input spam detected", m_type); - return; + return status; } - const pad_preview_values preview_values = get_preview_values(data); - const u32 battery_level = get_battery_level(pad_id); - if (callback) { + const pad_preview_values preview_values = get_preview_values(data); + const u32 battery_level = get_battery_level(pad_id); + if (pressed_button.value > 0) - return callback(pressed_button.value, pressed_button.name, pad_id, battery_level, preview_values); + callback(pressed_button.value, pressed_button.name, pad_id, battery_level, preview_values); else - return callback(0, "", pad_id, battery_level, preview_values); + callback(0, "", pad_id, battery_level, preview_values); } + + return status; } void PadHandlerBase::get_motion_sensors(const std::string& pad_id, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array& /*sensors*/) diff --git a/rpcs3/Emu/Io/PadHandler.h b/rpcs3/Emu/Io/PadHandler.h index 1816b63b08..ec72cb971d 100644 --- a/rpcs3/Emu/Io/PadHandler.h +++ b/rpcs3/Emu/Io/PadHandler.h @@ -57,6 +57,14 @@ using motion_fail_callback = std::function last_connection_status{{ false, false, false, false, false, false, false }}; @@ -207,7 +208,7 @@ public: // Binds a Pad to a device virtual bool bindPadToDevice(std::shared_ptr pad, u8 player_id); virtual void init_config(cfg_pad* cfg) = 0; - virtual void get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector& buttons = {}); + virtual connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector& buttons = {}); virtual void get_motion_sensors(const std::string& pad_id, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array& sensors); virtual std::unordered_map get_motion_axis_list() const { return {}; } diff --git a/rpcs3/Input/evdev_joystick_handler.cpp b/rpcs3/Input/evdev_joystick_handler.cpp index 0ad5e35da5..e465377fc2 100644 --- a/rpcs3/Input/evdev_joystick_handler.cpp +++ b/rpcs3/Input/evdev_joystick_handler.cpp @@ -292,7 +292,7 @@ std::shared_ptr evdev_joystick_handler::get return evdev_device; } -void evdev_joystick_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector& buttons) +PadHandlerBase::connection evdev_joystick_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector& buttons) { if (get_blacklist) m_blacklist.clear(); @@ -303,7 +303,7 @@ void evdev_joystick_handler::get_next_button_press(const std::string& padId, con { if (fail_callback) fail_callback(padId); - return; + return connection::disconnected; } libevdev* dev = device->device; @@ -357,7 +357,7 @@ void evdev_joystick_handler::get_next_button_press(const std::string& padId, con { if (callback) callback(0, "", padId, 0, preview_values); - return; + return connection::no_data; } struct @@ -448,16 +448,18 @@ void evdev_joystick_handler::get_next_button_press(const std::string& padId, con { if (m_blacklist.empty()) evdev_log.success("Evdev Calibration: Blacklist is clear. No input spam detected"); - return; + return connection::connected; } if (callback) { if (pressed_button.value > 0) - return callback(pressed_button.value, pressed_button.name, padId, 0, preview_values); + callback(pressed_button.value, pressed_button.name, padId, 0, preview_values); else - return callback(0, "", padId, 0, preview_values); + callback(0, "", padId, 0, preview_values); } + + return connection::connected; } void evdev_joystick_handler::get_motion_sensors(const std::string& padId, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array& sensors) diff --git a/rpcs3/Input/evdev_joystick_handler.h b/rpcs3/Input/evdev_joystick_handler.h index 822920822f..3e690538be 100644 --- a/rpcs3/Input/evdev_joystick_handler.h +++ b/rpcs3/Input/evdev_joystick_handler.h @@ -381,7 +381,7 @@ public: bool Init() override; std::vector list_devices() override; bool bindPadToDevice(std::shared_ptr pad, u8 player_id) override; - void get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist = false, const std::vector& buttons = {}) override; + connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist = false, const std::vector& buttons = {}) override; void get_motion_sensors(const std::string& padId, const motion_callback& callback, const motion_fail_callback& fail_callback, motion_preview_values preview_values, const std::array& sensors) override; std::unordered_map get_motion_axis_list() const override; void SetPadData(const std::string& padId, u8 player_id, u8 large_motor, u8 small_motor, s32 r, s32 g, s32 b, bool player_led, bool battery_led, u32 battery_led_brightness) override; diff --git a/rpcs3/Input/keyboard_pad_handler.h b/rpcs3/Input/keyboard_pad_handler.h index eb2530b7e8..e8dbd0814a 100644 --- a/rpcs3/Input/keyboard_pad_handler.h +++ b/rpcs3/Input/keyboard_pad_handler.h @@ -84,7 +84,7 @@ public: void init_config(cfg_pad* cfg) override; std::vector list_devices() override; - void get_next_button_press(const std::string& /*padId*/, const pad_callback& /*callback*/, const pad_fail_callback& /*fail_callback*/, bool /*get_blacklist*/ = false, const std::vector& /*buttons*/ = {}) override {} + connection get_next_button_press(const std::string& /*padId*/, const pad_callback& /*callback*/, const pad_fail_callback& /*fail_callback*/, bool /*get_blacklist*/ = false, const std::vector& /*buttons*/ = {}) override { return connection::connected; } bool bindPadToDevice(std::shared_ptr pad, u8 player_id) override; void process() override; diff --git a/rpcs3/Input/mm_joystick_handler.cpp b/rpcs3/Input/mm_joystick_handler.cpp index 88078f44e5..924eb1b21c 100644 --- a/rpcs3/Input/mm_joystick_handler.cpp +++ b/rpcs3/Input/mm_joystick_handler.cpp @@ -173,7 +173,7 @@ std::array mm_joystick_handler::get_m return mapping; } -void mm_joystick_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector& buttons) +PadHandlerBase::connection mm_joystick_handler::get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist, const std::vector& buttons) { if (get_blacklist) m_blacklist.clear(); @@ -182,7 +182,7 @@ void mm_joystick_handler::get_next_button_press(const std::string& padId, const { if (fail_callback) fail_callback(padId); - return; + return connection::disconnected; } static std::string cur_pad; @@ -197,7 +197,7 @@ void mm_joystick_handler::get_next_button_press(const std::string& padId, const input_log.error("MMJOY get_next_button_press for device [%s] failed with id = %d", padId, id); if (fail_callback) fail_callback(padId); - return; + return connection::disconnected; } } @@ -215,7 +215,7 @@ void mm_joystick_handler::get_next_button_press(const std::string& padId, const { if (fail_callback) fail_callback(padId); - return; + return connection::disconnected; } case JOYERR_NOERROR: { @@ -304,33 +304,35 @@ void mm_joystick_handler::get_next_button_press(const std::string& padId, const { if (m_blacklist.empty()) input_log.success("MMJOY Calibration: Blacklist is clear. No input spam detected"); - return; - } - - pad_preview_values preview_values{}; - if (buttons.size() == 10) - { - preview_values[0] = data[find_key(buttons[0])]; - preview_values[1] = data[find_key(buttons[1])]; - preview_values[2] = data[find_key(buttons[3])] - data[find_key(buttons[2])]; - preview_values[3] = data[find_key(buttons[5])] - data[find_key(buttons[4])]; - preview_values[4] = data[find_key(buttons[7])] - data[find_key(buttons[6])]; - preview_values[5] = data[find_key(buttons[9])] - data[find_key(buttons[8])]; + return connection::connected; } if (callback) { + pad_preview_values preview_values{}; + if (buttons.size() == 10) + { + preview_values[0] = data[find_key(buttons[0])]; + preview_values[1] = data[find_key(buttons[1])]; + preview_values[2] = data[find_key(buttons[3])] - data[find_key(buttons[2])]; + preview_values[3] = data[find_key(buttons[5])] - data[find_key(buttons[4])]; + preview_values[4] = data[find_key(buttons[7])] - data[find_key(buttons[6])]; + preview_values[5] = data[find_key(buttons[9])] - data[find_key(buttons[8])]; + } + if (pressed_button.value > 0) - return callback(pressed_button.value, pressed_button.name, padId, 0, preview_values); + callback(pressed_button.value, pressed_button.name, padId, 0, preview_values); else - return callback(0, "", padId, 0, preview_values); + callback(0, "", padId, 0, preview_values); } - break; + return connection::connected; } default: break; } + + return connection::no_data; } std::unordered_map mm_joystick_handler::GetButtonValues(const JOYINFOEX& js_info, const JOYCAPS& js_caps) diff --git a/rpcs3/Input/mm_joystick_handler.h b/rpcs3/Input/mm_joystick_handler.h index 803f45e79b..3b597da223 100644 --- a/rpcs3/Input/mm_joystick_handler.h +++ b/rpcs3/Input/mm_joystick_handler.h @@ -113,7 +113,7 @@ public: bool Init() override; std::vector list_devices() override; - void get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist = false, const std::vector& buttons = {}) override; + connection get_next_button_press(const std::string& padId, const pad_callback& callback, const pad_fail_callback& fail_callback, bool get_blacklist = false, const std::vector& buttons = {}) override; void init_config(cfg_pad* cfg) override; private: diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.cpp b/rpcs3/rpcs3qt/pad_settings_dialog.cpp index 72a064b7dd..e404ec4a40 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.cpp +++ b/rpcs3/rpcs3qt/pad_settings_dialog.cpp @@ -410,7 +410,7 @@ void pad_settings_dialog::InitButtons() }); // Enable Button Remapping - const auto callback = [this](u16 val, std::string name, std::string pad_name, u32 battery_level, pad_preview_values preview_values) + const auto callback = [this](PadHandlerBase::connection status, u16 val, std::string name, std::string pad_name, u32 battery_level, pad_preview_values preview_values) { SwitchPadInfo(pad_name, true); @@ -440,7 +440,7 @@ void pad_settings_dialog::InitButtons() ui->pb_battery->setValue(m_enable_battery ? battery_level : 0); - if (val <= 0) + if (val <= 0 || status == PadHandlerBase::connection::no_data) { return; } @@ -499,13 +499,13 @@ void pad_settings_dialog::InitButtons() if (data.has_new_data) { - if (data.success) + if (data.status == PadHandlerBase::disconnected) { - callback(data.val, std::move(data.name), std::move(data.pad_name), data.battery_level, std::move(data.preview_values)); + fail_callback(data.pad_name); } else { - fail_callback(data.pad_name); + callback(data.status, data.val, std::move(data.name), std::move(data.pad_name), data.battery_level, std::move(data.preview_values)); } } }); @@ -542,7 +542,7 @@ void pad_settings_dialog::InitButtons() m_cfg_entries[button_ids::id_pad_rstick_up].key }; - m_handler->get_next_button_press(m_device_name, + const PadHandlerBase::connection status = m_handler->get_next_button_press(m_device_name, [this](u16 val, std::string name, std::string pad_name, u32 battery_level, pad_preview_values preview_values) { std::lock_guard lock(m_input_mutex); @@ -552,16 +552,24 @@ void pad_settings_dialog::InitButtons() m_input_callback_data.battery_level = battery_level; m_input_callback_data.preview_values = std::move(preview_values); m_input_callback_data.has_new_data = true; - m_input_callback_data.success = true; + m_input_callback_data.status = PadHandlerBase::connection::connected; }, [this](std::string pad_name) { std::lock_guard lock(m_input_mutex); m_input_callback_data.pad_name = std::move(pad_name); m_input_callback_data.has_new_data = true; - m_input_callback_data.success = false; + m_input_callback_data.status = PadHandlerBase::connection::disconnected; }, false, buttons); + + if (status == PadHandlerBase::connection::no_data) + { + std::lock_guard lock(m_input_mutex); + m_input_callback_data.pad_name = m_device_name; + m_input_callback_data.has_new_data = true; + m_input_callback_data.status = status; + } } }); } @@ -578,18 +586,8 @@ void pad_settings_dialog::RefreshPads() } std::lock_guard lock(m_handler_mutex); - - m_handler->get_next_button_press(info.name, - [&](u16, std::string, std::string pad_name, u32, pad_preview_values) - { - info.name = std::move(pad_name); - switch_pad_info(i, info, true); - }, - [&](std::string pad_name) - { - info.name = std::move(pad_name); - switch_pad_info(i, info, false); - }, false); + const PadHandlerBase::connection status = m_handler->get_next_button_press(info.name, nullptr, nullptr, false); + switch_pad_info(i, info, status != PadHandlerBase::connection::disconnected); } } @@ -1220,7 +1218,7 @@ void pad_settings_dialog::OnPadButtonClicked(int id) case button_ids::id_blacklist: { std::lock_guard lock(m_handler_mutex); - m_handler->get_next_button_press(m_device_name, nullptr, nullptr, true); + [[maybe_unused]] const PadHandlerBase::connection status = m_handler->get_next_button_press(m_device_name, nullptr, nullptr, true); return; } default: diff --git a/rpcs3/rpcs3qt/pad_settings_dialog.h b/rpcs3/rpcs3qt/pad_settings_dialog.h index fdd41bb099..49ca0f8cc3 100644 --- a/rpcs3/rpcs3qt/pad_settings_dialog.h +++ b/rpcs3/rpcs3qt/pad_settings_dialog.h @@ -8,6 +8,7 @@ #include +#include "Emu/Io/PadHandler.h" #include "Emu/Io/pad_config.h" #include "Emu/GameInfo.h" #include "Utilities/Thread.h" @@ -161,7 +162,7 @@ private: std::mutex m_input_mutex; struct input_callback_data { - bool success = false; + PadHandlerBase::connection status = PadHandlerBase::disconnected; bool has_new_data = false; u16 val = 0; std::string name;