InputCommon: Clean up modifier ignoring logic.
This commit is contained in:
parent
f7bf26cd60
commit
aae913fbc6
|
@ -14,6 +14,7 @@
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
|
#include "Common/Logging/Log.h"
|
||||||
#include "Common/ScopeGuard.h"
|
#include "Common/ScopeGuard.h"
|
||||||
#include "Common/StringUtil.h"
|
#include "Common/StringUtil.h"
|
||||||
|
|
||||||
|
@ -29,24 +30,22 @@ class ControlExpression;
|
||||||
class HotkeySuppressions
|
class HotkeySuppressions
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
using Modifiers = std::vector<std::unique_ptr<ControlExpression>>;
|
||||||
using Suppressor = std::unique_ptr<Common::ScopeGuard>;
|
using Suppressor = std::unique_ptr<Common::ScopeGuard>;
|
||||||
|
|
||||||
bool IsSuppressed(Device::Input* input) const
|
bool IsSuppressed(Device::Input* input) const
|
||||||
{
|
{
|
||||||
// An input is suppressed if it exists in the map (with any modifier).
|
// Input is suppressed if it exists in the map at all.
|
||||||
auto it = m_suppressions.lower_bound({input, nullptr});
|
return m_suppressions.lower_bound({input, nullptr}) !=
|
||||||
return it != m_suppressions.end() && (it->first.first == input);
|
m_suppressions.lower_bound({input + 1, nullptr});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsSuppressedIgnoringModifiers(Device::Input* input, const Modifiers& ignore_modifiers) const;
|
||||||
|
|
||||||
// Suppresses each input + modifier pair.
|
// Suppresses each input + modifier pair.
|
||||||
// The returned object removes the suppression on destruction.
|
// The returned object removes the suppression on destruction.
|
||||||
Suppressor MakeSuppressor(const std::vector<std::unique_ptr<ControlExpression>>& modifiers,
|
Suppressor MakeSuppressor(const Modifiers* modifiers,
|
||||||
const std::unique_ptr<ControlExpression>& final_input);
|
const std::unique_ptr<ControlExpression>* final_input);
|
||||||
|
|
||||||
// Removes suppression for each input + modifier pair.
|
|
||||||
// The returned object restores the original suppression on destruction.
|
|
||||||
Suppressor MakeAntiSuppressor(const std::vector<std::unique_ptr<ControlExpression>>& modifiers,
|
|
||||||
const std::unique_ptr<ControlExpression>& final_input);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
using Suppression = std::pair<Device::Input*, Device::Input*>;
|
using Suppression = std::pair<Device::Input*, Device::Input*>;
|
||||||
|
@ -285,32 +284,29 @@ private:
|
||||||
Device::Output* output = nullptr;
|
Device::Output* output = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
HotkeySuppressions::Suppressor
|
bool HotkeySuppressions::IsSuppressedIgnoringModifiers(Device::Input* input,
|
||||||
HotkeySuppressions::MakeSuppressor(const std::vector<std::unique_ptr<ControlExpression>>& modifiers,
|
const Modifiers& ignore_modifiers) const
|
||||||
const std::unique_ptr<ControlExpression>& final_input)
|
|
||||||
{
|
{
|
||||||
for (auto& modifier : modifiers)
|
// Input is suppressed if it exists in the map with a modifier that we aren't ignoring.
|
||||||
++m_suppressions[{final_input->GetInput(), modifier->GetInput()}];
|
auto it = m_suppressions.lower_bound({input, nullptr});
|
||||||
|
auto it_end = m_suppressions.lower_bound({input + 1, nullptr});
|
||||||
|
|
||||||
return std::make_unique<Common::ScopeGuard>([this, &modifiers, &final_input]() {
|
return std::any_of(it, it_end, [&](auto& s) {
|
||||||
for (auto& modifier : modifiers)
|
return std::none_of(begin(ignore_modifiers), end(ignore_modifiers),
|
||||||
RemoveSuppression(modifier->GetInput(), final_input->GetInput());
|
[&](auto& m) { return m->GetInput() == s.first.second; });
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
HotkeySuppressions::Suppressor HotkeySuppressions::MakeAntiSuppressor(
|
HotkeySuppressions::Suppressor
|
||||||
const std::vector<std::unique_ptr<ControlExpression>>& modifiers,
|
HotkeySuppressions::MakeSuppressor(const Modifiers* modifiers,
|
||||||
const std::unique_ptr<ControlExpression>& final_input)
|
const std::unique_ptr<ControlExpression>* final_input)
|
||||||
{
|
{
|
||||||
decltype(m_suppressions) unsuppressed_modifiers;
|
for (auto& modifier : *modifiers)
|
||||||
|
++m_suppressions[{(*final_input)->GetInput(), modifier->GetInput()}];
|
||||||
|
|
||||||
for (auto& modifier : modifiers)
|
return std::make_unique<Common::ScopeGuard>([this, modifiers, final_input]() {
|
||||||
unsuppressed_modifiers.insert(
|
for (auto& modifier : *modifiers)
|
||||||
m_suppressions.extract({final_input->GetInput(), modifier->GetInput()}));
|
RemoveSuppression(modifier->GetInput(), (*final_input)->GetInput());
|
||||||
|
|
||||||
return std::make_unique<Common::ScopeGuard>(
|
|
||||||
[this, unsuppressed_modifiers{std::move(unsuppressed_modifiers)}]() mutable {
|
|
||||||
m_suppressions.merge(unsuppressed_modifiers);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -474,15 +470,14 @@ public:
|
||||||
{
|
{
|
||||||
const bool modifiers_pressed = std::all_of(m_modifiers.begin(), m_modifiers.end(),
|
const bool modifiers_pressed = std::all_of(m_modifiers.begin(), m_modifiers.end(),
|
||||||
[](const std::unique_ptr<ControlExpression>& input) {
|
[](const std::unique_ptr<ControlExpression>& input) {
|
||||||
// TODO: kill magic number.
|
return input->GetValue() > CONDITION_THRESHOLD;
|
||||||
return input->GetValue() > 0.5;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
const auto final_input_state = m_final_input->GetValueIgnoringSuppression();
|
const auto final_input_state = m_final_input->GetValueIgnoringSuppression();
|
||||||
|
|
||||||
if (modifiers_pressed)
|
if (modifiers_pressed)
|
||||||
{
|
{
|
||||||
if (final_input_state < 0.5)
|
if (final_input_state < CONDITION_THRESHOLD)
|
||||||
{
|
{
|
||||||
if (!m_suppressor)
|
if (!m_suppressor)
|
||||||
EnableSuppression();
|
EnableSuppression();
|
||||||
|
@ -491,10 +486,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
// Ignore suppression of our own modifiers. This also allows superset modifiers to function.
|
// Ignore suppression of our own modifiers. This also allows superset modifiers to function.
|
||||||
const auto anti_suppression =
|
const bool is_suppressed = s_hotkey_suppressions.IsSuppressedIgnoringModifiers(
|
||||||
s_hotkey_suppressions.MakeAntiSuppressor(m_modifiers, m_final_input);
|
m_final_input->GetInput(), m_modifiers);
|
||||||
|
|
||||||
const bool is_suppressed = s_hotkey_suppressions.IsSuppressed(m_final_input->GetInput());
|
|
||||||
|
|
||||||
// If some other hotkey suppressed us, require a release of final input to be ready again.
|
// If some other hotkey suppressed us, require a release of final input to be ready again.
|
||||||
if (is_suppressed)
|
if (is_suppressed)
|
||||||
|
@ -538,10 +531,10 @@ public:
|
||||||
private:
|
private:
|
||||||
void EnableSuppression() const
|
void EnableSuppression() const
|
||||||
{
|
{
|
||||||
m_suppressor = s_hotkey_suppressions.MakeSuppressor(m_modifiers, m_final_input);
|
m_suppressor = s_hotkey_suppressions.MakeSuppressor(&m_modifiers, &m_final_input);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::unique_ptr<ControlExpression>> m_modifiers;
|
HotkeySuppressions::Modifiers m_modifiers;
|
||||||
std::unique_ptr<ControlExpression> m_final_input;
|
std::unique_ptr<ControlExpression> m_final_input;
|
||||||
mutable HotkeySuppressions::Suppressor m_suppressor;
|
mutable HotkeySuppressions::Suppressor m_suppressor;
|
||||||
mutable bool m_is_ready = false;
|
mutable bool m_is_ready = false;
|
||||||
|
|
Loading…
Reference in New Issue