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.
This commit is contained in:
Megamouse 2022-10-21 22:55:31 +02:00
parent 6c0bc43776
commit 871ef2cdfe
9 changed files with 73 additions and 67 deletions

View File

@ -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<std::string>& /*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<std::string>& /*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<AnalogSensor, 4>& /*sensors*/)

View File

@ -57,6 +57,14 @@ using motion_fail_callback = std::function<void(std::string /*pad_name*/, motion
class PadHandlerBase
{
public:
enum connection
{
no_data,
connected,
disconnected
};
protected:
enum button
{
@ -92,13 +100,6 @@ protected:
button_count
};
enum connection
{
no_data,
connected,
disconnected
};
static constexpr u32 MAX_GAMEPADS = 7;
std::array<bool, MAX_GAMEPADS> 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> 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<std::string>& 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<std::string>& 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<AnalogSensor, 4>& sensors);
virtual std::unordered_map<u32, std::string> get_motion_axis_list() const { return {}; }

View File

@ -292,7 +292,7 @@ std::shared_ptr<evdev_joystick_handler::EvdevDevice> 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<std::string>& 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<std::string>& 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<AnalogSensor, 4>& sensors)

View File

@ -381,7 +381,7 @@ public:
bool Init() override;
std::vector<pad_list_entry> list_devices() override;
bool bindPadToDevice(std::shared_ptr<Pad> 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<std::string>& 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<std::string>& 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<AnalogSensor, 4>& sensors) override;
std::unordered_map<u32, std::string> 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;

View File

@ -84,7 +84,7 @@ public:
void init_config(cfg_pad* cfg) override;
std::vector<pad_list_entry> 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<std::string>& /*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<std::string>& /*buttons*/ = {}) override { return connection::connected; }
bool bindPadToDevice(std::shared_ptr<Pad> pad, u8 player_id) override;
void process() override;

View File

@ -173,7 +173,7 @@ std::array<u32, PadHandlerBase::button::button_count> 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<std::string>& 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<std::string>& 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<u64, u16> mm_joystick_handler::GetButtonValues(const JOYINFOEX& js_info, const JOYCAPS& js_caps)

View File

@ -113,7 +113,7 @@ public:
bool Init() override;
std::vector<pad_list_entry> 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<std::string>& 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<std::string>& buttons = {}) override;
void init_config(cfg_pad* cfg) override;
private:

View File

@ -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:

View File

@ -8,6 +8,7 @@
#include <mutex>
#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;