Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qquickspriteengine_p.h
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#ifndef QQUICKSPRITEENGINE_P_H
6#define QQUICKSPRITEENGINE_P_H
7
8//
9// W A R N I N G
10// -------------
11//
12// This file is not part of the Qt API. It exists purely as an
13// implementation detail. This header file may change from version to
14// version without notice, or even be removed.
15//
16// We mean it.
17//
18
19#include <private/qtquickglobal_p.h>
20
22
23#include <QObject>
24#include <QVector>
25#include <QTimer>
26#include <QElapsedTimer>
27#include <QList>
28#include <QQmlListProperty>
29#include <QImage>
30#include <QRandomGenerator>
31#include <private/qquickpixmap_p.h>
32#include <private/qtquickglobal_p.h>
33#include <utility>
34
35QT_BEGIN_NAMESPACE
36
37class QQuickSprite;
38class Q_QUICK_EXPORT QQuickStochasticState : public QObject //Currently for internal use only - Sprite and ParticleGroup
39{
40 Q_OBJECT
41 Q_PROPERTY(int duration READ duration WRITE setDuration NOTIFY durationChanged)
42 Q_PROPERTY(int durationVariation READ durationVariation WRITE setDurationVariation NOTIFY durationVariationChanged)
43 //Note that manually advanced sprites need to query this variable and implement own behaviour for it
44 Q_PROPERTY(bool randomStart READ randomStart WRITE setRandomStart NOTIFY randomStartChanged)
45 Q_PROPERTY(QVariantMap to READ to WRITE setTo NOTIFY toChanged)
46 Q_PROPERTY(QString name READ name WRITE setName NOTIFY nameChanged)
47
48public:
49 QQuickStochasticState(QObject* parent = nullptr)
50 : QObject(parent)
51 {
52 }
53
54 int duration() const
55 {
56 return m_duration;
57 }
58
59 QString name() const
60 {
61 return m_name;
62 }
63
64 QVariantMap to() const
65 {
66 return m_to;
67 }
68
69 int durationVariation() const
70 {
71 return m_durationVariation;
72 }
73
74
75 virtual int variedDuration() const
76 {
77 return qMax(0.0 , m_duration
78 + (m_durationVariation * QRandomGenerator::global()->bounded(2.0))
79 - m_durationVariation);
80 }
81
82 bool randomStart() const
83 {
84 return m_randomStart;
85 }
86
87Q_SIGNALS:
88 void durationChanged(int arg);
89
90 void nameChanged(const QString &arg);
91
92 void toChanged(const QVariantMap &arg);
93
94 void durationVariationChanged(int arg);
95
96 void entered();//### Just playing around - don't expect full state API
97
98 void randomStartChanged(bool arg);
99
100public Q_SLOTS:
101 void setDuration(int arg)
102 {
103 if (m_duration != arg) {
104 m_duration = arg;
105 Q_EMIT durationChanged(arg);
106 }
107 }
108
109 void setName(const QString &arg)
110 {
111 if (m_name != arg) {
112 m_name = arg;
113 Q_EMIT nameChanged(arg);
114 }
115 }
116
117 void setTo(const QVariantMap &arg)
118 {
119 if (m_to != arg) {
120 m_to = arg;
121 Q_EMIT toChanged(arg);
122 }
123 }
124
125 void setDurationVariation(int arg)
126 {
127 if (m_durationVariation != arg) {
128 m_durationVariation = arg;
129 Q_EMIT durationVariationChanged(arg);
130 }
131 }
132
133 void setRandomStart(bool arg)
134 {
135 if (m_randomStart != arg) {
136 m_randomStart = arg;
137 Q_EMIT randomStartChanged(arg);
138 }
139 }
140
141private:
142 QString m_name;
143 QVariantMap m_to;
144 int m_duration = -1;
145 int m_durationVariation = 0;
146
147 friend class QQuickStochasticEngine;
148 bool m_randomStart = false;
149};
150
151class Q_QUICK_EXPORT QQuickStochasticEngine : public QObject
152{
153 Q_OBJECT
154 //TODO: Optimize single state case?
155 Q_PROPERTY(QString globalGoal READ globalGoal WRITE setGlobalGoal NOTIFY globalGoalChanged FINAL)
156 Q_PROPERTY(QQmlListProperty<QQuickStochasticState> states READ states FINAL)
157public:
158 explicit QQuickStochasticEngine(QObject *parent = nullptr);
159 QQuickStochasticEngine(const QList<QQuickStochasticState*> &states, QObject *parent = nullptr);
160 ~QQuickStochasticEngine() override;
161
162 QQmlListProperty<QQuickStochasticState> states()
163 {
164 return QQmlListProperty<QQuickStochasticState>(this, &m_states);
165 }
166
167 QString globalGoal() const
168 {
169 return m_globalGoal;
170 }
171
172 int count() const {return m_things.size();}
173 void setCount(int c);
174
175 void setGoal(int state, int sprite=0, bool jump=false);
176 void start(int index=0, int state=0);
177 virtual void restart(int index=0);
178 virtual void advance(int index=0);//Sends state to the next chosen state, unlike goal.
179 void stop(int index=0);
180 int curState(int index=0) const {return m_things[index];}
181
182 QQuickStochasticState* state(int idx) const {return m_states[idx];}
183 int stateIndex(QQuickStochasticState* s) const {return m_states.indexOf(s);}
184 int stateIndex(const QString& s) const {
185 for (int i=0; i<m_states.size(); i++)
186 if (m_states[i]->name() == s)
187 return i;
188 return -1;
189 }
190
191 int stateCount() {return m_states.size();}
192private:
193Q_SIGNALS:
194
195 void globalGoalChanged(const QString &arg);
196 void stateChanged(int idx);
197
198public Q_SLOTS:
199 void setGlobalGoal(const QString &arg)
200 {
201 if (m_globalGoal != arg) {
202 m_globalGoal = arg;
203 Q_EMIT globalGoalChanged(arg);
204 }
205 }
206
207 uint updateSprites(uint time);
208
209protected:
210 friend class QQuickParticleSystem;
211 void addToUpdateList(uint t, int idx);
212 int nextState(int curState, int idx=0);
213 int goalSeek(int curState, int idx, int dist=-1);
214 QList<QQuickStochasticState*> m_states;
215 //### Consider struct or class for the four data variables?
216 QVector<int> m_things;//int is the index in m_states of the current state
217 QVector<int> m_goals;
218 QVector<int> m_duration;
219 QVector<int> m_startTimes;
220 QVector<std::pair<uint, QVector<int> > > m_stateUpdates;//### This could be done faster - priority queue?
221
222 QElapsedTimer m_advanceTimer;
223 uint m_timeOffset;
224 QString m_globalGoal;
225 int m_maxFrames;
226 int m_imageStateCount;
227 bool m_addAdvance;
228};
229
230class Q_QUICK_EXPORT QQuickSpriteEngine : public QQuickStochasticEngine
231{
232 Q_OBJECT
233 Q_PROPERTY(QQmlListProperty<QQuickSprite> sprites READ sprites FINAL)
234public:
235 explicit QQuickSpriteEngine(QObject *parent = nullptr);
236 QQuickSpriteEngine(const QList<QQuickSprite*> &sprites, QObject *parent = nullptr);
237 ~QQuickSpriteEngine() override;
238 QQmlListProperty<QQuickSprite> sprites()
239 {
240 return QQmlListProperty<QQuickSprite>(this, &m_sprites);
241 }
242
243 QQuickSprite* sprite(int sprite = 0) const;
244 int spriteState(int sprite = 0) const;
245 int spriteStart(int sprite = 0) const;
246 int spriteFrames(int sprite = 0) const;
247 int spriteDuration(int sprite = 0) const;
248 int spriteX(int sprite = 0) const;
249 int spriteY(int sprite = 0) const;
250 int spriteWidth(int sprite = 0) const;
251 int spriteHeight(int sprite = 0) const;
252 int spriteCount() const;//Like state count
253 int maxFrames() const;
254
255 void restart(int index=0) override;
256 void advance(int index=0) override;
257
258 //Similar API to QQuickPixmap for async loading convenience
259 bool isNull() const { return status() == QQuickPixmap::Null; }
260 bool isReady() const { return status() == QQuickPixmap::Ready; }
261 bool isLoading() const { return status() == QQuickPixmap::Loading; }
262 bool isError() const { return status() == QQuickPixmap::Error; }
263 QQuickPixmap::Status status() const; //Composed status of all Sprites
264 void startAssemblingImage();
265 QImage assembledImage(int maxSize = 2048);
266
267private:
268 int pseudospriteProgress(int, int, int *rd = nullptr) const;
269 QList<QQuickSprite*> m_sprites;
270 bool m_startedImageAssembly;
271 bool m_loaded;
272 bool m_errorsPrinted;
273};
274
275//Common use is to have your own list property which is transparently an engine
276inline void spriteAppend(QQmlListProperty<QQuickSprite> *p, QQuickSprite* s)
277{
278 reinterpret_cast<QList<QQuickSprite *> *>(p->data)->append(s);
279 p->object->metaObject()->invokeMethod(p->object, "createEngine");
280}
281
282inline QQuickSprite* spriteAt(QQmlListProperty<QQuickSprite> *p, qsizetype idx)
283{
284 return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->at(idx);
285}
286
287inline void spriteClear(QQmlListProperty<QQuickSprite> *p)
288{
289 reinterpret_cast<QList<QQuickSprite *> *>(p->data)->clear();
290 p->object->metaObject()->invokeMethod(p->object, "createEngine");
291}
292
293inline qsizetype spriteCount(QQmlListProperty<QQuickSprite> *p)
294{
295 return reinterpret_cast<QList<QQuickSprite *> *>(p->data)->size();
296}
297
298inline void spriteReplace(QQmlListProperty<QQuickSprite> *p, qsizetype idx, QQuickSprite *s)
299{
300 reinterpret_cast<QList<QQuickSprite *> *>(p->data)->replace(idx, s);
301 p->object->metaObject()->invokeMethod(p->object, "createEngine");
302}
303
304inline void spriteRemoveLast(QQmlListProperty<QQuickSprite> *p)
305{
306 reinterpret_cast<QList<QQuickSprite *> *>(p->data)->removeLast();
307 p->object->metaObject()->invokeMethod(p->object, "createEngine");
308}
309
310QT_END_NAMESPACE
311
312#endif // QQUICKSPRITEENGINE_P_H
QT_REQUIRE_CONFIG(animation)
QT_REQUIRE_CONFIG(quick_sprite)
void spriteReplace(QQmlListProperty< QQuickSprite > *p, qsizetype idx, QQuickSprite *s)
void spriteAppend(QQmlListProperty< QQuickSprite > *p, QQuickSprite *s)
void spriteRemoveLast(QQmlListProperty< QQuickSprite > *p)
qsizetype spriteCount(QQmlListProperty< QQuickSprite > *p)
QQuickSprite * spriteAt(QQmlListProperty< QQuickSprite > *p, qsizetype idx)
void spriteClear(QQmlListProperty< QQuickSprite > *p)