diff --git a/Source/Core/InputCommon/ControlReference/ControlReference.cpp b/Source/Core/InputCommon/ControlReference/ControlReference.cpp index 09bcdaa59f..e53c5c3877 100644 --- a/Source/Core/InputCommon/ControlReference/ControlReference.cpp +++ b/Source/Core/InputCommon/ControlReference/ControlReference.cpp @@ -31,7 +31,9 @@ void ControlReference::UpdateReference(const ciface::Core::DeviceContainer& devi const ciface::Core::DeviceQualifier& default_device) { ControlFinder finder(devices, default_device, IsInput()); - std::tie(m_parse_status, m_parsed_expression) = ParseExpression(expression, finder); + std::tie(m_parse_status, m_parsed_expression) = ParseExpression(expression); + if (m_parsed_expression) + m_parsed_expression->UpdateReferences(finder); } int ControlReference::BoundCount() const diff --git a/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp b/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp index 3bac0243dc..ce58b0f968 100644 --- a/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp +++ b/Source/Core/InputCommon/ControlReference/ExpressionParser.cpp @@ -212,16 +212,11 @@ class ControlExpression : public Expression { public: ControlQualifier qualifier; - Device::Control* control; + Device::Control* control = nullptr; // Keep a shared_ptr to the device so the control pointer doesn't become invalid std::shared_ptr m_device; - ControlExpression(ControlQualifier qualifier_, std::shared_ptr device, - Device::Control* control_) - : qualifier(qualifier_), control(control_), m_device(std::move(device)) - { - } - + ControlExpression(ControlQualifier qualifier_) : qualifier(qualifier_) {} ControlState GetValue() const override { return control ? control->ToInput()->GetState() : 0.0; } void SetValue(ControlState value) override { @@ -229,6 +224,11 @@ public: control->ToOutput()->SetState(value); } int CountNumControls() const override { return control ? 1 : 0; } + void UpdateReferences(ControlFinder& finder) override + { + m_device = finder.FindDevice(qualifier); + control = finder.FindControl(qualifier); + } operator std::string() const override { return "`" + static_cast(qualifier) + "`"; } }; @@ -276,6 +276,12 @@ public: return lhs->CountNumControls() + rhs->CountNumControls(); } + void UpdateReferences(ControlFinder& finder) override + { + lhs->UpdateReferences(finder); + rhs->UpdateReferences(finder); + } + operator std::string() const override { return OpName(op) + "(" + (std::string)(*lhs) + ", " + (std::string)(*rhs) + ")"; @@ -319,6 +325,7 @@ public: } int CountNumControls() const override { return inner->CountNumControls(); } + void UpdateReferences(ControlFinder& finder) override { inner->UpdateReferences(finder); } operator std::string() const override { return OpName(op) + "(" + (std::string)(*inner) + ")"; } }; @@ -346,6 +353,12 @@ public: static_cast(*m_rhs) + ')'; } + void UpdateReferences(ControlFinder& finder) override + { + m_lhs->UpdateReferences(finder); + m_rhs->UpdateReferences(finder); + } + private: const std::unique_ptr& GetActiveChild() const { @@ -390,16 +403,11 @@ struct ParseResult class Parser { public: - Parser(std::vector tokens_, ControlFinder& finder_) : tokens(tokens_), finder(finder_) - { - m_it = tokens.begin(); - } - + explicit Parser(std::vector tokens_) : tokens(tokens_) { m_it = tokens.begin(); } ParseResult Parse() { return Toplevel(); } private: std::vector tokens; std::vector::iterator m_it; - ControlFinder& finder; Token Chew() { return *m_it++; } Token Peek() { return *m_it; } @@ -415,12 +423,7 @@ private: switch (tok.type) { case TOK_CONTROL: - { - std::shared_ptr device = finder.FindDevice(tok.qualifier); - Device::Control* control = finder.FindControl(tok.qualifier); - return {ParseStatus::Successful, - std::make_unique(tok.qualifier, std::move(device), control)}; - } + return {ParseStatus::Successful, std::make_unique(tok.qualifier)}; case TOK_LPAREN: return Paren(); default: @@ -508,7 +511,7 @@ private: ParseResult Toplevel() { return Binary(); } }; -static ParseResult ParseComplexExpression(const std::string& str, ControlFinder& finder) +static ParseResult ParseComplexExpression(const std::string& str) { Lexer l(str); std::vector tokens; @@ -516,29 +519,25 @@ static ParseResult ParseComplexExpression(const std::string& str, ControlFinder& if (tokenize_status != ParseStatus::Successful) return {tokenize_status}; - return Parser(tokens, finder).Parse(); + return Parser(tokens).Parse(); } -static std::unique_ptr ParseBarewordExpression(const std::string& str, - ControlFinder& finder) +static std::unique_ptr ParseBarewordExpression(const std::string& str) { ControlQualifier qualifier; qualifier.control_name = str; qualifier.has_device = false; - std::shared_ptr device = finder.FindDevice(qualifier); - Device::Control* control = finder.FindControl(qualifier); - return std::make_unique(qualifier, std::move(device), control); + return std::make_unique(qualifier); } -std::pair> ParseExpression(const std::string& str, - ControlFinder& finder) +std::pair> ParseExpression(const std::string& str) { if (StripSpaces(str).empty()) return std::make_pair(ParseStatus::EmptyExpression, nullptr); - auto bareword_expr = ParseBarewordExpression(str, finder); - ParseResult complex_result = ParseComplexExpression(str, finder); + auto bareword_expr = ParseBarewordExpression(str); + ParseResult complex_result = ParseComplexExpression(str); if (complex_result.status != ParseStatus::Successful) { diff --git a/Source/Core/InputCommon/ControlReference/ExpressionParser.h b/Source/Core/InputCommon/ControlReference/ExpressionParser.h index 8fde647390..398b273e0f 100644 --- a/Source/Core/InputCommon/ControlReference/ExpressionParser.h +++ b/Source/Core/InputCommon/ControlReference/ExpressionParser.h @@ -54,6 +54,7 @@ public: virtual ControlState GetValue() const = 0; virtual void SetValue(ControlState state) = 0; virtual int CountNumControls() const = 0; + virtual void UpdateReferences(ControlFinder& finder) = 0; virtual operator std::string() const = 0; }; @@ -64,7 +65,6 @@ enum class ParseStatus EmptyExpression, }; -std::pair> ParseExpression(const std::string& expr, - ControlFinder& finder); +std::pair> ParseExpression(const std::string& expr); } }