diff options
| author | Michael Maltese <michaeljosephmaltese@gmail.com> | 2016-10-11 17:48:38 -0700 |
|---|---|---|
| committer | Michael Maltese <michaeljosephmaltese@gmail.com> | 2017-02-07 22:59:10 -0800 |
| commit | a509f56116d308c96e38898e07d3538f26a1b7af (patch) | |
| tree | 1df255d62c9057cb3b53869afab04e737e96f0e0 /Source/Core/InputCommon/ControllerInterface | |
| parent | f621a6af431e53a71890f916dd812ccf987ab429 (diff) | |
InputCommon: Extract ControlReference from ControllerInterface
Better separation of concerns. Relegates `ControllerInterface` to
enumerating input controls, and the new `ControlReference` deals with
combining inputs and configuration expression parsing.
Diffstat (limited to 'Source/Core/InputCommon/ControllerInterface')
6 files changed, 0 insertions, 884 deletions
diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp index 635284d2c5..1a72fa172c 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.cpp @@ -4,7 +4,6 @@ #include <mutex> -#include "Common/Thread.h" #include "InputCommon/ControllerInterface/ControllerInterface.h" #ifdef CIFACE_USE_XINPUT @@ -33,13 +32,6 @@ #include "InputCommon/ControllerInterface/Pipes/Pipes.h" #endif -using namespace ciface::ExpressionParser; - -namespace -{ -const ControlState INPUT_DETECT_THRESHOLD = 0.55; -} - ControllerInterface g_controller_interface; // @@ -236,133 +228,3 @@ void ControllerInterface::InvokeHotplugCallbacks() const for (const auto& callback : m_hotplug_callbacks) callback(); } - -// -// InputReference :: State -// -// Gets the state of an input reference -// override function for ControlReference::State ... -// -ControlState ControllerInterface::InputReference::State(const ControlState ignore) -{ - if (parsed_expression) - return parsed_expression->GetValue() * range; - else - return 0.0; -} - -// -// OutputReference :: State -// -// Set the state of all binded outputs -// overrides ControlReference::State .. combined them so I could make the GUI simple / inputs == -// same as outputs one list -// I was lazy and it works so watever -// -ControlState ControllerInterface::OutputReference::State(const ControlState state) -{ - if (parsed_expression) - parsed_expression->SetValue(state); - return 0.0; -} - -// -// UpdateReference -// -// Updates a controlreference's binded devices/controls -// need to call this to re-parse a control reference's expression after changing it -// -void ControllerInterface::UpdateReference(ControllerInterface::ControlReference* ref, - const ciface::Core::DeviceQualifier& default_device) const -{ - delete ref->parsed_expression; - ref->parsed_expression = nullptr; - - ControlFinder finder(*this, default_device, ref->is_input); - ref->parse_error = ParseExpression(ref->expression, finder, &ref->parsed_expression); -} - -// -// InputReference :: Detect -// -// Wait for input on all binded devices -// supports not detecting inputs that were held down at the time of Detect start, -// which is useful for those crazy flightsticks that have certain buttons that are always held down -// or some crazy axes or something -// upon input, return pointer to detected Control -// else return nullptr -// -ciface::Core::Device::Control* -ControllerInterface::InputReference::Detect(const unsigned int ms, - ciface::Core::Device* const device) -{ - unsigned int time = 0; - std::vector<bool> states(device->Inputs().size()); - - if (device->Inputs().size() == 0) - return nullptr; - - // get starting state of all inputs, - // so we can ignore those that were activated at time of Detect start - std::vector<ciface::Core::Device::Input *>::const_iterator i = device->Inputs().begin(), - e = device->Inputs().end(); - for (std::vector<bool>::iterator state = states.begin(); i != e; ++i) - *state++ = ((*i)->GetState() > (1 - INPUT_DETECT_THRESHOLD)); - - while (time < ms) - { - device->UpdateInput(); - i = device->Inputs().begin(); - for (std::vector<bool>::iterator state = states.begin(); i != e; ++i, ++state) - { - // detected an input - if ((*i)->IsDetectable() && (*i)->GetState() > INPUT_DETECT_THRESHOLD) - { - // input was released at some point during Detect call - // return the detected input - if (false == *state) - return *i; - } - else if ((*i)->GetState() < (1 - INPUT_DETECT_THRESHOLD)) - { - *state = false; - } - } - Common::SleepCurrentThread(10); - time += 10; - } - - // no input was detected - return nullptr; -} - -// -// OutputReference :: Detect -// -// Totally different from the inputReference detect / I have them combined so it was simpler to make -// the GUI. -// The GUI doesn't know the difference between an input and an output / it's odd but I was lazy and -// it was easy -// -// set all binded outputs to <range> power for x milliseconds return false -// -ciface::Core::Device::Control* -ControllerInterface::OutputReference::Detect(const unsigned int ms, - ciface::Core::Device* const device) -{ - // ignore device - - // don't hang if we don't even have any controls mapped - if (BoundCount() > 0) - { - State(1); - unsigned int slept = 0; - - // this loop is to make stuff like flashing keyboard LEDs work - while (ms > (slept += 10)) - Common::SleepCurrentThread(10); - - State(0); - } - return nullptr; -} diff --git a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h index 845c6cbbf6..d9d85cdd77 100644 --- a/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h +++ b/Source/Core/InputCommon/ControllerInterface/ControllerInterface.h @@ -11,9 +11,7 @@ #include <vector> #include "Common/CommonTypes.h" -#include "Common/Thread.h" #include "InputCommon/ControllerInterface/Device.h" -#include "InputCommon/ControllerInterface/ExpressionParser.h" // enable disable sources #ifdef _WIN32 @@ -45,75 +43,6 @@ class ControllerInterface : public ciface::Core::DeviceContainer { public: - // - // ControlReference - // - // These are what you create to actually use the inputs, InputReference or OutputReference. - // - // After being bound to devices and controls with ControllerInterface::UpdateReference, - // each one can link to multiple devices and controls - // when you change a ControlReference's expression, - // you must use ControllerInterface::UpdateReference on it to rebind controls - // - class ControlReference - { - friend class ControllerInterface; - - public: - virtual ControlState State(const ControlState state = 0) = 0; - virtual ciface::Core::Device::Control* Detect(const unsigned int ms, - ciface::Core::Device* const device) = 0; - - ControlState range; - std::string expression; - const bool is_input; - ciface::ExpressionParser::ExpressionParseStatus parse_error; - - virtual ~ControlReference() { delete parsed_expression; } - int BoundCount() - { - if (parsed_expression) - return parsed_expression->num_controls; - else - return 0; - } - - protected: - ControlReference(const bool _is_input) - : range(1), is_input(_is_input), parsed_expression(nullptr) - { - } - ciface::ExpressionParser::Expression* parsed_expression; - }; - - // - // InputReference - // - // Control reference for inputs - // - class InputReference : public ControlReference - { - public: - InputReference() : ControlReference(true) {} - ControlState State(const ControlState state) override; - ciface::Core::Device::Control* Detect(const unsigned int ms, - ciface::Core::Device* const device) override; - }; - - // - // OutputReference - // - // Control reference for outputs - // - class OutputReference : public ControlReference - { - public: - OutputReference() : ControlReference(false) {} - ControlState State(const ControlState state) override; - ciface::Core::Device::Control* Detect(const unsigned int ms, - ciface::Core::Device* const device) override; - }; - ControllerInterface() : m_is_init(false), m_hwnd(nullptr) {} void Initialize(void* const hwnd); void RefreshDevices(); @@ -121,8 +50,6 @@ public: void AddDevice(std::shared_ptr<ciface::Core::Device> device); void RemoveDevice(std::function<bool(const ciface::Core::Device*)> callback); bool IsInit() const { return m_is_init; } - void UpdateReference(ControlReference* control, - const ciface::Core::DeviceQualifier& default_device) const; void UpdateInput(); void RegisterHotplugCallback(std::function<void(void)> callback); diff --git a/Source/Core/InputCommon/ControllerInterface/Device.cpp b/Source/Core/InputCommon/ControllerInterface/Device.cpp index 401e5b035b..930352a908 100644 --- a/Source/Core/InputCommon/ControllerInterface/Device.cpp +++ b/Source/Core/InputCommon/ControllerInterface/Device.cpp @@ -7,12 +7,6 @@ #include <string> #include <tuple> -// For InputGateOn() -// This is a really bad layering violation, but it's the cleanest -// place I could find to put it. -#include "Core/ConfigManager.h" -#include "Core/Host.h" - #include "InputCommon/ControllerInterface/Device.h" namespace ciface @@ -67,16 +61,6 @@ Device::Output* Device::FindOutput(const std::string& name) const return nullptr; } -bool Device::Control::InputGateOn() -{ - if (SConfig::GetInstance().m_BackgroundInput) - return true; - else if (Host_RendererHasFocus() || Host_UIHasFocus()) - return true; - else - return false; -} - // // DeviceQualifier :: ToString // diff --git a/Source/Core/InputCommon/ControllerInterface/Device.h b/Source/Core/InputCommon/ControllerInterface/Device.h index 657ece5016..bda6f1fb0a 100644 --- a/Source/Core/InputCommon/ControllerInterface/Device.h +++ b/Source/Core/InputCommon/ControllerInterface/Device.h @@ -42,8 +42,6 @@ public: public: virtual std::string GetName() const = 0; virtual ~Control() {} - bool InputGateOn(); - virtual Input* ToInput() { return nullptr; } virtual Output* ToOutput() { return nullptr; } }; @@ -59,15 +57,6 @@ public: // things like absolute axes/ absolute mouse position will override this virtual bool IsDetectable() { return true; } virtual ControlState GetState() const = 0; - - ControlState GetGatedState() - { - if (InputGateOn()) - return GetState(); - else - return 0.0; - } - Input* ToInput() override { return this; } }; @@ -81,13 +70,6 @@ public: public: virtual ~Output() {} virtual void SetState(ControlState state) = 0; - - void SetGatedState(ControlState state) - { - if (InputGateOn()) - SetState(state); - } - Output* ToOutput() override { return this; } }; diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp deleted file mode 100644 index 5e4c2375af..0000000000 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.cpp +++ /dev/null @@ -1,567 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#include <algorithm> -#include <cassert> -#include <iostream> -#include <map> -#include <memory> -#include <string> -#include <vector> - -#include "InputCommon/ControllerInterface/ExpressionParser.h" - -using namespace ciface::Core; - -namespace ciface -{ -namespace ExpressionParser -{ -enum TokenType -{ - TOK_DISCARD, - TOK_INVALID, - TOK_EOF, - TOK_LPAREN, - TOK_RPAREN, - TOK_AND, - TOK_OR, - TOK_NOT, - TOK_ADD, - TOK_CONTROL, -}; - -inline std::string OpName(TokenType op) -{ - switch (op) - { - case TOK_AND: - return "And"; - case TOK_OR: - return "Or"; - case TOK_NOT: - return "Not"; - case TOK_ADD: - return "Add"; - default: - assert(false); - return ""; - } -} - -class Token -{ -public: - TokenType type; - ControlQualifier qualifier; - - Token(TokenType type_) : type(type_) {} - Token(TokenType type_, ControlQualifier qualifier_) : type(type_), qualifier(qualifier_) {} - operator std::string() - { - switch (type) - { - case TOK_DISCARD: - return "Discard"; - case TOK_EOF: - return "EOF"; - case TOK_LPAREN: - return "("; - case TOK_RPAREN: - return ")"; - case TOK_AND: - return "&"; - case TOK_OR: - return "|"; - case TOK_NOT: - return "!"; - case TOK_ADD: - return "+"; - case TOK_CONTROL: - return "Device(" + (std::string)qualifier + ")"; - case TOK_INVALID: - break; - } - - return "Invalid"; - } -}; - -class Lexer -{ -public: - std::string expr; - std::string::iterator it; - - Lexer(const std::string& expr_) : expr(expr_) { it = expr.begin(); } - bool FetchBacktickString(std::string& value, char otherDelim = 0) - { - value = ""; - while (it != expr.end()) - { - char c = *it; - ++it; - if (c == '`') - return false; - if (c > 0 && c == otherDelim) - return true; - value += c; - } - return false; - } - - Token GetFullyQualifiedControl() - { - ControlQualifier qualifier; - std::string value; - - if (FetchBacktickString(value, ':')) - { - // Found colon, this is the device name - qualifier.has_device = true; - qualifier.device_qualifier.FromString(value); - FetchBacktickString(value); - } - - qualifier.control_name = value; - - return Token(TOK_CONTROL, qualifier); - } - - Token GetBarewordsControl(char c) - { - std::string name; - name += c; - - while (it != expr.end()) - { - c = *it; - if (!isalpha(c)) - break; - name += c; - ++it; - } - - ControlQualifier qualifier; - qualifier.control_name = name; - return Token(TOK_CONTROL, qualifier); - } - - Token NextToken() - { - if (it == expr.end()) - return Token(TOK_EOF); - - char c = *it++; - switch (c) - { - case ' ': - case '\t': - case '\n': - case '\r': - return Token(TOK_DISCARD); - case '(': - return Token(TOK_LPAREN); - case ')': - return Token(TOK_RPAREN); - case '&': - return Token(TOK_AND); - case '|': - return Token(TOK_OR); - case '!': - return Token(TOK_NOT); - case '+': - return Token(TOK_ADD); - case '`': - return GetFullyQualifiedControl(); - default: - if (isalpha(c)) - return GetBarewordsControl(c); - else - return Token(TOK_INVALID); - } - } - - ExpressionParseStatus Tokenize(std::vector<Token>& tokens) - { - while (true) - { - Token tok = NextToken(); - - if (tok.type == TOK_DISCARD) - continue; - - if (tok.type == TOK_INVALID) - { - tokens.clear(); - return EXPRESSION_PARSE_SYNTAX_ERROR; - } - - tokens.push_back(tok); - - if (tok.type == TOK_EOF) - break; - } - return EXPRESSION_PARSE_SUCCESS; - } -}; - -class ExpressionNode -{ -public: - virtual ~ExpressionNode() {} - virtual ControlState GetValue() { return 0; } - virtual void SetValue(ControlState state) {} - virtual int CountNumControls() { return 0; } - virtual operator std::string() { return ""; } -}; - -class DummyExpression : public ExpressionNode -{ -public: - std::string name; - - DummyExpression(const std::string& name_) : name(name_) {} - ControlState GetValue() override { return 0.0; } - void SetValue(ControlState value) override {} - int CountNumControls() override { return 0; } - operator std::string() override { return "`" + name + "`"; } -}; - -class ControlExpression : public ExpressionNode -{ -public: - ControlQualifier qualifier; - Device::Control* control; - - ControlExpression(ControlQualifier qualifier_, std::shared_ptr<Device> device, - Device::Control* control_) - : qualifier(qualifier_), control(control_), m_device(device) - { - } - - ControlState GetValue() override { return control->ToInput()->GetGatedState(); } - void SetValue(ControlState value) override { control->ToOutput()->SetGatedState(value); } - int CountNumControls() override { return 1; } - operator std::string() override { return "`" + (std::string)qualifier + "`"; } -private: - std::shared_ptr<Device> m_device; -}; - -class BinaryExpression : public ExpressionNode -{ -public: - TokenType op; - ExpressionNode* lhs; - ExpressionNode* rhs; - - BinaryExpression(TokenType op_, ExpressionNode* lhs_, ExpressionNode* rhs_) - : op(op_), lhs(lhs_), rhs(rhs_) - { - } - virtual ~BinaryExpression() - { - delete lhs; - delete rhs; - } - - ControlState GetValue() override - { - ControlState lhsValue = lhs->GetValue(); - ControlState rhsValue = rhs->GetValue(); - switch (op) - { - case TOK_AND: - return std::min(lhsValue, rhsValue); - case TOK_OR: - return std::max(lhsValue, rhsValue); - case TOK_ADD: - return std::min(lhsValue + rhsValue, 1.0); - default: - assert(false); - return 0; - } - } - - void SetValue(ControlState value) override - { - // Don't do anything special with the op we have. - // Treat "A & B" the same as "A | B". - lhs->SetValue(value); - rhs->SetValue(value); - } - - int CountNumControls() override { return lhs->CountNumControls() + rhs->CountNumControls(); } - operator std::string() override - { - return OpName(op) + "(" + (std::string)(*lhs) + ", " + (std::string)(*rhs) + ")"; - } -}; - -class UnaryExpression : public ExpressionNode -{ -public: - TokenType op; - ExpressionNode* inner; - - UnaryExpression(TokenType op_, ExpressionNode* inner_) : op(op_), inner(inner_) {} - virtual ~UnaryExpression() { delete inner; } - ControlState GetValue() override - { - ControlState value = inner->GetValue(); - switch (op) - { - case TOK_NOT: - return 1.0 - value; - default: - assert(false); - return 0; - } - } - - void SetValue(ControlState value) override - { - switch (op) - { - case TOK_NOT: - inner->SetValue(1.0 - value); - break; - - default: - assert(false); - } - } - - int CountNumControls() override { return inner->CountNumControls(); } - operator std::string() override { return OpName(op) + "(" + (std::string)(*inner) + ")"; } -}; - -std::shared_ptr<Device> ControlFinder::FindDevice(ControlQualifier qualifier) -{ - if (qualifier.has_device) - return container.FindDevice(qualifier.device_qualifier); - else - return container.FindDevice(default_device); -} - -Device::Control* ControlFinder::FindControl(ControlQualifier qualifier) -{ - const std::shared_ptr<Device> device = FindDevice(qualifier); - if (!device) - return nullptr; - - if (is_input) - return device->FindInput(qualifier.control_name); - else - return device->FindOutput(qualifier.control_name); -} - -class Parser -{ -public: - Parser(std::vector<Token> tokens_, ControlFinder& finder_) : tokens(tokens_), finder(finder_) - { - m_it = tokens.begin(); - } - - ExpressionParseStatus Parse(Expression** expr_out) - { - ExpressionNode* node; - ExpressionParseStatus status = Toplevel(&node); - if (status != EXPRESSION_PARSE_SUCCESS) - return status; - - *expr_out = new Expression(node); - return EXPRESSION_PARSE_SUCCESS; - } - -private: - std::vector<Token> tokens; - std::vector<Token>::iterator m_it; - ControlFinder& finder; - - Token Chew() { return *m_it++; } - Token Peek() { return *m_it; } - bool Expects(TokenType type) - { - Token tok = Chew(); - return tok.type == type; - } - - ExpressionParseStatus Atom(ExpressionNode** expr_out) - { - Token tok = Chew(); - switch (tok.type) - { - case TOK_CONTROL: - { - std::shared_ptr<Device> device = finder.FindDevice(tok.qualifier); - Device::Control* control = finder.FindControl(tok.qualifier); - if (control == nullptr) - { - *expr_out = new DummyExpression(tok.qualifier); - return EXPRESSION_PARSE_NO_DEVICE; - } - - *expr_out = new ControlExpression(tok.qualifier, device, control); - return EXPRESSION_PARSE_SUCCESS; - } - case TOK_LPAREN: - return Paren(expr_out); - default: - return EXPRESSION_PARSE_SYNTAX_ERROR; - } - } - - bool IsUnaryExpression(TokenType type) - { - switch (type) - { - case TOK_NOT: - return true; - default: - return false; - } - } - - ExpressionParseStatus Unary(ExpressionNode** expr_out) - { - if (IsUnaryExpression(Peek().type)) - { - Token tok = Chew(); - ExpressionNode* atom_expr; - ExpressionParseStatus status = Atom(&atom_expr); - if (status == EXPRESSION_PARSE_SYNTAX_ERROR) - return status; - *expr_out = new UnaryExpression(tok.type, atom_expr); - return EXPRESSION_PARSE_SUCCESS; - } - - return Atom(expr_out); - } - - bool IsBinaryToken(TokenType type) - { - switch (type) - { - case TOK_AND: - case TOK_OR: - case TOK_ADD: - return true; - default: - return false; - } - } - - ExpressionParseStatus Binary(ExpressionNode** expr_out) - { - ExpressionParseStatus status = Unary(expr_out); - if (status == EXPRESSION_PARSE_SYNTAX_ERROR) - return status; - - while (IsBinaryToken(Peek().type)) - { - Token tok = Chew(); - ExpressionNode* unary_expr; - status = Unary(&unary_expr); - if (status == EXPRESSION_PARSE_SYNTAX_ERROR) - { - delete *expr_out; - return status; - } - - *expr_out = new BinaryExpression(tok.type, *expr_out, unary_expr); - } - - return EXPRESSION_PARSE_SUCCESS; - } - - ExpressionParseStatus Paren(ExpressionNode** expr_out) - { - ExpressionParseStatus status; - - // lparen already chewed - if ((status = Toplevel(expr_out)) != EXPRESSION_PARSE_SUCCESS) - return status; - - if (!Expects(TOK_RPAREN)) - { - delete *expr_out; - return EXPRESSION_PARSE_SYNTAX_ERROR; - } - - return EXPRESSION_PARSE_SUCCESS; - } - - ExpressionParseStatus Toplevel(ExpressionNode** expr_out) { return Binary(expr_out); } -}; - -ControlState Expression::GetValue() -{ - return node->GetValue(); -} - -void Expression::SetValue(ControlState value) -{ - node->SetValue(value); -} - -Expression::Expression(ExpressionNode* node_) -{ - node = node_; - num_controls = node->CountNumControls(); -} - -Expression::~Expression() -{ - delete node; -} - -static ExpressionParseStatus ParseExpressionInner(const std::string& str, ControlFinder& finder, - Expression** expr_out) -{ - ExpressionParseStatus status; - Expression* expr; - *expr_out = nullptr; - - if (str == "") - return EXPRESSION_PARSE_SUCCESS; - - Lexer l(str); - std::vector<Token> tokens; - status = l.Tokenize(tokens); - if (status != EXPRESSION_PARSE_SUCCESS) - return status; - - Parser p(tokens, finder); - status = p.Parse(&expr); - if (status != EXPRESSION_PARSE_SUCCESS) - return status; - - *expr_out = expr; - return EXPRESSION_PARSE_SUCCESS; -} - -ExpressionParseStatus ParseExpression(const std::string& str, ControlFinder& finder, - Expression** expr_out) -{ - // Add compatibility with old simple expressions, which are simple - // barewords control names. - - ControlQualifier qualifier; - qualifier.control_name = str; - qualifier.has_device = false; - - std::shared_ptr<Device> device = finder.FindDevice(qualifier); - Device::Control* control = finder.FindControl(qualifier); - if (control) - { - *expr_out = new Expression(new ControlExpression(qualifier, device, control)); - return EXPRESSION_PARSE_SUCCESS; - } - - return ParseExpressionInner(str, finder, expr_out); -} -} -} diff --git a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h b/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h deleted file mode 100644 index 2c8f5a793f..0000000000 --- a/Source/Core/InputCommon/ControllerInterface/ExpressionParser.h +++ /dev/null @@ -1,72 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project -// Licensed under GPLv2+ -// Refer to the license.txt file included. - -#pragma once - -#include <memory> -#include <string> -#include "InputCommon/ControllerInterface/Device.h" - -namespace ciface -{ -namespace ExpressionParser -{ -class ControlQualifier -{ -public: - bool has_device; - Core::DeviceQualifier device_qualifier; - std::string control_name; - - ControlQualifier() : has_device(false) {} - operator std::string() - { - if (has_device) - return device_qualifier.ToString() + ":" + control_name; - else - return control_name; - } -}; - -class ControlFinder -{ -public: - ControlFinder(const Core::DeviceContainer& container_, const Core::DeviceQualifier& default_, - const bool is_input_) - : container(container_), default_device(default_), is_input(is_input_) - { - } - std::shared_ptr<Core::Device> FindDevice(ControlQualifier qualifier); - Core::Device::Control* FindControl(ControlQualifier qualifier); - -private: - const Core::DeviceContainer& container; - const Core::DeviceQualifier& default_device; - bool is_input; -}; - -class ExpressionNode; -class Expression -{ -public: - Expression() : node(nullptr) {} - Expression(ExpressionNode* node); - ~Expression(); - ControlState GetValue(); - void SetValue(ControlState state); - int num_controls; - ExpressionNode* node; -}; - -enum ExpressionParseStatus -{ - EXPRESSION_PARSE_SUCCESS = 0, - EXPRESSION_PARSE_SYNTAX_ERROR, - EXPRESSION_PARSE_NO_DEVICE, -}; - -ExpressionParseStatus ParseExpression(const std::string& expr, ControlFinder& finder, - Expression** expr_out); -} -} |
