1 | /**************************************************************************** |
---|---|
2 | ** |
3 | ** Copyright (C) 2020 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/QtTest> |
30 | #include <Qt3DCore/qaspectjob.h> |
31 | #include <Qt3DCore/qabstractaspect.h> |
32 | #include <Qt3DCore/private/qaspectmanager_p.h> |
33 | #include <Qt3DCore/private/qscheduler_p.h> |
34 | #include <private/qabstractaspect_p.h> |
35 | #include <private/qaspectjob_p.h> |
36 | |
37 | using namespace Qt3DCore; |
38 | |
39 | class JobPrivate : public QAspectJobPrivate |
40 | { |
41 | bool m_postFrameCalled = false; |
42 | |
43 | |
44 | public: |
45 | // QAspectJobPrivate interface |
46 | void postFrame(QAspectManager *aspectManager) |
47 | { |
48 | Q_ASSERT(aspectManager); |
49 | m_postFrameCalled = true; |
50 | } |
51 | |
52 | bool postFrameCalled() const |
53 | { |
54 | return m_postFrameCalled; |
55 | } |
56 | }; |
57 | |
58 | class Job : public QAspectJob |
59 | { |
60 | bool m_wasExecuted = false; |
61 | |
62 | public: |
63 | Job() |
64 | : QAspectJob(*new JobPrivate) |
65 | {} |
66 | |
67 | bool wasExecuted() const |
68 | { |
69 | return m_wasExecuted; |
70 | } |
71 | |
72 | bool postFrameCalled() const |
73 | { |
74 | Q_D(const Job); |
75 | return d->postFrameCalled(); |
76 | } |
77 | |
78 | void run() override |
79 | { |
80 | m_wasExecuted = true; |
81 | } |
82 | |
83 | private: |
84 | Q_DECLARE_PRIVATE(Job) |
85 | }; |
86 | using JobPtr = QSharedPointer<Job>; |
87 | |
88 | class AspectPrivate : public QAbstractAspectPrivate |
89 | { |
90 | bool m_jobsDoneCalled = false; |
91 | bool m_frameDoneCalled = false; |
92 | |
93 | public: |
94 | |
95 | bool jobsDoneCalled() const |
96 | { |
97 | return m_jobsDoneCalled; |
98 | } |
99 | |
100 | bool frameDoneCalled() const |
101 | { |
102 | return m_frameDoneCalled; |
103 | } |
104 | |
105 | // QAspectJobProviderInterface interface |
106 | void jobsDone() override |
107 | { |
108 | m_jobsDoneCalled = true; |
109 | } |
110 | |
111 | void frameDone() override |
112 | { |
113 | m_frameDoneCalled = true; |
114 | } |
115 | }; |
116 | |
117 | class Aspect : public QAbstractAspect |
118 | { |
119 | Q_OBJECT |
120 | |
121 | public: |
122 | Aspect() |
123 | : QAbstractAspect(*new AspectPrivate) |
124 | {} |
125 | |
126 | JobPtr firstJob() const { return m_first; } |
127 | JobPtr secondJob() const { return m_second; } |
128 | |
129 | private: |
130 | // QAbstractAspect interface |
131 | QVector<QAspectJobPtr> jobsToExecute(qint64) |
132 | { |
133 | return { m_first, m_second }; |
134 | } |
135 | |
136 | JobPtr m_first = JobPtr::create(); |
137 | JobPtr m_second = JobPtr::create(); |
138 | Q_DECLARE_PRIVATE(Aspect) |
139 | }; |
140 | |
141 | class tst_QScheduler : public QObject |
142 | { |
143 | Q_OBJECT |
144 | private Q_SLOTS: |
145 | |
146 | void checkInitialState() |
147 | { |
148 | // GIVEN |
149 | QScheduler scheduler; |
150 | |
151 | // THEN |
152 | QVERIFY(scheduler.aspectManager() == nullptr); |
153 | |
154 | // WHEN |
155 | QAspectManager m; |
156 | scheduler.setAspectManager(&m); |
157 | |
158 | // THEN |
159 | QCOMPARE(scheduler.aspectManager(), &m); |
160 | } |
161 | |
162 | void checkScheduleAndWaitForFrameAspectJobs() |
163 | { |
164 | // GIVEN |
165 | QScheduler scheduler; |
166 | QAspectManager manager; |
167 | Aspect aspect; |
168 | AspectPrivate *aspectPriv = static_cast<AspectPrivate *>(QObjectPrivate::get(o: &aspect)); |
169 | |
170 | manager.registerAspect(aspect: &aspect); |
171 | scheduler.setAspectManager(&manager); |
172 | |
173 | // THEN |
174 | const JobPtr first = aspect.firstJob(); |
175 | const JobPtr second = aspect.secondJob(); |
176 | QVERIFY(!aspectPriv->jobsDoneCalled()); |
177 | QVERIFY(!aspectPriv->frameDoneCalled()); |
178 | QVERIFY(!first->wasExecuted()); |
179 | QVERIFY(!second->wasExecuted()); |
180 | QVERIFY(!first->postFrameCalled()); |
181 | QVERIFY(!second->postFrameCalled()); |
182 | |
183 | // WHEN |
184 | const int count = scheduler.scheduleAndWaitForFrameAspectJobs(time: 0, dumpJobs: false); |
185 | |
186 | // THEN |
187 | QCOMPARE(count, 2); |
188 | QVERIFY(first->wasExecuted()); |
189 | QVERIFY(second->wasExecuted()); |
190 | QVERIFY(first->postFrameCalled()); |
191 | QVERIFY(second->postFrameCalled()); |
192 | QVERIFY(aspectPriv->jobsDoneCalled()); |
193 | QVERIFY(!aspectPriv->frameDoneCalled()); |
194 | |
195 | manager.unregisterAspect(aspect: &aspect); |
196 | } |
197 | }; |
198 | |
199 | QTEST_MAIN(tst_QScheduler) |
200 | |
201 | #include "tst_qscheduler.moc" |
202 |