From d3bcce569f699177ccb98d7a21d96519dd70949a Mon Sep 17 00:00:00 2001 From: Chris Adams Date: Wed, 21 Mar 2012 13:24:58 +1000 Subject: Add templated module api registration function This commit adds a templated module api registration function which allows clients to provide type information at registration time. We use this typeinformation in V4 if available, in order to allow module APIs to be used in v4 bindings. This commit also clarifies the ownership semantics of QObject module apis, and updates some documentation references which were missed during the rename of Declarative to Qml. Task-number: QTBUG-24894 Change-Id: Iebb61ca8d8eacbb15218549eab715e22f52a1474 Reviewed-by: Michael Brasser --- src/imports/localstorage/plugin.cpp | 2 +- src/qml/qml/qqml.h | 19 +++++++++++++++++-- src/qml/qml/qqmlengine.cpp | 1 + src/qml/qml/qqmlmetatype.cpp | 4 ++++ src/qml/qml/qqmlmetatype_p.h | 12 ++++++++---- src/qml/qml/qqmlprivate.h | 1 + src/qml/qml/v4/qv4irbuilder.cpp | 20 ++++++++++---------- 7 files changed, 42 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/imports/localstorage/plugin.cpp b/src/imports/localstorage/plugin.cpp index 0187d06e6a..4f08e71fd0 100644 --- a/src/imports/localstorage/plugin.cpp +++ b/src/imports/localstorage/plugin.cpp @@ -661,7 +661,7 @@ public: void registerTypes(const char *uri) { Q_ASSERT(QLatin1String(uri) == "QtQuick.LocalStorage"); - qmlRegisterModuleApi(uri, 2, 0, module_api_factory); + qmlRegisterModuleApi(uri, 2, 0, module_api_factory); } }; diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h index 32da2c616e..5b500e0814 100644 --- a/src/qml/qml/qqml.h +++ b/src/qml/qml/qqml.h @@ -421,7 +421,7 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi uri, versionMajor, versionMinor, - callback, 0 + callback, 0, 0 }; return QQmlPrivate::qmlregister(QQmlPrivate::ModuleApiRegistration, &api); @@ -435,7 +435,22 @@ inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMi uri, versionMajor, versionMinor, - 0, callback + 0, callback, 0 // unknown QObject instance type + }; + + return QQmlPrivate::qmlregister(QQmlPrivate::ModuleApiRegistration, &api); +} + +template +inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, + QObject *(*callback)(QQmlEngine *, QJSEngine *)) +{ + QQmlPrivate::RegisterModuleApi api = { + 1, + + uri, versionMajor, versionMinor, + + 0, callback, &T::staticMetaObject }; return QQmlPrivate::qmlregister(QQmlPrivate::ModuleApiRegistration, &api); diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 489b4f895a..3d09ebb83f 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1701,6 +1701,7 @@ QQmlEnginePrivate::moduleApiInstance(const QQmlMetaType::ModuleApi &module) a = new QQmlMetaType::ModuleApiInstance; a->scriptCallback = module.script; a->qobjectCallback = module.qobject; + a->instanceMetaObject = module.instanceMetaObject; moduleApiInstances.insert(module, a); } diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 985adbfec7..d4c19f8325 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -913,6 +913,10 @@ int registerModuleApi(const QQmlPrivate::RegisterModuleApi &api) import.minor = api.versionMinor; import.script = api.scriptApi; import.qobject = api.qobjectApi; + import.instanceMetaObject = (api.qobjectApi && api.version >= 1) ? api.instanceMetaObject : 0; // BC with version 0. + + if (import.qobject && !import.instanceMetaObject) // BC - check import.iMO rather than api.iMO. + qWarning() << "qmlRegisterModuleApi(): sub-optimal: use the templated version of this function instead!"; int index = data->moduleApiCount++; diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index b715d0c8f2..03017cafab 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -115,20 +115,23 @@ public: struct ModuleApiInstance { ModuleApiInstance() - : scriptCallback(0), qobjectCallback(0), qobjectApi(0) {} + : scriptCallback(0), qobjectCallback(0), qobjectApi(0), instanceMetaObject(0) {} QJSValue (*scriptCallback)(QQmlEngine *, QJSEngine *); QObject *(*qobjectCallback)(QQmlEngine *, QJSEngine *); - QJSValue scriptApi; QObject *qobjectApi; + const QMetaObject *instanceMetaObject; + QJSValue scriptApi; + }; struct ModuleApi { inline ModuleApi(); inline bool operator==(const ModuleApi &) const; int major; int minor; - QJSValue (*script)(QQmlEngine *, QJSEngine *); QObject *(*qobject)(QQmlEngine *, QJSEngine *); + const QMetaObject *instanceMetaObject; + QJSValue (*script)(QQmlEngine *, QJSEngine *); }; static ModuleApi moduleApi(const QString &, int, int); static QHash > moduleApis(); @@ -247,8 +250,9 @@ QQmlMetaType::ModuleApi::ModuleApi() { major = 0; minor = 0; - script = 0; qobject = 0; + instanceMetaObject = 0; + script = 0; } bool QQmlMetaType::ModuleApi::operator==(const ModuleApi &other) const diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h index b4c6fc3a12..82da62ff45 100644 --- a/src/qml/qml/qqmlprivate.h +++ b/src/qml/qml/qqmlprivate.h @@ -246,6 +246,7 @@ namespace QQmlPrivate QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *); QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *); + const QMetaObject *instanceMetaObject; }; enum RegistrationType { diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp index ea4d1afbbc..453120c6c7 100644 --- a/src/qml/qml/v4/qv4irbuilder.cpp +++ b/src/qml/qml/v4/qv4irbuilder.cpp @@ -428,18 +428,18 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast) if (r.isValid()) { if (r.type) { _expr.code = _block->ATTACH_TYPE(name, r.type, IR::Name::ScopeStorage, line, column); - } /*else if (r.importNamespace) { + } else if (r.importNamespace) { QQmlMetaType::ModuleApiInstance *moduleApi = m_expression->importCache->moduleApi(r.importNamespace); - if (moduleApi) { - if (moduleApi->qobjectCallback) { - moduleApi->qobjectApi = moduleApi->qobjectCallback(QQmlEnginePrivate::get(m_engine), QQmlEnginePrivate::get(m_engine)); - moduleApi->qobjectCallback = 0; - moduleApi->scriptCallback = 0; - } - if (moduleApi->qobjectApi) - _expr.code = _block->MODULE_OBJECT(name, moduleApi->qobjectApi->metaObject(), IR::Name::MemberStorage, line, column); + if (moduleApi && moduleApi->instanceMetaObject) { + // Note: we don't need to check moduleApi->qobjectCallback here, since + // we did that check in registerModuleApi() in qqmlmetatype.cpp. + // We cannot create the QObject Module Api Instance here, + // as we might be running in a loader thread. + // Thus, V4 can only handle bindings which use Module APIs which + // were registered with the templated registration function. + _expr.code = _block->MODULE_OBJECT(name, moduleApi->instanceMetaObject, IR::Name::MemberStorage, line, column); } - }*/ //### we can't create the actual QObject here, as we may be running in a thread (can be reenabled once QTBUG-24894 is handled) + } // We don't support anything else } else { bool found = false; -- cgit v1.2.3