diff --git a/Source/Core/InputCommon/CMakeLists.txt b/Source/Core/InputCommon/CMakeLists.txt
index 265f5a433d..518bdbb3ba 100644
--- a/Source/Core/InputCommon/CMakeLists.txt
+++ b/Source/Core/InputCommon/CMakeLists.txt
@@ -3,7 +3,8 @@ set(SRCS Src/ControllerEmu.cpp
Src/UDPWiimote.cpp
Src/UDPWrapper.cpp
Src/ControllerInterface/ControllerInterface.cpp
- Src/ControllerInterface/Device.cpp)
+ Src/ControllerInterface/Device.cpp
+ Src/ControllerInterface/ExpressionParser.cpp)
if(WIN32)
set(SRCS ${SRCS}
diff --git a/Source/Core/InputCommon/InputCommon.vcxproj b/Source/Core/InputCommon/InputCommon.vcxproj
index c3243854a2..03aaf1b3ea 100644
--- a/Source/Core/InputCommon/InputCommon.vcxproj
+++ b/Source/Core/InputCommon/InputCommon.vcxproj
@@ -167,6 +167,7 @@
+
@@ -180,6 +181,7 @@
+
diff --git a/Source/Core/InputCommon/InputCommon.vcxproj.filters b/Source/Core/InputCommon/InputCommon.vcxproj.filters
index b4d5ff074f..ce4558f1ad 100644
--- a/Source/Core/InputCommon/InputCommon.vcxproj.filters
+++ b/Source/Core/InputCommon/InputCommon.vcxproj.filters
@@ -23,6 +23,12 @@
ControllerInterface\DInput
+
+ ControllerInterface
+
+
+ ControllerInterface
+
@@ -42,6 +48,9 @@
ControllerInterface\Device
+
+ ControllerInterface
+
ControllerInterface\DInput
@@ -72,4 +81,4 @@
{5a9c1b94-2eab-4357-b44f-87d5db50da3d}
-
\ No newline at end of file
+
diff --git a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.cpp b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.cpp
index e672e4598c..58e0653bbe 100644
--- a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.cpp
+++ b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.cpp
@@ -21,6 +21,8 @@
#include "Thread.h"
+using namespace ciface::ExpressionParser;
+
namespace
{
const float INPUT_DETECT_THRESHOLD = 0.55f;
@@ -187,48 +189,10 @@ bool ControllerInterface::UpdateOutput(const bool force)
//
ControlState ControllerInterface::InputReference::State( const ControlState ignore )
{
- //if (NULL == device)
- //return 0;
-
- ControlState state = 0;
-
- std::vector::const_iterator
- ci = m_controls.begin(),
- ce = m_controls.end();
-
- // bit of hax for "NOT" to work at start of expression
- if (ci != ce)
- {
- if (ci->mode == 2)
- state = 1;
- }
-
- for (; ci!=ce; ++ci)
- {
- const ControlState istate = ci->control->ToInput()->GetState();
-
- switch (ci->mode)
- {
- // OR
- case 0 :
- state = std::max(state, istate);
- break;
- // AND
- case 1 :
- state = std::min(state, istate);
- break;
- // NOT
- case 2 :
- state = std::max(std::min(state, 1.0f - istate), 0.0f);
- break;
- // ADD
- case 3 :
- state += istate;
- break;
- }
- }
-
- return std::min(1.0f, state * range);
+ if (parsed_expression)
+ return parsed_expression->GetValue();
+ else
+ return 0.0f;
}
//
@@ -240,17 +204,9 @@ ControlState ControllerInterface::InputReference::State( const ControlState igno
//
ControlState ControllerInterface::OutputReference::State(const ControlState state)
{
- const ControlState tmp_state = std::min(1.0f, state * range);
-
- // output ref just ignores the modes ( |&!... )
-
- std::vector::iterator
- ci = m_controls.begin(),
- ce = m_controls.end();
- for (; ci != ce; ++ci)
- ci->control->ToOutput()->SetState(tmp_state);
-
- return state; // just return the output, watever
+ if (parsed_expression)
+ parsed_expression->SetValue(state);
+ return 0.0f;
}
//
@@ -262,65 +218,13 @@ ControlState ControllerInterface::OutputReference::State(const ControlState stat
void ControllerInterface::UpdateReference(ControllerInterface::ControlReference* ref
, const DeviceQualifier& default_device) const
{
- ref->m_controls.clear();
+ delete ref->parsed_expression;
+ ref->parsed_expression = NULL;
- // adding | to parse the last item, silly
- std::istringstream ss(ref->expression + '|');
-
- const std::string mode_chars("|&!^");
-
- ControlReference::DeviceControl devc;
-
- std::string dev_str;
- std::string ctrl_str;
-
- char c = 0;
- while (ss.read(&c, 1))
- {
- const size_t f = mode_chars.find(c);
-
- if (mode_chars.npos != f)
- {
- // add ctrl
- if (ctrl_str.size())
- {
- DeviceQualifier devq;
-
- // using default device or alterate device inside `backticks`
- if (dev_str.empty())
- devq = default_device;
- else
- devq.FromString(dev_str);
-
- // find device
- Device* const def_device = FindDevice(devq);
-
- if (def_device)
- {
- if (ref->is_input)
- devc.control = FindInput(ctrl_str, def_device);
- else
- devc.control = FindOutput(ctrl_str, def_device);
-
- if (devc.control)
- ref->m_controls.push_back(devc);
- }
- }
- // reset stuff for next ctrl
- devc.mode = (int)f;
- ctrl_str.clear();
- }
- else if ('`' == c)
- {
- // different device
- if (std::getline(ss, dev_str, '`').eof())
- break; // no terminating '`' character
- }
- else
- {
- ctrl_str += c;
- }
- }
+ ControlFinder finder(*this, default_device, ref->is_input);
+ ExpressionParseStatus status;
+ status = ParseExpression(ref->expression, finder, &ref->parsed_expression);
+ // XXX: do something with status?
}
//
@@ -388,7 +292,7 @@ Device::Control* ControllerInterface::OutputReference::Detect(const unsigned int
// ignore device
// don't hang if we don't even have any controls mapped
- if (m_controls.size())
+ if (BoundCount() > 0)
{
State(1);
unsigned int slept = 0;
diff --git a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h
index db3a82bf3b..57903a08a7 100644
--- a/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h
+++ b/Source/Core/InputCommon/Src/ControllerInterface/ControllerInterface.h
@@ -9,6 +9,7 @@
#include "Common.h"
#include "Thread.h"
+#include "ExpressionParser.h"
#include "Device.h"
// enable disable sources
@@ -53,30 +54,28 @@ public:
class ControlReference
{
friend class ControllerInterface;
-
public:
- virtual ~ControlReference() {}
-
virtual ControlState State(const ControlState state = 0) = 0;
virtual Device::Control* Detect(const unsigned int ms, Device* const device) = 0;
- size_t BoundCount() const { return m_controls.size(); }
- ControlState range;
+ ControlState range;
std::string expression;
const bool is_input;
+ 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) {}
-
- struct DeviceControl
- {
- DeviceControl() : control(NULL), mode(0) {}
-
- Device::Control* control;
- int mode;
- };
-
- std::vector m_controls;
+ ControlReference(const bool _is_input) : range(1), is_input(_is_input), parsed_expression(NULL) {}
+ ciface::ExpressionParser::Expression *parsed_expression;
};
//
diff --git a/Source/Core/InputCommon/Src/ControllerInterface/ExpressionParser.cpp b/Source/Core/InputCommon/Src/ControllerInterface/ExpressionParser.cpp
new file mode 100644
index 0000000000..81ceab5913
--- /dev/null
+++ b/Source/Core/InputCommon/Src/ControllerInterface/ExpressionParser.cpp
@@ -0,0 +1,516 @@
+
+#include "ExpressionParser.h"
+
+#include
+#include
+#include
+#include