diff options
| author | Filoppi <filippotarpini@hotmail.it> | 2021-03-12 00:01:18 +0200 |
|---|---|---|
| committer | Filoppi <filippotarpini@hotmail.it> | 2021-05-24 02:38:06 +0300 |
| commit | 93e3e691f9a3a9913b56ebe71b4bd34fd21ce5c9 (patch) | |
| tree | 7977561633ae2ff25bf61f887c4873bc74169ce6 /Source/Core/InputCommon/ControlReference | |
| parent | 975f8e2a25653b3a9a4d8db42285f5b4de50b589 (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.cpp | 42 | ||||
| -rw-r--r-- | Source/Core/InputCommon/ControlReference/ExpressionParser.h | 7 |
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; |
