diff options
| author | Jordan Woyak <jordan.woyak@gmail.com> | 2019-01-26 12:17:30 -0600 |
|---|---|---|
| committer | Jordan Woyak <jordan.woyak@gmail.com> | 2019-10-11 18:12:16 -0500 |
| commit | fd07ae8cec5c77ac60788350610739e6ac094547 (patch) | |
| tree | 8f0dac16bcbc972f22f649f4d4c37eefa157f6d2 /Source/Core/InputCommon/ControlReference/ExpressionParser.cpp | |
| parent | d4f9b8c4efe9ce48aac5b43487c5d6c5d5fbd83b (diff) | |
ExpressionParser: Move FunctionExpression type definitions into another file.
Diffstat (limited to 'Source/Core/InputCommon/ControlReference/ExpressionParser.cpp')
| -rw-r--r-- | Source/Core/InputCommon/ControlReference/ExpressionParser.cpp | 258 |
1 files changed, 3 insertions, 255 deletions
diff --git a/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp b/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp index 1c9ea370ce..b0704d3d8d 100644 --- a/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp @@ -2,29 +2,24 @@ // Licensed under GPLv2+ // Refer to the license.txt file included. -#include <algorithm> #include <cassert> -#include <chrono> #include <cmath> #include <iostream> -#include <locale> -#include <map> #include <memory> #include <regex> #include <string> +#include <utility> #include <vector> -#include "Common/MathUtil.h" #include "Common/StringUtil.h" + #include "InputCommon/ControlReference/ExpressionParser.h" +#include "InputCommon/ControlReference/FunctionExpression.h" namespace ciface::ExpressionParser { using namespace ciface::Core; -constexpr int LOOP_MAX_REPS = 10000; -constexpr ControlState CONDITION_THRESHOLD = 0.5; - enum TokenType { TOK_DISCARD, @@ -420,253 +415,6 @@ public: } }; -class FunctionExpression : public Expression -{ -public: - int CountNumControls() const override - { - int result = 0; - - for (auto& arg : m_args) - result += arg->CountNumControls(); - - return result; - } - - void UpdateReferences(ControlEnvironment& env) override - { - for (auto& arg : m_args) - arg->UpdateReferences(env); - } - - operator std::string() const override - { - std::string result = '!' + GetFuncName(); - - for (auto& arg : m_args) - result += ' ' + static_cast<std::string>(*arg); - - return result; - } - - bool SetArguments(std::vector<std::unique_ptr<Expression>>&& args) - { - m_args = std::move(args); - - return ValidateArguments(m_args); - } - -protected: - virtual std::string GetFuncName() const = 0; - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) = 0; - - Expression& GetArg(u32 number) { return *m_args[number]; } - const Expression& GetArg(u32 number) const { return *m_args[number]; } - -private: - std::vector<std::unique_ptr<Expression>> m_args; -}; - -// TODO: Return an oscillating value to make it apparent something was spelled wrong? -class UnknownFunctionExpression : public FunctionExpression -{ -private: - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override - { - return false; - } - ControlState GetValue() const override { return 0.0; } - void SetValue(ControlState value) override {} - std::string GetFuncName() const override { return "unknown"; } -}; - -class ToggleExpression : public FunctionExpression -{ -private: - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override - { - return 1 == args.size(); - } - - ControlState GetValue() const override - { - const ControlState inner_value = GetArg(0).GetValue(); - - if (inner_value < CONDITION_THRESHOLD) - { - m_released = true; - } - else if (m_released && inner_value > CONDITION_THRESHOLD) - { - m_released = false; - m_state ^= true; - } - - return m_state; - } - - void SetValue(ControlState value) override {} - std::string GetFuncName() const override { return "toggle"; } - - mutable bool m_released{}; - mutable bool m_state{}; -}; - -class NotExpression : public FunctionExpression -{ -private: - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override - { - return 1 == args.size(); - } - - ControlState GetValue() const override { return 1.0 - GetArg(0).GetValue(); } - void SetValue(ControlState value) override { GetArg(0).SetValue(1.0 - value); } - std::string GetFuncName() const override { return ""; } -}; - -class SinExpression : public FunctionExpression -{ -private: - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override - { - return 1 == args.size(); - } - - ControlState GetValue() const override { return std::sin(GetArg(0).GetValue()); } - void SetValue(ControlState value) override {} - std::string GetFuncName() const override { return "sin"; } -}; - -class TimerExpression : public FunctionExpression -{ -private: - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override - { - return 1 == args.size(); - } - - ControlState GetValue() const override - { - const auto now = Clock::now(); - const auto elapsed = now - m_start_time; - - using FSec = std::chrono::duration<ControlState>; - - const ControlState val = GetArg(0).GetValue(); - - ControlState progress = std::chrono::duration_cast<FSec>(elapsed).count() / val; - - if (std::isinf(progress)) - { - // User configured a 0.0 length timer. Reset the timer and return 0.0. - progress = 0.0; - m_start_time = now; - } - else if (progress >= 1.0) - { - const ControlState reset_count = std::floor(progress); - - m_start_time += std::chrono::duration_cast<Clock::duration>(FSec(val * reset_count)); - progress -= reset_count; - } - - return progress; - } - void SetValue(ControlState value) override {} - std::string GetFuncName() const override { return "timer"; } - -private: - using Clock = std::chrono::steady_clock; - mutable Clock::time_point m_start_time = Clock::now(); -}; - -class IfExpression : public FunctionExpression -{ -private: - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override - { - return 3 == args.size(); - } - - ControlState GetValue() const override - { - return (GetArg(0).GetValue() > CONDITION_THRESHOLD) ? GetArg(1).GetValue() : - GetArg(2).GetValue(); - } - - void SetValue(ControlState value) override {} - std::string GetFuncName() const override { return "if"; } -}; - -class UnaryMinusExpression : public FunctionExpression -{ -private: - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override - { - return 1 == args.size(); - } - - ControlState GetValue() const override - { - // Subtraction for clarity: - return 0.0 - GetArg(0).GetValue(); - } - - void SetValue(ControlState value) override {} - std::string GetFuncName() const override { return "minus"; } -}; - -class WhileExpression : public FunctionExpression -{ - virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) override - { - return 2 == args.size(); - } - - ControlState GetValue() const override - { - // Returns 1.0 on successful loop, 0.0 on reps exceeded. Sensible? - - for (int i = 0; i != LOOP_MAX_REPS; ++i) - { - // Check condition of 1st argument: - const ControlState val = GetArg(0).GetValue(); - if (val < CONDITION_THRESHOLD) - return 1.0; - - // Evaluate 2nd argument: - GetArg(1).GetValue(); - } - - // Exceeded max reps: - return 0.0; - } - - void SetValue(ControlState value) override {} - std::string GetFuncName() const override { return "while"; } -}; - -std::unique_ptr<FunctionExpression> MakeFunctionExpression(std::string name) -{ - if (name.empty()) - return std::make_unique<NotExpression>(); - else if ("if" == name) - return std::make_unique<IfExpression>(); - else if ("sin" == name) - return std::make_unique<SinExpression>(); - else if ("timer" == name) - return std::make_unique<TimerExpression>(); - else if ("toggle" == name) - return std::make_unique<ToggleExpression>(); - else if ("while" == name) - return std::make_unique<WhileExpression>(); - else if ("minus" == name) - return std::make_unique<UnaryMinusExpression>(); - else - return std::make_unique<UnknownFunctionExpression>(); -} - class LiteralExpression : public Expression { public: |
