SIGN IN SIGN UP

QQuick3DParticleSystem: fix quadratic behavior in the dtor

For each of the four member containers, the respective loop over
setSystem(nullptr) will modify them, since setSystem() will attempt to
unregister from the QQuick3DParticleSystem, which then performs a
removeAll() on said member container.

The code recognized this, and took copies to iterate over, so as to
avoid running off the end of the container while it's being modified
by the body of the loop. So far so good.

Observe, however, that we iterate each container _forward_. That means
that each setSystem() call will erase the first element of the
container and move all others one step to the front. Yes, QList has a
prepend buffer, but no, that isn't increased by this operation. As a
consequence, each loop does the equivalent of

   while (!c.empty())
       c.erase(c.begin());

on a vector, which is obviously quadratic.

To fix, observe that none of the setSystem() calls complains if it
doesn't find 'this' in the system. So we can just move the contents of
these variables out of the way, and the removeAll()s performed on the
member containers by each setSystem() call will be no-ops.

This also prevents the guaranteed detach that happened in the old code
by taking a copy and modifying the container, so it's a win even if
removeAll() should ever be changed to recognize a remove at the begin
and increase the prepend buffer instead of moving elements (which is
unlikely at this point, seeing as users will by now have come to
depend on the stability of data()/begin() under a removeAll()).

Amends 4838a84935cd9f2a4d74cdbf737b9c3da11aabfa (picked to 6.1).

Pick-to: 6.12 6.11 6.8
Change-Id: I3f25a0a2fdaef7cec47273dc447d59dfbe441336
Reviewed-by: Christian Strømme <christian.stromme@qt.io>
M
Marc Mutz committed
5d75c5eadaa7fc60bb0965b8c3276e4a69615dc2
Parent: a1781ec