mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-26 15:45:42 +00:00
Factorize input hooks into reusable monitor classes
Those monitors will need some context so this will be useful in the nearby future.
This commit is contained in:
parent
3f9ba4acb6
commit
99ec667b20
|
@ -55,6 +55,8 @@ set(SRCS
|
|||
inputbindingdialog.cpp
|
||||
inputbindingdialog.h
|
||||
inputbindingdialog.ui
|
||||
inputbindingmonitor.cpp
|
||||
inputbindingmonitor.h
|
||||
inputbindingwidgets.cpp
|
||||
inputbindingwidgets.h
|
||||
main.cpp
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
<ClCompile Include="displaysettingswidget.cpp" />
|
||||
<ClCompile Include="hotkeysettingswidget.cpp" />
|
||||
<ClCompile Include="inputbindingdialog.cpp" />
|
||||
<ClCompile Include="inputbindingmonitor.cpp" />
|
||||
<ClCompile Include="inputbindingwidgets.cpp" />
|
||||
<ClCompile Include="qtdisplaywidget.cpp" />
|
||||
<ClCompile Include="gamelistsettingswidget.cpp" />
|
||||
|
@ -105,6 +106,7 @@
|
|||
<QtMoc Include="gamelistmodel.h" />
|
||||
<QtMoc Include="gamelistsearchdirectoriesmodel.h" />
|
||||
<QtMoc Include="autoupdaterdialog.h" />
|
||||
<ClInclude Include="inputbindingmonitor.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="settingwidgetbinder.h" />
|
||||
<QtMoc Include="consolesettingswidget.h" />
|
||||
|
|
|
@ -60,11 +60,13 @@
|
|||
<ClCompile Include="$(IntDir)moc_postprocessingchainconfigwidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_postprocessingshaderconfigwidget.cpp" />
|
||||
<ClCompile Include="$(IntDir)moc_postprocessingsettingswidget.cpp" />
|
||||
<ClCompile Include="inputbindingmonitor.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="qtutils.h" />
|
||||
<ClInclude Include="settingwidgetbinder.h" />
|
||||
<ClInclude Include="resource.h" />
|
||||
<ClInclude Include="inputbindingmonitor.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="resources">
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#include "common/string_util.h"
|
||||
#include "core/settings.h"
|
||||
#include "frontend-common/controller_interface.h"
|
||||
#include "inputbindingmonitor.h"
|
||||
#include "qthostinterface.h"
|
||||
#include "qtutils.h"
|
||||
#include <QtCore/QTimer>
|
||||
|
@ -210,27 +211,7 @@ void InputButtonBindingDialog::hookControllerInput()
|
|||
if (!controller_interface)
|
||||
return;
|
||||
|
||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
||||
if (ei.type == ControllerInterface::Hook::Type::Axis)
|
||||
{
|
||||
// wait until it's at least half pushed so we don't get confused between axises with small movement
|
||||
if (std::abs(ei.value) < 0.5f)
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
|
||||
// TODO: this probably should consider the "last value"
|
||||
QMetaObject::invokeMethod(this, "bindToControllerAxis", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number), Q_ARG(std::optional<bool>, ei.value > 0));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
else if (ei.type == ControllerInterface::Hook::Type::Button && ei.value > 0.0f)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "bindToControllerButton", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
});
|
||||
controller_interface->SetHook(InputButtonBindingMonitor(this));
|
||||
}
|
||||
|
||||
void InputButtonBindingDialog::unhookControllerInput()
|
||||
|
@ -274,27 +255,7 @@ void InputAxisBindingDialog::hookControllerInput()
|
|||
if (!controller_interface)
|
||||
return;
|
||||
|
||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
||||
if (ei.type == ControllerInterface::Hook::Type::Axis)
|
||||
{
|
||||
// wait until it's at least half pushed so we don't get confused between axises with small movement
|
||||
if (std::abs(ei.value) < 0.5f)
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
|
||||
QMetaObject::invokeMethod(this, "bindToControllerAxis", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number), Q_ARG(std::optional<bool>, std::nullopt));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
else if (ei.type == ControllerInterface::Hook::Type::Button && m_axis_type == Controller::AxisType::Half &&
|
||||
ei.value > 0.0f)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "bindToControllerButton", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
});
|
||||
controller_interface->SetHook(InputAxisBindingMonitor(this, m_axis_type));
|
||||
}
|
||||
|
||||
void InputAxisBindingDialog::unhookControllerInput()
|
||||
|
|
60
src/duckstation-qt/inputbindingmonitor.cpp
Normal file
60
src/duckstation-qt/inputbindingmonitor.cpp
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "inputbindingmonitor.h"
|
||||
|
||||
ControllerInterface::Hook::CallbackResult
|
||||
InputButtonBindingMonitor::operator()(const ControllerInterface::Hook& ei) const
|
||||
{
|
||||
if (ei.type == ControllerInterface::Hook::Type::Axis)
|
||||
{
|
||||
// wait until it's at least half pushed so we don't get confused between axises with small movement
|
||||
if (std::abs(ei.value) < 0.5f)
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
|
||||
// TODO: this probably should consider the "last value"
|
||||
QMetaObject::invokeMethod(m_parent, "bindToControllerAxis", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number), Q_ARG(std::optional<bool>, ei.value > 0));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
else if (ei.type == ControllerInterface::Hook::Type::Button && ei.value > 0.0f)
|
||||
{
|
||||
QMetaObject::invokeMethod(m_parent, "bindToControllerButton", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
}
|
||||
|
||||
ControllerInterface::Hook::CallbackResult InputAxisBindingMonitor::operator()(const ControllerInterface::Hook& ei) const
|
||||
{
|
||||
if (ei.type == ControllerInterface::Hook::Type::Axis)
|
||||
{
|
||||
// wait until it's at least half pushed so we don't get confused between axises with small movement
|
||||
if (std::abs(ei.value) < 0.5f)
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
|
||||
QMetaObject::invokeMethod(m_parent, "bindToControllerAxis", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number), Q_ARG(std::optional<bool>, std::nullopt));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
else if (ei.type == ControllerInterface::Hook::Type::Button && m_axis_type == Controller::AxisType::Half &&
|
||||
ei.value > 0.0f)
|
||||
{
|
||||
QMetaObject::invokeMethod(m_parent, "bindToControllerButton", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
}
|
||||
|
||||
ControllerInterface::Hook::CallbackResult
|
||||
InputRumbleBindingMonitor::operator()(const ControllerInterface::Hook& ei) const
|
||||
{
|
||||
if (ei.type == ControllerInterface::Hook::Type::Button && ei.value > 0.0f)
|
||||
{
|
||||
QMetaObject::invokeMethod(m_parent, "bindToControllerRumble", Q_ARG(int, ei.controller_index));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
}
|
45
src/duckstation-qt/inputbindingmonitor.h
Normal file
45
src/duckstation-qt/inputbindingmonitor.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#pragma once
|
||||
|
||||
#include "frontend-common/controller_interface.h"
|
||||
#include <QtCore/QObject>
|
||||
|
||||
// NOTE: Those Monitor classes must be copyable to meet the requirements of std::function, but at the same time we want
|
||||
// copies to be opaque to the caling code and share context. Therefore, all mutable context of the monitor (if required)
|
||||
// must be enclosed in a std::shared_ptr. m_parent/m_axis_type don't mutate so they don't need to be stored as such.
|
||||
|
||||
class InputButtonBindingMonitor
|
||||
{
|
||||
public:
|
||||
explicit InputButtonBindingMonitor(QObject* parent) : m_parent(parent) {}
|
||||
|
||||
ControllerInterface::Hook::CallbackResult operator()(const ControllerInterface::Hook& ei) const;
|
||||
|
||||
private:
|
||||
QObject* m_parent;
|
||||
};
|
||||
|
||||
class InputAxisBindingMonitor
|
||||
{
|
||||
public:
|
||||
explicit InputAxisBindingMonitor(QObject* parent, Controller::AxisType axis_type)
|
||||
: m_parent(parent), m_axis_type(axis_type)
|
||||
{
|
||||
}
|
||||
|
||||
ControllerInterface::Hook::CallbackResult operator()(const ControllerInterface::Hook& ei) const;
|
||||
|
||||
private:
|
||||
QObject* m_parent;
|
||||
Controller::AxisType m_axis_type;
|
||||
};
|
||||
|
||||
class InputRumbleBindingMonitor
|
||||
{
|
||||
public:
|
||||
explicit InputRumbleBindingMonitor(QObject* parent) : m_parent(parent) {}
|
||||
|
||||
ControllerInterface::Hook::CallbackResult operator()(const ControllerInterface::Hook& ei) const;
|
||||
|
||||
private:
|
||||
QObject* m_parent;
|
||||
};
|
|
@ -4,6 +4,7 @@
|
|||
#include "core/settings.h"
|
||||
#include "frontend-common/controller_interface.h"
|
||||
#include "inputbindingdialog.h"
|
||||
#include "inputbindingmonitor.h"
|
||||
#include "qthostinterface.h"
|
||||
#include "qtutils.h"
|
||||
#include <QtCore/QTimer>
|
||||
|
@ -236,27 +237,7 @@ void InputButtonBindingWidget::hookControllerInput()
|
|||
if (!controller_interface)
|
||||
return;
|
||||
|
||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
||||
if (ei.type == ControllerInterface::Hook::Type::Axis)
|
||||
{
|
||||
// wait until it's at least half pushed so we don't get confused between axises with small movement
|
||||
if (std::abs(ei.value) < 0.5f)
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
|
||||
// TODO: this probably should consider the "last value"
|
||||
QMetaObject::invokeMethod(this, "bindToControllerAxis", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number), Q_ARG(std::optional<bool>, ei.value > 0));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
else if (ei.type == ControllerInterface::Hook::Type::Button && ei.value > 0.0f)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "bindToControllerButton", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
});
|
||||
controller_interface->SetHook(InputButtonBindingMonitor(this));
|
||||
}
|
||||
|
||||
void InputButtonBindingWidget::unhookControllerInput()
|
||||
|
@ -306,27 +287,7 @@ void InputAxisBindingWidget::hookControllerInput()
|
|||
if (!controller_interface)
|
||||
return;
|
||||
|
||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
||||
if (ei.type == ControllerInterface::Hook::Type::Axis)
|
||||
{
|
||||
// wait until it's at least half pushed so we don't get confused between axises with small movement
|
||||
if (std::abs(ei.value) < 0.5f)
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
|
||||
QMetaObject::invokeMethod(this, "bindToControllerAxis", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number), Q_ARG(std::optional<bool>, std::nullopt));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
else if (ei.type == ControllerInterface::Hook::Type::Button && m_axis_type == Controller::AxisType::Half &&
|
||||
ei.value > 0.0f)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "bindToControllerButton", Q_ARG(int, ei.controller_index),
|
||||
Q_ARG(int, ei.button_or_axis_number));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
});
|
||||
controller_interface->SetHook(InputAxisBindingMonitor(this, m_axis_type));
|
||||
}
|
||||
|
||||
void InputAxisBindingWidget::unhookControllerInput()
|
||||
|
@ -391,15 +352,7 @@ void InputRumbleBindingWidget::hookControllerInput()
|
|||
if (!controller_interface)
|
||||
return;
|
||||
|
||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
||||
if (ei.type == ControllerInterface::Hook::Type::Button && ei.value > 0.0f)
|
||||
{
|
||||
QMetaObject::invokeMethod(this, "bindToControllerRumble", Q_ARG(int, ei.controller_index));
|
||||
return ControllerInterface::Hook::CallbackResult::StopMonitoring;
|
||||
}
|
||||
|
||||
return ControllerInterface::Hook::CallbackResult::ContinueMonitoring;
|
||||
});
|
||||
controller_interface->SetHook(InputRumbleBindingMonitor(this));
|
||||
}
|
||||
|
||||
void InputRumbleBindingWidget::unhookControllerInput()
|
||||
|
|
Loading…
Reference in a new issue