Hallo, I have the following question, I'm trying to do the next thing, when a player kills 2 enemies they should die simultaneously with simple animation
(a few pics change over time). So in order to achieve this parallelism I create a number of threads equal to the number of enemies to be killed
(e.g. 2 enemies to be killed = 2 threads to be created)
below the code of creating threads, it works just fine:
std::vector<QFuture<void>> threadResults;
for(int i = 0; i < blantsToKill.size(); ++i) {
threadResults.push_back(QtConcurrent::run(this, &GameManager::killBlant, std::ref(blantsToKill[i])));
}
std::for_each(threadResults.begin(), threadResults.end(), std::bind(&QFuture<void>::waitForFinished, std::placeholders::_1));
std::vector<QFuture<void>> threadResults;
for(int i = 0; i < blantsToKill.size(); ++i) {
threadResults.push_back(QtConcurrent::run(this, &GameManager::killBlant, std::ref(blantsToKill[i])));
}
std::for_each(threadResults.begin(), threadResults.end(), std::bind(&QFuture<void>::waitForFinished, std::placeholders::_1));
To copy to clipboard, switch view to plain text mode
But here the problem appears, the function is called, and slots called as well, however i get the following message "QObject::startTimer: Timers cannot be started from another thread" and pictures for my QGraphicsPixmapItem are not updated.
I tried Qt::QueuedConnection and it didn't help a bit.
void Blant::die()
{
timeLine->setUpdateInterval(100);
timeLine->setDuration(400);
connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animateDying(qreal)), Qt::DirectConnection);
connect(timeLine, SIGNAL(finished()), this, SLOT(finishDying()), Qt::DirectConnection);
timeLine->start();
// so the function wouldn't return before animation finished.
delay(400 + 100 * 2);
}
void Blant::die()
{
QTimeLine* timeLine = new QTimeLine(m_animationMoveTime);
timeLine->setUpdateInterval(100);
timeLine->setDuration(400);
connect(timeLine, SIGNAL(valueChanged(qreal)), this, SLOT(animateDying(qreal)), Qt::DirectConnection);
connect(timeLine, SIGNAL(finished()), this, SLOT(finishDying()), Qt::DirectConnection);
timeLine->start();
// so the function wouldn't return before animation finished.
delay(400 + 100 * 2);
}
To copy to clipboard, switch view to plain text mode
I guess, it's important to note, that if I don't use threads my code works fine, but without parallel execution the enemies killed subsequently.
Also except TimeLine created in this function, at this particular moment no other timers work.
I thought problem could be with delay, however after substituting it with a code (just to check how it works without delay) like this:
volatile long i = 0;
while(i < 10000000000) {
++i;
}
volatile long i = 0;
while(i < 10000000000) {
++i;
}
To copy to clipboard, switch view to plain text mode
it's still the same problem.
this is slot animateDying, finishDying is mostly the same.
void Blant::animateDying(qreal)
{
qDebug() << "ololo" << m_nextFrame;
setPixmap((m_blantsPictures[m_blantColor].dyings[m_nextFrame++]));
if(m_nextFrame == m_blantsPictures[m_blantColor].dyings.size() - 1)
m_nextFrame = 0;
}
void Blant::animateDying(qreal)
{
qDebug() << "ololo" << m_nextFrame;
setPixmap((m_blantsPictures[m_blantColor].dyings[m_nextFrame++]));
if(m_nextFrame == m_blantsPictures[m_blantColor].dyings.size() - 1)
m_nextFrame = 0;
}
To copy to clipboard, switch view to plain text mode
So any help would be much appreciated, including any thoughts how the simultaneous effect could be achieved without addittional threads.
Bookmarks