summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Ottens <kevin.ottens@kdab.com>2016-08-23 16:26:10 +0200
committerSean Harmer <sean.harmer@kdab.com>2016-08-24 19:33:24 +0000
commit335052336eb0e1816f24a4f120551ee2b23ac1aa (patch)
tree1be1483acc4071a44f665686eeb45e7991a38b65
parent81ecbf04bf7c8a091916f0fa4c8840d499099453 (diff)
Move input, chord and sequence logic out of job
The bookkeeping and activation logic of ActionInput, InputChord and InputSequence now move outside of the job, which make them testable properly. The tests already show bugs which will be fixed in following commits. Change-Id: I4e434118a6ba285d08632c43d487b17ee5b4cb66 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
-rw-r--r--src/input/backend/actioninput.cpp21
-rw-r--r--src/input/backend/inputchord.cpp20
-rw-r--r--src/input/backend/inputsequence.cpp20
-rw-r--r--src/input/backend/updateaxisactionjob.cpp62
-rw-r--r--tests/auto/input/actioninput/tst_actioninput.cpp53
-rw-r--r--tests/auto/input/inputchord/inputchord.pro2
-rw-r--r--tests/auto/input/inputchord/tst_inputchord.cpp140
-rw-r--r--tests/auto/input/inputsequence/inputsequence.pro2
-rw-r--r--tests/auto/input/inputsequence/tst_inputsequence.cpp246
9 files changed, 503 insertions, 63 deletions
diff --git a/src/input/backend/actioninput.cpp b/src/input/backend/actioninput.cpp
index 7b620611e..c22d20730 100644
--- a/src/input/backend/actioninput.cpp
+++ b/src/input/backend/actioninput.cpp
@@ -41,6 +41,8 @@
#include <Qt3DInput/qactioninput.h>
#include <Qt3DInput/qabstractphysicaldevice.h>
#include <Qt3DInput/private/qactioninput_p.h>
+#include <Qt3DInput/private/qinputdeviceintegration_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
QT_BEGIN_NAMESPACE
@@ -85,6 +87,25 @@ void ActionInput::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
bool ActionInput::process(InputHandler *inputHandler, qint64 currentTime)
{
+ Q_UNUSED(currentTime);
+
+ QAbstractPhysicalDeviceBackendNode *physicalDeviceBackend = nullptr;
+
+ const auto integrations = inputHandler->inputDeviceIntegrations();
+ for (QInputDeviceIntegration *integration : integrations) {
+ physicalDeviceBackend = integration->physicalDevice(sourceDevice());
+ if (physicalDeviceBackend)
+ break;
+ }
+
+ if (!physicalDeviceBackend)
+ return false;
+
+ for (int button : qAsConst(m_buttons)) {
+ if (physicalDeviceBackend->isButtonPressed(button))
+ return true;
+ }
+
return false;
}
diff --git a/src/input/backend/inputchord.cpp b/src/input/backend/inputchord.cpp
index 81394c935..e9ce8315f 100644
--- a/src/input/backend/inputchord.cpp
+++ b/src/input/backend/inputchord.cpp
@@ -40,6 +40,7 @@
#include "inputchord_p.h"
#include <Qt3DInput/qinputchord.h>
#include <Qt3DInput/private/qinputchord_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
@@ -134,7 +135,24 @@ void InputChord::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
bool InputChord::process(InputHandler *inputHandler, qint64 currentTime)
{
- return false;
+ if (m_startTime != 0) {
+ // Check if we are still inside the time limit for the chord
+ if ((currentTime - m_startTime) > m_timeout) {
+ reset();
+ return false;
+ }
+ }
+
+ bool triggered = false;
+ for (const Qt3DCore::QNodeId &actionInputId : qAsConst(m_chords)) {
+ AbstractActionInput *actionInput = inputHandler->lookupActionInput(actionInputId);
+ if (actionInput && actionInput->process(inputHandler, currentTime)) {
+ triggered |= actionTriggered(actionInputId);
+ if (m_startTime == 0)
+ m_startTime = currentTime;
+ }
+ }
+ return triggered;
}
} // namespace Input
diff --git a/src/input/backend/inputsequence.cpp b/src/input/backend/inputsequence.cpp
index 94616fdac..f9771d066 100644
--- a/src/input/backend/inputsequence.cpp
+++ b/src/input/backend/inputsequence.cpp
@@ -41,6 +41,7 @@
#include <Qt3DInput/qinputsequence.h>
#include <Qt3DInput/qabstractphysicaldevice.h>
#include <Qt3DInput/private/qinputsequence_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
#include <Qt3DCore/qpropertyupdatedchange.h>
#include <Qt3DCore/qpropertynodeaddedchange.h>
#include <Qt3DCore/qpropertynoderemovedchange.h>
@@ -159,7 +160,24 @@ void InputSequence::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
bool InputSequence::process(InputHandler *inputHandler, qint64 currentTime)
{
- return false;
+ if (m_startTime != 0) {
+ // Check if we are still inside the time limit for the sequence
+ if ((currentTime - m_startTime) > m_timeout) {
+ reset();
+ return false;
+ }
+ }
+
+ bool triggered = false;
+ for (const Qt3DCore::QNodeId &actionInputId : qAsConst(m_sequences)) {
+ AbstractActionInput *actionInput = inputHandler->lookupActionInput(actionInputId);
+ if (actionInput && actionInput->process(inputHandler, currentTime)) {
+ triggered |= actionTriggered(actionInputId, currentTime);
+ if (m_startTime == 0)
+ m_startTime = currentTime;
+ }
+ }
+ return triggered;
}
} // namespace Input
diff --git a/src/input/backend/updateaxisactionjob.cpp b/src/input/backend/updateaxisactionjob.cpp
index 3a1bfb465..0cbd325c9 100644
--- a/src/input/backend/updateaxisactionjob.cpp
+++ b/src/input/backend/updateaxisactionjob.cpp
@@ -101,65 +101,9 @@ void UpdateAxisActionJob::updateAction(LogicalDevice *device)
bool UpdateAxisActionJob::processActionInput(const Qt3DCore::QNodeId actionInputId)
{
-
- if (m_handler->actionInputManager()->lookupResource(actionInputId)) {
- ActionInput *actionInput = m_handler->actionInputManager()->lookupResource(actionInputId);
- QAbstractPhysicalDeviceBackendNode *physicalDeviceBackend = nullptr;
-
- const auto integrations = m_handler->inputDeviceIntegrations();
- for (QInputDeviceIntegration *integration : integrations) {
- if ((physicalDeviceBackend = integration->physicalDevice(actionInput->sourceDevice())) != nullptr)
- break;
- }
-
- if (physicalDeviceBackend != nullptr) {
- // Update the value
- return anyOfRequiredButtonsPressed(actionInput->buttons(), physicalDeviceBackend);
- }
- } else if (m_handler->inputSequenceManager()->lookupResource(actionInputId)) {
- InputSequence *inputSequence = m_handler->inputSequenceManager()->lookupResource(actionInputId);
- const qint64 startTime = inputSequence->startTime();
- if (startTime != 0) {
- // Check if we are still inside the time limit for the chord
- if ((m_currentTime - startTime) > inputSequence->timeout()) {
- inputSequence->reset();
- return false;
- }
- }
- bool actionTriggered = false;
- const auto actionInputIds = inputSequence->sequences();
- for (const Qt3DCore::QNodeId actionInputId : actionInputIds) {
- if (processActionInput(actionInputId)){
- actionTriggered |= inputSequence->actionTriggered(actionInputId, m_currentTime);
- // Set the start time if it wasn't set before
- if (startTime == 0)
- inputSequence->setStartTime(m_currentTime);
- }
- }
- return actionTriggered;
- } else if (m_handler->inputChordManager()->lookupResource(actionInputId)) {
- InputChord *inputChord = m_handler->inputChordManager()->lookupResource(actionInputId);
- const qint64 startTime = inputChord->startTime();
- if (startTime != 0) {
- // Check if we are still inside the time limit for the chord
- if ((m_currentTime - startTime) > inputChord->timeout()) {
- inputChord->reset();
- return false;
- }
- }
- bool actionTriggered = false;
- const auto actionInputIds = inputChord->chords();
- for (const Qt3DCore::QNodeId actionInputId : actionInputIds) {
- if (processActionInput(actionInputId)){
- actionTriggered |= inputChord->actionTriggered(actionInputId);
- if (startTime == 0)
- inputChord->setStartTime(m_currentTime);
- }
- }
- return actionTriggered;
- }
- //Should Never reach this point
- return false;
+ AbstractActionInput *actionInput = m_handler->lookupActionInput(actionInputId);
+ Q_ASSERT(actionInput);
+ return actionInput->process(m_handler, m_currentTime);
}
void UpdateAxisActionJob::updateAxis(LogicalDevice *device)
diff --git a/tests/auto/input/actioninput/tst_actioninput.cpp b/tests/auto/input/actioninput/tst_actioninput.cpp
index 6c9f60908..2db4cf760 100644
--- a/tests/auto/input/actioninput/tst_actioninput.cpp
+++ b/tests/auto/input/actioninput/tst_actioninput.cpp
@@ -32,6 +32,7 @@
#include <Qt3DCore/QPropertyUpdatedChange>
#include <Qt3DInput/private/actioninput_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
#include <Qt3DInput/QActionInput>
class tst_ActionInput : public Qt3DCore::QBackendNodeTester
@@ -119,6 +120,58 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendActionInput.sourceDevice(), device.id());
}
+
+ void shouldDealWithKeyPresses()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ Qt3DInput::Input::ActionInput backendActionInput;
+ Qt3DInput::QActionInput actionInput;
+ actionInput.setButtons(QVector<int>() << Qt::Key_Space << Qt::Key_Return);
+ actionInput.setSourceDevice(device);
+ simulateInitialization(&actionInput, &backendActionInput);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, true);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Space, true);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Return, true);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Space, false);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, false);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Return, false);
+
+ // THEN
+ QCOMPARE(backendActionInput.process(&handler, 1000000000), false);
+ }
};
QTEST_APPLESS_MAIN(tst_ActionInput)
diff --git a/tests/auto/input/inputchord/inputchord.pro b/tests/auto/input/inputchord/inputchord.pro
index 323b7fa80..09bbbb3ec 100644
--- a/tests/auto/input/inputchord/inputchord.pro
+++ b/tests/auto/input/inputchord/inputchord.pro
@@ -8,4 +8,4 @@ CONFIG += testcase
SOURCES += tst_inputchord.cpp
-include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/input/inputchord/tst_inputchord.cpp b/tests/auto/input/inputchord/tst_inputchord.cpp
index 35316e6fb..7fa93451c 100644
--- a/tests/auto/input/inputchord/tst_inputchord.cpp
+++ b/tests/auto/input/inputchord/tst_inputchord.cpp
@@ -28,11 +28,15 @@
#include <QtTest/QTest>
#include <qbackendnodetester.h>
+#include "testdevice.h"
#include <Qt3DCore/QPropertyUpdatedChange>
#include <Qt3DCore/QPropertyNodeAddedChange>
#include <Qt3DCore/QPropertyNodeRemovedChange>
+#include <Qt3DInput/private/actioninput_p.h>
#include <Qt3DInput/private/inputchord_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
+#include <Qt3DInput/private/inputmanagers_p.h>
#include <Qt3DInput/QActionInput>
#include <Qt3DInput/QInputChord>
@@ -136,6 +140,142 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendInputChord.chords().size(), 0);
}
+
+ void shouldActivateWhenAllArePressed()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q << Qt::Key_W);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_A << Qt::Key_S);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ Qt3DInput::Input::InputChord backendInputChord;
+ Qt3DInput::QInputChord inputChord;
+ inputChord.setTimeout(300);
+ inputChord.addChord(firstInput);
+ inputChord.addChord(secondInput);
+ simulateInitialization(&inputChord, &backendInputChord);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, false);
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000100), true); // Yes, that's a bug
+ QCOMPARE(backendInputChord.process(&handler, 1000000150), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_A, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000200), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000300), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_W, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000400), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_W, false);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000500), true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000600), true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000700), true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000800), true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000900), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000001000), false);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000001100), false);
+ }
+
+ void shouldRespectChordTimeout()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_W);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ Qt3DInput::Input::InputChord backendInputChord;
+ Qt3DInput::QInputChord inputChord;
+ inputChord.setTimeout(300);
+ inputChord.addChord(firstInput);
+ inputChord.addChord(secondInput);
+ simulateInitialization(&inputChord, &backendInputChord);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000000), true); // Yes, that's a bug
+ QCOMPARE(backendInputChord.process(&handler, 1000000050), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_W, true);
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000400), false); // Too late
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000600), true); // Yes, that's yet another bug
+
+ // THEN
+ QCOMPARE(backendInputChord.process(&handler, 1000000800), true); // Yes, that's yet another bug
+ }
};
QTEST_APPLESS_MAIN(tst_InputChord)
diff --git a/tests/auto/input/inputsequence/inputsequence.pro b/tests/auto/input/inputsequence/inputsequence.pro
index e547dfe2e..1fdb21f5b 100644
--- a/tests/auto/input/inputsequence/inputsequence.pro
+++ b/tests/auto/input/inputsequence/inputsequence.pro
@@ -8,4 +8,4 @@ CONFIG += testcase
SOURCES += tst_inputsequence.cpp
-include(../../core/common/common.pri)
+include(../commons/commons.pri)
diff --git a/tests/auto/input/inputsequence/tst_inputsequence.cpp b/tests/auto/input/inputsequence/tst_inputsequence.cpp
index d32f25ae9..3adbe601d 100644
--- a/tests/auto/input/inputsequence/tst_inputsequence.cpp
+++ b/tests/auto/input/inputsequence/tst_inputsequence.cpp
@@ -28,10 +28,14 @@
#include <QtTest/QTest>
#include <qbackendnodetester.h>
+#include "testdevice.h"
#include <Qt3DCore/QPropertyUpdatedChange>
#include <Qt3DCore/QPropertyNodeAddedChange>
#include <Qt3DCore/QPropertyNodeRemovedChange>
+#include <Qt3DInput/private/actioninput_p.h>
+#include <Qt3DInput/private/inputhandler_p.h>
+#include <Qt3DInput/private/inputmanagers_p.h>
#include <Qt3DInput/private/inputsequence_p.h>
#include <Qt3DInput/QActionInput>
#include <Qt3DInput/QInputSequence>
@@ -150,6 +154,248 @@ private Q_SLOTS:
// THEN
QCOMPARE(backendInputSequence.sequences().size(), 0);
}
+
+ void shouldActivateWhenSequenceIsConsumedInOrderOnly()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q << Qt::Key_A);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_S << Qt::Key_W);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ auto thirdInput = new Qt3DInput::QActionInput;
+ thirdInput->setButtons(QVector<int>() << Qt::Key_D << Qt::Key_E);
+ thirdInput->setSourceDevice(device);
+ auto backendThirdInput = handler.actionInputManager()->getOrCreateResource(thirdInput->id());
+ simulateInitialization(thirdInput, backendThirdInput);
+
+ Qt3DInput::Input::InputSequence backendInputSequence;
+ Qt3DInput::QInputSequence inputSequence;
+ inputSequence.setButtonInterval(150);
+ inputSequence.setTimeout(450);
+ inputSequence.addSequence(firstInput);
+ inputSequence.addSequence(secondInput);
+ inputSequence.addSequence(thirdInput);
+ simulateInitialization(&inputSequence, &backendInputSequence);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Up, false);
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000100), true); // Yes, that's a bug
+ QCOMPARE(backendInputSequence.process(&handler, 1000000150), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000200), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_E, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000300), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_E, false);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000400), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000500), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000600), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_E, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000700), true);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_E, false);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000800), false);
+
+
+ // Now out of order
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000900), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000001000), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_D, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000001100), true); // Yes, that's another bug
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_D, false);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000001200), false);
+ }
+
+ void shouldRespectSequenceTimeout()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q << Qt::Key_A);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_S << Qt::Key_W);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ auto thirdInput = new Qt3DInput::QActionInput;
+ thirdInput->setButtons(QVector<int>() << Qt::Key_D << Qt::Key_E);
+ thirdInput->setSourceDevice(device);
+ auto backendThirdInput = handler.actionInputManager()->getOrCreateResource(thirdInput->id());
+ simulateInitialization(thirdInput, backendThirdInput);
+
+ Qt3DInput::Input::InputSequence backendInputSequence;
+ Qt3DInput::QInputSequence inputSequence;
+ inputSequence.setButtonInterval(250);
+ inputSequence.setTimeout(450);
+ inputSequence.addSequence(firstInput);
+ inputSequence.addSequence(secondInput);
+ inputSequence.addSequence(thirdInput);
+ simulateInitialization(&inputSequence, &backendInputSequence);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000100), true); // Yes, that's a bug
+ QCOMPARE(backendInputSequence.process(&handler, 1000000150), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000300), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_E, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000600), false); // Too late
+ }
+
+ void shouldRespectSequenceButtonInterval()
+ {
+ // GIVEN
+ TestDeviceIntegration deviceIntegration;
+ TestDevice *device = deviceIntegration.createPhysicalDevice("keyboard");
+ TestDeviceBackendNode *deviceBackend = deviceIntegration.physicalDevice(device->id());
+ Qt3DInput::Input::InputHandler handler;
+ handler.addInputDeviceIntegration(&deviceIntegration);
+
+ auto firstInput = new Qt3DInput::QActionInput;
+ firstInput->setButtons(QVector<int>() << Qt::Key_Q << Qt::Key_A);
+ firstInput->setSourceDevice(device);
+ auto backendFirstInput = handler.actionInputManager()->getOrCreateResource(firstInput->id());
+ simulateInitialization(firstInput, backendFirstInput);
+
+ auto secondInput = new Qt3DInput::QActionInput;
+ secondInput->setButtons(QVector<int>() << Qt::Key_S << Qt::Key_W);
+ secondInput->setSourceDevice(device);
+ auto backendSecondInput = handler.actionInputManager()->getOrCreateResource(secondInput->id());
+ simulateInitialization(secondInput, backendSecondInput);
+
+ auto thirdInput = new Qt3DInput::QActionInput;
+ thirdInput->setButtons(QVector<int>() << Qt::Key_D << Qt::Key_E);
+ thirdInput->setSourceDevice(device);
+ auto backendThirdInput = handler.actionInputManager()->getOrCreateResource(thirdInput->id());
+ simulateInitialization(thirdInput, backendThirdInput);
+
+ Qt3DInput::Input::InputSequence backendInputSequence;
+ Qt3DInput::QInputSequence inputSequence;
+ inputSequence.setButtonInterval(100);
+ inputSequence.setTimeout(450);
+ inputSequence.addSequence(firstInput);
+ inputSequence.addSequence(secondInput);
+ inputSequence.addSequence(thirdInput);
+ simulateInitialization(&inputSequence, &backendInputSequence);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000100), true); // Yes, that's a bug
+ QCOMPARE(backendInputSequence.process(&handler, 1000000150), false);
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_Q, false);
+ deviceBackend->setButtonPressed(Qt::Key_S, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000250), false); // Too late
+
+ // WHEN
+ deviceBackend->setButtonPressed(Qt::Key_S, false);
+ deviceBackend->setButtonPressed(Qt::Key_E, true);
+
+ // THEN
+ QCOMPARE(backendInputSequence.process(&handler, 1000000300), true); // Yes, that's yet another bug
+ }
};
QTEST_APPLESS_MAIN(tst_InputSequence)