summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/ControlReference
diff options
context:
space:
mode:
authorFiloppi <filippotarpini@hotmail.it>2021-03-12 00:01:18 +0200
committerFiloppi <filippotarpini@hotmail.it>2021-05-24 02:38:06 +0300
commit93e3e691f9a3a9913b56ebe71b4bd34fd21ce5c9 (patch)
tree7977561633ae2ff25bf61f887c4873bc74169ce6 /Source/Core/InputCommon/ControlReference
parent975f8e2a25653b3a9a4d8db42285f5b4de50b589 (diff)
Expose Control Expression variables to mappings UI
-add a way to reset their value (from the mappings UI) -fix "memory leak" where they would never be cleaned, one would be created every time you wrote a character after a "$" -fix ability to create variables with an empty string by just writing "$" (+added error for it) -Add $ operator to the UI operators list, to expose this functionality even more
Diffstat (limited to 'Source/Core/InputCommon/ControlReference')
-rw-r--r--Source/Core/InputCommon/ControlReference/ExpressionParser.cpp42
-rw-r--r--Source/Core/InputCommon/ControlReference/ExpressionParser.h7
2 files changed, 40 insertions, 9 deletions
diff --git a/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp b/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp
index 1a7ca5a8ef..6948ff07ac 100644
--- a/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp
+++ b/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp
@@ -461,20 +461,24 @@ class VariableExpression : public Expression
public:
VariableExpression(std::string name) : m_name(name) {}
- ControlState GetValue() const override { return *m_value_ptr; }
+ ControlState GetValue() const override { return m_variable_ptr ? *m_variable_ptr : 0; }
- void SetValue(ControlState value) override { *m_value_ptr = value; }
+ void SetValue(ControlState value) override
+ {
+ if (m_variable_ptr)
+ *m_variable_ptr = value;
+ }
int CountNumControls() const override { return 1; }
void UpdateReferences(ControlEnvironment& env) override
{
- m_value_ptr = env.GetVariablePtr(m_name);
+ m_variable_ptr = env.GetVariablePtr(m_name);
}
protected:
const std::string m_name;
- ControlState* m_value_ptr{};
+ std::shared_ptr<ControlState> m_variable_ptr;
};
class HotkeyExpression : public Expression
@@ -621,9 +625,30 @@ Device::Output* ControlEnvironment::FindOutput(ControlQualifier qualifier) const
return device->FindOutput(qualifier.control_name);
}
-ControlState* ControlEnvironment::GetVariablePtr(const std::string& name)
+std::shared_ptr<ControlState> ControlEnvironment::GetVariablePtr(const std::string& name)
{
- return &m_variables[name];
+ // Do not accept an empty string as key, even if the expression parser already prevents this case.
+ if (name.empty())
+ return nullptr;
+ std::shared_ptr<ControlState>& variable = m_variables[name];
+ // If new, make a shared ptr
+ if (!variable)
+ {
+ variable = std::make_shared<ControlState>();
+ }
+ return variable;
+}
+
+void ControlEnvironment::CleanUnusedVariables()
+{
+ for (auto it = m_variables.begin(); it != m_variables.end();)
+ {
+ // Don't count ourselves as reference
+ if (it->second.use_count() <= 1)
+ m_variables.erase(it++);
+ else
+ ++it;
+ }
}
ParseResult ParseResult::MakeEmptyResult()
@@ -785,7 +810,10 @@ private:
}
case TOK_VARIABLE:
{
- return ParseResult::MakeSuccessfulResult(std::make_unique<VariableExpression>(tok.data));
+ if (tok.data.empty())
+ return ParseResult::MakeErrorResult(tok, _trans("Expected variable name."));
+ else
+ return ParseResult::MakeSuccessfulResult(std::make_unique<VariableExpression>(tok.data));
}
case TOK_LPAREN:
{
diff --git a/Source/Core/InputCommon/ControlReference/ExpressionParser.h b/Source/Core/InputCommon/ControlReference/ExpressionParser.h
index 14670848ae..d36e00888f 100644
--- a/Source/Core/InputCommon/ControlReference/ExpressionParser.h
+++ b/Source/Core/InputCommon/ControlReference/ExpressionParser.h
@@ -143,7 +143,7 @@ public:
class ControlEnvironment
{
public:
- using VariableContainer = std::map<std::string, ControlState>;
+ using VariableContainer = std::map<std::string, std::shared_ptr<ControlState>>;
ControlEnvironment(const Core::DeviceContainer& container_, const Core::DeviceQualifier& default_,
VariableContainer& vars)
@@ -154,7 +154,10 @@ public:
std::shared_ptr<Core::Device> FindDevice(ControlQualifier qualifier) const;
Core::Device::Input* FindInput(ControlQualifier qualifier) const;
Core::Device::Output* FindOutput(ControlQualifier qualifier) const;
- ControlState* GetVariablePtr(const std::string& name);
+ // Returns an existing variable by the specified name if already existing. Creates it otherwise.
+ std::shared_ptr<ControlState> GetVariablePtr(const std::string& name);
+
+ void CleanUnusedVariables();
private:
VariableContainer& m_variables;