Browse Source

added plugin services (untested)

pull/2/head
Skycoder42 7 years ago
parent
commit
5d79594ef9
No known key found for this signature in database GPG Key ID: 8E01AD9EF0578D2B
  1. 9
      src/mvvmcore/qpmx.json
  2. 67
      src/mvvmcore/serviceregistry.cpp
  3. 14
      src/mvvmcore/serviceregistry.h
  4. 27
      src/mvvmcore/serviceregistry_p.h

9
src/mvvmcore/qpmx.json

@ -1,5 +1,11 @@
{ {
"dependencies": [], "dependencies": [
{
"package": "de.skycoder42.qpluginfactory",
"provider": "qpm",
"version": "1.3.0"
}
],
"license": { "license": {
"file": "", "file": "",
"name": "" "name": ""
@ -10,5 +16,6 @@
], ],
"publishers": { "publishers": {
}, },
"qbsFile": "",
"source": false "source": false
} }

67
src/mvvmcore/serviceregistry.cpp

@ -8,6 +8,8 @@
#include <QtCore/QCoreApplication> #include <QtCore/QCoreApplication>
#include <QtCore/QThread> #include <QtCore/QThread>
#include <qpluginfactory.h>
using namespace QtMvvm; using namespace QtMvvm;
Q_GLOBAL_STATIC_WITH_ARGS(ServiceRegistry, _instance, Q_GLOBAL_STATIC_WITH_ARGS(ServiceRegistry, _instance,
@ -66,6 +68,19 @@ void ServiceRegistry::registerService(const QByteArray &iid, const std::function
registerService(iid, fn, std::move(injectables), DestroyOnAppDestroy, weak); registerService(iid, fn, std::move(injectables), DestroyOnAppDestroy, weak);
} }
void ServiceRegistry::registerService(QByteArray iid, QString pluginKey, QString pluginType, ServiceRegistry::DestructionScope scope, bool weak)
{
QMutexLocker _(&d->serviceMutex);
if(d->serviceBlocked(iid))
throw ServiceExistsException(iid);
auto info = QSharedPointer<ServiceRegistryPrivate::PluginServiceInfo>::create(std::move(pluginKey),
std::move(pluginType),
std::move(iid),
weak,
scope);
d->services.insert(info->iid(), info);
}
QObject *ServiceRegistry::serviceObj(const QByteArray &iid) QObject *ServiceRegistry::serviceObj(const QByteArray &iid)
{ {
QMutexLocker _(&d->serviceMutex); QMutexLocker _(&d->serviceMutex);
@ -228,35 +243,71 @@ QObject *ServiceRegistryPrivate::ServiceInfo::instance(ServiceRegistryPrivate *d
ServiceRegistryPrivate::FnServiceInfo::FnServiceInfo(std::function<QObject*(QObjectList)> creator, QByteArrayList injectables, bool weak, ServiceRegistry::DestructionScope scope) : ServiceRegistryPrivate::FnServiceInfo::FnServiceInfo(std::function<QObject*(QObjectList)> &&creator, QByteArrayList &&injectables, bool weak, ServiceRegistry::DestructionScope scope) :
ServiceInfo{weak, scope}, ServiceInfo{weak, scope},
creator{std::move(creator)}, _creator{std::move(creator)},
injectables{std::move(injectables)} _injectables{std::move(injectables)}
{} {}
QObject *ServiceRegistryPrivate::FnServiceInfo::construct(ServiceRegistryPrivate *d) const QObject *ServiceRegistryPrivate::FnServiceInfo::construct(ServiceRegistryPrivate *d) const
{ {
QObjectList params; QObjectList params;
params.reserve(injectables.size()); params.reserve(_injectables.size());
for(const auto &iid : injectables) { for(const auto &iid : _injectables) {
auto ref = d->services.value(iid); auto ref = d->services.value(iid);
if(!ref) if(!ref)
throw ServiceDependencyException(iid); throw ServiceDependencyException(iid);
params.append(ref->instance(d, iid)); params.append(ref->instance(d, iid));
} }
return creator(params); return _creator(params);
} }
ServiceRegistryPrivate::MetaServiceInfo::MetaServiceInfo(const QMetaObject *metaObject, bool weak, ServiceRegistry::DestructionScope scope) : ServiceRegistryPrivate::MetaServiceInfo::MetaServiceInfo(const QMetaObject *metaObject, bool weak, ServiceRegistry::DestructionScope scope) :
ServiceInfo{weak, scope}, ServiceInfo{weak, scope},
metaObject{metaObject} _metaObject{metaObject}
{} {}
QObject *ServiceRegistryPrivate::MetaServiceInfo::construct(ServiceRegistryPrivate *d) const QObject *ServiceRegistryPrivate::MetaServiceInfo::construct(ServiceRegistryPrivate *d) const
{ {
return d->constructInjectedLocked(metaObject, nullptr); //services are created without a parent return d->constructInjectedLocked(_metaObject, nullptr); //services are created without a parent
}
ServiceRegistryPrivate::PluginServiceInfo::PluginServiceInfo(QString &&key, QString &&type, QByteArray &&iid, bool weak, ServiceRegistry::DestructionScope scope) :
ServiceInfo{weak, scope},
_key{std::move(key)},
_type{std::move(type)},
_iid{std::move(iid)}
{}
const QByteArray &ServiceRegistryPrivate::PluginServiceInfo::iid() const
{
return _iid;
}
QObject *ServiceRegistryPrivate::PluginServiceInfo::construct(ServiceRegistryPrivate *d) const
{
try {
QPluginFactoryBase factory{_type, _iid};
QObject *obj = nullptr;
if(_key.isEmpty()){
if(!factory.allKeys().isEmpty())
obj = factory.plugin(factory.allKeys().value(0));
} else
obj = factory.plugin(_key);
if(!obj) {
throw ServiceConstructionException{"No plugin of type \"" + _type.toUtf8() +
"\" found that can provide the interface \"" + _iid +
(_key.isEmpty() ? QByteArray{"\""} : QByteArray{"\" for the key: " + _key.toUtf8()})};
}
d->injectLocked(obj);
return obj;
} catch(QPluginLoadException &e) { //convert exception...
throw ServiceConstructionException{e.what()};
}
} }
// ------------- Exceptions Implementation ------------- // ------------- Exceptions Implementation -------------

14
src/mvvmcore/serviceregistry.h

@ -57,6 +57,9 @@ public:
template <typename TService> template <typename TService>
void registerObject(TService *service, DestructionScope scope = DestroyOnAppDestroy, bool weak = false); void registerObject(TService *service, DestructionScope scope = DestroyOnAppDestroy, bool weak = false);
template <typename TInterface>
void registerPlugin(QString pluginKey, QString pluginType, DestructionScope scope = DestroyOnAppDestroy, bool weak = false);
//! Register a service by an iid via their metadata //! Register a service by an iid via their metadata
void registerService(const QByteArray &iid, void registerService(const QByteArray &iid,
const QMetaObject *metaObject, const QMetaObject *metaObject,
@ -75,6 +78,11 @@ public:
const std::function<QObject*(const QObjectList &)> &fn, const std::function<QObject*(const QObjectList &)> &fn,
QByteArrayList injectables, QByteArrayList injectables,
bool weak); bool weak);
void registerService(QByteArray iid,
QString pluginKey,
QString pluginType,
DestructionScope scope = DestroyOnAppDestroy,
bool weak = false);
//! Returns the service for the given interface //! Returns the service for the given interface
template <typename TInterface> template <typename TInterface>
@ -226,6 +234,12 @@ void ServiceRegistry::registerObject(TService *service, DestructionScope scope,
#undef QTMVVM_SERVICE_ASSERT #undef QTMVVM_SERVICE_ASSERT
template<typename TInterface>
void ServiceRegistry::registerPlugin(QString pluginKey, QString pluginType, DestructionScope scope, bool weak)
{
registerService(qobject_interface_iid<TInterface*>(), std::move(pluginKey), std::move(pluginType), scope, weak);
}
template<typename TInterface> template<typename TInterface>
TInterface *ServiceRegistry::service() TInterface *ServiceRegistry::service()
{ {

27
src/mvvmcore/serviceregistry_p.h

@ -34,14 +34,14 @@ public:
class FnServiceInfo : public ServiceInfo { class FnServiceInfo : public ServiceInfo {
public: public:
FnServiceInfo(std::function<QObject*(QObjectList)> creator, QByteArrayList injectables, bool weak, ServiceRegistry::DestructionScope scope); FnServiceInfo(std::function<QObject*(QObjectList)> &&creator, QByteArrayList &&injectables, bool weak, ServiceRegistry::DestructionScope scope);
protected: protected:
QObject *construct(ServiceRegistryPrivate *d) const final; QObject *construct(ServiceRegistryPrivate *d) const final;
private: private:
std::function<QObject*(QObjectList)> creator; std::function<QObject*(QObjectList)> _creator;
QByteArrayList injectables; QByteArrayList _injectables;
}; };
class MetaServiceInfo : public ServiceInfo { class MetaServiceInfo : public ServiceInfo {
@ -52,7 +52,26 @@ public:
QObject *construct(ServiceRegistryPrivate *d) const final; QObject *construct(ServiceRegistryPrivate *d) const final;
private: private:
const QMetaObject *metaObject; const QMetaObject *_metaObject;
};
class PluginServiceInfo : public ServiceInfo {
public:
PluginServiceInfo(QString &&key,
QString &&type,
QByteArray &&iid,
bool weak,
ServiceRegistry::DestructionScope scope);
const QByteArray &iid() const;
protected:
QObject *construct(ServiceRegistryPrivate *d) const final;
private:
QString _key;
QString _type;
QByteArray _iid;
}; };
QMutex serviceMutex{QMutex::Recursive}; QMutex serviceMutex{QMutex::Recursive};

Loading…
Cancel
Save