mirror of
https://github.com/RetroDECK/Duckstation.git
synced 2024-11-30 01:25:51 +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.cpp
|
||||||
inputbindingdialog.h
|
inputbindingdialog.h
|
||||||
inputbindingdialog.ui
|
inputbindingdialog.ui
|
||||||
|
inputbindingmonitor.cpp
|
||||||
|
inputbindingmonitor.h
|
||||||
inputbindingwidgets.cpp
|
inputbindingwidgets.cpp
|
||||||
inputbindingwidgets.h
|
inputbindingwidgets.h
|
||||||
main.cpp
|
main.cpp
|
||||||
|
|
|
@ -66,6 +66,7 @@
|
||||||
<ClCompile Include="displaysettingswidget.cpp" />
|
<ClCompile Include="displaysettingswidget.cpp" />
|
||||||
<ClCompile Include="hotkeysettingswidget.cpp" />
|
<ClCompile Include="hotkeysettingswidget.cpp" />
|
||||||
<ClCompile Include="inputbindingdialog.cpp" />
|
<ClCompile Include="inputbindingdialog.cpp" />
|
||||||
|
<ClCompile Include="inputbindingmonitor.cpp" />
|
||||||
<ClCompile Include="inputbindingwidgets.cpp" />
|
<ClCompile Include="inputbindingwidgets.cpp" />
|
||||||
<ClCompile Include="qtdisplaywidget.cpp" />
|
<ClCompile Include="qtdisplaywidget.cpp" />
|
||||||
<ClCompile Include="gamelistsettingswidget.cpp" />
|
<ClCompile Include="gamelistsettingswidget.cpp" />
|
||||||
|
@ -105,6 +106,7 @@
|
||||||
<QtMoc Include="gamelistmodel.h" />
|
<QtMoc Include="gamelistmodel.h" />
|
||||||
<QtMoc Include="gamelistsearchdirectoriesmodel.h" />
|
<QtMoc Include="gamelistsearchdirectoriesmodel.h" />
|
||||||
<QtMoc Include="autoupdaterdialog.h" />
|
<QtMoc Include="autoupdaterdialog.h" />
|
||||||
|
<ClInclude Include="inputbindingmonitor.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
<ClInclude Include="settingwidgetbinder.h" />
|
<ClInclude Include="settingwidgetbinder.h" />
|
||||||
<QtMoc Include="consolesettingswidget.h" />
|
<QtMoc Include="consolesettingswidget.h" />
|
||||||
|
|
|
@ -60,11 +60,13 @@
|
||||||
<ClCompile Include="$(IntDir)moc_postprocessingchainconfigwidget.cpp" />
|
<ClCompile Include="$(IntDir)moc_postprocessingchainconfigwidget.cpp" />
|
||||||
<ClCompile Include="$(IntDir)moc_postprocessingshaderconfigwidget.cpp" />
|
<ClCompile Include="$(IntDir)moc_postprocessingshaderconfigwidget.cpp" />
|
||||||
<ClCompile Include="$(IntDir)moc_postprocessingsettingswidget.cpp" />
|
<ClCompile Include="$(IntDir)moc_postprocessingsettingswidget.cpp" />
|
||||||
|
<ClCompile Include="inputbindingmonitor.cpp" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="qtutils.h" />
|
<ClInclude Include="qtutils.h" />
|
||||||
<ClInclude Include="settingwidgetbinder.h" />
|
<ClInclude Include="settingwidgetbinder.h" />
|
||||||
<ClInclude Include="resource.h" />
|
<ClInclude Include="resource.h" />
|
||||||
|
<ClInclude Include="inputbindingmonitor.h" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Filter Include="resources">
|
<Filter Include="resources">
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "common/string_util.h"
|
#include "common/string_util.h"
|
||||||
#include "core/settings.h"
|
#include "core/settings.h"
|
||||||
#include "frontend-common/controller_interface.h"
|
#include "frontend-common/controller_interface.h"
|
||||||
|
#include "inputbindingmonitor.h"
|
||||||
#include "qthostinterface.h"
|
#include "qthostinterface.h"
|
||||||
#include "qtutils.h"
|
#include "qtutils.h"
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
@ -210,27 +211,7 @@ void InputButtonBindingDialog::hookControllerInput()
|
||||||
if (!controller_interface)
|
if (!controller_interface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
controller_interface->SetHook(InputButtonBindingMonitor(this));
|
||||||
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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputButtonBindingDialog::unhookControllerInput()
|
void InputButtonBindingDialog::unhookControllerInput()
|
||||||
|
@ -274,27 +255,7 @@ void InputAxisBindingDialog::hookControllerInput()
|
||||||
if (!controller_interface)
|
if (!controller_interface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
controller_interface->SetHook(InputAxisBindingMonitor(this, m_axis_type));
|
||||||
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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputAxisBindingDialog::unhookControllerInput()
|
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 "core/settings.h"
|
||||||
#include "frontend-common/controller_interface.h"
|
#include "frontend-common/controller_interface.h"
|
||||||
#include "inputbindingdialog.h"
|
#include "inputbindingdialog.h"
|
||||||
|
#include "inputbindingmonitor.h"
|
||||||
#include "qthostinterface.h"
|
#include "qthostinterface.h"
|
||||||
#include "qtutils.h"
|
#include "qtutils.h"
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
|
@ -236,27 +237,7 @@ void InputButtonBindingWidget::hookControllerInput()
|
||||||
if (!controller_interface)
|
if (!controller_interface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
controller_interface->SetHook(InputButtonBindingMonitor(this));
|
||||||
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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputButtonBindingWidget::unhookControllerInput()
|
void InputButtonBindingWidget::unhookControllerInput()
|
||||||
|
@ -306,27 +287,7 @@ void InputAxisBindingWidget::hookControllerInput()
|
||||||
if (!controller_interface)
|
if (!controller_interface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
controller_interface->SetHook(InputAxisBindingMonitor(this, m_axis_type));
|
||||||
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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputAxisBindingWidget::unhookControllerInput()
|
void InputAxisBindingWidget::unhookControllerInput()
|
||||||
|
@ -391,15 +352,7 @@ void InputRumbleBindingWidget::hookControllerInput()
|
||||||
if (!controller_interface)
|
if (!controller_interface)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
controller_interface->SetHook([this](const ControllerInterface::Hook& ei) {
|
controller_interface->SetHook(InputRumbleBindingMonitor(this));
|
||||||
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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputRumbleBindingWidget::unhookControllerInput()
|
void InputRumbleBindingWidget::unhookControllerInput()
|
||||||
|
|
Loading…
Reference in a new issue