From 7e56f832354400c4bc48b559e263dbd067f64c22 Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Tue, 19 Jun 2018 19:34:51 +0200 Subject: [PATCH] made shure quick presenter keeps presenting order --- src/imports/mvvmquick/qqmlquickpresenter.cpp | 54 ++++++++++++-------- src/imports/mvvmquick/qqmlquickpresenter.h | 9 ++-- 2 files changed, 40 insertions(+), 23 deletions(-) diff --git a/src/imports/mvvmquick/qqmlquickpresenter.cpp b/src/imports/mvvmquick/qqmlquickpresenter.cpp index e8301ae..48a7a62 100644 --- a/src/imports/mvvmquick/qqmlquickpresenter.cpp +++ b/src/imports/mvvmquick/qqmlquickpresenter.cpp @@ -16,11 +16,8 @@ using namespace QtMvvm; QQmlQuickPresenter::QQmlQuickPresenter(QQmlEngine *engine) : - QObject(engine), - _engine(engine), - _latestComponent(), - _componentCache(), - _loadCache() + QObject{engine}, + _engine{engine} { QuickPresenterPrivate::setQmlPresenter(this); connect(QuickPresenterPrivate::currentPresenter(), &QuickPresenter::inputViewFactoryChanged, @@ -105,16 +102,19 @@ void QQmlQuickPresenter::hapticLongPress() void QQmlQuickPresenter::present(ViewModel *viewModel, const QVariantHash ¶ms, const QUrl &viewUrl, QPointer parent) { auto component = _componentCache.object(viewUrl); - if(component) - addObject(component, viewModel, params, parent); - else { + if(component) { + _loadQueue.enqueue(std::make_tuple(*component, viewModel, params, parent)); + processShowQueue(); + } else { //create component (and replace latest) if(_latestComponent) { disconnect(_latestComponent, &QQmlComponent::progressChanged, this, &QQmlQuickPresenter::loadingProgressChanged); } - _latestComponent = new QQmlComponent(_engine, this); - _loadCache.insert(_latestComponent, std::make_tuple(viewModel, params, parent)); + _latestComponent = new QQmlComponent{_engine}; + component = new QSharedPointer{_latestComponent.data()}; + _componentCache.insert(viewUrl, component); + _loadQueue.enqueue(std::make_tuple(*component, viewModel, params, parent)); //setup ui status emit viewLoadingChanged(true); @@ -157,31 +157,45 @@ void QQmlQuickPresenter::statusChanged(QQmlComponent::Status status) case QQmlComponent::Ready: { logDebug() << "Loaded and cached component" << component->url(); - _componentCache.insert(component->url(), component); - auto loadInfo = _loadCache.value(component); - disconnect(component, &QQmlComponent::progressChanged, - this, &QQmlQuickPresenter::loadingProgressChanged); - addObject(component, std::get<0>(loadInfo), std::get<1>(loadInfo), std::get<2>(loadInfo)); break; } case QQmlComponent::Error: { - auto loadInfo = _loadCache.value(component); - logWarning().noquote() << "Failed to load component for" << std::get<0>(loadInfo)->metaObject()->className() + logWarning().noquote() << "Failed to load component" << component->url() << "with error:" << component->errorString().trimmed(); - std::get<0>(loadInfo)->deleteLater(); - component->deleteLater(); + _componentCache.remove(component->url()); break; } default: return; //not break. code after must not be executed in this case } - _loadCache.remove(component); if(_latestComponent == component) { + disconnect(component, &QQmlComponent::progressChanged, + this, &QQmlQuickPresenter::loadingProgressChanged); _latestComponent = nullptr; emit viewLoadingChanged(false); } + processShowQueue(); +} + +void QQmlQuickPresenter::processShowQueue() +{ + while(!_loadQueue.isEmpty()) { + auto loadInfo = _loadQueue.head(); + switch(std::get<0>(loadInfo)->status()){ + case QQmlComponent::Ready: + addObject(std::get<0>(loadInfo).data(), std::get<1>(loadInfo), std::get<2>(loadInfo), std::get<3>(loadInfo)); + break; + case QQmlComponent::Null: + case QQmlComponent::Error: + std::get<1>(loadInfo)->deleteLater(); + break; + default: + return; //not break. code after must not be executed in this case + } + _loadQueue.dequeue(); + } } void QQmlQuickPresenter::addObject(QQmlComponent *component, ViewModel *viewModel, const QVariantHash ¶ms, const QPointer &parent) diff --git a/src/imports/mvvmquick/qqmlquickpresenter.h b/src/imports/mvvmquick/qqmlquickpresenter.h index e1dd42e..cef0afc 100644 --- a/src/imports/mvvmquick/qqmlquickpresenter.h +++ b/src/imports/mvvmquick/qqmlquickpresenter.h @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include @@ -158,14 +160,15 @@ private Q_SLOTS: void statusChanged(QQmlComponent::Status status); private: - using PresentTuple = std::tuple>; + using PresentTuple = std::tuple, ViewModel*, QVariantHash, QPointer>; QQmlEngine *_engine; QPointer _qmlPresenter; QPointer _latestComponent; - QCache _componentCache; - QHash _loadCache; + QCache> _componentCache; + QQueue _loadQueue; + void processShowQueue(); void addObject(QQmlComponent *component, ViewModel *viewModel, const QVariantHash ¶ms, const QPointer &parent); };