Valgrind: Use generic timed future for uncertain progress

Change-Id: Idb7f1b1e5a0fcd0351d6c30f5a6dadcbec191898
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
This commit is contained in:
hjk
2014-05-05 14:23:37 +02:00
parent 9e457eefc8
commit 5ac261bff2
8 changed files with 74 additions and 33 deletions

View File

@@ -54,6 +54,8 @@
#include <QTimer> #include <QTimer>
#include <QVariant> #include <QVariant>
#include <math.h>
static const char kSettingsGroup[] = "Progress"; static const char kSettingsGroup[] = "Progress";
static const char kDetailsPinned[] = "DetailsPinned"; static const char kDetailsPinned[] = "DetailsPinned";
@@ -737,6 +739,24 @@ FutureProgress *ProgressManager::addTask(const QFuture<void> &future, const QStr
return m_instance->doAddTask(future, title, type, flags); return m_instance->doAddTask(future, title, type, flags);
} }
/*!
Shows a progress indicator for task given by the QFuture given by
the QFutureInterface \a futureInterface.
The progress indicator shows the specified \a title along with the progress bar.
The progress indicator will increase monotonically with time, at \a expectedSeconds
it will reach about 80%, and continue to increase with a decreasingly slower rate.
\sa addTask
*/
FutureProgress *ProgressManager::addTimedTask(QFutureInterface<void> *futureInterface, const QString &title,
Id type, int expectedSeconds, ProgressFlags flags)
{
FutureProgress *fp = m_instance->doAddTask(futureInterface->future(), title, type, flags);
(void) new ProgressTimer(fp, futureInterface, expectedSeconds);
return fp;
}
void ProgressManager::setApplicationLabel(const QString &text) void ProgressManager::setApplicationLabel(const QString &text)
{ {
m_instance->doSetApplicationLabel(text); m_instance->doSetApplicationLabel(text);
@@ -747,3 +767,35 @@ void ProgressManager::cancelTasks(const Id type)
if (m_instance) if (m_instance)
m_instance->doCancelTasks(type); m_instance->doCancelTasks(type);
} }
ProgressTimer::ProgressTimer(QObject *parent,
QFutureInterface<void> *futureInterface,
int expectedSeconds)
: QTimer(parent),
m_futureInterface(futureInterface),
m_expectedTime(expectedSeconds),
m_currentTime(0)
{
m_futureWatcher.setFuture(futureInterface->future());
m_futureInterface->setProgressRange(0, 100);
m_futureInterface->setProgressValue(0);
setInterval(1000); // 1 second
connect(this, SIGNAL(timeout()), this, SLOT(handleTimeout()));
connect(&m_futureWatcher, SIGNAL(started()), this, SLOT(start()));
}
void ProgressTimer::handleTimeout()
{
++m_currentTime;
// This maps expectation to atan(1) to Pi/4 ~= 0.78, i.e. snaps
// from 78% to 100% when expectations are met at the time the
// future finishes. That's not bad for a random choice.
const double mapped = atan2(m_currentTime, m_expectedTime);
const double progress = 100 * 2 * mapped / 3.14;
m_futureInterface->setProgressValue(int(progress));
}

View File

@@ -55,6 +55,8 @@ public:
static FutureProgress *addTask(const QFuture<void> &future, const QString &title, static FutureProgress *addTask(const QFuture<void> &future, const QString &title,
Core::Id type, ProgressFlags flags = 0); Core::Id type, ProgressFlags flags = 0);
static FutureProgress *addTimedTask(QFutureInterface<void> *fi, const QString &title,
Core::Id type, int expectedSeconds, ProgressFlags flags = 0);
static void setApplicationLabel(const QString &text); static void setApplicationLabel(const QString &text);
public slots: public slots:

View File

@@ -38,6 +38,7 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QPointer> #include <QPointer>
#include <QPropertyAnimation> #include <QPropertyAnimation>
#include <QTimer>
#include <QToolButton> #include <QToolButton>
namespace Core { namespace Core {
@@ -125,6 +126,24 @@ public:
void paintEvent(QPaintEvent *event); void paintEvent(QPaintEvent *event);
}; };
class ProgressTimer : public QTimer
{
Q_OBJECT
public:
ProgressTimer(QObject *parent, QFutureInterface<void> *futureInterface, int expectedSeconds);
private slots:
void handleTimeout();
private:
QFutureInterface<void> *m_futureInterface;
QFutureWatcher<void> m_futureWatcher;
int m_expectedTime;
int m_currentTime;
};
} // namespace Internal } // namespace Internal
} // namespace Core } // namespace Core

View File

