summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControlReference
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2019-01-26 14:04:14 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2019-10-11 18:12:17 -0500
commit9e536382c44074ae8af620adb605fe107f3ef42c (patch)
treea703fb98c66e24fc35b166fe8bd9126dd4d97b7b /Source/Core/InputCommon/ControlReference
parentbbd6b1848fcaeaafbe14babb3911557e1a503c76 (diff)
ExpressionParser: Add function to smooth inputs.
Diffstat (limited to 'Source/Core/InputCommon/ControlReference')
-rw-r--r--Source/Core/InputCommon/ControlReference/FunctionExpression.cpp47
1 files changed, 47 insertions, 0 deletions
diff --git a/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp b/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
index 629b8eae0b..8692d04c78 100644
--- a/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
+++ b/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
@@ -226,6 +226,51 @@ class DeadzoneExpression : public FunctionExpression
std::string GetFuncName() const override { return "deadzone"; }
};
+// usage: smooth(input, seconds)
+// seconds is seconds to change from 0.0 to 1.0
+class SmoothExpression : public FunctionExpression
+{
+ virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override
+ {
+ return 2 == args.size();
+ }
+
+ ControlState GetValue() const override
+ {
+ const auto now = Clock::now();
+ const auto elapsed = now - m_last_update;
+ m_last_update = now;
+
+ const ControlState desired_value = GetArg(0).GetValue();
+ const ControlState smooth = GetArg(1).GetValue();
+
+ using FSec = std::chrono::duration<ControlState>;
+
+ const ControlState max_move = std::chrono::duration_cast<FSec>(elapsed).count() / smooth;
+
+ if (std::isinf(max_move))
+ {
+ m_value = desired_value;
+ }
+ else
+ {
+ const ControlState diff = desired_value - m_value;
+ m_value += std::copysign(std::min(max_move, std::abs(diff)), diff);
+ }
+
+ return m_value;
+ }
+
+ void SetValue(ControlState value) override {}
+ std::string GetFuncName() const override { return "smooth"; }
+
+private:
+ using Clock = std::chrono::steady_clock;
+
+ mutable ControlState m_value = 0.0;
+ mutable Clock::time_point m_last_update = Clock::now();
+};
+
std::unique_ptr<FunctionExpression> MakeFunctionExpression(std::string name)
{
if (name.empty())
@@ -244,6 +289,8 @@ std::unique_ptr<FunctionExpression> MakeFunctionExpression(std::string name)
return std::make_unique<UnaryMinusExpression>();
else if ("deadzone" == name)
return std::make_unique<DeadzoneExpression>();
+ else if ("smooth" == name)
+ return std::make_unique<SmoothExpression>();
else
return std::make_unique<UnknownFunctionExpression>();
}