summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorColin Ogilvie <colin.ogilvie@kdab.com>2016-01-15 13:40:10 +0000
committerPaul Lemire <paul.lemire@kdab.com>2016-01-19 15:21:06 +0000
commitd38cd8cd2d913f30b0e23c8d6b9a274f4f47036d (patch)
tree67894812a624be31f705207a84b3c3bc6fe9878b /src
parent034ac26201c87179a9bba25571f926a212542cd9 (diff)
Aggregate action functionality
Change-Id: Iac5e6bfd2ad67b3c1c9a794ea528204eff238d20 Reviewed-by: Sean Harmer <sean.harmer@kdab.com>
Diffstat (limited to 'src')
-rw-r--r--src/input/backend/inputchord.cpp36
-rw-r--r--src/input/backend/inputchord_p.h7
-rw-r--r--src/input/backend/inputsequence.cpp60
-rw-r--r--src/input/backend/inputsequence_p.h9
-rw-r--r--src/input/backend/updateaxisactionjob.cpp72
-rw-r--r--src/input/backend/updateaxisactionjob_p.h5
-rw-r--r--src/input/frontend/qinputaspect.cpp2
7 files changed, 173 insertions, 18 deletions
diff --git a/src/input/backend/inputchord.cpp b/src/input/backend/inputchord.cpp
index b788a13f5..5d3d13e91 100644
--- a/src/input/backend/inputchord.cpp
+++ b/src/input/backend/inputchord.cpp
@@ -47,7 +47,9 @@ namespace Input {
InputChord::InputChord()
: Qt3DCore::QBackendNode()
, m_inputs()
+ , m_inputsToTrigger()
, m_tolerance(0)
+ , m_startTime(0)
, m_enabled(false)
{
}
@@ -65,7 +67,33 @@ void InputChord::cleanup()
{
m_enabled = false;
m_tolerance = 0;
+ m_startTime = 0;
m_inputs.clear();
+ m_inputsToTrigger.clear();
+}
+
+void InputChord::reset()
+{
+ m_startTime = 0;
+ m_inputsToTrigger.clear();
+ Q_FOREACH (Qt3DCore::QNodeId input, m_inputs)
+ m_inputsToTrigger.push_back(input);
+}
+
+bool InputChord::actionTriggered(Qt3DCore::QNodeId input)
+{
+ m_inputsToTrigger.removeOne(input);
+ if (m_inputsToTrigger.isEmpty()) {
+ //All Triggered
+ reset();
+ return true;
+ }
+ return false;
+}
+
+void InputChord::setStartTime(qint64 time)
+{
+ m_startTime = time;
}
void InputChord::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
@@ -78,11 +106,15 @@ void InputChord::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
m_tolerance = propertyChange->value().toInt();
}
} else if (e->type() == Qt3DCore::NodeAdded) {
- if (propertyChange->propertyName() == QByteArrayLiteral("input"))
+ if (propertyChange->propertyName() == QByteArrayLiteral("input")) {
m_inputs.push_back(propertyChange->value().value<Qt3DCore::QNodeId>());
+ m_inputsToTrigger.push_back(propertyChange->value().value<Qt3DCore::QNodeId>());
+ }
} else if (e->type() == Qt3DCore::NodeRemoved) {
- if (propertyChange->propertyName() == QByteArrayLiteral("input"))
+ if (propertyChange->propertyName() == QByteArrayLiteral("input")) {
m_inputs.removeOne(propertyChange->value().value<Qt3DCore::QNodeId>());
+ m_inputsToTrigger.removeOne(propertyChange->value().value<Qt3DCore::QNodeId>());
+ }
}
}
diff --git a/src/input/backend/inputchord_p.h b/src/input/backend/inputchord_p.h
index a8870e531..633a66489 100644
--- a/src/input/backend/inputchord_p.h
+++ b/src/input/backend/inputchord_p.h
@@ -66,12 +66,17 @@ public:
inline QVector<Qt3DCore::QNodeId> inputs() const { return m_inputs; }
inline int tolerance() const { return m_tolerance; }
+ inline qint64 startTime() const { return m_startTime; }
+ void setStartTime(qint64 time);
inline bool isEnabled() const { return m_enabled; }
+ void reset();
+ bool actionTriggered(Qt3DCore::QNodeId input);
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
-
private:
QVector<Qt3DCore::QNodeId> m_inputs;
+ QVector<Qt3DCore::QNodeId> m_inputsToTrigger;
int m_tolerance;
+ qint64 m_startTime;
bool m_enabled;
};
diff --git a/src/input/backend/inputsequence.cpp b/src/input/backend/inputsequence.cpp
index 43847d3d4..aa854bdb1 100644
--- a/src/input/backend/inputsequence.cpp
+++ b/src/input/backend/inputsequence.cpp
@@ -38,6 +38,7 @@
#include <Qt3DInput/qinputsequence.h>
#include <Qt3DInput/qabstractphysicaldevice.h>
#include <Qt3DCore/qscenepropertychange.h>
+#include <QDateTime>
QT_BEGIN_NAMESPACE
@@ -48,9 +49,12 @@ namespace Input {
InputSequence::InputSequence()
: Qt3DCore::QBackendNode()
, m_inputs()
+ , m_inputsToTrigger()
, m_timeout(0)
, m_interval(0)
, m_sequential(true)
+ , m_startTime(0)
+ , m_lastInputTime(0)
, m_enabled(false)
{
}
@@ -71,8 +75,56 @@ void InputSequence::cleanup()
m_enabled = false;
m_timeout = 0;
m_interval = 0;
+ m_startTime = 0;
+ m_lastInputTime = 0;
+ m_lastInputId = Qt3DCore::QNodeId();
m_sequential = true;
m_inputs.clear();
+ m_inputsToTrigger.clear();
+}
+
+void InputSequence::setStartTime(qint64 time)
+{
+ m_startTime = time;
+}
+
+void InputSequence::reset()
+{
+ m_startTime = 0;
+ m_lastInputTime = 0;
+ m_inputsToTrigger = m_inputs;
+ m_lastInputId = Qt3DCore::QNodeId();
+}
+
+bool InputSequence::actionTriggered(Qt3DCore::QNodeId input, const qint64 currentTime)
+{
+ // If we are running the root of a sequence and input is not the first element of the sequence
+ // reset and return false
+ if (m_sequential && (!m_inputs.empty() && m_inputsToTrigger.first() != input)) {
+ if (!(input == m_lastInputId && ((currentTime - m_lastInputTime) < 200)))
+ reset();
+ return false;
+ }
+
+ // Otherwise save the last input
+ m_lastInputId = input;
+ // Return false if we've spent too much time in between two sequences
+ if ((m_lastInputTime != 0) && ((currentTime - m_lastInputTime) > m_interval)) {
+ reset();
+ return false;
+ }
+
+ // Update lastInputTime and remove the inputs to trigger from the sequence
+ m_lastInputTime = currentTime;
+ m_inputsToTrigger.removeOne(input);
+
+ // If we have no more remaining inputs in the sequences of inputs
+ if (m_inputsToTrigger.isEmpty()) {
+ // All Triggered
+ reset();
+ return true;
+ }
+ return false;
}
void InputSequence::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
@@ -89,11 +141,15 @@ void InputSequence::sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e)
m_sequential = propertyChange->value().toBool();
}
} else if (e->type() == Qt3DCore::NodeAdded) {
- if (propertyChange->propertyName() == QByteArrayLiteral("input"))
+ if (propertyChange->propertyName() == QByteArrayLiteral("input")) {
m_inputs.push_back(propertyChange->value().value<Qt3DCore::QNodeId>());
+ m_inputsToTrigger.push_back(propertyChange->value().value<Qt3DCore::QNodeId>());
+ }
} else if (e->type() == Qt3DCore::NodeRemoved) {
- if (propertyChange->propertyName() == QByteArrayLiteral("input"))
+ if (propertyChange->propertyName() == QByteArrayLiteral("input")) {
m_inputs.removeOne(propertyChange->value().value<Qt3DCore::QNodeId>());
+ m_inputsToTrigger.removeOne(propertyChange->value().value<Qt3DCore::QNodeId>());
+ }
}
}
diff --git a/src/input/backend/inputsequence_p.h b/src/input/backend/inputsequence_p.h
index ef916aa7c..c44c0dcfe 100644
--- a/src/input/backend/inputsequence_p.h
+++ b/src/input/backend/inputsequence_p.h
@@ -67,15 +67,24 @@ public:
inline QVector<Qt3DCore::QNodeId> inputs() const { return m_inputs; }
inline int timeout() const { return m_timeout; }
inline int interval() const { return m_interval; }
+ inline qint64 startTime() const { return m_startTime; }
+ void setStartTime(qint64 time);
inline bool isSequential() const { return m_sequential; }
inline bool isEnabled() const { return m_enabled; }
+ bool sequenceTriggered() const;
+ void reset();
+ bool actionTriggered(Qt3DCore::QNodeId input, const qint64 currentTime);
void sceneChangeEvent(const Qt3DCore::QSceneChangePtr &e) Q_DECL_OVERRIDE;
private:
QVector<Qt3DCore::QNodeId> m_inputs;
+ QVector<Qt3DCore::QNodeId> m_inputsToTrigger;
int m_timeout;
int m_interval;
bool m_sequential;
+ qint64 m_startTime;
+ qint64 m_lastInputTime;
+ Qt3DCore::QNodeId m_lastInputId;
bool m_enabled;
};
diff --git a/src/input/backend/updateaxisactionjob.cpp b/src/input/backend/updateaxisactionjob.cpp
index 406aa952c..6b7f0f457 100644
--- a/src/input/backend/updateaxisactionjob.cpp
+++ b/src/input/backend/updateaxisactionjob.cpp
@@ -62,8 +62,9 @@ bool anyOfRequiredKeysPressed(const QVector<int> &keys, QAbstractPhysicalDeviceB
} // anonymous
-UpdateAxisActionJob::UpdateAxisActionJob(InputHandler *handler, HLogicalDevice handle)
+UpdateAxisActionJob::UpdateAxisActionJob(qint64 currentTime, InputHandler *handler, HLogicalDevice handle)
: Qt3DCore::QAspectJob()
+ , m_currentTime(currentTime)
, m_handler(handler)
, m_handle(handle)
{
@@ -85,21 +86,70 @@ void UpdateAxisActionJob::updateAction(LogicalDevice *device)
Action *action = m_handler->actionManager()->lookupResource(actionId);
Q_FOREACH (const Qt3DCore::QNodeId actionInputId, action->inputs()) {
- ActionInput *actionInput = m_handler->actionInputManager()->lookupResource(actionInputId);
- QAbstractPhysicalDeviceBackendNode *physicalDeviceBackend = Q_NULLPTR;
+ actionTriggered |= processActionInput(actionInputId);
+ }
+ action->setActionTriggered(actionTriggered);
+ }
+}
- Q_FOREACH (QInputDeviceIntegration *integration, m_handler->inputDeviceIntegrations()) {
- if ((physicalDeviceBackend = integration->physicalDevice(actionInput->sourceDevice())) != Q_NULLPTR)
- break;
- }
+bool UpdateAxisActionJob::processActionInput(const Qt3DCore::QNodeId actionInputId)
+{
- if (physicalDeviceBackend != Q_NULLPTR) {
- // Update the value
- actionTriggered |= anyOfRequiredKeysPressed(actionInput->keys(), physicalDeviceBackend);
+ if (m_handler->actionInputManager()->lookupResource(actionInputId)) {
+ ActionInput *actionInput = m_handler->actionInputManager()->lookupResource(actionInputId);
+ QAbstractPhysicalDeviceBackendNode *physicalDeviceBackend = Q_NULLPTR;
+
+ Q_FOREACH (QInputDeviceIntegration *integration, m_handler->inputDeviceIntegrations()) {
+ if ((physicalDeviceBackend = integration->physicalDevice(actionInput->sourceDevice())) != Q_NULLPTR)
+ break;
+ }
+
+ if (physicalDeviceBackend != Q_NULLPTR) {
+ // Update the value
+ return anyOfRequiredKeysPressed(actionInput->keys(), 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;
}
}
- action->setActionTriggered(actionTriggered);
+ bool actionTriggered = false;
+ Q_FOREACH (const Qt3DCore::QNodeId actionInputId, inputSequence->inputs()) {
+ 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->tolerance()) {
+ inputChord->reset();
+ return false;
+ }
+ }
+ bool actionTriggered = false;
+ Q_FOREACH (const Qt3DCore::QNodeId actionInputId, inputChord->inputs()) {
+ if (processActionInput(actionInputId)){
+ actionTriggered |= inputChord->actionTriggered(actionInputId);
+ if (startTime == 0)
+ inputChord->setStartTime(m_currentTime);
+ }
+ }
+ return actionTriggered;
}
+ //Should Never reach this point
+ return false;
}
void UpdateAxisActionJob::updateAxis(LogicalDevice *device)
diff --git a/src/input/backend/updateaxisactionjob_p.h b/src/input/backend/updateaxisactionjob_p.h
index 7d2aa5ec6..15356284c 100644
--- a/src/input/backend/updateaxisactionjob_p.h
+++ b/src/input/backend/updateaxisactionjob_p.h
@@ -49,6 +49,7 @@
//
#include <Qt3DCore/qaspectjob.h>
+#include <Qt3DCore/qnodeid.h>
#include <Qt3DInput/private/handle_types_p.h>
QT_BEGIN_NAMESPACE
@@ -62,13 +63,15 @@ class InputHandler;
class UpdateAxisActionJob : public Qt3DCore::QAspectJob
{
public:
- explicit UpdateAxisActionJob(InputHandler *handler, HLogicalDevice handle);
+ explicit UpdateAxisActionJob(qint64 currentTime, InputHandler *handler, HLogicalDevice handle);
void run() Q_DECL_FINAL;
private:
void updateAction(LogicalDevice *device);
+ bool processActionInput(const Qt3DCore::QNodeId actionInputId);
void updateAxis(LogicalDevice *device);
+ const qint64 m_currentTime;
InputHandler *m_handler;
HLogicalDevice m_handle;
};
diff --git a/src/input/frontend/qinputaspect.cpp b/src/input/frontend/qinputaspect.cpp
index b1889be66..aba2fbba3 100644
--- a/src/input/frontend/qinputaspect.cpp
+++ b/src/input/frontend/qinputaspect.cpp
@@ -175,7 +175,7 @@ QVector<QAspectJobPtr> QInputAspect::jobsToExecute(qint64 time)
QHash<Input::HLogicalDevice, QAspectJobPtr> logicalDeviceJobs;
Q_FOREACH (Input::HLogicalDevice devHandle, d->m_inputHandler->logicalDeviceManager()->activeDevices()) {
- QAspectJobPtr updateAxisActionJob(new Input::UpdateAxisActionJob(d->m_inputHandler.data(), devHandle));
+ QAspectJobPtr updateAxisActionJob(new Input::UpdateAxisActionJob(time, d->m_inputHandler.data(), devHandle));
logicalDeviceJobs.insert(devHandle, updateAxisActionJob);
Q_FOREACH (const QAspectJobPtr job, jobs)