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 <QVariant>
#include <math.h>
static const char kSettingsGroup[] = "Progress";
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);
}
/*!
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)
{
m_instance->doSetApplicationLabel(text);
@@ -747,3 +767,35 @@ void ProgressManager::cancelTasks(const Id type)
if (m_instance)
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,
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);
public slots:

View File

@@ -38,6 +38,7 @@
#include <QHBoxLayout>
#include <QPointer>
#include <QPropertyAnimation>
#include <QTimer>
#include <QToolButton>
namespace Core {
@@ -125,6 +126,24 @@ public:
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 Core

View File

@@ -48,11 +48,8 @@ CallgrindRunControl::CallgrindRunControl(const AnalyzerStartParameters &sp,
, m_markAsPaused(false)
{
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, SIGNAL(statusMessage(QString)), SLOT(showStatusMessage(QString)));
m_progress->setProgressRange(0, 2);
}
void CallgrindRunControl::showStatusMessage(const QString &msg)
@@ -157,8 +154,3 @@ void CallgrindRunControl::slotFinished()
{
emit parserDataReady(this);
}
void CallgrindRunControl::slotStarted()
{
m_progress->setProgressValue(1);
}

View File

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

View File

@@ -57,10 +57,6 @@ MemcheckRunControl::MemcheckRunControl(const AnalyzerStartParameters &sp,
SIGNAL(suppressionCount(QString,qint64)));
connect(&m_parser, SIGNAL(internalError(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
@@ -132,10 +128,5 @@ QStringList MemcheckRunControl::suppressionFiles() const
return m_settings->suppressionFiles();
}
void MemcheckRunControl::status(const Status &status)
{
m_progress->setProgressValue(status.state() + 1);
}
} // namespace Internal
} // namespace Valgrind

View File

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

View File

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