7#include <QtQuick/qsgnode.h>
9#include <QQmlComponent>
15
16
17
18
19
20
21
25
26
27
28
29
32
33
34
35
36
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
65
66
67
68
69
70
73
74
75
76
77
78
79
80
82
83
84
85
86
87
88
89
90
91
93QQuickItemParticle::QQuickItemParticle(QQuickItem *parent) :
94 QQuickParticlePainter(parent), m_fade(
true), m_lastT(0), m_activeCount(0), m_delegate(
nullptr)
96 setFlag(QQuickItem::ItemHasContents);
97 clock =
new Clock(
this);
98 connect(
this, &QQuickItemParticle::systemChanged,
this, &QQuickItemParticle::reconnectSystem);
99 connect(
this, &QQuickItemParticle::parentChanged,
this, &QQuickItemParticle::reconnectParent);
100 connect(
this, &QQuickItemParticle::enabledChanged,
this, &QQuickItemParticle::updateClock);
101 reconnectSystem(m_system);
102 reconnectParent(parent);
105QQuickItemParticle::~QQuickItemParticle()
108 qDeleteAll(m_managed);
111void QQuickItemParticle::freeze(QQuickItem* item)
117void QQuickItemParticle::unfreeze(QQuickItem* item)
119 m_stasis.remove(item);
122void QQuickItemParticle::take(QQuickItem *item,
bool prioritize)
125 m_pendingItems.push_front(item);
127 m_pendingItems.push_back(item);
130void QQuickItemParticle::give(QQuickItem *item)
132 for (
auto groupId : groupIds()) {
133 for (QQuickParticleData* data : std::as_const(m_system->groupData[groupId]->data)) {
134 if (data->delegate == item){
135 m_deletables << item;
136 data->delegate =
nullptr;
137 m_system->groupData[groupId]->kill(data);
144void QQuickItemParticle::initialize(
int gIdx,
int pIdx)
150void QQuickItemParticle::commit(
int,
int)
154void QQuickItemParticle::processDeletables()
156 foreach (QQuickItem* item, m_deletables){
158 item->setOpacity(0.);
159 item->setVisible(
false);
160 QQuickItemParticleAttached* mpa;
161 if ((mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(item)))) {
162 if (mpa->m_parentItem !=
nullptr)
163 item->setParentItem(mpa->m_parentItem);
167 if ((idx = m_managed.indexOf(item)) != -1) {
168 m_managed.takeAt(idx);
173 m_deletables.clear();
176void QQuickItemParticle::tick(
int time)
180 for (
auto groupId : groupIds()) {
181 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
182 if (!d->delegate && d->t != -1 && d->stillAlive(m_system)) {
183 QQuickItem* parentItem =
nullptr;
184 if (!m_pendingItems.isEmpty()){
185 QQuickItem *item = m_pendingItems.front();
186 m_pendingItems.pop_front();
187 parentItem = item->parentItem();
189 }
else if (m_delegate){
190 d->delegate = qobject_cast<QQuickItem*>(m_delegate->create(qmlContext(
this)));
192 m_managed << d->delegate;
194 if (d && d->delegate){
195 d->delegate->setX(d->curX(m_system) - d->delegate->width() / 2);
196 d->delegate->setY(d->curY(m_system) - d->delegate->height() / 2);
197 QQuickItemParticleAttached* mpa = qobject_cast<QQuickItemParticleAttached*>(qmlAttachedPropertiesObject<QQuickItemParticle>(d->delegate));
199 mpa->m_parentItem = parentItem;
203 d->delegate->setParentItem(
this);
205 d->delegate->setOpacity(0.);
206 d->delegate->setVisible(
false);
214void QQuickItemParticle::reset()
216 QQuickParticlePainter::reset();
220 QSet<QQuickItem*> lost = QSet<QQuickItem*>(m_managed.cbegin(), m_managed.cend());
221 for (
auto groupId : groupIds()) {
222 for (QQuickParticleData* d : std::as_const(m_system->groupData[groupId]->data)) {
223 lost.remove(d->delegate);
226 m_deletables.unite(lost);
232QSGNode* QQuickItemParticle::updatePaintNode(QSGNode* n, UpdatePaintNodeData* d)
236 m_pleaseReset =
false;
238 if (clockShouldUpdate()) {
243 n->markDirty(QSGNode::DirtyMaterial);
244 return QQuickItem::updatePaintNode(n,d);
247void QQuickItemParticle::prepareNextFrame()
251 qint64 timeStamp = m_system->systemSync(
this);
252 qreal curT = timeStamp/1000.0;
253 qreal dt = curT - m_lastT;
259 for (
auto groupId : groupIds()) {
260 for (QQuickParticleData* data : std::as_const(m_system->groupData[groupId]->data)) {
261 QQuickItem* item = data->delegate;
264 float t = ((timeStamp / 1000.0f) - data->t) / data->lifeSpan;
265 if (m_stasis.contains(item)) {
270 m_deletables << item;
271 data->delegate =
nullptr;
273 data->delegate->setVisible(
true);
283 item->setX(data->curX(m_system) - item->width() / 2 - m_systemOffset.x());
284 item->setY(data->curY(m_system) - item->height() / 2 - m_systemOffset.y());
289QQuickItemParticleAttached *QQuickItemParticle::qmlAttachedProperties(QObject *object)
291 return new QQuickItemParticleAttached(object);
294bool QQuickItemParticle::clockShouldUpdate()
const
296 QQuickItem *parentItem = qobject_cast<QQuickItem *>(parent());
297 return (m_system && m_system->isRunning() && !m_system->isPaused() && m_system->isEnabled()
298 && ((parentItem && parentItem->isEnabled()) || !parentItem) && isEnabled());
301void QQuickItemParticle::reconnectParent(QQuickItem *parentItem)
304 disconnect(m_parentEnabledStateConnection);
306 m_parentEnabledStateConnection = connect(parentItem, &QQuickParticleSystem::enabledChanged,
307 this, &QQuickItemParticle::updateClock);
311void QQuickItemParticle::reconnectSystem(QQuickParticleSystem *system)
314 disconnect(m_systemRunStateConnection);
315 disconnect(m_systemPauseStateConnection);
316 disconnect(m_systemEnabledStateConnection);
318 m_systemRunStateConnection = connect(m_system, &QQuickParticleSystem::runningChanged,
this, [
this](){
319 QQuickItemParticle::updateClock();
321 m_systemPauseStateConnection = connect(m_system, &QQuickParticleSystem::pausedChanged,
this, [
this](){
322 QQuickItemParticle::updateClock();
324 m_systemEnabledStateConnection = connect(m_system, &QQuickParticleSystem::enabledChanged,
this,
325 &QQuickItemParticle::updateClock);
329void QQuickItemParticle::updateClock()
331 if (clockShouldUpdate()) {
332 if (!clock->isRunning())
335 if (clock->isRunning())
342#include "moc_qquickitemparticle_p.cpp"