Browse Source

refactored presenter to be initialize as service

pull/2/head
Skycoder42 7 years ago
parent
commit
e6674ab5e9
  1. 2
      examples/mvvmquick/SampleQuick/main.cpp
  2. 1
      examples/mvvmwidgets/SampleWidgets/main.cpp
  3. 32
      src/mvvmcore/coreapp.cpp
  4. 2
      src/mvvmcore/coreapp.h
  5. 4
      src/mvvmcore/coreapp_p.h
  6. 8
      src/mvvmcore/serviceregistry.cpp
  7. 10
      src/mvvmcore/serviceregistry.h
  8. 23
      src/mvvmquick/inputviewfactory.cpp
  9. 44
      src/mvvmquick/quickpresenter.cpp
  10. 6
      src/mvvmquick/quickpresenter.h
  11. 13
      src/mvvmwidgets/settingsdialog.cpp
  12. 41
      src/mvvmwidgets/widgetspresenter.cpp
  13. 6
      src/mvvmwidgets/widgetspresenter.h

2
examples/mvvmquick/SampleQuick/main.cpp

@ -37,8 +37,6 @@ int main(int argc, char *argv[])
qmlRegisterUncreatableType<TabViewModel>("de.skycoder42.QtMvvm.Sample", 1, 0, "TabViewModel", QStringLiteral("ViewModels cannot be created")); qmlRegisterUncreatableType<TabViewModel>("de.skycoder42.QtMvvm.Sample", 1, 0, "TabViewModel", QStringLiteral("ViewModels cannot be created"));
qmlRegisterUncreatableType<TabItemViewModel>("de.skycoder42.QtMvvm.Sample", 1, 0, "TabItemViewModel", QStringLiteral("ViewModels cannot be created")); qmlRegisterUncreatableType<TabItemViewModel>("de.skycoder42.QtMvvm.Sample", 1, 0, "TabItemViewModel", QStringLiteral("ViewModels cannot be created"));
QtMvvm::QuickPresenter::registerAsPresenter();
QtMvvm::ServiceRegistry::instance()->registerObject<EchoService>(); QtMvvm::ServiceRegistry::instance()->registerObject<EchoService>();
QtMvvm::ServiceRegistry::instance()->registerInterface<IEventService, QuickEventService>(); QtMvvm::ServiceRegistry::instance()->registerInterface<IEventService, QuickEventService>();

1
examples/mvvmwidgets/SampleWidgets/main.cpp

@ -20,7 +20,6 @@ int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
QtMvvm::WidgetsPresenter::registerAsPresenter();
QtMvvm::WidgetsPresenter::registerView<SampleView>(); QtMvvm::WidgetsPresenter::registerView<SampleView>();
QtMvvm::WidgetsPresenter::registerView<ResultDialog>(); QtMvvm::WidgetsPresenter::registerView<ResultDialog>();
QtMvvm::WidgetsPresenter::registerView<TabView>(); QtMvvm::WidgetsPresenter::registerView<TabView>();

32
src/mvvmcore/coreapp.cpp

