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 | |
41 | using namespace Qt3DCore; |
42 | |
43 | class tst_QSkeleton: public QSkeleton |
44 | { |
45 | Q_OBJECT |
46 | public: |
47 | tst_QSkeleton() |
48 | { |
49 | qRegisterMetaType<Qt3DCore::QJoint*>(); |
50 | } |
51 | |
52 | private 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 | |
164 | QTEST_MAIN(tst_QSkeleton) |
165 | |
166 | #include "tst_qskeleton.moc" |
167 | |