Migration of QtMvvm from github
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

109 lines
3.0 KiB

8 years ago
#include "serviceregistry.h"
#include "serviceregistry_p.h"
#include <QtCore/QGlobalStatic>
8 years ago
#include <QtCore/QRegularExpression>
#include <QtCore/QMetaProperty>
8 years ago
using namespace QtMvvm;
Q_GLOBAL_STATIC_WITH_ARGS(ServiceRegistry, _instance,
(new ServiceRegistryPrivate()))
ServiceRegistry::ServiceRegistry(ServiceRegistryPrivate *d_ptr) :
d(d_ptr)
{}
ServiceRegistry *ServiceRegistry::instance()
{
return _instance;
}
void ServiceRegistry::registerService(const QByteArray &iid, const QMetaObject *metaObject)
{
8 years ago
QMutexLocker _(&d->serviceMutex);
Q_ASSERT(!d->services.contains(iid)); //TODO exception
d->services.insert(iid, QSharedPointer<ServiceRegistryPrivate::MetaServiceInfo>::create(metaObject));
8 years ago
}
8 years ago
void ServiceRegistry::registerService(const QByteArray &iid, const std::function<QObject*(const QObjectList &)> &fn, QByteArrayList injectables)
8 years ago
{
8 years ago
QMutexLocker _(&d->serviceMutex);
Q_ASSERT(!d->services.contains(iid)); //TODO exception
d->services.insert(iid, QSharedPointer<ServiceRegistryPrivate::FnServiceInfo>::create(fn, injectables));
8 years ago
}
// ------------- Private Implementation -------------
8 years ago
ServiceRegistryPrivate::ServiceRegistryPrivate() :
serviceMutex(),
services()
{}
ServiceRegistryPrivate::ServiceInfo::ServiceInfo() :
_instance(nullptr)
{}
ServiceRegistryPrivate::ServiceInfo::~ServiceInfo()
{
if(_instance)
QMetaObject::invokeMethod(_instance, "deleteLater");
}
QObject *ServiceRegistryPrivate::ServiceInfo::instance(ServiceRegistryPrivate *d)
{
if(!_instance)
_instance = construct(d);
return _instance;
}
ServiceRegistryPrivate::FnServiceInfo::FnServiceInfo(const std::function<QObject*(QObjectList)> &creator, const QByteArrayList &injectables) :
creator(creator),
injectables(injectables)
{}
QObject *ServiceRegistryPrivate::FnServiceInfo::construct(ServiceRegistryPrivate *d) const
{
QObjectList params;
foreach(auto inj, injectables)
params.append(d->services.value(inj)->instance(d));//TODO exception
return creator(params);
}
ServiceRegistryPrivate::MetaServiceInfo::MetaServiceInfo(const QMetaObject *metaObject) :
metaObject(metaObject)
{}
QObject *ServiceRegistryPrivate::MetaServiceInfo::construct(ServiceRegistryPrivate *d) const
8 years ago
{
8 years ago
auto instance = metaObject->newInstance();
Q_ASSERT(instance); //TODO exception
static QRegularExpression nameRegex(QStringLiteral(R"__(^__qtmvvm_inject_(.+)$)__"),
QRegularExpression::OptimizeOnFirstUsageOption);
for(auto i = 0; i < metaObject->propertyCount(); i++) {
auto prop = metaObject->property(i);
auto match = nameRegex.match(QString::fromUtf8(prop.name()));
if(match.hasMatch()) {
auto tPropIndex = metaObject->indexOfProperty(qUtf8Printable(match.captured(1)));
if(tPropIndex == -1)
continue; //TODO warning
auto tProp = metaObject->property(tPropIndex);
auto inject = prop.read(instance).toByteArray();
auto injObj = d->services.value(inject)->instance(d); //TODO exception
tProp.write(instance, QVariant::fromValue(injObj)); //TODO check if casting works
}
}
8 years ago
8 years ago
//TODO call "init" method
return instance;
8 years ago
}