* factor having a runner into QueryMatch::isEnabled

* only run a match when the job is actually done, in case people write runners that don't like to have both match and run entered simultaneously (high likliehood of that happening); lets them write runners with fewer threading concerns

svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=805919
This commit is contained in:
Aaron J. Seigo 2008-05-09 17:19:27 +00:00
parent 09fb90b051
commit c0279bc3e2
3 changed files with 67 additions and 17 deletions

View File

@ -169,7 +169,7 @@ void QueryMatch::setEnabled( bool enabled )
bool QueryMatch::isEnabled() const bool QueryMatch::isEnabled() const
{ {
return d->enabled; return d->enabled && d->runner;
} }
bool QueryMatch::operator<(const QueryMatch& other) const bool QueryMatch::operator<(const QueryMatch& other) const
@ -190,7 +190,6 @@ void QueryMatch::run(const RunnerContext &context) const
{ {
//kDebug() << "we run the term" << context->query() << "whose type is" << context->mimetype(); //kDebug() << "we run the term" << context->query() << "whose type is" << context->mimetype();
if (d->runner) { if (d->runner) {
//TODO: this could be dangerous if the runner is deleted behind our backs.
d->runner->run(context, *this); d->runner->run(context, *this);
} }
} }

View File

@ -143,22 +143,21 @@ void RunnerRestrictionPolicy::destructed(Job* job)
class FindMatchesJob : public Job class FindMatchesJob : public Job
{ {
public: public:
FindMatchesJob(const QString& term, Plasma::AbstractRunner* runner, Plasma::RunnerContext* context, QObject* parent = 0); FindMatchesJob(Plasma::AbstractRunner* runner, Plasma::RunnerContext* context, QObject* parent = 0);
int priority() const; int priority() const;
Plasma::AbstractRunner* runner() const;
protected: protected:
void run(); void run();
private: private:
QString m_term;
Plasma::RunnerContext* m_context; Plasma::RunnerContext* m_context;
Plasma::AbstractRunner* m_runner; Plasma::AbstractRunner* m_runner;
}; };
FindMatchesJob::FindMatchesJob( const QString& term, Plasma::AbstractRunner* runner, FindMatchesJob::FindMatchesJob(Plasma::AbstractRunner* runner,
Plasma::RunnerContext* context, QObject* parent ) Plasma::RunnerContext* context, QObject* parent)
: ThreadWeaver::Job(parent), : ThreadWeaver::Job(parent),
m_term(term),
m_context(context), m_context(context),
m_runner(runner) m_runner(runner)
{ {
@ -178,6 +177,10 @@ int FindMatchesJob::priority() const
return m_runner->priority(); return m_runner->priority();
} }
Plasma::AbstractRunner* FindMatchesJob::runner() const
{
return m_runner;
}
/***************************************************** /*****************************************************
* RunnerManager::Private class * RunnerManager::Private class
@ -188,7 +191,8 @@ class RunnerManager::Private
public: public:
Private(RunnerManager *parent) Private(RunnerManager *parent)
: q(parent) : q(parent),
deferredRun(0)
{ {
matchChangeTimer.setSingleShot(true); matchChangeTimer.setSingleShot(true);
connect(&matchChangeTimer, SIGNAL(timeout()), q, SLOT(scheduleMatchesChanged())); connect(&matchChangeTimer, SIGNAL(timeout()), q, SLOT(scheduleMatchesChanged()));
@ -273,11 +277,24 @@ public:
//kDebug() << "All runners loaded, total:" << runners.count(); //kDebug() << "All runners loaded, total:" << runners.count();
} }
void jobDone(ThreadWeaver::Job* job)
{
FindMatchesJob *runJob = static_cast<FindMatchesJob*>(job);
if (deferredRun.isEnabled() && runJob->runner() == deferredRun.runner()) {
//kDebug() << "job actually done, running now **************";
deferredRun.run(context);
deferredRun = QueryMatch(0);
}
searchJobs.removeAll(runJob);
delete runJob;
}
RunnerManager *q; RunnerManager *q;
QueryMatch deferredRun;
RunnerContext context; RunnerContext context;
QTimer matchChangeTimer; QTimer matchChangeTimer;
AbstractRunner::List runners; AbstractRunner::List runners;
QList<ThreadWeaver::Job*> searchJobs; QList<FindMatchesJob*> searchJobs;
QStringList prioritylist; QStringList prioritylist;
QStringList blacklist; QStringList blacklist;
KConfigGroup config; KConfigGroup config;
@ -341,11 +358,29 @@ QList<QueryMatch> RunnerManager::matches() const
void RunnerManager::run(const QueryMatch &match) void RunnerManager::run(const QueryMatch &match)
{ {
if (!match.isEnabled()) {
return;
}
//TODO: this function is not const as it may be used for learning //TODO: this function is not const as it may be used for learning
AbstractRunner *runner = match.runner();
foreach (FindMatchesJob *job, d->searchJobs) {
if (job->runner() == runner && !job->isFinished()) {
//kDebug() << "!!!!!!!!!!!!!!!!!!! uh oh!";
d->deferredRun = match;
return;
}
}
match.run(d->context); match.run(d->context);
if (d->deferredRun.isValid()) {
d->deferredRun = QueryMatch(0);
}
} }
void RunnerManager::launchQuery (const QString & term, const QString & runnerName) void RunnerManager::launchQuery(const QString & term, const QString & runnerName)
{ {
if (term.isEmpty()) { if (term.isEmpty()) {
reset(); reset();
@ -370,14 +405,13 @@ void RunnerManager::launchQuery (const QString & term, const QString & runnerNam
runable = d->runners; runable = d->runners;
} }
bool jobsLaunched=false;
foreach (Plasma::AbstractRunner* r, runable) { foreach (Plasma::AbstractRunner* r, runable) {
if ((r->ignoredTypes() & d->context.type()) == 0) { if ((r->ignoredTypes() & d->context.type()) == 0) {
// kDebug() << "launching" << r->name(); // kDebug() << "launching" << r->name();
jobsLaunched=true; FindMatchesJob *job = new FindMatchesJob(r, &d->context, this);
Job *job = new FindMatchesJob(term, r, &d->context, this); connect(job, SIGNAL(done(ThreadWeaver::Job*)), this, SLOT(jobDone(ThreadWeaver::Job*)));
Weaver::instance()->enqueue( job ); Weaver::instance()->enqueue(job);
d->searchJobs.append( job ); d->searchJobs.append(job);
} }
} }
} }
@ -416,6 +450,11 @@ bool RunnerManager::execQuery(const QString &term, const QString &runnerName)
return true; return true;
} }
QString RunnerManager::query() const
{
return d->context.query();
}
void RunnerManager::reset() void RunnerManager::reset()
{ {
// If ThreadWeaver is idle, it is safe to clear previous jobs // If ThreadWeaver is idle, it is safe to clear previous jobs
@ -425,6 +464,13 @@ void RunnerManager::reset()
} else { } else {
Weaver::instance()->dequeue(); Weaver::instance()->dequeue();
} }
if (d->deferredRun.isEnabled()) {
//kDebug() << "job actually done, running now **************";
d->deferredRun.run(d->context);
d->deferredRun = QueryMatch(0);
}
d->context.reset(); d->context.reset();
//FIXME: if the weaver is not idle we have a number of jobs that //FIXME: if the weaver is not idle we have a number of jobs that
@ -433,7 +479,6 @@ void RunnerManager::reset()
// or discard results // or discard results
} }
} // Plasma namespace
}
#include "runnermanager.moc" #include "runnermanager.moc"

View File

@ -95,6 +95,11 @@ class PLASMA_EXPORT RunnerManager : public QObject
*/ */
bool execQuery(const QString &term, const QString & runnerName); bool execQuery(const QString &term, const QString & runnerName);
/**
* @return the current query term
*/
QString query() const;
/** /**
* Reset the current data and stops the query * Reset the current data and stops the query
*/ */
@ -109,6 +114,7 @@ class PLASMA_EXPORT RunnerManager : public QObject
private: private:
Q_PRIVATE_SLOT(d, void scheduleMatchesChanged()) Q_PRIVATE_SLOT(d, void scheduleMatchesChanged())
Q_PRIVATE_SLOT(d, void matchesChanged()) Q_PRIVATE_SLOT(d, void matchesChanged())
Q_PRIVATE_SLOT(d, void jobDone(ThreadWeaver::Job*))
class Private; class Private;
Private * const d; Private * const d;