From 18b51204417bac5f0d436d219885c0ac42e2eb70 Mon Sep 17 00:00:00 2001 From: Jordan Woyak Date: Sat, 26 Jan 2019 14:40:47 -0600 Subject: [PATCH] ExpressionParser: Add !tap function which activates after X (defaults to 2) taps within Y seconds. --- .../ControlReference/FunctionExpression.cpp | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) 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>& args) override + { + return 2 == args.size() || 3 == args.size(); + } + + ControlState GetValue() const override + { + const auto now = Clock::now(); + + using FSec = std::chrono::duration; + + const auto elapsed = std::chrono::duration_cast(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 MakeFunctionExpression(std::string name) { if (name.empty()) @@ -335,6 +397,8 @@ std::unique_ptr MakeFunctionExpression(std::string name) return std::make_unique(); else if ("hold" == name) return std::make_unique(); + else if ("tap" == name) + return std::make_unique(); else return std::make_unique(); }