@@ -48,11 +48,8 @@ CallgrindRunControl::CallgrindRunControl(const AnalyzerStartParameters &sp,
, m_markAsPaused(false) , m_markAsPaused(false)
{ {
connect(&m_runner, SIGNAL(finished()), this, SLOT(slotFinished())); connect(&m_runner, SIGNAL(finished()), this, SLOT(slotFinished()));
connect(&m_runner, SIGNAL(started()), this, SLOT(slotStarted()));
connect(m_runner.parser(), SIGNAL(parserDataReady()), this, SLOT(slotFinished())); connect(m_runner.parser(), SIGNAL(parserDataReady()), this, SLOT(slotFinished()));
connect(&m_runner, SIGNAL(statusMessage(QString)), SLOT(showStatusMessage(QString))); connect(&m_runner, SIGNAL(statusMessage(QString)), SLOT(showStatusMessage(QString)));
m_progress->setProgressRange(0, 2);
} }
void CallgrindRunControl::showStatusMessage(const QString &msg) void CallgrindRunControl::showStatusMessage(const QString &msg)
@@ -157,8 +154,3 @@ void CallgrindRunControl::slotFinished()
{ {
emit parserDataReady(this); emit parserDataReady(this);
} }
void CallgrindRunControl::slotStarted()
{
m_progress->setProgressValue(1);
}

View File

@@ -75,7 +75,6 @@ signals:
private slots: private slots:
void slotFinished(); void slotFinished();
void slotStarted();
void showStatusMessage(const QString &msg); void showStatusMessage(const QString &msg);
private: private:

View File

@@ -57,10 +57,6 @@ MemcheckRunControl::MemcheckRunControl(const AnalyzerStartParameters &sp,
SIGNAL(suppressionCount(QString,qint64))); SIGNAL(suppressionCount(QString,qint64)));
connect(&m_parser, SIGNAL(internalError(QString)), connect(&m_parser, SIGNAL(internalError(QString)),
SIGNAL(internalParserError(QString))); SIGNAL(internalParserError(QString)));
connect(&m_parser, SIGNAL(status(Valgrind::XmlProtocol::Status)),
SLOT(status(Valgrind::XmlProtocol::Status)));
m_progress->setProgressRange(0, XmlProtocol::Status::Finished + 1);
} }
QString MemcheckRunControl::progressTitle() const QString MemcheckRunControl::progressTitle() const
@@ -132,10 +128,5 @@ QStringList MemcheckRunControl::suppressionFiles() const
return m_settings->suppressionFiles(); return m_settings->suppressionFiles();
} }
void MemcheckRunControl::status(const Status &status)
{
m_progress->setProgressValue(status.state() + 1);
}
} // namespace Internal } // namespace Internal
} // namespace Valgrind } // namespace Valgrind

View File

@@ -62,9 +62,6 @@ protected:
virtual QStringList toolArguments() const; virtual QStringList toolArguments() const;
virtual ValgrindRunner *runner(); virtual ValgrindRunner *runner();
private slots:
void status(const Valgrind::XmlProtocol::Status &status);
private: private:
XmlProtocol::ThreadedParser m_parser; XmlProtocol::ThreadedParser m_parser;
Memcheck::MemcheckRunner m_runner; Memcheck::MemcheckRunner m_runner;

View File

@@ -53,8 +53,6 @@ using namespace ProjectExplorer;
namespace Valgrind { namespace Valgrind {
namespace Internal { namespace Internal {
const int progressMaximum = 1000000;
ValgrindRunControl::ValgrindRunControl(const AnalyzerStartParameters &sp, ValgrindRunControl::ValgrindRunControl(const AnalyzerStartParameters &sp,
ProjectExplorer::RunConfiguration *runConfiguration) ProjectExplorer::RunConfiguration *runConfiguration)
: AnalyzerRunControl(sp, runConfiguration), : AnalyzerRunControl(sp, runConfiguration),
@@ -80,14 +78,11 @@ bool ValgrindRunControl::startEngine()
{ {
emit starting(this); emit starting(this);
FutureProgress *fp = ProgressManager::addTask(m_progress->future(), FutureProgress *fp = ProgressManager::addTimedTask(m_progress, progressTitle(), "valgrind", 100);
progressTitle(), "valgrind");
fp->setKeepOnFinish(FutureProgress::HideOnFinish); fp->setKeepOnFinish(FutureProgress::HideOnFinish);
connect(fp, SIGNAL(canceled()), this, SLOT(handleProgressCanceled())); connect(fp, SIGNAL(canceled()), this, SLOT(handleProgressCanceled()));
connect(fp, SIGNAL(finished()), this, SLOT(handleProgressFinished())); connect(fp, SIGNAL(finished()), this, SLOT(handleProgressFinished()));
m_progress->setProgressRange(0, progressMaximum);
m_progress->reportStarted(); m_progress->reportStarted();
m_progress->setProgressValue(progressMaximum / 10);
const AnalyzerStartParameters &sp = startParameters(); const AnalyzerStartParameters &sp = startParameters();
#if VALGRIND_DEBUG_OUTPUT #if VALGRIND_DEBUG_OUTPUT
@@ -183,12 +178,6 @@ void ValgrindRunControl::runnerFinished()
void ValgrindRunControl::receiveProcessOutput(const QString &output, OutputFormat format) void ValgrindRunControl::receiveProcessOutput(const QString &output, OutputFormat format)
{ {
int progress = m_progress->progressValue();
if (progress < 5 * progressMaximum / 10)
progress += progress / 100;
else if (progress < 9 * progressMaximum / 10)
progress += progress / 1000;
m_progress->setProgressValue(progress);
appendMessage(output, format); appendMessage(output, format);
} }