monnzz
11th December 2016, 15:44
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));
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()
{
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);
}
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;
}
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;
}
So any help would be much appreciated, including any thoughts how the simultaneous effect could be achieved without addittional threads.
(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));
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()
{
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);
}
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;
}
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;
}
So any help would be much appreciated, including any thoughts how the simultaneous effect could be achieved without addittional threads.