1/****************************************************************************
2**
3** Copyright (C) 2015 Klaralvdalens Datakonsult AB (KDAB).
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the Qt3D module of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29#include <QtTest/QTest>
30#include <Qt3DCore/qskeleton.h>
31#include <Qt3DCore/private/qskeleton_p.h>
32#include <Qt3DCore/qjoint.h>
33
34#include <Qt3DCore/private/qnode_p.h>
35#include <Qt3DCore/private/qscene_p.h>
36#include <Qt3DCore/private/qnodecreatedchangegenerator_p.h>
37
38#include <QSignalSpy>
39#include <testpostmanarbiter.h>
40
41using namespace Qt3DCore;
42
43class tst_QSkeleton: public QSkeleton
44{
45 Q_OBJECT
46public:
47 tst_QSkeleton()
48 {
49 qRegisterMetaType<Qt3DCore::QJoint*>();
50 }
51
52private Q_SLOTS:
53 void checkDefaultConstruction()
54 {
55 // GIVEN
56 QSkeleton skeleton;
57
58 // THEN
59 QCOMPARE(skeleton.jointCount(), 0);
60 }
61
62 void checkCreationChange_data()
63 {
64 QTest::addColumn<QSkeleton *>(name: "skeleton");
65
66 QSkeleton *defaultConstructed = new QSkeleton();
67 QTest::newRow(dataTag: "defaultConstructed") << defaultConstructed;
68
69 QSkeleton *skeletonWithOneJoint = new QSkeleton();
70 skeletonWithOneJoint->setRootJoint(new QJoint());
71 QTest::newRow(dataTag: "skeletonWithOneJoint") << skeletonWithOneJoint;
72 }
73
74 void checkCreationChange()
75 {
76 // GIVEN
77 QFETCH(QSkeleton *, skeleton);
78
79 // WHEN
80 QNodeCreatedChangeGenerator creationChangeGenerator(skeleton);
81 QVector<QNodeCreatedChangeBasePtr> creationChanges = creationChangeGenerator.creationChanges();
82
83 const int jointCount = skeleton->rootJoint() ? 1 : 0;
84
85 // THEN
86 QCOMPARE(creationChanges.size(), 1 + jointCount);
87
88 const auto creationChangeData = qSharedPointerCast<QNodeCreatedChange<QSkeletonData>>(src: creationChanges.first());
89 const QSkeletonData &data = creationChangeData->data;
90
91 // THEN
92 QCOMPARE(skeleton->id(), creationChangeData->subjectId());
93 QCOMPARE(skeleton->isEnabled(), creationChangeData->isNodeEnabled());
94 QCOMPARE(skeleton->metaObject(), creationChangeData->metaObject());
95 if (skeleton->rootJoint()) {
96 QCOMPARE(skeleton->rootJoint()->id(), data.rootJointId);
97 }
98 }
99
100 void checkPropertyUpdates()
101 {
102 // GIVEN
103 TestArbiter arbiter;
104 QScopedPointer<QSkeleton> skeleton(new QSkeleton());
105 arbiter.setArbiterOnNode(skeleton.data());
106
107 // WHEN
108 QJoint *joint = new QJoint(skeleton.data());
109 arbiter.dirtyNodes.clear();
110
111 skeleton->setRootJoint(joint);
112
113 // THEN
114 QCOMPARE(arbiter.dirtyNodes.size(), 1);
115 QCOMPARE(arbiter.dirtyNodes.front(), skeleton.data());
116
117 arbiter.dirtyNodes.clear();
118
119 // WHEN
120 skeleton->setRootJoint(nullptr);
121
122 // THEN
123 QCOMPARE(arbiter.dirtyNodes.size(), 1);
124 QCOMPARE(arbiter.dirtyNodes.front(), skeleton.data());
125
126 arbiter.dirtyNodes.clear();
127 }
128
129 void checkRootJointBookkeeping()
130 {
131 // GIVEN
132 QScopedPointer<QSkeleton> skeleton(new QSkeleton);
133 {
134 // WHEN
135 QJoint joint;
136 skeleton->setRootJoint(&joint);
137
138 // THEN
139 QCOMPARE(joint.parent(), skeleton.data());
140 QCOMPARE(skeleton->rootJoint(), &joint);
141 }
142 // THEN (Should not crash and parameter be unset)
143 QVERIFY(skeleton->rootJoint() == nullptr);
144
145 {
146 // WHEN
147 QSkeleton someOtherSkeleton;
148 QScopedPointer<QJoint> joint(new QJoint(&someOtherSkeleton));
149 skeleton->setRootJoint(joint.data());
150
151 // THEN
152 QCOMPARE(joint->parent(), &someOtherSkeleton);
153 QCOMPARE(skeleton->rootJoint(), joint.data());
154
155 // WHEN
156 skeleton.reset();
157 joint.reset();
158
159 // THEN Should not crash when the joint is destroyed (tests for failed removal of destruction helper)
160 }
161 }
162};
163
164QTEST_MAIN(tst_QSkeleton)
165
166#include "tst_qskeleton.moc"
167

source code of qt3d/tests/auto/core/qskeleton/tst_qskeleton.cpp