Qt
Internal/Contributor docs for the Qt SDK. <b>Note:</b> These are NOT official API docs; those are found <a href='https://doc.qt.io/'>here</a>.
Loading...
Searching...
No Matches
qquickitemparticle.cpp
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
4#undef QT_NO_FOREACH // this file contains unported legacy Q_FOREACH uses
5
7#include <QtQuick/qsgnode.h>
8#include <QTimer>
9#include <QQmlComponent>
10#include <QDebug>
11
13
95 QQuickParticlePainter(parent), m_fade(true), m_lastT(0), m_activeCount(0), m_delegate(nullptr)
96{
98 clock = new Clock(this);
99 connect(this, &QQuickItemParticle::systemChanged, this, &QQuickItemParticle::reconnectSystem);
100 connect(this, &QQuickItemParticle::parentChanged, this, &QQuickItemParticle::reconnectParent);
101 connect(this, &QQuickItemParticle::enabledChanged, this, &QQuickItemParticle::updateClock);
102 reconnectSystem(m_system);
103 reconnectParent(parent);
104}
105
107{
108 delete clock;
109 qDeleteAll(m_managed);
110}
111
113{
114 m_stasis << item;
115}
116
117
122
124{
125 if (prioritize)
126 m_pendingItems.push_front(item);
127 else
128 m_pendingItems.push_back(item);
129}
130
132{
133 for (auto groupId : groupIds()) {
134 for (QQuickParticleData* data : std::as_const(m_system->groupData[groupId]->data)) {
135 if (data->delegate == item){
136 m_deletables << item;
137 data->delegate = nullptr;
138 m_system->groupData[groupId]->kill(data);
139 return;
140 }
141 }
142 }
143}
144
145void QQuickItemParticle::initialize(int gIdx, int pIdx)
146{
147 Q_UNUSED(gIdx);
148 Q_UNUSED(pIdx);
149}
150
152{
153}
154
155void QQuickItemParticle::processDeletables()
156{
157 foreach (QQuickItem* item, m_deletables){
158 if (m_fade)
159 item->setOpacity(0.);
160 item->setVisible(false);
162 if ((mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(item)))) {
163 if (mpa->m_parentItem != nullptr)
164 item->setParentItem(mpa->m_parentItem);
165 mpa->detach();
166 }
167 int idx = -1;
168 if ((idx = m_managed.indexOf(item)) != -1) {
169 m_managed.takeAt(idx);
170 delete item;
171 }
172 m_activeCount--;
173 }
174 m_deletables.clear();
175}
176
177void QQuickItemParticle::tick(int time)
178{
179 Q_UNUSED(time);//only needed because QTickAnimationProxy expects one
180 processDeletables();
181 for (auto groupId : groupIds()) {
182 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
183 if (!d->delegate && d->t != -1 && d->stillAlive(m_system)) {
184 QQuickItem* parentItem = nullptr;
185 if (!m_pendingItems.isEmpty()){
186 QQuickItem *item = m_pendingItems.front();
187 m_pendingItems.pop_front();
189 d->delegate = item;
190 }else if (m_delegate){
191 d->delegate = qobject_cast<QQuickItem*>(m_delegate->create(qmlContext(this)));
192 if (d->delegate)
193 m_managed << d->delegate;
194 }
195 if (d && d->delegate){//###Data can be zero if creating an item leads to a reset - this screws things up.
196 d->delegate->setX(d->curX(m_system) - d->delegate->width() / 2); //TODO: adjust for system?
197 d->delegate->setY(d->curY(m_system) - d->delegate->height() / 2);
198 QQuickItemParticleAttached* mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(d->delegate));
199 if (mpa){
200 mpa->m_parentItem = parentItem;
201 mpa->m_mp = this;
202 mpa->attach();
203 }
204 d->delegate->setParentItem(this);
205 if (m_fade)
206 d->delegate->setOpacity(0.);
207 d->delegate->setVisible(false);//Will be set to true when we prepare the next frame
208 m_activeCount++;
209 }
210 }
211 }
212 }
213}
214
216{
218
219 // delete all managed items which had their logical particles cleared
220 // but leave it alone if the logical particle is maintained
221 QSet<QQuickItem*> lost = QSet<QQuickItem*>(m_managed.cbegin(), m_managed.cend());
222 for (auto groupId : groupIds()) {
223 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
224 lost.remove(d->delegate);
225 }
226 }
227 m_deletables.unite(lost);
228 //TODO: This doesn't yet handle calling detach on taken particles in the system reset case
229 processDeletables();
230}
231
232
234{
235 //Dummy update just to get painting tick
236 if (m_pleaseReset)
237 m_pleaseReset = false;
238
239 if (clockShouldUpdate()) {
241 update(); //Get called again
242 }
243 if (n)
244 n->markDirty(QSGNode::DirtyMaterial);
246}
247
249{
250 if (!m_system)
251 return;
252 qint64 timeStamp = m_system->systemSync(this);
253 qreal curT = timeStamp/1000.0;
254 qreal dt = curT - m_lastT;
255 m_lastT = curT;
256 if (!m_activeCount)
257 return;
258
259 //TODO: Size, better fade?
260 for (auto groupId : groupIds()) {
261 for (QQuickParticleData* data : std::as_const(m_system->groupData[groupId]->data)) {
262 QQuickItem* item = data->delegate;
263 if (!item)
264 continue;
265 float t = ((timeStamp / 1000.0f) - data->t) / data->lifeSpan;
266 if (m_stasis.contains(item)) {
267 data->t += dt;//Stasis effect
268 continue;
269 }
270 if (t >= 1.0f){//Usually happens from load
271 m_deletables << item;
272 data->delegate = nullptr;
273 }else{//Fade
274 data->delegate->setVisible(true);
275 if (m_fade){
276 float o = 1.f;
277 if (t <0.2f)
278 o = t * 5;
279 if (t > 0.8f)
280 o = (1-t)*5;
281 item->setOpacity(o);
282 }
283 }
284 item->setX(data->curX(m_system) - item->width() / 2 - m_systemOffset.x());
285 item->setY(data->curY(m_system) - item->height() / 2 - m_systemOffset.y());
286 }
287 }
288}
289
294
295bool QQuickItemParticle::clockShouldUpdate() const
296{
299 && ((parentItem && parentItem->isEnabled()) || !parentItem) && isEnabled());
300}
301
302void QQuickItemParticle::reconnectParent(QQuickItem *parentItem)
303{
304 updateClock();
305 disconnect(m_parentEnabledStateConnection);
306 if (parentItem) {
307 m_parentEnabledStateConnection = connect(parentItem, &QQuickParticleSystem::enabledChanged,
308 this, &QQuickItemParticle::updateClock);
309 }
310}
311
312void QQuickItemParticle::reconnectSystem(QQuickParticleSystem *system)
313{
314 updateClock();
315 disconnect(m_systemRunStateConnection);
316 disconnect(m_systemPauseStateConnection);
317 disconnect(m_systemEnabledStateConnection);
318 if (system) {
319 m_systemRunStateConnection = connect(m_system, &QQuickParticleSystem::runningChanged, this, [this](){
320 QQuickItemParticle::updateClock();
321 });
322 m_systemPauseStateConnection = connect(m_system, &QQuickParticleSystem::pausedChanged, this, [this](){
323 QQuickItemParticle::updateClock();
324 });
325 m_systemEnabledStateConnection = connect(m_system, &QQuickParticleSystem::enabledChanged, this,
326 &QQuickItemParticle::updateClock);
327 }
328}
329
330void QQuickItemParticle::updateClock()
331{
332 if (clockShouldUpdate()) {
333 if (!clock->isRunning())
334 clock->start();
335 } else {
336 if (clock->isRunning())
337 clock->pause();
338 }
339}
340
342
343#include "moc_qquickitemparticle_p.cpp"
DarwinBluetooth::DeviceInquiryDelegate * m_delegate
void setX(qreal x)
void setOpacity(qreal opacity)
void setParentItem(QGraphicsItem *parent)
Sets this item's parent item to newParent.
QGraphicsItem * parentItem() const
Returns a pointer to this item's parent item.
void setVisible(bool visible)
If visible is true, the item is made visible.
void setY(qreal y)
void push_front(rvalue_ref t)
Definition qlist.h:677
bool isEmpty() const noexcept
Definition qlist.h:401
void push_back(parameter_type t)
Definition qlist.h:675
T takeAt(qsizetype i)
Definition qlist.h:609
reference front()
Definition qlist.h:687
void pop_front() noexcept
Definition qlist.h:680
const_iterator cend() const noexcept
Definition qlist.h:631
const_iterator cbegin() const noexcept
Definition qlist.h:630
\inmodule QtCore
Definition qobject.h:103
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2960
constexpr qreal x() const noexcept
Returns the x coordinate of this point.
Definition qpoint.h:343
constexpr qreal y() const noexcept
Returns the y coordinate of this point.
Definition qpoint.h:348
virtual QObject * create(QQmlContext *context=nullptr)
Create an object instance from this component, within the specified context.
static QQuickItemParticleAttached * qmlAttachedProperties(QObject *object)
void commit(int gIdx, int pIdx) override
void give(QQuickItem *item)
void initialize(int gIdx, int pIdx) override
QQuickItemParticle(QQuickItem *parent=nullptr)
\qmltype ItemParticle \instantiates QQuickItemParticle \inqmlmodule QtQuick.Particles \inherits Parti...
QSGNode * updatePaintNode(QSGNode *, UpdatePaintNodeData *) override
Called on the render thread when it is time to sync the state of the item with the scene graph.
void freeze(QQuickItem *item)
void take(QQuickItem *item, bool prioritize=false)
void unfreeze(QQuickItem *item)
The QQuickItem class provides the most basic of all visual items in \l {Qt Quick}.
Definition qquickitem.h:63
void parentChanged(QQuickItem *)
virtual QSGNode * updatePaintNode(QSGNode *, UpdatePaintNodeData *)
Called on the render thread when it is time to sync the state of the item with the scene graph.
void setFlag(Flag flag, bool enabled=true)
Enables the specified flag for this item if enabled is true; if enabled is false, the flag is disable...
QQuickItem * parentItem() const
QQuickItem * parent
\qmlproperty Item QtQuick::Item::parent This property holds the visual parent of the item.
Definition qquickitem.h:67
void enabledChanged()
bool isEnabled() const
void update()
Schedules a call to updatePaintNode() for this item.
void systemChanged(QQuickParticleSystem *arg)
const GroupIDs & groupIds() const
QQuickParticleSystem * m_system
QQuickParticleSystem * system
void runningChanged(bool arg)
QVarLengthArray< QQuickParticleGroupData *, 32 > groupData
void pausedChanged(bool arg)
int systemSync(QQuickParticlePainter *p)
\group qtquick-scenegraph-nodes \title Qt Quick Scene Graph Node classes
Definition qsgnode.h:37
@ DirtyMaterial
Definition qsgnode.h:75
bool remove(const T &value)
Definition qset.h:63
void clear()
Definition qset.h:61
QSet< T > & unite(const QSet< T > &other)
Definition qset.h:229
bool contains(const T &value) const
Definition qset.h:71
T * data() noexcept
qDeleteAll(list.begin(), list.end())
Combined button and popup list for selecting options.
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
GLfloat n
GLdouble GLdouble t
Definition qopenglext.h:243
QQmlContext * qmlContext(const QObject *obj)
Definition qqml.cpp:75
QQuickItem * qobject_cast< QQuickItem * >(QObject *o)
Definition qquickitem.h:492
#define Q_UNUSED(x)
long long qint64
Definition qtypes.h:60
double qreal
Definition qtypes.h:187
QObject::connect nullptr
myObject disconnect()
[26]
QGraphicsItem * item
qsizetype indexOf(const AT &t, qsizetype from=0) const noexcept
Definition qlist.h:962