summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControlReference
diff options
context:
space:
mode:
authorJordan Woyak <jordan.woyak@gmail.com>2019-01-26 12:17:30 -0600
committerJordan Woyak <jordan.woyak@gmail.com>2019-10-11 18:12:16 -0500
commitfd07ae8cec5c77ac60788350610739e6ac094547 (patch)
tree8f0dac16bcbc972f22f649f4d4c37eefa157f6d2 /Source/Core/InputCommon/ControlReference
parentd4f9b8c4efe9ce48aac5b43487c5d6c5d5fbd83b (diff)
ExpressionParser: Move FunctionExpression type definitions into another file.
Diffstat (limited to 'Source/Core/InputCommon/ControlReference')
-rw-r--r--Source/Core/InputCommon/ControlReference/ExpressionParser.cpp258
-rw-r--r--Source/Core/InputCommon/ControlReference/ExpressionParser.h2
-rw-r--r--Source/Core/InputCommon/ControlReference/FunctionExpression.cpp261
-rw-r--r--Source/Core/InputCommon/ControlReference/FunctionExpression.h41
4 files changed, 306 insertions, 256 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:
diff --git a/Source/Core/InputCommon/ControlReference/ExpressionParser.h b/Source/Core/InputCommon/ControlReference/ExpressionParser.h
index d9f7a5eb2b..0cb84af5cd 100644
--- a/Source/Core/InputCommon/ControlReference/ExpressionParser.h
+++ b/Source/Core/InputCommon/ControlReference/ExpressionParser.h
@@ -7,7 +7,7 @@
#include <map>
#include <memory>
#include <string>
-#include <utility>
+
#include "InputCommon/ControllerInterface/Device.h"
namespace ciface::ExpressionParser
diff --git a/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp b/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
new file mode 100644
index 0000000000..15a66ec9d1
--- /dev/null
+++ b/Source/Core/InputCommon/ControlReference/FunctionExpression.cpp
@@ -0,0 +1,261 @@
+// Copyright 2019 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#include <chrono>
+#include <cmath>
+
+#include "InputCommon/ControlReference/FunctionExpression.h"
+
+namespace ciface
+{
+namespace ExpressionParser
+{
+constexpr int LOOP_MAX_REPS = 10000;
+constexpr ControlState CONDITION_THRESHOLD = 0.5;
+
+// 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>();
+}
+
+int FunctionExpression::CountNumControls() const
+{
+ int result = 0;
+
+ for (auto& arg : m_args)
+ result += arg->CountNumControls();
+
+ return result;
+}
+
+void FunctionExpression::UpdateReferences(ControlEnvironment& env)
+{
+ for (auto& arg : m_args)
+ arg->UpdateReferences(env);
+}
+
+FunctionExpression::operator std::string() const
+{
+ std::string result = '!' + GetFuncName();
+
+ for (auto& arg : m_args)
+ result += ' ' + static_cast<std::string>(*arg);
+
+ return result;
+}
+
+bool FunctionExpression::SetArguments(std::vector<std::unique_ptr<Expression>>&& args)
+{
+ m_args = std::move(args);
+
+ return ValidateArguments(m_args);
+}
+
+Expression& FunctionExpression::GetArg(u32 number)
+{
+ return *m_args[number];
+}
+
+const Expression& FunctionExpression::GetArg(u32 number) const
+{
+ return *m_args[number];
+}
+
+} // namespace ExpressionParser
+} // namespace ciface
diff --git a/Source/Core/InputCommon/ControlReference/FunctionExpression.h b/Source/Core/InputCommon/ControlReference/FunctionExpression.h
new file mode 100644
index 0000000000..8ac7e9800c
--- /dev/null
+++ b/Source/Core/InputCommon/ControlReference/FunctionExpression.h
@@ -0,0 +1,41 @@
+// Copyright 2019 Dolphin Emulator Project
+// Licensed under GPLv2+
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <string>
+#include <vector>
+
+#include "InputCommon/ControlReference/ExpressionParser.h"
+#include "InputCommon/ControlReference/FunctionExpression.h"
+
+namespace ciface
+{
+namespace ExpressionParser
+{
+class FunctionExpression : public Expression
+{
+public:
+ int CountNumControls() const override;
+ void UpdateReferences(ControlEnvironment& env) override;
+ operator std::string() const override;
+
+ bool SetArguments(std::vector<std::unique_ptr<Expression>>&& args);
+
+protected:
+ virtual std::string GetFuncName() const = 0;
+ virtual bool ValidateArguments(const std::vector<std::unique_ptr<Expression>>& args) = 0;
+
+ Expression& GetArg(u32 number);
+ const Expression& GetArg(u32 number) const;
+
+private:
+ std::vector<std::unique_ptr<Expression>> m_args;
+};
+
+std::unique_ptr<FunctionExpression> MakeFunctionExpression(std::string name);
+
+} // namespace ExpressionParser
+} // namespace ciface