@ -22,14 +22,6 @@ CoreApp *CoreApp::instance()
return CoreAppPrivate::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() void CoreApp::disableAutoBoot()
{ {
CoreAppPrivate::bootEnabled = false; CoreAppPrivate::bootEnabled = false;
@ -40,6 +32,7 @@ void CoreApp::registerApp()
//register metatypes //register metatypes
qRegisterMetaType<const QMetaObject*>("const QMetaObject*"); qRegisterMetaType<const QMetaObject*>("const QMetaObject*");
qRegisterMetaType<MessageConfig::StandardButton>(); qRegisterMetaType<MessageConfig::StandardButton>();
registerInterfaceConverter<IPresenter>();
//setup //setup
setParent(qApp); setParent(qApp);
@ -49,11 +42,6 @@ void CoreApp::registerApp()
QMetaObject::invokeMethod(this, "bootApp", Qt::QueuedConnection); QMetaObject::invokeMethod(this, "bootApp", Qt::QueuedConnection);
} }
IPresenter *CoreApp::presenter() const
{
return d->presenter.data();
}
void CoreApp::show(const char *viewModelName, const QVariantHash &params) void CoreApp::show(const char *viewModelName, const QVariantHash &params)
{ {
auto metaId = QMetaType::type(viewModelName); auto metaId = QMetaType::type(viewModelName);
@ -87,8 +75,17 @@ MessageResult *CoreApp::showDialog(const MessageConfig &config)
void CoreApp::bootApp() void CoreApp::bootApp()
{ {
if(!d->presenter) if(!d->presenter) {
logWarning() << "No presenter has been set before the app start"; try {
d->presenter = ServiceRegistry::instance()->service<IPresenter>();
} catch(ServiceConstructionException &e) {
logCritical() << "Unable to get a presenter with error"
<< e.what();
qApp->exit(EXIT_FAILURE);
return;
}
}
auto res = startApp(QCoreApplication::arguments()); auto res = startApp(QCoreApplication::arguments());
if(res == EXIT_SUCCESS) { if(res == EXIT_SUCCESS) {
connect(qApp, &QCoreApplication::aboutToQuit, connect(qApp, &QCoreApplication::aboutToQuit,
@ -164,11 +161,6 @@ QScopedPointer<CoreAppPrivate> &CoreAppPrivate::dInstance()
return instance->d; return instance->d;
} }
IPresenter *CoreAppPrivate::currentPresenter() const
{
return presenter.data();
}
void CoreAppPrivate::showViewModel(const QMetaObject *metaObject, const QVariantHash &params, QPointer<ViewModel> parent, quint32 requestCode) void CoreAppPrivate::showViewModel(const QMetaObject *metaObject, const QVariantHash &params, QPointer<ViewModel> parent, quint32 requestCode)
{ {
if(presenter) { if(presenter) {

2
src/mvvmcore/coreapp.h

@ -23,11 +23,9 @@ public:
~CoreApp(); ~CoreApp();
static CoreApp *instance(); static CoreApp *instance();
static void setMainPresenter(IPresenter *presenter);
static void disableAutoBoot(); static void disableAutoBoot();
void registerApp(); void registerApp();
IPresenter *presenter() const;
template <typename TViewModel> template <typename TViewModel>
static inline void show(const QVariantHash &params = {}); static inline void show(const QVariantHash &params = {});

4
src/mvvmcore/coreapp_p.h

@ -16,8 +16,6 @@ class Q_MVVMCORE_EXPORT CoreAppPrivate : public QObject
public: public:
static QScopedPointer<CoreAppPrivate> &dInstance(); static QScopedPointer<CoreAppPrivate> &dInstance();
IPresenter *currentPresenter() const;
public Q_SLOTS: public Q_SLOTS:
void showViewModel(const QMetaObject *metaObject, void showViewModel(const QMetaObject *metaObject,
const QVariantHash &params, const QVariantHash &params,
@ -31,7 +29,7 @@ private:
static bool bootEnabled; static bool bootEnabled;
static QPointer<CoreApp> instance; static QPointer<CoreApp> instance;
QScopedPointer<IPresenter> presenter; IPresenter *presenter;
}; };
} }

8
src/mvvmcore/serviceregistry.cpp

@ -22,6 +22,12 @@ ServiceRegistry *ServiceRegistry::instance()
return _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) void ServiceRegistry::registerService(const QByteArray &iid, const QMetaObject *metaObject, bool weak)
{ {
QMutexLocker _(&d->serviceMutex); QMutexLocker _(&d->serviceMutex);
@ -242,7 +248,7 @@ QException *ServiceConstructionException::clone() const
ServiceDependencyException::ServiceDependencyException(const QByteArray &iid) : 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) : ServiceDependencyException::ServiceDependencyException(const ServiceDependencyException * const other) :

10
src/mvvmcore/serviceregistry.h

@ -20,6 +20,10 @@ public:
static ServiceRegistry* instance(); static ServiceRegistry* instance();
template <typename TInterface>
bool isRegistered() const;
bool isRegistered(const QByteArray &iid) const;
template <typename TInterface, typename TService> template <typename TInterface, typename TService>
void registerInterface(bool weak = false); void registerInterface(bool weak = false);
template <typename TInterface, typename TService, typename TFunc> template <typename TInterface, typename TService, typename TFunc>
@ -96,6 +100,12 @@ protected:
// ------------- Generic Implementation ------------- // ------------- Generic Implementation -------------
template<typename TInterface>
bool ServiceRegistry::isRegistered() const
{
return isRegistered(__helpertypes::inject_iid<TInterface*>());
}
#define QTMVVM_SERVICE_ASSERT(tint, tsvc) \ #define QTMVVM_SERVICE_ASSERT(tint, tsvc) \
static_assert(__helpertypes::is_valid_interface<TInterface, TService>::value, "TService must implement the given TInterface interface and be a qobject class"); \ static_assert(__helpertypes::is_valid_interface<TInterface, TService>::value, "TService must implement the given TInterface interface and be a qobject class"); \
Q_ASSERT_X(qobject_interface_iid<TInterface*>(), Q_FUNC_INFO, "TInterface must be registered with Q_DECLARE_INTERFACE"); Q_ASSERT_X(qobject_interface_iid<TInterface*>(), Q_FUNC_INFO, "TInterface must be registered with Q_DECLARE_INTERFACE");

23
src/mvvmquick/inputviewfactory.cpp

@ -8,33 +8,12 @@
#include <QtMvvmCore/private/qtmvvm_logging_p.h> #include <QtMvvmCore/private/qtmvvm_logging_p.h>
#include <qurlvalidator.h>
using namespace QtMvvm; using namespace QtMvvm;
namespace {
void initPrivateQml()
{
qmlRegisterType<QUrlValidator>("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() : InputViewFactory::InputViewFactory() :
QObject(nullptr), QObject(nullptr),
d(new InputViewFactoryPrivate()) d(new InputViewFactoryPrivate())
{ {}
initResources();
}
InputViewFactory::~InputViewFactory() {} InputViewFactory::~InputViewFactory() {}

44
src/mvvmquick/quickpresenter.cpp

@ -7,16 +7,39 @@
#include <QtCore/QDirIterator> #include <QtCore/QDirIterator>
#include <QtCore/QMetaMethod> #include <QtCore/QMetaMethod>
#include <QtMvvmCore/private/coreapp_p.h> #include <QtQml/qqml.h>
#include <QtMvvmCore/private/qtmvvm_logging_p.h> #include <QtMvvmCore/private/qtmvvm_logging_p.h>
#include <qurlvalidator.h>
namespace {
void qtMvvmQuickInit()
{
qmlRegisterType<QUrlValidator>("de.skycoder42.QtMvvm.Quick.Private", 1, 0, "UrlValidator");
QtMvvm::ServiceRegistry::instance()->registerInterface<QtMvvm::IPresenter, QtMvvm::QuickPresenter>(true);
}
void initResources()
{
#ifdef QT_STATIC
qtMvvmQuickInit();
Q_INIT_RESOURCE(qtmvvmquick_module);
#endif
}
}
Q_COREAPP_STARTUP_FUNCTION(qtMvvmQuickInit)
using namespace QtMvvm; using namespace QtMvvm;
QuickPresenter::QuickPresenter(QObject *parent) : QuickPresenter::QuickPresenter(QObject *parent) :
QObject(parent), QObject(parent),
IPresenter(), IPresenter(),
d(new QuickPresenterPrivate()) d(new QuickPresenterPrivate())
{} {
initResources();
}
QuickPresenter::~QuickPresenter() {} QuickPresenter::~QuickPresenter() {}
@ -174,17 +197,16 @@ QuickPresenterPrivate::QuickPresenterPrivate() :
QuickPresenter *QuickPresenterPrivate::currentPresenter() QuickPresenter *QuickPresenterPrivate::currentPresenter()
{ {
auto presenter = static_cast<QuickPresenter*>(CoreAppPrivate::dInstance()->currentPresenter()); try {
if(!presenter) {
presenter = new QuickPresenter();
CoreApp::setMainPresenter(presenter);
}
#ifndef Q_NO_DEBUG #ifndef Q_NO_DEBUG
Q_ASSERT_X(dynamic_cast<QuickPresenter*>(CoreAppPrivate::dInstance()->currentPresenter()), Q_ASSERT_X(dynamic_cast<QuickPresenter*>(ServiceRegistry::instance()->service<IPresenter>()),
Q_FUNC_INFO, Q_FUNC_INFO,
"Cannot register views if the current presenter does not extend QtMvvm::QuickPresenter"); "Cannot register views if the current presenter does not extend QtMvvm::QuickPresenter");
#endif #endif
return presenter; return static_cast<QuickPresenter*>(ServiceRegistry::instance()->service<IPresenter>());
} catch(QException &e) {
qFatal(e.what());
}
} }
void QuickPresenterPrivate::setQmlPresenter(QObject *presenter) void QuickPresenterPrivate::setQmlPresenter(QObject *presenter)

6
src/mvvmquick/quickpresenter.h

@ -7,7 +7,7 @@
#include <QtCore/qmetaobject.h> #include <QtCore/qmetaobject.h>
#include <QtMvvmCore/ipresenter.h> #include <QtMvvmCore/ipresenter.h>
#include <QtMvvmCore/coreapp.h> #include <QtMvvmCore/serviceregistry.h>
#include "QtMvvmQuick/qtmvvmquick_global.h" #include "QtMvvmQuick/qtmvvmquick_global.h"
#include "QtMvvmQuick/inputviewfactory.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) Q_PROPERTY(InputViewFactory* inputViewFactory READ inputViewFactory WRITE setInputViewFactory NOTIFY inputViewFactoryChanged)
public: public:
explicit QuickPresenter(QObject *parent = nullptr); Q_INVOKABLE explicit QuickPresenter(QObject *parent = nullptr);
~QuickPresenter(); ~QuickPresenter();
template <typename TPresenter = QuickPresenter> template <typename TPresenter = QuickPresenter>
@ -62,7 +62,7 @@ template<typename TPresenter>
void QuickPresenter::registerAsPresenter() void QuickPresenter::registerAsPresenter()
{ {
static_assert(std::is_base_of<QuickPresenter, TPresenter>::value, "TPresenter must inherit QtMvvm::QuickPresenter!"); static_assert(std::is_base_of<QuickPresenter, TPresenter>::value, "TPresenter must inherit QtMvvm::QuickPresenter!");
CoreApp::setMainPresenter(new TPresenter()); ServiceRegistry::instance()->registerInterface<IPresenter, TPresenter>();
} }
template<typename TViewModel> template<typename TViewModel>

13
src/mvvmwidgets/settingsdialog.cpp

@ -13,25 +13,12 @@
#include <QtMvvmCore/private/qtmvvm_logging_p.h> #include <QtMvvmCore/private/qtmvvm_logging_p.h>
namespace {
void initResources()
{
#ifdef QT_STATIC
Q_INIT_RESOURCE(qtmvvmsettingswidgets_module);
#endif
}
}
using namespace QtMvvm; using namespace QtMvvm;
SettingsDialog::SettingsDialog(ViewModel *viewModel, QWidget *parent) : SettingsDialog::SettingsDialog(ViewModel *viewModel, QWidget *parent) :
QDialog(parent), QDialog(parent),
d(new SettingsDialogPrivate(this, viewModel)) d(new SettingsDialogPrivate(this, viewModel))
{ {
initResources();
d->ui->setupUi(this); d->ui->setupUi(this);
connect(d->ui->buttonBox, &QDialogButtonBox::clicked, connect(d->ui->buttonBox, &QDialogButtonBox::clicked,
d, &SettingsDialogPrivate::buttonBoxClicked); d, &SettingsDialogPrivate::buttonBoxClicked);

41
src/mvvmwidgets/widgetspresenter.cpp

@ -4,6 +4,7 @@
#include "settingsdialog.h" #include "settingsdialog.h"
#include <QtCore/QMetaProperty> #include <QtCore/QMetaProperty>
#include <QtCore/QCoreApplication>
#include <QtWidgets/QDialog> #include <QtWidgets/QDialog>
#include <QtWidgets/QMainWindow> #include <QtWidgets/QMainWindow>
@ -18,18 +19,37 @@
#include <QtWidgets/QFileDialog> #include <QtWidgets/QFileDialog>
#include <QtWidgets/QLabel> #include <QtWidgets/QLabel>
#include <QtMvvmCore/private/coreapp_p.h>
#include <QtMvvmCore/private/qtmvvm_logging_p.h> #include <QtMvvmCore/private/qtmvvm_logging_p.h>
#include <dialogmaster.h> #include <dialogmaster.h>
namespace {
void qtMvvmWidgetsInit()
{
QtMvvm::ServiceRegistry::instance()->registerInterface<QtMvvm::IPresenter, QtMvvm::WidgetsPresenter>(true);
}
void initResources()
{
#ifdef QT_STATIC
qtMvvmWidgetsInit();
Q_INIT_RESOURCE(qtmvvmsettingswidgets_module);
#endif
}
}
Q_COREAPP_STARTUP_FUNCTION(qtMvvmWidgetsInit)
using namespace QtMvvm; using namespace QtMvvm;
WidgetsPresenter::WidgetsPresenter(QObject *parent) : WidgetsPresenter::WidgetsPresenter(QObject *parent) :
QObject(parent), QObject(parent),
IPresenter(), IPresenter(),
d(new WidgetsPresenterPrivate()) d(new WidgetsPresenterPrivate())
{} {
initResources();
}
WidgetsPresenter::~WidgetsPresenter() {} WidgetsPresenter::~WidgetsPresenter() {}
@ -402,15 +422,14 @@ WidgetsPresenterPrivate::WidgetsPresenterPrivate() :
WidgetsPresenter *WidgetsPresenterPrivate::currentPresenter() WidgetsPresenter *WidgetsPresenterPrivate::currentPresenter()
{ {
auto presenter = static_cast<WidgetsPresenter*>(CoreAppPrivate::dInstance()->currentPresenter()); try {
if(!presenter) {
presenter = new WidgetsPresenter();
CoreApp::setMainPresenter(presenter);
}
#ifndef Q_NO_DEBUG #ifndef Q_NO_DEBUG
Q_ASSERT_X(dynamic_cast<WidgetsPresenter*>(CoreAppPrivate::dInstance()->currentPresenter()), Q_ASSERT_X(dynamic_cast<WidgetsPresenter*>(ServiceRegistry::instance()->service<IPresenter>()),
Q_FUNC_INFO, Q_FUNC_INFO,
"Cannot register widgets if the current presenter does not extend QtMvvm::WidgetsPresenter"); "Cannot register widgets if the current presenter does not extend QtMvvm::WidgetsPresenter");
#endif #endif
return presenter; return static_cast<WidgetsPresenter*>(ServiceRegistry::instance()->service<IPresenter>());
} catch(QException &e) {
qFatal(e.what());
}
} }

6
src/mvvmwidgets/widgetspresenter.h

@ -5,7 +5,7 @@
#include <QtCore/qscopedpointer.h> #include <QtCore/qscopedpointer.h>
#include <QtMvvmCore/ipresenter.h> #include <QtMvvmCore/ipresenter.h>
#include <QtMvvmCore/coreapp.h> #include <QtMvvmCore/serviceregistry.h>
#include <QtWidgets/qwidget.h> #include <QtWidgets/qwidget.h>
@ -23,7 +23,7 @@ class Q_MVVMWIDGETS_EXPORT WidgetsPresenter : public QObject, public IPresenter
Q_PROPERTY(InputWidgetFactory* inputWidgetFactory READ inputWidgetFactory WRITE setInputWidgetFactory NOTIFY inputWidgetFactoryChanged) Q_PROPERTY(InputWidgetFactory* inputWidgetFactory READ inputWidgetFactory WRITE setInputWidgetFactory NOTIFY inputWidgetFactoryChanged)
public: public:
explicit WidgetsPresenter(QObject *parent = nullptr); Q_INVOKABLE explicit WidgetsPresenter(QObject *parent = nullptr);
~WidgetsPresenter(); ~WidgetsPresenter();
template <typename TPresenter = WidgetsPresenter> template <typename TPresenter = WidgetsPresenter>
@ -69,7 +69,7 @@ template<typename TPresenter>
void WidgetsPresenter::registerAsPresenter() void WidgetsPresenter::registerAsPresenter()
{ {
static_assert(std::is_base_of<WidgetsPresenter, TPresenter>::value, "TPresenter must inherit QtMvvm::WidgetsPresenter!"); static_assert(std::is_base_of<WidgetsPresenter, TPresenter>::value, "TPresenter must inherit QtMvvm::WidgetsPresenter!");
CoreApp::setMainPresenter(new TPresenter()); ServiceRegistry::instance()->registerInterface<IPresenter, TPresenter>();
} }
template<typename TView> template<typename TView>

Loading…
Cancel
Save