summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2019-01-26 14:40:47 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2019-10-11 18:12:17 -0500
commit18b51204417bac5f0d436d219885c0ac42e2eb70 (patch)
treec5a551722de540c7c178fe725d1e3caf25d8de62 /Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
parentf2e499d5873eebb8417527deaf694e26a06cb5a9 (diff)
ExpressionParser: Add !tap function which activates after X (defaults to 2) taps within Y seconds.
Diffstat (limited to 'Source/Core/InputCommon/ControlReference/FunctionExpression.cpp')
-rw-r--r--Source/Core/InputCommon/ControlReference/FunctionExpression.cpp64
1 files changed, 64 insertions, 0 deletions
diff --git a/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp b/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
index b7dfe23e02..9e6607bce4 100644
--- a/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
+++ b/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
@@ -313,6 +313,68 @@ private:
mutable Clock::time_point m_start_time = Clock::now();
};
+// usage: !tap(input, seconds, taps=2)
+class TapExpression : public FunctionExpression
+{
+ virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
+ {
+ return 2 == args.size() || 3 == args.size();
+ }
+
+ ControlState GetValue() const override
+ {
+ const auto now = Clock::now();
+
+ using FSec = std::chrono::duration<ControlState>;
+
+ const auto elapsed = std::chrono::duration_cast<FSec>(now - m_start_time).count();
+
+ const ControlState input = GetArg(0).GetValue();
+ const ControlState seconds = GetArg(1).GetValue();
+
+ const bool is_time_up = elapsed > seconds;
+
+ const u32 desired_taps = (3 == GetArgCount()) ? u32(GetArg(2).GetValue() + 0.5) : 2;
+
+ if (input < CONDITION_THRESHOLD)
+ {
+ m_released = true;
+
+ if (m_taps > 0 && is_time_up)
+ {
+ m_taps = 0;
+ }
+ }
+ else
+ {
+ if (m_released)
+ {
+ if (!m_taps)
+ {
+ m_start_time = now;
+ }
+
+ ++m_taps;
+ m_released = false;
+ }
+
+ return desired_taps == m_taps;
+ }
+
+ return 0.0;
+ }
+
+ void SetValue(ControlState value) override {}
+ std::string GetFuncName() const override { return "tap"; }
+
+private:
+ using Clock = std::chrono::steady_clock;
+
+ mutable bool m_released = true;
+ mutable u32 m_taps = 0;
+ mutable Clock::time_point m_start_time = Clock::now();
+};
+
std::unique_ptr<FunctionExpression> MakeFunctionExpression(std::string name)
{
if (name.empty())
@@ -335,6 +397,8 @@ std::unique_ptr<FunctionExpression> MakeFunctionExpression(std::string name)
return std::make_unique<SmoothExpression>();
else if ("hold" == name)
return std::make_unique<HoldExpression>();
+ else if ("tap" == name)
+ return std::make_unique<TapExpression>();
else
return std::make_unique<UnknownFunctionExpression>();
}