summaryrefslogtreecommitdiffstats
path: root/src/declarative/util/qdeclarativexmllistmodel.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/util/qdeclarativexmllistmodel.cpp')
-rw-r--r--src/declarative/util/qdeclarativexmllistmodel.cpp296
1 files changed, 91 insertions, 205 deletions
diff --git a/src/declarative/util/qdeclarativexmllistmodel.cpp b/src/declarative/util/qdeclarativexmllistmodel.cpp
index 9a74c04..983a25e 100644
--- a/src/declarative/util/qdeclarativexmllistmodel.cpp
+++ b/src/declarative/util/qdeclarativexmllistmodel.cpp
@@ -147,226 +147,114 @@ struct XmlQueryJob
QString prefix;
};
-
-class QDeclarativeXmlQueryEngine;
-class QDeclarativeXmlQueryThreadObject : public QObject
+class QDeclarativeXmlQuery : public QObject
{
Q_OBJECT
public:
- QDeclarativeXmlQueryThreadObject(QDeclarativeXmlQueryEngine *);
-
- void processJobs();
- virtual bool event(QEvent *e);
-
-private:
- QDeclarativeXmlQueryEngine *m_queryEngine;
-};
-
-
-class QDeclarativeXmlQueryEngine : public QThread
-{
- Q_OBJECT
-public:
- QDeclarativeXmlQueryEngine(QDeclarativeEngine *eng);
- ~QDeclarativeXmlQueryEngine();
-
- int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache);
- void abort(int id);
-
- void processJobs();
-
- static QDeclarativeXmlQueryEngine *instance(QDeclarativeEngine *engine);
-
-signals:
- void queryCompleted(const QDeclarativeXmlQueryResult &);
- void error(void*, const QString&);
-
-protected:
- void run();
-
-private:
- void processQuery(XmlQueryJob *job);
- void doQueryJob(XmlQueryJob *job, QDeclarativeXmlQueryResult *currentResult);
- void doSubQueryJob(XmlQueryJob *job, QDeclarativeXmlQueryResult *currentResult);
- void getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const;
- void addIndexToRangeList(QList<QDeclarativeXmlListRange> *ranges, int index) const;
-
- QMutex m_mutex;
- QDeclarativeXmlQueryThreadObject *m_threadObject;
- QList<XmlQueryJob> m_jobs;
- QSet<int> m_cancelledJobs;
- QAtomicInt m_queryIds;
-
- QDeclarativeEngine *m_engine;
- QObject *m_eventLoopQuitHack;
-
- static QHash<QDeclarativeEngine *,QDeclarativeXmlQueryEngine*> queryEngines;
- static QMutex queryEnginesMutex;
-};
-QHash<QDeclarativeEngine *,QDeclarativeXmlQueryEngine*> QDeclarativeXmlQueryEngine::queryEngines;
-QMutex QDeclarativeXmlQueryEngine::queryEnginesMutex;
-
-
-QDeclarativeXmlQueryThreadObject::QDeclarativeXmlQueryThreadObject(QDeclarativeXmlQueryEngine *e)
- : m_queryEngine(e)
-{
-}
-
-void QDeclarativeXmlQueryThreadObject::processJobs()
-{
- QCoreApplication::postEvent(this, new QEvent(QEvent::User));
-}
-
-bool QDeclarativeXmlQueryThreadObject::event(QEvent *e)
-{
- if (e->type() == QEvent::User) {
- m_queryEngine->processJobs();
- return true;
- } else {
- return QObject::event(e);
+ QDeclarativeXmlQuery(QObject *parent=0)
+ : QObject(parent), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1) {
+ qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult");
+ moveToThread(&m_thread);
+ m_thread.start(QThread::IdlePriority);
}
-}
-
-
-
-QDeclarativeXmlQueryEngine::QDeclarativeXmlQueryEngine(QDeclarativeEngine *eng)
-: QThread(eng), m_threadObject(0), m_queryIds(XMLLISTMODEL_CLEAR_ID + 1), m_engine(eng), m_eventLoopQuitHack(0)
-{
- qRegisterMetaType<QDeclarativeXmlQueryResult>("QDeclarativeXmlQueryResult");
-
- m_eventLoopQuitHack = new QObject;
- m_eventLoopQuitHack->moveToThread(this);
- connect(m_eventLoopQuitHack, SIGNAL(destroyed(QObject*)), SLOT(quit()), Qt::DirectConnection);
- start(QThread::IdlePriority);
-}
-
-QDeclarativeXmlQueryEngine::~QDeclarativeXmlQueryEngine()
-{
- queryEnginesMutex.lock();
- queryEngines.remove(m_engine);
- queryEnginesMutex.unlock();
- m_eventLoopQuitHack->deleteLater();
- wait();
-}
-
-int QDeclarativeXmlQueryEngine::doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache) {
- {
- QMutexLocker m1(&m_mutex);
- m_queryIds.ref();
- if (m_queryIds <= 0)
- m_queryIds = 1;
- }
-
- XmlQueryJob job;
- job.queryId = m_queryIds;
- job.data = data;
- job.query = QLatin1String("doc($src)") + query;
- job.namespaces = namespaces;
- job.keyRoleResultsCache = keyRoleResultsCache;
-
- for (int i=0; i<roleObjects->count(); i++) {
- if (!roleObjects->at(i)->isValid()) {
- job.roleQueries << QString();
- continue;
+ ~QDeclarativeXmlQuery() {
+ if(m_thread.isRunning()) {
+ m_thread.quit();
+ m_thread.wait();
}
- job.roleQueries << roleObjects->at(i)->query();
- job.roleQueryErrorId << static_cast<void*>(roleObjects->at(i));
- if (roleObjects->at(i)->isKey())
- job.keyRoleQueries << job.roleQueries.last();
}
- {
+ void abort(int id) {
QMutexLocker ml(&m_mutex);
- m_jobs.append(job);
- if (m_threadObject)
- m_threadObject->processJobs();
+ if (id != -1) {
+ m_jobs.remove(id);
+ }
}
- return job.queryId;
-}
+ int doQuery(QString query, QString namespaces, QByteArray data, QList<QDeclarativeXmlListModelRole *>* roleObjects, QStringList keyRoleResultsCache) {
+ {
+ QMutexLocker m1(&m_mutex);
+ m_queryIds.ref();
+ if (m_queryIds <= 0)
+ m_queryIds = 1;
+ }
-void QDeclarativeXmlQueryEngine::abort(int id)
-{
- QMutexLocker ml(&m_mutex);
- if (id != -1) {
- m_cancelledJobs.insert(id);
- if (m_threadObject)
- m_threadObject->processJobs();
- }
-}
+ XmlQueryJob job;
+ job.queryId = m_queryIds;
+ job.data = data;
+ job.query = QLatin1String("doc($src)") + query;
+ job.namespaces = namespaces;
+ job.keyRoleResultsCache = keyRoleResultsCache;
+
+ for (int i=0; i<roleObjects->count(); i++) {
+ if (!roleObjects->at(i)->isValid()) {
+ job.roleQueries << QString();
+ continue;
+ }
+ job.roleQueries << roleObjects->at(i)->query();
+ job.roleQueryErrorId << static_cast<void*>(roleObjects->at(i));
+ if (roleObjects->at(i)->isKey())
+ job.keyRoleQueries << job.roleQueries.last();
+ }
-void QDeclarativeXmlQueryEngine::run()
-{
- m_mutex.lock();
- m_threadObject = new QDeclarativeXmlQueryThreadObject(this);
- m_mutex.unlock();
+ {
+ QMutexLocker ml(&m_mutex);
+ m_jobs.insert(m_queryIds, job);
+ }
- processJobs();
- exec();
+ QMetaObject::invokeMethod(this, "processQuery", Qt::QueuedConnection, Q_ARG(int, job.queryId));
+ return job.queryId;
+ }
- delete m_threadObject;
- m_threadObject = 0;
-}
+private slots:
+ void processQuery(int queryId) {
+ XmlQueryJob job;
-void QDeclarativeXmlQueryEngine::processJobs()
-{
- QMutexLocker locker(&m_mutex);
+ {
+ QMutexLocker ml(&m_mutex);
+ if (!m_jobs.contains(queryId))
+ return;
+ job = m_jobs.value(queryId);
+ }
- while (true) {
- if (m_cancelledJobs.isEmpty() && m_jobs.isEmpty())
- return;
+ QDeclarativeXmlQueryResult result;
+ result.queryId = job.queryId;
+ doQueryJob(&job, &result);
+ doSubQueryJob(&job, &result);
- if (!m_cancelledJobs.isEmpty()) {
- for (QList<XmlQueryJob>::Iterator it = m_jobs.begin(); it != m_jobs.end(); ++it) {
- int queryId = (*it).queryId;
- if (m_cancelledJobs.remove(queryId))
- it = m_jobs.erase(it);
+ {
+ QMutexLocker ml(&m_mutex);
+ if (m_jobs.contains(queryId)) {
+ emit queryCompleted(result);
+ m_jobs.remove(queryId);
}
- m_cancelledJobs.clear();
}
+ }
- if (!m_jobs.isEmpty()) {
- XmlQueryJob currentJob = m_jobs.takeLast();
+Q_SIGNALS:
+ void queryCompleted(const QDeclarativeXmlQueryResult &);
+ void error(void*, const QString&);
- locker.unlock();
- processQuery(&currentJob);
- locker.relock();
- }
- }
-}
+protected:
-QDeclarativeXmlQueryEngine *QDeclarativeXmlQueryEngine::instance(QDeclarativeEngine *engine)
-{
- queryEnginesMutex.lock();
- QDeclarativeXmlQueryEngine *queryEng = queryEngines.value(engine);
- if (!queryEng) {
- queryEng = new QDeclarativeXmlQueryEngine(engine);
- queryEngines.insert(engine, queryEng);
- }
- queryEnginesMutex.unlock();
- return queryEng;
-}
+private:
+ void doQueryJob(XmlQueryJob *job, QDeclarativeXmlQueryResult *currentResult);
+ void doSubQueryJob(XmlQueryJob *job, QDeclarativeXmlQueryResult *currentResult);
+ void getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const;
+ void addIndexToRangeList(QList<QDeclarativeXmlListRange> *ranges, int index) const;
-void QDeclarativeXmlQueryEngine::processQuery(XmlQueryJob *job)
-{
- QDeclarativeXmlQueryResult result;
- result.queryId = job->queryId;
- doQueryJob(job, &result);
- doSubQueryJob(job, &result);
+private:
+ QMutex m_mutex;
+ QThread m_thread;
+ QMap<int, XmlQueryJob> m_jobs;
+ QAtomicInt m_queryIds;
+};
- {
- QMutexLocker ml(&m_mutex);
- if (m_cancelledJobs.contains(job->queryId)) {
- m_cancelledJobs.remove(job->queryId);
- } else {
- emit queryCompleted(result);
- }
- }
-}
+Q_GLOBAL_STATIC(QDeclarativeXmlQuery, globalXmlQuery)
-void QDeclarativeXmlQueryEngine::doQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult)
+void QDeclarativeXmlQuery::doQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult)
{
Q_ASSERT(currentJob->queryId != -1);
@@ -405,7 +293,7 @@ void QDeclarativeXmlQueryEngine::doQueryJob(XmlQueryJob *currentJob, QDeclarativ
currentResult->size = (count > 0 ? count : 0);
}
-void QDeclarativeXmlQueryEngine::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const
+void QDeclarativeXmlQuery::getValuesOfKeyRoles(const XmlQueryJob& currentJob, QStringList *values, QXmlQuery *query) const
{
const QStringList &keysQueries = currentJob.keyRoleQueries;
QString keysQuery;
@@ -426,7 +314,7 @@ void QDeclarativeXmlQueryEngine::getValuesOfKeyRoles(const XmlQueryJob& currentJ
}
}
-void QDeclarativeXmlQueryEngine::addIndexToRangeList(QList<QDeclarativeXmlListRange> *ranges, int index) const {
+void QDeclarativeXmlQuery::addIndexToRangeList(QList<QDeclarativeXmlListRange> *ranges, int index) const {
if (ranges->isEmpty())
ranges->append(qMakePair(index, 1));
else if (ranges->last().first + ranges->last().second == index)
@@ -435,7 +323,7 @@ void QDeclarativeXmlQueryEngine::addIndexToRangeList(QList<QDeclarativeXmlListRa
ranges->append(qMakePair(index, 1));
}
-void QDeclarativeXmlQueryEngine::doSubQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult)
+void QDeclarativeXmlQuery::doSubQueryJob(XmlQueryJob *currentJob, QDeclarativeXmlQueryResult *currentResult)
{
Q_ASSERT(currentJob->queryId != -1);
@@ -695,6 +583,10 @@ void QDeclarativeXmlListModelPrivate::clear_role(QDeclarativeListProperty<QDecla
QDeclarativeXmlListModel::QDeclarativeXmlListModel(QObject *parent)
: QListModelInterface(*(new QDeclarativeXmlListModelPrivate), parent)
{
+ connect(globalXmlQuery(), SIGNAL(queryCompleted(QDeclarativeXmlQueryResult)),
+ this, SLOT(queryCompleted(QDeclarativeXmlQueryResult)));
+ connect(globalXmlQuery(), SIGNAL(error(void*,QString)),
+ this, SLOT(queryError(void*,QString)));
}
QDeclarativeXmlListModel::~QDeclarativeXmlListModel()
@@ -960,12 +852,6 @@ void QDeclarativeXmlListModel::classBegin()
{
Q_D(QDeclarativeXmlListModel);
d->isComponentComplete = false;
-
- QDeclarativeXmlQueryEngine *queryEngine = QDeclarativeXmlQueryEngine::instance(qmlEngine(this));
- connect(queryEngine, SIGNAL(queryCompleted(QDeclarativeXmlQueryResult)),
- SLOT(queryCompleted(QDeclarativeXmlQueryResult)));
- connect(queryEngine, SIGNAL(error(void*,QString)),
- SLOT(queryError(void*,QString)));
}
void QDeclarativeXmlListModel::componentComplete()
@@ -995,7 +881,7 @@ void QDeclarativeXmlListModel::reload()
if (!d->isComponentComplete)
return;
- QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->abort(d->queryId);
+ globalXmlQuery()->abort(d->queryId);
d->queryId = -1;
if (d->size < 0)
@@ -1011,7 +897,7 @@ void QDeclarativeXmlListModel::reload()
}
if (!d->xml.isEmpty()) {
- d->queryId = QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache);
+ d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, d->xml.toUtf8(), &d->roleObjects, d->keyRoleResultsCache);
d->notifyQueryStarted(false);
} else if (d->src.isEmpty()) {
@@ -1072,7 +958,7 @@ void QDeclarativeXmlListModel::requestFinished()
d->queryId = XMLLISTMODEL_CLEAR_ID;
QTimer::singleShot(0, this, SLOT(dataCleared()));
} else {
- d->queryId = QDeclarativeXmlQueryEngine::instance(qmlEngine(this))->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
+ d->queryId = globalXmlQuery()->doQuery(d->query, d->namespaces, data, &d->roleObjects, d->keyRoleResultsCache);
}
disconnect(d->reply, 0, this, 0);
d->reply->deleteLater();