From e6674ab5e9637c61c92d94ecef5cb5b6d2bfbcfa Mon Sep 17 00:00:00 2001 From: Skycoder42 Date: Tue, 27 Feb 2018 14:43:18 +0100 Subject: [PATCH] refactored presenter to be initialize as service --- examples/mvvmquick/SampleQuick/main.cpp | 2 - examples/mvvmwidgets/SampleWidgets/main.cpp | 1 - src/mvvmcore/coreapp.cpp | 32 ++++++--------- src/mvvmcore/coreapp.h | 2 - src/mvvmcore/coreapp_p.h | 4 +- src/mvvmcore/serviceregistry.cpp | 8 +++- src/mvvmcore/serviceregistry.h | 10 +++++ src/mvvmquick/inputviewfactory.cpp | 23 +---------- src/mvvmquick/quickpresenter.cpp | 44 +++++++++++++++------ src/mvvmquick/quickpresenter.h | 6 +-- src/mvvmwidgets/settingsdialog.cpp | 13 ------ src/mvvmwidgets/widgetspresenter.cpp | 41 +++++++++++++------ src/mvvmwidgets/widgetspresenter.h | 6 +-- 13 files changed, 100 insertions(+), 92 deletions(-) diff --git a/examples/mvvmquick/SampleQuick/main.cpp b/examples/mvvmquick/SampleQuick/main.cpp index 5fc2820..7e83fdb 100644 --- a/examples/mvvmquick/SampleQuick/main.cpp +++ b/examples/mvvmquick/SampleQuick/main.cpp @@ -37,8 +37,6 @@ int main(int argc, char *argv[]) qmlRegisterUncreatableType("de.skycoder42.QtMvvm.Sample", 1, 0, "TabViewModel", QStringLiteral("ViewModels cannot be created")); qmlRegisterUncreatableType("de.skycoder42.QtMvvm.Sample", 1, 0, "TabItemViewModel", QStringLiteral("ViewModels cannot be created")); - QtMvvm::QuickPresenter::registerAsPresenter(); - QtMvvm::ServiceRegistry::instance()->registerObject(); QtMvvm::ServiceRegistry::instance()->registerInterface(); diff --git a/examples/mvvmwidgets/SampleWidgets/main.cpp b/examples/mvvmwidgets/SampleWidgets/main.cpp index 489c21b..81376e3 100644 --- a/examples/mvvmwidgets/SampleWidgets/main.cpp +++ b/examples/mvvmwidgets/SampleWidgets/main.cpp @@ -20,7 +20,6 @@ int main(int argc, char *argv[]) { QApplication a(argc, argv); - QtMvvm::WidgetsPresenter::registerAsPresenter(); QtMvvm::WidgetsPresenter::registerView(); QtMvvm::WidgetsPresenter::registerView(); QtMvvm::WidgetsPresenter::registerView(); diff --git a/src/mvvmcore/coreapp.cpp b/src/mvvmcore/coreapp.cpp index 04a43a8..3097a21 100644 --- a/src/mvvmcore/coreapp.cpp +++ b/src/mvvmcore/coreapp.cpp @@ -22,14 +22,6 @@ CoreApp *CoreApp::instance() return CoreAppPrivate::instance; } -void CoreApp::setMainPresenter(IPresenter *presenter) -{ - if(!CoreAppPrivate::instance) - logCritical() << "Failed to set presenter - no core app has been created yet"; - else - CoreAppPrivate::instance->d->presenter.reset(presenter); -} - void CoreApp::disableAutoBoot() { CoreAppPrivate::bootEnabled = false; @@ -40,6 +32,7 @@ void CoreApp::registerApp() //register metatypes qRegisterMetaType("const QMetaObject*"); qRegisterMetaType(); + registerInterfaceConverter(); //setup setParent(qApp); @@ -49,11 +42,6 @@ void CoreApp::registerApp() QMetaObject::invokeMethod(this, "bootApp", Qt::QueuedConnection); } -IPresenter *CoreApp::presenter() const -{ - return d->presenter.data(); -} - void CoreApp::show(const char *viewModelName, const QVariantHash ¶ms) { auto metaId = QMetaType::type(viewModelName); @@ -87,8 +75,17 @@ MessageResult *CoreApp::showDialog(const MessageConfig &config) void CoreApp::bootApp() { - if(!d->presenter) - logWarning() << "No presenter has been set before the app start"; + if(!d->presenter) { + try { + d->presenter = ServiceRegistry::instance()->service(); + } catch(ServiceConstructionException &e) { + logCritical() << "Unable to get a presenter with error" + << e.what(); + qApp->exit(EXIT_FAILURE); + return; + } + } + auto res = startApp(QCoreApplication::arguments()); if(res == EXIT_SUCCESS) { connect(qApp, &QCoreApplication::aboutToQuit, @@ -164,11 +161,6 @@ QScopedPointer &CoreAppPrivate::dInstance() return instance->d; } -IPresenter *CoreAppPrivate::currentPresenter() const -{ - return presenter.data(); -} - void CoreAppPrivate::showViewModel(const QMetaObject *metaObject, const QVariantHash ¶ms, QPointer parent, quint32 requestCode) { if(presenter) { diff --git a/src/mvvmcore/coreapp.h b/src/mvvmcore/coreapp.h index 37179d5..6a8815d 100644 --- a/src/mvvmcore/coreapp.h +++ b/src/mvvmcore/coreapp.h @@ -23,11 +23,9 @@ public: ~CoreApp(); static CoreApp *instance(); - static void setMainPresenter(IPresenter *presenter); static void disableAutoBoot(); void registerApp(); - IPresenter *presenter() const; template static inline void show(const QVariantHash ¶ms = {}); diff --git a/src/mvvmcore/coreapp_p.h b/src/mvvmcore/coreapp_p.h index 8e1e20e..90ffdac 100644 --- a/src/mvvmcore/coreapp_p.h +++ b/src/mvvmcore/coreapp_p.h @@ -16,8 +16,6 @@ class Q_MVVMCORE_EXPORT CoreAppPrivate : public QObject public: static QScopedPointer &dInstance(); - IPresenter *currentPresenter() const; - public Q_SLOTS: void showViewModel(const QMetaObject *metaObject, const QVariantHash ¶ms, @@ -31,7 +29,7 @@ private: static bool bootEnabled; static QPointer instance; - QScopedPointer presenter; + IPresenter *presenter; }; } diff --git a/src/mvvmcore/serviceregistry.cpp b/src/mvvmcore/serviceregistry.cpp index 05e25fe..c70dca4 100644 --- a/src/mvvmcore/serviceregistry.cpp +++ b/src/mvvmcore/serviceregistry.cpp @@ -22,6 +22,12 @@ ServiceRegistry *ServiceRegistry::instance() return _instance; } +bool ServiceRegistry::isRegistered(const QByteArray &iid) const +{ + QMutexLocker _(&d->serviceMutex); + return d->services.contains(iid); +} + void ServiceRegistry::registerService(const QByteArray &iid, const QMetaObject *metaObject, bool weak) { QMutexLocker _(&d->serviceMutex); @@ -242,7 +248,7 @@ QException *ServiceConstructionException::clone() const ServiceDependencyException::ServiceDependencyException(const QByteArray &iid) : - ServiceConstructionException("Failed to construct service because of missing dependency: " + iid) + ServiceConstructionException("Failed to construct missing service: " + iid) {} ServiceDependencyException::ServiceDependencyException(const ServiceDependencyException * const other) : diff --git a/src/mvvmcore/serviceregistry.h b/src/mvvmcore/serviceregistry.h index 51f1d53..4eb0328 100644 --- a/src/mvvmcore/serviceregistry.h +++ b/src/mvvmcore/serviceregistry.h @@ -20,6 +20,10 @@ public: static ServiceRegistry* instance(); + template + bool isRegistered() const; + bool isRegistered(const QByteArray &iid) const; + template void registerInterface(bool weak = false); template @@ -96,6 +100,12 @@ protected: // ------------- Generic Implementation ------------- +template +bool ServiceRegistry::isRegistered() const +{ + return isRegistered(__helpertypes::inject_iid()); +} + #define QTMVVM_SERVICE_ASSERT(tint, tsvc) \ static_assert(__helpertypes::is_valid_interface::value, "TService must implement the given TInterface interface and be a qobject class"); \ Q_ASSERT_X(qobject_interface_iid(), Q_FUNC_INFO, "TInterface must be registered with Q_DECLARE_INTERFACE"); diff --git a/src/mvvmquick/inputviewfactory.cpp b/src/mvvmquick/inputviewfactory.cpp index 7312fe9..c11bc78 100644 --- a/src/mvvmquick/inputviewfactory.cpp +++ b/src/mvvmquick/inputviewfactory.cpp @@ -8,33 +8,12 @@ #include -#include using namespace QtMvvm; -namespace { - -void initPrivateQml() -{ - qmlRegisterType("de.skycoder42.QtMvvm.Quick.Private", 1, 0, "UrlValidator"); -} - -void initResources() -{ -#ifdef QT_STATIC - initPrivateQml(); - Q_INIT_RESOURCE(qtmvvmquick_module); -#endif -} - -} -Q_COREAPP_STARTUP_FUNCTION(initPrivateQml) - InputViewFactory::InputViewFactory() : QObject(nullptr), d(new InputViewFactoryPrivate()) -{ - initResources(); -} +{} InputViewFactory::~InputViewFactory() {} diff --git a/src/mvvmquick/quickpresenter.cpp b/src/mvvmquick/quickpresenter.cpp index 792b67c..1c75749 100644 --- a/src/mvvmquick/quickpresenter.cpp +++ b/src/mvvmquick/quickpresenter.cpp @@ -7,16 +7,39 @@ #include #include -#include +#include + #include +#include +namespace { + +void qtMvvmQuickInit() +{ + qmlRegisterType("de.skycoder42.QtMvvm.Quick.Private", 1, 0, "UrlValidator"); + QtMvvm::ServiceRegistry::instance()->registerInterface(true); +} + +void initResources() +{ +#ifdef QT_STATIC + qtMvvmQuickInit(); + Q_INIT_RESOURCE(qtmvvmquick_module); +#endif +} + +} +Q_COREAPP_STARTUP_FUNCTION(qtMvvmQuickInit) + using namespace QtMvvm; QuickPresenter::QuickPresenter(QObject *parent) : QObject(parent), IPresenter(), d(new QuickPresenterPrivate()) -{} +{ + initResources(); +} QuickPresenter::~QuickPresenter() {} @@ -174,17 +197,16 @@ QuickPresenterPrivate::QuickPresenterPrivate() : QuickPresenter *QuickPresenterPrivate::currentPresenter() { - auto presenter = static_cast(CoreAppPrivate::dInstance()->currentPresenter()); - if(!presenter) { - presenter = new QuickPresenter(); - CoreApp::setMainPresenter(presenter); - } + try { #ifndef Q_NO_DEBUG - Q_ASSERT_X(dynamic_cast(CoreAppPrivate::dInstance()->currentPresenter()), - Q_FUNC_INFO, - "Cannot register views if the current presenter does not extend QtMvvm::QuickPresenter"); + Q_ASSERT_X(dynamic_cast(ServiceRegistry::instance()->service()), + Q_FUNC_INFO, + "Cannot register views if the current presenter does not extend QtMvvm::QuickPresenter"); #endif - return presenter; + return static_cast(ServiceRegistry::instance()->service()); + } catch(QException &e) { + qFatal(e.what()); + } } void QuickPresenterPrivate::setQmlPresenter(QObject *presenter) diff --git a/src/mvvmquick/quickpresenter.h b/src/mvvmquick/quickpresenter.h index 334c908..f276407 100644 --- a/src/mvvmquick/quickpresenter.h +++ b/src/mvvmquick/quickpresenter.h @@ -7,7 +7,7 @@ #include #include -#include +#include #include "QtMvvmQuick/qtmvvmquick_global.h" #include "QtMvvmQuick/inputviewfactory.h" @@ -23,7 +23,7 @@ class Q_MVVMQUICK_EXPORT QuickPresenter : public QObject, public IPresenter Q_PROPERTY(InputViewFactory* inputViewFactory READ inputViewFactory WRITE setInputViewFactory NOTIFY inputViewFactoryChanged) public: - explicit QuickPresenter(QObject *parent = nullptr); + Q_INVOKABLE explicit QuickPresenter(QObject *parent = nullptr); ~QuickPresenter(); template @@ -62,7 +62,7 @@ template void QuickPresenter::registerAsPresenter() { static_assert(std::is_base_of::value, "TPresenter must inherit QtMvvm::QuickPresenter!"); - CoreApp::setMainPresenter(new TPresenter()); + ServiceRegistry::instance()->registerInterface(); } template diff --git a/src/mvvmwidgets/settingsdialog.cpp b/src/mvvmwidgets/settingsdialog.cpp index bea2e10..4e2e3ae 100644 --- a/src/mvvmwidgets/settingsdialog.cpp +++ b/src/mvvmwidgets/settingsdialog.cpp @@ -13,25 +13,12 @@ #include -namespace { - -void initResources() -{ -#ifdef QT_STATIC - Q_INIT_RESOURCE(qtmvvmsettingswidgets_module); -#endif -} - -} - using namespace QtMvvm; SettingsDialog::SettingsDialog(ViewModel *viewModel, QWidget *parent) : QDialog(parent), d(new SettingsDialogPrivate(this, viewModel)) { - initResources(); - d->ui->setupUi(this); connect(d->ui->buttonBox, &QDialogButtonBox::clicked, d, &SettingsDialogPrivate::buttonBoxClicked); diff --git a/src/mvvmwidgets/widgetspresenter.cpp b/src/mvvmwidgets/widgetspresenter.cpp index bd190c2..730e4e8 100644 --- a/src/mvvmwidgets/widgetspresenter.cpp +++ b/src/mvvmwidgets/widgetspresenter.cpp @@ -4,6 +4,7 @@ #include "settingsdialog.h" #include +#include #include #include @@ -18,18 +19,37 @@ #include #include -#include #include #include +namespace { + +void qtMvvmWidgetsInit() +{ + QtMvvm::ServiceRegistry::instance()->registerInterface(true); +} + +void initResources() +{ +#ifdef QT_STATIC + qtMvvmWidgetsInit(); + Q_INIT_RESOURCE(qtmvvmsettingswidgets_module); +#endif +} + +} +Q_COREAPP_STARTUP_FUNCTION(qtMvvmWidgetsInit) + using namespace QtMvvm; WidgetsPresenter::WidgetsPresenter(QObject *parent) : QObject(parent), IPresenter(), d(new WidgetsPresenterPrivate()) -{} +{ + initResources(); +} WidgetsPresenter::~WidgetsPresenter() {} @@ -402,15 +422,14 @@ WidgetsPresenterPrivate::WidgetsPresenterPrivate() : WidgetsPresenter *WidgetsPresenterPrivate::currentPresenter() { - auto presenter = static_cast(CoreAppPrivate::dInstance()->currentPresenter()); - if(!presenter) { - presenter = new WidgetsPresenter(); - CoreApp::setMainPresenter(presenter); - } + try { #ifndef Q_NO_DEBUG - Q_ASSERT_X(dynamic_cast(CoreAppPrivate::dInstance()->currentPresenter()), - Q_FUNC_INFO, - "Cannot register widgets if the current presenter does not extend QtMvvm::WidgetsPresenter"); + Q_ASSERT_X(dynamic_cast(ServiceRegistry::instance()->service()), + Q_FUNC_INFO, + "Cannot register widgets if the current presenter does not extend QtMvvm::WidgetsPresenter"); #endif - return presenter; + return static_cast(ServiceRegistry::instance()->service()); + } catch(QException &e) { + qFatal(e.what()); + } } diff --git a/src/mvvmwidgets/widgetspresenter.h b/src/mvvmwidgets/widgetspresenter.h index 30840b1..44d5348 100644 --- a/src/mvvmwidgets/widgetspresenter.h +++ b/src/mvvmwidgets/widgetspresenter.h @@ -5,7 +5,7 @@ #include #include -#include +#include #include @@ -23,7 +23,7 @@ class Q_MVVMWIDGETS_EXPORT WidgetsPresenter : public QObject, public IPresenter Q_PROPERTY(InputWidgetFactory* inputWidgetFactory READ inputWidgetFactory WRITE setInputWidgetFactory NOTIFY inputWidgetFactoryChanged) public: - explicit WidgetsPresenter(QObject *parent = nullptr); + Q_INVOKABLE explicit WidgetsPresenter(QObject *parent = nullptr); ~WidgetsPresenter(); template @@ -69,7 +69,7 @@ template void WidgetsPresenter::registerAsPresenter() { static_assert(std::is_base_of::value, "TPresenter must inherit QtMvvm::WidgetsPresenter!"); - CoreApp::setMainPresenter(new TPresenter()); + ServiceRegistry::instance()->registerInterface(); } template