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
37using namespace Qt3DCore;
38
39class JobPrivate : public QAspectJobPrivate
40{
41 bool m_postFrameCalled = false;
42
43
44public:
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
58class Job : public QAspectJob
59{
60 bool m_wasExecuted = false;
61
62public:
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
83private:
84 Q_DECLARE_PRIVATE(Job)
85};
86using JobPtr = QSharedPointer<Job>;
87
88class AspectPrivate : public QAbstractAspectPrivate
89{
90 bool m_jobsDoneCalled = false;
91 bool m_frameDoneCalled = false;
92
93public:
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
117class Aspect : public QAbstractAspect
118{
119 Q_OBJECT
120
121public:
122 Aspect()
123 : QAbstractAspect(*new AspectPrivate)
124 {}
125
126 JobPtr firstJob() const { return m_first; }
127 JobPtr secondJob() const { return m_second; }
128
129private:
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
141class tst_QScheduler : public QObject
142{
143 Q_OBJECT
144private 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
199QTEST_MAIN(tst_QScheduler)
200
201#include "tst_qscheduler.moc"
202

source code of qt3d/tests/auto/core/qscheduler/tst_qscheduler.cpp