Backport the isValid() method along with 957813 and 957814

CCBUG: 188940

svn path=/branches/KDE/4.2/kdelibs/; revision=957816
This commit is contained in:
Jacopo De Simoi 2009-04-22 22:58:40 +00:00
parent 259e98fdfc
commit bfec24062b
3 changed files with 55 additions and 16 deletions

View File

@ -110,6 +110,11 @@ class RunnerContextPrivate : public QSharedData
}
}
void invalidate()
{
q = &s_dummyContext;
}
QReadWriteLock lock;
QList<QueryMatch> matches;
QMap<QString, const QueryMatch*> matchesById;
@ -117,8 +122,11 @@ class RunnerContextPrivate : public QSharedData
QString mimeType;
RunnerContext::Type type;
RunnerContext * q;
static RunnerContext s_dummyContext;
};
RunnerContext RunnerContextPrivate::s_dummyContext;
RunnerContext::RunnerContext(QObject *parent)
: QObject(parent),
d(new RunnerContextPrivate(this))
@ -143,14 +151,17 @@ void RunnerContext::reset()
// We will detach if we are a copy of someone. But we will reset
// if we are the 'main' context others copied from. Resetting
// one RunnerContext makes all the copies obsolete.
d->q = 0; //we need to mark the q pointer of the detached RunnerContextPrivate
//as dirty on detach to avoid receiving results for old queries
// We need to invalidate the RunnerContextPrivate before detaching
// to avoid receiving results for old queries.
d->invalidate();
d.detach();
d->q = this; //now that we detached the d pointer we need to mark its q pointer as
//this to receive the signals
// Now that we detached the d pointer we need to reset its q pointer
d->q = this;
// we still have to remove all the matches, since if the
// ref count was 1 (e.g. only the RunnerContext is using
@ -197,11 +208,18 @@ QString RunnerContext::mimeType() const
return d->mimeType;
}
bool RunnerContext::isValid()
{
// if our qptr is dirty, we aren't useful anymore
return (d->q != &(d->s_dummyContext));
}
bool RunnerContext::addMatches(const QString &term, const QList<QueryMatch> &matches)
{
Q_UNUSED(term)
if (matches.isEmpty() || (!d->q)) { //Bail out if the query is empty or the qptr is dirty
if (matches.isEmpty() || (!isValid())) {
//Bail out if the query is empty or the qptr is dirty
return false;
}
@ -221,7 +239,7 @@ bool RunnerContext::addMatches(const QString &term, const QList<QueryMatch> &mat
// we always want to sent the signal of the object that created
// the d pointer
emit d->q->matchesChanged();
return true;
}
@ -229,17 +247,18 @@ bool RunnerContext::addMatch(const QString &term, const QueryMatch &match)
{
Q_UNUSED(term)
if (!d->q) { // Bail out if the qptr is dirty
if (!isValid()) {
// Bail out if the qptr is dirty
return false;
}
LOCK_FOR_WRITE(this)
d->matches.append(match);
d->matchesById.insert(match.id(), &d->matches.at(d->matches.size() - 1));
UNLOCK(this);
//kDebug()<< "added match" << match->text();
emit d->q->matchesChanged();
emit d->q->matchesChanged();
return true;
}

View File

@ -102,6 +102,26 @@ class PLASMA_EXPORT RunnerContext : public QObject
*/
QString mimeType() const;
/**
* @returns true if this context is no longer valid and therefore
* matching using it should abort. Most useful as an optimization technique
* inside of AbstractRunner subclasses in the match method, e.g.:
*
* while (.. a possibly large iteration) {
* if (!context.isValid()) {
* return;
* }
*
* ... some processing ...
* }
*
* While not required to be used within runners, it provies a nice way
* to avoid unecessary processing in runners that may run for an extended
* period (as measured in 10s of ms) and therefore improve the user experience. @since 4.2.3
*/
bool isValid();
/**
* Appends lists of matches to the list of matches.
*

View File

@ -161,7 +161,7 @@ void FindMatchesJob::run()
{
// kDebug() << "Running match for " << m_runner->objectName()
// << " in Thread " << thread()->id() << endl;
m_runner->performMatch(m_context);
if (m_context.isValid()) m_runner->performMatch(m_context);
}
int FindMatchesJob::priority() const
@ -349,7 +349,7 @@ public:
if (deferredRun.isEnabled() && runJob->runner() == deferredRun.runner()) {
//kDebug() << "job actually done, running now **************";
QueryMatch tmpRun = deferredRun;
deferredRun = QueryMatch(0);
deferredRun = QueryMatch(0);
tmpRun.run(context);
}
@ -484,7 +484,7 @@ void RunnerManager::launchQuery(const QString &term)
void RunnerManager::launchQuery(const QString &untrimmedTerm, const QString &runnerName)
{
QString term = untrimmedTerm.trimmed();
if (d->runners.isEmpty()) {
d->loadRunners();
}
@ -534,7 +534,7 @@ bool RunnerManager::execQuery(const QString &term)
bool RunnerManager::execQuery(const QString &untrimmedTerm, const QString &runnerName)
{
QString term = untrimmedTerm.trimmed();
if (d->runners.isEmpty()) {
d->loadRunners();
}