From 09aafbd1373b5d1152ac7a453a140a7f76c2e90e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Fri, 13 Nov 2015 19:34:47 +0100 Subject: It's starting to work --- common/clientapi.h | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) (limited to 'common/clientapi.h') diff --git a/common/clientapi.h b/common/clientapi.h index 9a32188..a424424 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -101,11 +102,34 @@ public: /** * Asynchronusly load a dataset with tree structure information */ - // template - // static TreeSet loadTree(Query) - // { + template + static QSharedPointer loadModel(Query query) + { + auto model = QSharedPointer >::create(query, QList() << "summary" << "uid"); + auto resultProvider = QSharedPointer >::create(model); + + // Query all resources and aggregate results + KAsync::iterate(getResources(query.resources, ApplicationDomain::getTypeName())) + .template each([query, resultProvider](const QByteArray &resource, KAsync::Future &future) { + auto facade = FacadeFactory::instance().getFacade(resourceName(resource), resource); + if (facade) { + facade->load(query, resultProvider).template then([&future](){future.setFinished();}).exec(); + //Keep the facade alive for the lifetime of the resultSet. + resultProvider->setFacade(facade); + } else { + //Ignore the error and carry on + future.setFinished(); + } + }).template then([query, resultProvider]() { + resultProvider->initialResultSetComplete(); + if (!query.liveQuery) { + resultProvider->complete(); + } + }).exec(); + + return model; + } - // } template static std::shared_ptr > getFacade(const QByteArray &resourceInstanceIdentifier) { -- cgit v1.2.3 From 0f24357d01bd8a278f03793db863d3f71ac37ef2 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Wed, 18 Nov 2015 00:51:55 +0100 Subject: Don't use a smart pointer for the result provider We're not doing any lifetime management anyways. --- common/clientapi.h | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'common/clientapi.h') diff --git a/common/clientapi.h b/common/clientapi.h index a424424..707e81d 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -35,6 +35,8 @@ #include "facadefactory.h" #include "log.h" +Q_DECLARE_METATYPE(std::shared_ptr); + namespace async { //This should abstract if we execute from eventloop or in thread. //It supposed to allow the caller to finish the current method before executing the runner. @@ -75,9 +77,8 @@ public: // Query all resources and aggregate results KAsync::iterate(getResources(query.resources, ApplicationDomain::getTypeName())) .template each([query, resultSet](const QByteArray &resource, KAsync::Future &future) { - auto facade = FacadeFactory::instance().getFacade(resourceName(resource), resource); - if (facade) { - facade->load(query, resultSet).template then([&future](){future.setFinished();}).exec(); + if (auto facade = FacadeFactory::instance().getFacade(resourceName(resource), resource)) { + facade->load(query, *resultSet).template then([&future](){future.setFinished();}).exec(); //Keep the facade alive for the lifetime of the resultSet. resultSet->setFacade(facade); } else { @@ -106,15 +107,18 @@ public: static QSharedPointer loadModel(Query query) { auto model = QSharedPointer >::create(query, QList() << "summary" << "uid"); - auto resultProvider = QSharedPointer >::create(model); + auto resultProvider = std::make_shared >(model); + //Keep the resultprovider alive for as long as the model lives + model->setProperty("resultProvider", QVariant::fromValue(std::shared_ptr(resultProvider))); // Query all resources and aggregate results KAsync::iterate(getResources(query.resources, ApplicationDomain::getTypeName())) .template each([query, resultProvider](const QByteArray &resource, KAsync::Future &future) { auto facade = FacadeFactory::instance().getFacade(resourceName(resource), resource); if (facade) { - facade->load(query, resultProvider).template then([&future](){future.setFinished();}).exec(); + facade->load(query, *resultProvider).template then([&future](){future.setFinished();}).exec(); //Keep the facade alive for the lifetime of the resultSet. + //FIXME this would have to become a list resultProvider->setFacade(facade); } else { //Ignore the error and carry on -- cgit v1.2.3 From ef205affdb73bfdbef5830996e6336e583660fbc Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 19 Nov 2015 09:37:42 +0100 Subject: Use the new modelresult in the dummyclient --- common/clientapi.h | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'common/clientapi.h') diff --git a/common/clientapi.h b/common/clientapi.h index 707e81d..179bb5c 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -100,6 +100,10 @@ public: return resultSet->emitter(); } + enum Roles { + DomainObjectRole = Qt::UserRole + 1 //Must be the same as in ModelResult + }; + /** * Asynchronusly load a dataset with tree structure information */ -- cgit v1.2.3 From 8d5684292ef92f32487ba32df716a00c4a0841b5 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 19 Nov 2015 17:37:39 +0100 Subject: Loading data with the new model for the test client --- common/clientapi.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'common/clientapi.h') diff --git a/common/clientapi.h b/common/clientapi.h index 179bb5c..6b11ad5 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -110,7 +110,7 @@ public: template static QSharedPointer loadModel(Query query) { - auto model = QSharedPointer >::create(query, QList() << "summary" << "uid"); + auto model = QSharedPointer >::create(query, query.requestedProperties.toList()); auto resultProvider = std::make_shared >(model); //Keep the resultprovider alive for as long as the model lives model->setProperty("resultProvider", QVariant::fromValue(std::shared_ptr(resultProvider))); -- cgit v1.2.3 From 94a2cd6ec21bf0466a9a50d6e4a0a956ed47bc82 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Thu, 19 Nov 2015 23:23:56 +0100 Subject: Move implementations to the cpp file. I finally figured out how to do that with cpp files. It requires instantiating the code with all expected classes, but that's not a big problem since we know all types. This will hopefully greatly reduce the compiletimes... --- common/clientapi.h | 109 ++++------------------------------------------------- 1 file changed, 7 insertions(+), 102 deletions(-) (limited to 'common/clientapi.h') diff --git a/common/clientapi.h b/common/clientapi.h index 6b11ad5..c48c6e9 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -22,21 +22,17 @@ #include #include -#include -#include -#include -#include #include #include "query.h" #include "resultprovider.h" #include "applicationdomaintype.h" -#include "facadefactory.h" -#include "log.h" Q_DECLARE_METATYPE(std::shared_ptr); +class QAbstractItemModel; + namespace async { //This should abstract if we execute from eventloop or in thread. //It supposed to allow the caller to finish the current method before executing the runner. @@ -62,43 +58,7 @@ public: * Asynchronusly load a dataset */ template - static QSharedPointer > load(Query query) - { - auto resultSet = QSharedPointer >::create(); - - //Execute the search in a thread. - //We must guarantee that the emitter is returned before the first result is emitted. - //The result provider must be threadsafe. - async::run([query, resultSet](){ - QEventLoop eventLoop; - resultSet->onDone([&eventLoop](){ - eventLoop.quit(); - }); - // Query all resources and aggregate results - KAsync::iterate(getResources(query.resources, ApplicationDomain::getTypeName())) - .template each([query, resultSet](const QByteArray &resource, KAsync::Future &future) { - if (auto facade = FacadeFactory::instance().getFacade(resourceName(resource), resource)) { - facade->load(query, *resultSet).template then([&future](){future.setFinished();}).exec(); - //Keep the facade alive for the lifetime of the resultSet. - resultSet->setFacade(facade); - } else { - //Ignore the error and carry on - future.setFinished(); - } - }).template then([query, resultSet]() { - resultSet->initialResultSetComplete(); - if (!query.liveQuery) { - resultSet->complete(); - } - }).exec(); - - //Keep the thread alive until the result is ready - if (!resultSet->isDone()) { - eventLoop.exec(); - } - }); - return resultSet->emitter(); - } + static QSharedPointer > load(Query query); enum Roles { DomainObjectRole = Qt::UserRole + 1 //Must be the same as in ModelResult @@ -108,56 +68,13 @@ public: * Asynchronusly load a dataset with tree structure information */ template - static QSharedPointer loadModel(Query query) - { - auto model = QSharedPointer >::create(query, query.requestedProperties.toList()); - auto resultProvider = std::make_shared >(model); - //Keep the resultprovider alive for as long as the model lives - model->setProperty("resultProvider", QVariant::fromValue(std::shared_ptr(resultProvider))); - - // Query all resources and aggregate results - KAsync::iterate(getResources(query.resources, ApplicationDomain::getTypeName())) - .template each([query, resultProvider](const QByteArray &resource, KAsync::Future &future) { - auto facade = FacadeFactory::instance().getFacade(resourceName(resource), resource); - if (facade) { - facade->load(query, *resultProvider).template then([&future](){future.setFinished();}).exec(); - //Keep the facade alive for the lifetime of the resultSet. - //FIXME this would have to become a list - resultProvider->setFacade(facade); - } else { - //Ignore the error and carry on - future.setFinished(); - } - }).template then([query, resultProvider]() { - resultProvider->initialResultSetComplete(); - if (!query.liveQuery) { - resultProvider->complete(); - } - }).exec(); - - return model; - } - - template - static std::shared_ptr > getFacade(const QByteArray &resourceInstanceIdentifier) - { - if (auto facade = FacadeFactory::instance().getFacade(resourceName(resourceInstanceIdentifier), resourceInstanceIdentifier)) { - return facade; - } - return std::make_shared >(); - } + static QSharedPointer loadModel(Query query); /** * Create a new entity. */ template - static KAsync::Job create(const DomainType &domainObject) { - //Potentially move to separate thread as well - auto facade = getFacade(domainObject.resourceInstanceIdentifier()); - return facade->create(domainObject).template then([facade](){}, [](int errorCode, const QString &error) { - Warning() << "Failed to create"; - }); - } + static KAsync::Job create(const DomainType &domainObject); /** * Modify an entity. @@ -165,25 +82,13 @@ public: * This includes moving etc. since these are also simple settings on a property. */ template - static KAsync::Job modify(const DomainType &domainObject) { - //Potentially move to separate thread as well - auto facade = getFacade(domainObject.resourceInstanceIdentifier()); - return facade->modify(domainObject).template then([facade](){}, [](int errorCode, const QString &error) { - Warning() << "Failed to modify"; - }); - } + static KAsync::Job modify(const DomainType &domainObject); /** * Remove an entity. */ template - static KAsync::Job remove(const DomainType &domainObject) { - //Potentially move to separate thread as well - auto facade = getFacade(domainObject.resourceInstanceIdentifier()); - return facade->remove(domainObject).template then([facade](){}, [](int errorCode, const QString &error) { - Warning() << "Failed to remove"; - }); - } + static KAsync::Job remove(const DomainType &domainObject); /** * Shutdown resource. -- cgit v1.2.3 From 4926e7f613ea3e03a2865eec66c6a8c1ec0b6516 Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sat, 28 Nov 2015 16:07:15 +0100 Subject: Cleanup --- common/clientapi.h | 12 ------------ 1 file changed, 12 deletions(-) (limited to 'common/clientapi.h') diff --git a/common/clientapi.h b/common/clientapi.h index c48c6e9..7fee6ae 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -33,12 +33,6 @@ Q_DECLARE_METATYPE(std::shared_ptr); class QAbstractItemModel; -namespace async { - //This should abstract if we execute from eventloop or in thread. - //It supposed to allow the caller to finish the current method before executing the runner. - void run(const std::function &runner); -} - namespace Akonadi2 { using namespace async; @@ -54,12 +48,6 @@ public: static QString storageLocation(); static QByteArray resourceName(const QByteArray &instanceIdentifier); - /** - * Asynchronusly load a dataset - */ - template - static QSharedPointer > load(Query query); - enum Roles { DomainObjectRole = Qt::UserRole + 1 //Must be the same as in ModelResult }; -- cgit v1.2.3 From 887abffb3f712acaa23eae174d5890f337fe43cb Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Sat, 28 Nov 2015 16:20:38 +0100 Subject: Cleanup --- common/clientapi.h | 5 ----- 1 file changed, 5 deletions(-) (limited to 'common/clientapi.h') diff --git a/common/clientapi.h b/common/clientapi.h index 7fee6ae..04f1305 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -26,17 +26,12 @@ #include #include "query.h" -#include "resultprovider.h" #include "applicationdomaintype.h" -Q_DECLARE_METATYPE(std::shared_ptr); - class QAbstractItemModel; namespace Akonadi2 { -using namespace async; - /** * Store interface used in the client API. */ -- cgit v1.2.3 From b5648af02ea7246b41d24e242c5f94e43e43980e Mon Sep 17 00:00:00 2001 From: Christian Mollekopf Date: Mon, 30 Nov 2015 11:09:31 +0100 Subject: Provide status information about children fetch state The fetch state is per parent. --- common/clientapi.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'common/clientapi.h') diff --git a/common/clientapi.h b/common/clientapi.h index 04f1305..8f87562 100644 --- a/common/clientapi.h +++ b/common/clientapi.h @@ -44,7 +44,8 @@ public: static QByteArray resourceName(const QByteArray &instanceIdentifier); enum Roles { - DomainObjectRole = Qt::UserRole + 1 //Must be the same as in ModelResult + DomainObjectRole = Qt::UserRole + 1, //Must be the same as in ModelResult + ChildrenFetchedRole }; /** -- cgit v1.2.3