1// Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "inputsequence_p.h"
5
6#include <Qt3DInput/qabstractphysicaldevice.h>
7#include <Qt3DInput/qinputsequence.h>
8#include <QtCore/QDateTime>
9
10#include <Qt3DInput/private/inputhandler_p.h>
11#include <Qt3DInput/private/qinputsequence_p.h>
12
13QT_BEGIN_NAMESPACE
14
15namespace Qt3DInput {
16
17namespace Input {
18
19InputSequence::InputSequence()
20 : AbstractActionInput()
21 , m_sequences()
22 , m_inputsToTrigger()
23 , m_timeout(0)
24 , m_buttonInterval(0)
25 , m_startTime(0)
26 , m_lastInputTime(0)
27{
28}
29
30void InputSequence::cleanup()
31{
32 setEnabled(false);
33 m_timeout = 0;
34 m_buttonInterval = 0;
35 m_startTime = 0;
36 m_lastInputTime = 0;
37 m_lastInputId = Qt3DCore::QNodeId();
38 m_sequences.clear();
39 m_inputsToTrigger.clear();
40}
41
42void InputSequence::setStartTime(qint64 time)
43{
44 m_startTime = time;
45}
46
47void InputSequence::reset()
48{
49 m_startTime = 0;
50 m_lastInputTime = 0;
51 m_inputsToTrigger = m_sequences;
52 m_lastInputId = Qt3DCore::QNodeId();
53}
54
55bool InputSequence::actionTriggered(Qt3DCore::QNodeId input, const qint64 currentTime)
56{
57 if (input != m_inputsToTrigger.first())
58 return false;
59
60 // Save the last input
61 m_lastInputId = input;
62 // Return false if we've spent too much time in between two sequences
63 if ((m_lastInputTime != 0) && ((currentTime - m_lastInputTime) > m_buttonInterval)) {
64 reset();
65 return false;
66 }
67
68 // Update lastInputTime and remove the inputs to trigger from the sequence
69 m_lastInputTime = currentTime;
70 m_inputsToTrigger.removeOne(t: input);
71
72 // If we have no more remaining inputs in the sequences of inputs
73 if (m_inputsToTrigger.isEmpty()) {
74 // All Triggered
75 reset();
76 return true;
77 }
78 return false;
79}
80
81void InputSequence::syncFromFrontEnd(const Qt3DCore::QNode *frontEnd, bool firstTime)
82{
83 AbstractActionInput::syncFromFrontEnd(frontEnd, firstTime);
84 const QInputSequence *node = qobject_cast<const QInputSequence *>(object: frontEnd);
85 if (!node)
86 return;
87
88 m_timeout = milliToNano(milli: node->timeout());
89 m_buttonInterval = milliToNano(milli: node->buttonInterval());
90 m_sequences = Qt3DCore::qIdsForNodes(nodes: node->sequences());
91 m_inputsToTrigger = m_sequences;
92}
93
94bool InputSequence::process(InputHandler *inputHandler, qint64 currentTime)
95{
96 if (!isEnabled())
97 return false;
98
99 if (m_startTime != 0) {
100 // Check if we are still inside the time limit for the sequence
101 if ((currentTime - m_startTime) > m_timeout) {
102 reset();
103 return false;
104 }
105 }
106
107 bool triggered = false;
108 for (const Qt3DCore::QNodeId &actionInputId : std::as_const(t&: m_sequences)) {
109 AbstractActionInput *actionInput = inputHandler->lookupActionInput(id: actionInputId);
110 if (actionInput && actionInput->process(inputHandler, currentTime)) {
111 triggered |= actionTriggered(input: actionInputId, currentTime);
112 if (m_startTime == 0)
113 m_startTime = currentTime;
114 }
115 }
116 return triggered;
117}
118
119} // namespace Input
120
121} // namespace Qt3DInput
122
123QT_END_NAMESPACE
124
125

source code of qt3d/src/input/backend/inputsequence.cpp