Load frames as they're needed instead of loading everything at once, and cache them for optimization. The cache is cleared when a new animation is played.

Resolve an issue where if a preanim transitions into (a)idle it would get stuck on the first frame of that (removed the ticker->stop();)
This commit is contained in:
Crystalwarrior 2019-09-15 02:14:40 +03:00
parent 938f1aeea1
commit 37d192b430
2 changed files with 35 additions and 17 deletions

View File

@ -42,6 +42,7 @@ private:
QTimer *preanim_timer; QTimer *preanim_timer;
QTimer *ticker; QTimer *ticker;
QString last_path; QString last_path;
QImageReader *m_reader = new QImageReader();
QElapsedTimer actual_time; QElapsedTimer actual_time;
const int time_mod = 60; const int time_mod = 60;
@ -51,6 +52,7 @@ private:
int y = 0; int y = 0;
int frame = 0; int frame = 0;
int max_frames = 0;
bool m_flipped = false; bool m_flipped = false;
bool play_once = true; bool play_once = true;

View File

@ -21,7 +21,9 @@ AOCharMovie::AOCharMovie(QWidget *p_parent, AOApplication *p_ao_app) : QLabel(p_
void AOCharMovie::play(QString p_char, QString p_emote, QString emote_prefix) void AOCharMovie::play(QString p_char, QString p_emote, QString emote_prefix)
{ {
#ifdef DEBUG_CHARMOVIE
actual_time.restart(); actual_time.restart();
#endif
QString emote_path; QString emote_path;
QList<QString> pathlist; QList<QString> pathlist;
pathlist = { pathlist = {
@ -42,28 +44,31 @@ void AOCharMovie::play(QString p_char, QString p_emote, QString emote_prefix)
this->clear(); this->clear();
ticker->stop(); ticker->stop();
preanim_timer->stop();
movie_frames.clear(); movie_frames.clear();
movie_delays.clear(); movie_delays.clear();
QImageReader *m_reader = new QImageReader(emote_path); m_reader->setFileName(emote_path);
QImage f_image = m_reader->read(); QImage f_image = m_reader->read();
while (!f_image.isNull()) int f_delay = m_reader->nextImageDelay();
frame = 0;
max_frames = m_reader->imageCount();
#ifdef DEBUG_CHARMOVIE
qDebug() << max_frames << "Setting image to " << emote_path << "Time taken to process image:" << actual_time.elapsed();
actual_time.restart();
#endif
this->set_frame(movie_frames[frame]);
this->show();
if (max_frames > 1)
{ {
movie_frames.append(this->get_pixmap(f_image)); movie_frames.append(this->get_pixmap(f_image));
movie_delays.append(m_reader->nextImageDelay()); movie_delays.append(f_delay);
f_image = m_reader->read();
}
delete m_reader;
this->show();
qDebug() << "Setting image to " << emote_path << "Time taken to process image:" << actual_time.elapsed();
frame = 0;
actual_time.restart();
this->set_frame(movie_frames[frame]);
if (movie_frames.size() > 0)
ticker->start(movie_delays[frame]); ticker->start(movie_delays[frame]);
}
} }
void AOCharMovie::play_pre(QString p_char, QString p_emote, int duration) void AOCharMovie::play_pre(QString p_char, QString p_emote, int duration)
@ -136,19 +141,30 @@ void AOCharMovie::move(int ax, int ay)
void AOCharMovie::movie_ticker() void AOCharMovie::movie_ticker()
{ {
++frame; ++frame;
if(frame == movie_frames.size()) if(frame == max_frames)
{ {
if(play_once) if(play_once)
{ {
preanim_done(); preanim_done();
ticker->stop();
return; return;
} }
else else
frame = 0; frame = 0;
} }
// qint64 difference = elapsed - movie_delays[frame]; // qint64 difference = elapsed - movie_delays[frame];
if(frame >= movie_frames.size())
{
m_reader->jumpToImage(frame);
movie_frames.resize(frame + 1);
movie_frames[frame] = this->get_pixmap(m_reader->read());
movie_delays.resize(frame + 1);
movie_delays[frame] = m_reader->nextImageDelay();
}
#ifdef DEBUG_CHARMOVIE
qDebug() << frame << movie_delays[frame] << "actual time taken from last frame:" << actual_time.restart(); qDebug() << frame << movie_delays[frame] << "actual time taken from last frame:" << actual_time.restart();
#endif
this->set_frame(movie_frames[frame]); this->set_frame(movie_frames[frame]);
ticker->setInterval(movie_delays[frame]); ticker->setInterval(movie_delays[frame]);
} }