Merge pull request #8138 from german77/data-no-race
core: hid: Reduce the amount of data races
This commit is contained in:
commit
32e2fb5d33
|
@ -132,7 +132,7 @@ void EmulatedConsole::SetMotionParam(Common::ParamPackage param) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
|
void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
auto& raw_status = console.motion_values.raw_status;
|
auto& raw_status = console.motion_values.raw_status;
|
||||||
auto& emulated = console.motion_values.emulated;
|
auto& emulated = console.motion_values.emulated;
|
||||||
|
|
||||||
|
@ -151,6 +151,7 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
|
||||||
emulated.UpdateOrientation(raw_status.delta_timestamp);
|
emulated.UpdateOrientation(raw_status.delta_timestamp);
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ConsoleTriggerType::Motion);
|
TriggerOnChange(ConsoleTriggerType::Motion);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -166,6 +167,7 @@ void EmulatedConsole::SetMotion(const Common::Input::CallbackStatus& callback) {
|
||||||
// Find what is this value
|
// Find what is this value
|
||||||
motion.verticalization_error = 0.0f;
|
motion.verticalization_error = 0.0f;
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ConsoleTriggerType::Motion);
|
TriggerOnChange(ConsoleTriggerType::Motion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,11 +175,12 @@ void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, st
|
||||||
if (index >= console.touch_values.size()) {
|
if (index >= console.touch_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
|
|
||||||
console.touch_values[index] = TransformToTouch(callback);
|
console.touch_values[index] = TransformToTouch(callback);
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ConsoleTriggerType::Touch);
|
TriggerOnChange(ConsoleTriggerType::Touch);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -189,26 +192,32 @@ void EmulatedConsole::SetTouch(const Common::Input::CallbackStatus& callback, st
|
||||||
.pressed = console.touch_values[index].pressed.value,
|
.pressed = console.touch_values[index].pressed.value,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ConsoleTriggerType::Touch);
|
TriggerOnChange(ConsoleTriggerType::Touch);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleMotionValues EmulatedConsole::GetMotionValues() const {
|
ConsoleMotionValues EmulatedConsole::GetMotionValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return console.motion_values;
|
return console.motion_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
TouchValues EmulatedConsole::GetTouchValues() const {
|
TouchValues EmulatedConsole::GetTouchValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return console.touch_values;
|
return console.touch_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
ConsoleMotion EmulatedConsole::GetMotion() const {
|
ConsoleMotion EmulatedConsole::GetMotion() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return console.motion_state;
|
return console.motion_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
TouchFingerState EmulatedConsole::GetTouch() const {
|
TouchFingerState EmulatedConsole::GetTouch() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return console.touch_state;
|
return console.touch_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
|
void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
|
||||||
|
std::scoped_lock lock{callback_mutex};
|
||||||
for (const auto& poller_pair : callback_list) {
|
for (const auto& poller_pair : callback_list) {
|
||||||
const ConsoleUpdateCallback& poller = poller_pair.second;
|
const ConsoleUpdateCallback& poller = poller_pair.second;
|
||||||
if (poller.on_change) {
|
if (poller.on_change) {
|
||||||
|
@ -218,13 +227,13 @@ void EmulatedConsole::TriggerOnChange(ConsoleTriggerType type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) {
|
int EmulatedConsole::SetCallback(ConsoleUpdateCallback update_callback) {
|
||||||
std::lock_guard lock{mutex};
|
std::scoped_lock lock{callback_mutex};
|
||||||
callback_list.insert_or_assign(last_callback_key, update_callback);
|
callback_list.insert_or_assign(last_callback_key, update_callback);
|
||||||
return last_callback_key++;
|
return last_callback_key++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedConsole::DeleteCallback(int key) {
|
void EmulatedConsole::DeleteCallback(int key) {
|
||||||
std::lock_guard lock{mutex};
|
std::scoped_lock lock{callback_mutex};
|
||||||
const auto& iterator = callback_list.find(key);
|
const auto& iterator = callback_list.find(key);
|
||||||
if (iterator == callback_list.end()) {
|
if (iterator == callback_list.end()) {
|
||||||
LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
|
LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
|
||||||
|
|
|
@ -183,6 +183,7 @@ private:
|
||||||
TouchDevices touch_devices;
|
TouchDevices touch_devices;
|
||||||
|
|
||||||
mutable std::mutex mutex;
|
mutable std::mutex mutex;
|
||||||
|
mutable std::mutex callback_mutex;
|
||||||
std::unordered_map<int, ConsoleUpdateCallback> callback_list;
|
std::unordered_map<int, ConsoleUpdateCallback> callback_list;
|
||||||
int last_callback_key = 0;
|
int last_callback_key = 0;
|
||||||
|
|
||||||
|
|
|
@ -353,14 +353,17 @@ void EmulatedController::DisableConfiguration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::EnableSystemButtons() {
|
void EmulatedController::EnableSystemButtons() {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
system_buttons_enabled = true;
|
system_buttons_enabled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::DisableSystemButtons() {
|
void EmulatedController::DisableSystemButtons() {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
system_buttons_enabled = false;
|
system_buttons_enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::ResetSystemButtons() {
|
void EmulatedController::ResetSystemButtons() {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
controller.home_button_state.home.Assign(false);
|
controller.home_button_state.home.Assign(false);
|
||||||
controller.capture_button_state.capture.Assign(false);
|
controller.capture_button_state.capture.Assign(false);
|
||||||
}
|
}
|
||||||
|
@ -494,139 +497,141 @@ void EmulatedController::SetButton(const Common::Input::CallbackStatus& callback
|
||||||
if (index >= controller.button_values.size()) {
|
if (index >= controller.button_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
{
|
std::unique_lock lock{mutex};
|
||||||
std::lock_guard lock{mutex};
|
bool value_changed = false;
|
||||||
bool value_changed = false;
|
const auto new_status = TransformToButton(callback);
|
||||||
const auto new_status = TransformToButton(callback);
|
auto& current_status = controller.button_values[index];
|
||||||
auto& current_status = controller.button_values[index];
|
|
||||||
|
|
||||||
// Only read button values that have the same uuid or are pressed once
|
// Only read button values that have the same uuid or are pressed once
|
||||||
if (current_status.uuid != uuid) {
|
if (current_status.uuid != uuid) {
|
||||||
if (!new_status.value) {
|
if (!new_status.value) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
current_status.toggle = new_status.toggle;
|
|
||||||
current_status.uuid = uuid;
|
|
||||||
|
|
||||||
// Update button status with current
|
|
||||||
if (!current_status.toggle) {
|
|
||||||
current_status.locked = false;
|
|
||||||
if (current_status.value != new_status.value) {
|
|
||||||
current_status.value = new_status.value;
|
|
||||||
value_changed = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Toggle button and lock status
|
|
||||||
if (new_status.value && !current_status.locked) {
|
|
||||||
current_status.locked = true;
|
|
||||||
current_status.value = !current_status.value;
|
|
||||||
value_changed = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unlock button ready for next press
|
|
||||||
if (!new_status.value && current_status.locked) {
|
|
||||||
current_status.locked = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!value_changed) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_configuring) {
|
|
||||||
controller.npad_button_state.raw = NpadButton::None;
|
|
||||||
controller.debug_pad_button_state.raw = 0;
|
|
||||||
TriggerOnChange(ControllerTriggerType::Button, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (index) {
|
|
||||||
case Settings::NativeButton::A:
|
|
||||||
controller.npad_button_state.a.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.a.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::B:
|
|
||||||
controller.npad_button_state.b.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.b.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::X:
|
|
||||||
controller.npad_button_state.x.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.x.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::Y:
|
|
||||||
controller.npad_button_state.y.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.y.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::LStick:
|
|
||||||
controller.npad_button_state.stick_l.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::RStick:
|
|
||||||
controller.npad_button_state.stick_r.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::L:
|
|
||||||
controller.npad_button_state.l.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.l.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::R:
|
|
||||||
controller.npad_button_state.r.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.r.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::ZL:
|
|
||||||
controller.npad_button_state.zl.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.zl.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::ZR:
|
|
||||||
controller.npad_button_state.zr.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.zr.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::Plus:
|
|
||||||
controller.npad_button_state.plus.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.plus.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::Minus:
|
|
||||||
controller.npad_button_state.minus.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.minus.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::DLeft:
|
|
||||||
controller.npad_button_state.left.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.d_left.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::DUp:
|
|
||||||
controller.npad_button_state.up.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.d_up.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::DRight:
|
|
||||||
controller.npad_button_state.right.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.d_right.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::DDown:
|
|
||||||
controller.npad_button_state.down.Assign(current_status.value);
|
|
||||||
controller.debug_pad_button_state.d_down.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::SL:
|
|
||||||
controller.npad_button_state.left_sl.Assign(current_status.value);
|
|
||||||
controller.npad_button_state.right_sl.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::SR:
|
|
||||||
controller.npad_button_state.left_sr.Assign(current_status.value);
|
|
||||||
controller.npad_button_state.right_sr.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::Home:
|
|
||||||
if (!system_buttons_enabled) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
controller.home_button_state.home.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
case Settings::NativeButton::Screenshot:
|
|
||||||
if (!system_buttons_enabled) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
controller.capture_button_state.capture.Assign(current_status.value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_status.toggle = new_status.toggle;
|
||||||
|
current_status.uuid = uuid;
|
||||||
|
|
||||||
|
// Update button status with current
|
||||||
|
if (!current_status.toggle) {
|
||||||
|
current_status.locked = false;
|
||||||
|
if (current_status.value != new_status.value) {
|
||||||
|
current_status.value = new_status.value;
|
||||||
|
value_changed = true;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Toggle button and lock status
|
||||||
|
if (new_status.value && !current_status.locked) {
|
||||||
|
current_status.locked = true;
|
||||||
|
current_status.value = !current_status.value;
|
||||||
|
value_changed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Unlock button ready for next press
|
||||||
|
if (!new_status.value && current_status.locked) {
|
||||||
|
current_status.locked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!value_changed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_configuring) {
|
||||||
|
controller.npad_button_state.raw = NpadButton::None;
|
||||||
|
controller.debug_pad_button_state.raw = 0;
|
||||||
|
lock.unlock();
|
||||||
|
TriggerOnChange(ControllerTriggerType::Button, false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (index) {
|
||||||
|
case Settings::NativeButton::A:
|
||||||
|
controller.npad_button_state.a.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.a.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::B:
|
||||||
|
controller.npad_button_state.b.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.b.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::X:
|
||||||
|
controller.npad_button_state.x.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.x.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::Y:
|
||||||
|
controller.npad_button_state.y.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.y.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::LStick:
|
||||||
|
controller.npad_button_state.stick_l.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::RStick:
|
||||||
|
controller.npad_button_state.stick_r.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::L:
|
||||||
|
controller.npad_button_state.l.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.l.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::R:
|
||||||
|
controller.npad_button_state.r.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.r.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::ZL:
|
||||||
|
controller.npad_button_state.zl.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.zl.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::ZR:
|
||||||
|
controller.npad_button_state.zr.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.zr.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::Plus:
|
||||||
|
controller.npad_button_state.plus.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.plus.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::Minus:
|
||||||
|
controller.npad_button_state.minus.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.minus.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::DLeft:
|
||||||
|
controller.npad_button_state.left.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.d_left.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::DUp:
|
||||||
|
controller.npad_button_state.up.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.d_up.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::DRight:
|
||||||
|
controller.npad_button_state.right.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.d_right.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::DDown:
|
||||||
|
controller.npad_button_state.down.Assign(current_status.value);
|
||||||
|
controller.debug_pad_button_state.d_down.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::SL:
|
||||||
|
controller.npad_button_state.left_sl.Assign(current_status.value);
|
||||||
|
controller.npad_button_state.right_sl.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::SR:
|
||||||
|
controller.npad_button_state.left_sr.Assign(current_status.value);
|
||||||
|
controller.npad_button_state.right_sr.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::Home:
|
||||||
|
if (!system_buttons_enabled) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
controller.home_button_state.home.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
case Settings::NativeButton::Screenshot:
|
||||||
|
if (!system_buttons_enabled) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
controller.capture_button_state.capture.Assign(current_status.value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
|
|
||||||
if (!is_connected) {
|
if (!is_connected) {
|
||||||
if (npad_id_type == NpadIdType::Player1 && npad_type != NpadStyleIndex::Handheld) {
|
if (npad_id_type == NpadIdType::Player1 && npad_type != NpadStyleIndex::Handheld) {
|
||||||
Connect();
|
Connect();
|
||||||
|
@ -643,7 +648,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
|
||||||
if (index >= controller.stick_values.size()) {
|
if (index >= controller.stick_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
const auto stick_value = TransformToStick(callback);
|
const auto stick_value = TransformToStick(callback);
|
||||||
|
|
||||||
// Only read stick values that have the same uuid or are over the threshold to avoid flapping
|
// Only read stick values that have the same uuid or are over the threshold to avoid flapping
|
||||||
|
@ -659,6 +664,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
controller.analog_stick_state.left = {};
|
controller.analog_stick_state.left = {};
|
||||||
controller.analog_stick_state.right = {};
|
controller.analog_stick_state.right = {};
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Stick, false);
|
TriggerOnChange(ControllerTriggerType::Stick, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -685,6 +691,7 @@ void EmulatedController::SetStick(const Common::Input::CallbackStatus& callback,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Stick, true);
|
TriggerOnChange(ControllerTriggerType::Stick, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -693,7 +700,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
|
||||||
if (index >= controller.trigger_values.size()) {
|
if (index >= controller.trigger_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
const auto trigger_value = TransformToTrigger(callback);
|
const auto trigger_value = TransformToTrigger(callback);
|
||||||
|
|
||||||
// Only read trigger values that have the same uuid or are pressed once
|
// Only read trigger values that have the same uuid or are pressed once
|
||||||
|
@ -709,6 +716,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
controller.gc_trigger_state.left = 0;
|
controller.gc_trigger_state.left = 0;
|
||||||
controller.gc_trigger_state.right = 0;
|
controller.gc_trigger_state.right = 0;
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Trigger, false);
|
TriggerOnChange(ControllerTriggerType::Trigger, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -727,6 +735,7 @@ void EmulatedController::SetTrigger(const Common::Input::CallbackStatus& callbac
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Trigger, true);
|
TriggerOnChange(ControllerTriggerType::Trigger, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -735,7 +744,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
|
||||||
if (index >= controller.motion_values.size()) {
|
if (index >= controller.motion_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
auto& raw_status = controller.motion_values[index].raw_status;
|
auto& raw_status = controller.motion_values[index].raw_status;
|
||||||
auto& emulated = controller.motion_values[index].emulated;
|
auto& emulated = controller.motion_values[index].emulated;
|
||||||
|
|
||||||
|
@ -756,6 +765,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
|
||||||
force_update_motion = raw_status.force_update;
|
force_update_motion = raw_status.force_update;
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Motion, false);
|
TriggerOnChange(ControllerTriggerType::Motion, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -767,6 +777,7 @@ void EmulatedController::SetMotion(const Common::Input::CallbackStatus& callback
|
||||||
motion.orientation = emulated.GetOrientation();
|
motion.orientation = emulated.GetOrientation();
|
||||||
motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
|
motion.is_at_rest = !emulated.IsMoving(motion_sensitivity);
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Motion, true);
|
TriggerOnChange(ControllerTriggerType::Motion, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -775,10 +786,11 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
|
||||||
if (index >= controller.battery_values.size()) {
|
if (index >= controller.battery_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
controller.battery_values[index] = TransformToBattery(callback);
|
controller.battery_values[index] = TransformToBattery(callback);
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Battery, false);
|
TriggerOnChange(ControllerTriggerType::Battery, false);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -835,6 +847,8 @@ void EmulatedController::SetBattery(const Common::Input::CallbackStatus& callbac
|
||||||
};
|
};
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Battery, true);
|
TriggerOnChange(ControllerTriggerType::Battery, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -932,6 +946,7 @@ void EmulatedController::SetSupportedNpadStyleTag(NpadStyleTag supported_styles)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const {
|
bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
|
const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NpadStyleIndex::ProController:
|
case NpadStyleIndex::ProController:
|
||||||
|
@ -947,6 +962,7 @@ bool EmulatedController::IsControllerFullkey(bool use_temporary_value) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::IsControllerSupported(bool use_temporary_value) const {
|
bool EmulatedController::IsControllerSupported(bool use_temporary_value) const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
|
const auto type = is_configuring && use_temporary_value ? tmp_npad_type : npad_type;
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case NpadStyleIndex::ProController:
|
case NpadStyleIndex::ProController:
|
||||||
|
@ -982,40 +998,44 @@ void EmulatedController::Connect(bool use_temporary_value) {
|
||||||
LOG_ERROR(Service_HID, "Controller type {} is not supported", type);
|
LOG_ERROR(Service_HID, "Controller type {} is not supported", type);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
{
|
|
||||||
std::lock_guard lock{mutex};
|
|
||||||
if (is_configuring) {
|
|
||||||
tmp_is_connected = true;
|
|
||||||
TriggerOnChange(ControllerTriggerType::Connected, false);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_connected) {
|
std::unique_lock lock{mutex};
|
||||||
return;
|
if (is_configuring) {
|
||||||
}
|
tmp_is_connected = true;
|
||||||
is_connected = true;
|
lock.unlock();
|
||||||
|
TriggerOnChange(ControllerTriggerType::Connected, false);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_connected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is_connected = true;
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Connected, true);
|
TriggerOnChange(ControllerTriggerType::Connected, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::Disconnect() {
|
void EmulatedController::Disconnect() {
|
||||||
{
|
std::unique_lock lock{mutex};
|
||||||
std::lock_guard lock{mutex};
|
if (is_configuring) {
|
||||||
if (is_configuring) {
|
tmp_is_connected = false;
|
||||||
tmp_is_connected = false;
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Disconnected, false);
|
TriggerOnChange(ControllerTriggerType::Disconnected, false);
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_connected) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
is_connected = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!is_connected) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
is_connected = false;
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Disconnected, true);
|
TriggerOnChange(ControllerTriggerType::Disconnected, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmulatedController::IsConnected(bool get_temporary_value) const {
|
bool EmulatedController::IsConnected(bool get_temporary_value) const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
if (get_temporary_value && is_configuring) {
|
if (get_temporary_value && is_configuring) {
|
||||||
return tmp_is_connected;
|
return tmp_is_connected;
|
||||||
}
|
}
|
||||||
|
@ -1029,10 +1049,12 @@ bool EmulatedController::IsVibrationEnabled() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
NpadIdType EmulatedController::GetNpadIdType() const {
|
NpadIdType EmulatedController::GetNpadIdType() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return npad_id_type;
|
return npad_id_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) const {
|
NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
if (get_temporary_value && is_configuring) {
|
if (get_temporary_value && is_configuring) {
|
||||||
return tmp_npad_type;
|
return tmp_npad_type;
|
||||||
}
|
}
|
||||||
|
@ -1040,27 +1062,28 @@ NpadStyleIndex EmulatedController::GetNpadStyleIndex(bool get_temporary_value) c
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
|
void EmulatedController::SetNpadStyleIndex(NpadStyleIndex npad_type_) {
|
||||||
{
|
std::unique_lock lock{mutex};
|
||||||
std::lock_guard lock{mutex};
|
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
if (tmp_npad_type == npad_type_) {
|
if (tmp_npad_type == npad_type_) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
tmp_npad_type = npad_type_;
|
|
||||||
TriggerOnChange(ControllerTriggerType::Type, false);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
tmp_npad_type = npad_type_;
|
||||||
if (npad_type == npad_type_) {
|
lock.unlock();
|
||||||
return;
|
TriggerOnChange(ControllerTriggerType::Type, false);
|
||||||
}
|
return;
|
||||||
if (is_connected) {
|
|
||||||
LOG_WARNING(Service_HID, "Controller {} type changed while it's connected",
|
|
||||||
NpadIdTypeToIndex(npad_id_type));
|
|
||||||
}
|
|
||||||
npad_type = npad_type_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (npad_type == npad_type_) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (is_connected) {
|
||||||
|
LOG_WARNING(Service_HID, "Controller {} type changed while it's connected",
|
||||||
|
NpadIdTypeToIndex(npad_id_type));
|
||||||
|
}
|
||||||
|
npad_type = npad_type_;
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(ControllerTriggerType::Type, true);
|
TriggerOnChange(ControllerTriggerType::Type, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1088,30 +1111,37 @@ LedPattern EmulatedController::GetLedPattern() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
ButtonValues EmulatedController::GetButtonsValues() const {
|
ButtonValues EmulatedController::GetButtonsValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return controller.button_values;
|
return controller.button_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
SticksValues EmulatedController::GetSticksValues() const {
|
SticksValues EmulatedController::GetSticksValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return controller.stick_values;
|
return controller.stick_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
TriggerValues EmulatedController::GetTriggersValues() const {
|
TriggerValues EmulatedController::GetTriggersValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return controller.trigger_values;
|
return controller.trigger_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerMotionValues EmulatedController::GetMotionValues() const {
|
ControllerMotionValues EmulatedController::GetMotionValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return controller.motion_values;
|
return controller.motion_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
ColorValues EmulatedController::GetColorsValues() const {
|
ColorValues EmulatedController::GetColorsValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return controller.color_values;
|
return controller.color_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
BatteryValues EmulatedController::GetBatteryValues() const {
|
BatteryValues EmulatedController::GetBatteryValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return controller.battery_values;
|
return controller.battery_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
HomeButtonState EmulatedController::GetHomeButtons() const {
|
HomeButtonState EmulatedController::GetHomeButtons() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1119,6 +1149,7 @@ HomeButtonState EmulatedController::GetHomeButtons() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
CaptureButtonState EmulatedController::GetCaptureButtons() const {
|
CaptureButtonState EmulatedController::GetCaptureButtons() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1126,6 +1157,7 @@ CaptureButtonState EmulatedController::GetCaptureButtons() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
NpadButtonState EmulatedController::GetNpadButtons() const {
|
NpadButtonState EmulatedController::GetNpadButtons() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1133,6 +1165,7 @@ NpadButtonState EmulatedController::GetNpadButtons() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
DebugPadButton EmulatedController::GetDebugPadButtons() const {
|
DebugPadButton EmulatedController::GetDebugPadButtons() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1140,20 +1173,27 @@ DebugPadButton EmulatedController::GetDebugPadButtons() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalogSticks EmulatedController::GetSticks() const {
|
AnalogSticks EmulatedController::GetSticks() const {
|
||||||
|
std::unique_lock lock{mutex};
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Some drivers like stick from buttons need constant refreshing
|
// Some drivers like stick from buttons need constant refreshing
|
||||||
for (auto& device : stick_devices) {
|
for (auto& device : stick_devices) {
|
||||||
if (!device) {
|
if (!device) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
lock.unlock();
|
||||||
device->SoftUpdate();
|
device->SoftUpdate();
|
||||||
|
lock.lock();
|
||||||
}
|
}
|
||||||
|
|
||||||
return controller.analog_stick_state;
|
return controller.analog_stick_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
NpadGcTriggerState EmulatedController::GetTriggers() const {
|
NpadGcTriggerState EmulatedController::GetTriggers() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -1161,26 +1201,35 @@ NpadGcTriggerState EmulatedController::GetTriggers() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
MotionState EmulatedController::GetMotions() const {
|
MotionState EmulatedController::GetMotions() const {
|
||||||
|
std::unique_lock lock{mutex};
|
||||||
|
|
||||||
|
// Some drivers like mouse motion need constant refreshing
|
||||||
if (force_update_motion) {
|
if (force_update_motion) {
|
||||||
for (auto& device : motion_devices) {
|
for (auto& device : motion_devices) {
|
||||||
if (!device) {
|
if (!device) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
lock.unlock();
|
||||||
device->ForceUpdate();
|
device->ForceUpdate();
|
||||||
|
lock.lock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return controller.motion_state;
|
return controller.motion_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerColors EmulatedController::GetColors() const {
|
ControllerColors EmulatedController::GetColors() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return controller.colors_state;
|
return controller.colors_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
BatteryLevelState EmulatedController::GetBattery() const {
|
BatteryLevelState EmulatedController::GetBattery() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return controller.battery_state;
|
return controller.battery_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) {
|
void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npad_service_update) {
|
||||||
|
std::scoped_lock lock{callback_mutex};
|
||||||
for (const auto& poller_pair : callback_list) {
|
for (const auto& poller_pair : callback_list) {
|
||||||
const ControllerUpdateCallback& poller = poller_pair.second;
|
const ControllerUpdateCallback& poller = poller_pair.second;
|
||||||
if (!is_npad_service_update && poller.is_npad_service) {
|
if (!is_npad_service_update && poller.is_npad_service) {
|
||||||
|
@ -1193,13 +1242,13 @@ void EmulatedController::TriggerOnChange(ControllerTriggerType type, bool is_npa
|
||||||
}
|
}
|
||||||
|
|
||||||
int EmulatedController::SetCallback(ControllerUpdateCallback update_callback) {
|
int EmulatedController::SetCallback(ControllerUpdateCallback update_callback) {
|
||||||
std::lock_guard lock{mutex};
|
std::scoped_lock lock{callback_mutex};
|
||||||
callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
|
callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
|
||||||
return last_callback_key++;
|
return last_callback_key++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedController::DeleteCallback(int key) {
|
void EmulatedController::DeleteCallback(int key) {
|
||||||
std::lock_guard lock{mutex};
|
std::scoped_lock lock{callback_mutex};
|
||||||
const auto& iterator = callback_list.find(key);
|
const auto& iterator = callback_list.find(key);
|
||||||
if (iterator == callback_list.end()) {
|
if (iterator == callback_list.end()) {
|
||||||
LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
|
LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
|
||||||
|
|
|
@ -400,7 +400,7 @@ private:
|
||||||
*/
|
*/
|
||||||
void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
|
void TriggerOnChange(ControllerTriggerType type, bool is_service_update);
|
||||||
|
|
||||||
NpadIdType npad_id_type;
|
const NpadIdType npad_id_type;
|
||||||
NpadStyleIndex npad_type{NpadStyleIndex::None};
|
NpadStyleIndex npad_type{NpadStyleIndex::None};
|
||||||
NpadStyleTag supported_style_tag{NpadStyleSet::All};
|
NpadStyleTag supported_style_tag{NpadStyleSet::All};
|
||||||
bool is_connected{false};
|
bool is_connected{false};
|
||||||
|
@ -434,6 +434,7 @@ private:
|
||||||
StickDevices tas_stick_devices;
|
StickDevices tas_stick_devices;
|
||||||
|
|
||||||
mutable std::mutex mutex;
|
mutable std::mutex mutex;
|
||||||
|
mutable std::mutex callback_mutex;
|
||||||
std::unordered_map<int, ControllerUpdateCallback> callback_list;
|
std::unordered_map<int, ControllerUpdateCallback> callback_list;
|
||||||
int last_callback_key = 0;
|
int last_callback_key = 0;
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& cal
|
||||||
if (index >= device_status.keyboard_values.size()) {
|
if (index >= device_status.keyboard_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
bool value_changed = false;
|
bool value_changed = false;
|
||||||
const auto new_status = TransformToButton(callback);
|
const auto new_status = TransformToButton(callback);
|
||||||
auto& current_status = device_status.keyboard_values[index];
|
auto& current_status = device_status.keyboard_values[index];
|
||||||
|
@ -201,6 +201,7 @@ void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& cal
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::Keyboard);
|
TriggerOnChange(DeviceTriggerType::Keyboard);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -208,6 +209,7 @@ void EmulatedDevices::SetKeyboardButton(const Common::Input::CallbackStatus& cal
|
||||||
// Index should be converted from NativeKeyboard to KeyboardKeyIndex
|
// Index should be converted from NativeKeyboard to KeyboardKeyIndex
|
||||||
UpdateKey(index, current_status.value);
|
UpdateKey(index, current_status.value);
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::Keyboard);
|
TriggerOnChange(DeviceTriggerType::Keyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,7 +229,7 @@ void EmulatedDevices::SetKeyboardModifier(const Common::Input::CallbackStatus& c
|
||||||
if (index >= device_status.keyboard_moddifier_values.size()) {
|
if (index >= device_status.keyboard_moddifier_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
bool value_changed = false;
|
bool value_changed = false;
|
||||||
const auto new_status = TransformToButton(callback);
|
const auto new_status = TransformToButton(callback);
|
||||||
auto& current_status = device_status.keyboard_moddifier_values[index];
|
auto& current_status = device_status.keyboard_moddifier_values[index];
|
||||||
|
@ -259,6 +261,7 @@ void EmulatedDevices::SetKeyboardModifier(const Common::Input::CallbackStatus& c
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::KeyboardModdifier);
|
TriggerOnChange(DeviceTriggerType::KeyboardModdifier);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -289,6 +292,7 @@ void EmulatedDevices::SetKeyboardModifier(const Common::Input::CallbackStatus& c
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::KeyboardModdifier);
|
TriggerOnChange(DeviceTriggerType::KeyboardModdifier);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -297,7 +301,7 @@ void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callba
|
||||||
if (index >= device_status.mouse_button_values.size()) {
|
if (index >= device_status.mouse_button_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
bool value_changed = false;
|
bool value_changed = false;
|
||||||
const auto new_status = TransformToButton(callback);
|
const auto new_status = TransformToButton(callback);
|
||||||
auto& current_status = device_status.mouse_button_values[index];
|
auto& current_status = device_status.mouse_button_values[index];
|
||||||
|
@ -329,6 +333,7 @@ void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callba
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -351,6 +356,7 @@ void EmulatedDevices::SetMouseButton(const Common::Input::CallbackStatus& callba
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -359,13 +365,14 @@ void EmulatedDevices::SetMouseAnalog(const Common::Input::CallbackStatus& callba
|
||||||
if (index >= device_status.mouse_analog_values.size()) {
|
if (index >= device_status.mouse_analog_values.size()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
const auto analog_value = TransformToAnalog(callback);
|
const auto analog_value = TransformToAnalog(callback);
|
||||||
|
|
||||||
device_status.mouse_analog_values[index] = analog_value;
|
device_status.mouse_analog_values[index] = analog_value;
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
device_status.mouse_position_state = {};
|
device_status.mouse_position_state = {};
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -379,17 +386,19 @@ void EmulatedDevices::SetMouseAnalog(const Common::Input::CallbackStatus& callba
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callback) {
|
void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callback) {
|
||||||
std::lock_guard lock{mutex};
|
std::unique_lock lock{mutex};
|
||||||
const auto touch_value = TransformToTouch(callback);
|
const auto touch_value = TransformToTouch(callback);
|
||||||
|
|
||||||
device_status.mouse_stick_value = touch_value;
|
device_status.mouse_stick_value = touch_value;
|
||||||
|
|
||||||
if (is_configuring) {
|
if (is_configuring) {
|
||||||
device_status.mouse_position_state = {};
|
device_status.mouse_position_state = {};
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -397,42 +406,52 @@ void EmulatedDevices::SetMouseStick(const Common::Input::CallbackStatus& callbac
|
||||||
device_status.mouse_position_state.x = touch_value.x.value;
|
device_status.mouse_position_state.x = touch_value.x.value;
|
||||||
device_status.mouse_position_state.y = touch_value.y.value;
|
device_status.mouse_position_state.y = touch_value.y.value;
|
||||||
|
|
||||||
|
lock.unlock();
|
||||||
TriggerOnChange(DeviceTriggerType::Mouse);
|
TriggerOnChange(DeviceTriggerType::Mouse);
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardValues EmulatedDevices::GetKeyboardValues() const {
|
KeyboardValues EmulatedDevices::GetKeyboardValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return device_status.keyboard_values;
|
return device_status.keyboard_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardModifierValues EmulatedDevices::GetKeyboardModdifierValues() const {
|
KeyboardModifierValues EmulatedDevices::GetKeyboardModdifierValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return device_status.keyboard_moddifier_values;
|
return device_status.keyboard_moddifier_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseButtonValues EmulatedDevices::GetMouseButtonsValues() const {
|
MouseButtonValues EmulatedDevices::GetMouseButtonsValues() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return device_status.mouse_button_values;
|
return device_status.mouse_button_values;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardKey EmulatedDevices::GetKeyboard() const {
|
KeyboardKey EmulatedDevices::GetKeyboard() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return device_status.keyboard_state;
|
return device_status.keyboard_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
KeyboardModifier EmulatedDevices::GetKeyboardModifier() const {
|
KeyboardModifier EmulatedDevices::GetKeyboardModifier() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return device_status.keyboard_moddifier_state;
|
return device_status.keyboard_moddifier_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseButton EmulatedDevices::GetMouseButtons() const {
|
MouseButton EmulatedDevices::GetMouseButtons() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return device_status.mouse_button_state;
|
return device_status.mouse_button_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
MousePosition EmulatedDevices::GetMousePosition() const {
|
MousePosition EmulatedDevices::GetMousePosition() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return device_status.mouse_position_state;
|
return device_status.mouse_position_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
AnalogStickState EmulatedDevices::GetMouseWheel() const {
|
AnalogStickState EmulatedDevices::GetMouseWheel() const {
|
||||||
|
std::scoped_lock lock{mutex};
|
||||||
return device_status.mouse_wheel_state;
|
return device_status.mouse_wheel_state;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
|
void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
|
||||||
|
std::scoped_lock lock{callback_mutex};
|
||||||
for (const auto& poller_pair : callback_list) {
|
for (const auto& poller_pair : callback_list) {
|
||||||
const InterfaceUpdateCallback& poller = poller_pair.second;
|
const InterfaceUpdateCallback& poller = poller_pair.second;
|
||||||
if (poller.on_change) {
|
if (poller.on_change) {
|
||||||
|
@ -442,13 +461,13 @@ void EmulatedDevices::TriggerOnChange(DeviceTriggerType type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int EmulatedDevices::SetCallback(InterfaceUpdateCallback update_callback) {
|
int EmulatedDevices::SetCallback(InterfaceUpdateCallback update_callback) {
|
||||||
std::lock_guard lock{mutex};
|
std::scoped_lock lock{callback_mutex};
|
||||||
callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
|
callback_list.insert_or_assign(last_callback_key, std::move(update_callback));
|
||||||
return last_callback_key++;
|
return last_callback_key++;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmulatedDevices::DeleteCallback(int key) {
|
void EmulatedDevices::DeleteCallback(int key) {
|
||||||
std::lock_guard lock{mutex};
|
std::scoped_lock lock{callback_mutex};
|
||||||
const auto& iterator = callback_list.find(key);
|
const auto& iterator = callback_list.find(key);
|
||||||
if (iterator == callback_list.end()) {
|
if (iterator == callback_list.end()) {
|
||||||
LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
|
LOG_ERROR(Input, "Tried to delete non-existent callback {}", key);
|
||||||
|
|
|
@ -200,6 +200,7 @@ private:
|
||||||
MouseStickDevice mouse_stick_device;
|
MouseStickDevice mouse_stick_device;
|
||||||
|
|
||||||
mutable std::mutex mutex;
|
mutable std::mutex mutex;
|
||||||
|
mutable std::mutex callback_mutex;
|
||||||
std::unordered_map<int, InterfaceUpdateCallback> callback_list;
|
std::unordered_map<int, InterfaceUpdateCallback> callback_list;
|
||||||
int last_callback_key = 0;
|
int last_callback_key = 0;
|
||||||
|
|
||||||
|
|
Reference in New Issue