aboutsummaryrefslogtreecommitdiffstats
path: root/src/qml/qml
diff options
context:
space:
mode:
authorGlenn Watson <glenn.watson@nokia.com>2012-07-24 11:41:50 +1000
committerQt by Nokia <qt-info@nokia.com>2012-08-08 07:55:19 +0200
commit6ebf215fdaf2d757ab90ae4d46c4b938e978e2dc (patch)
tree515da352f1cc4d5567b6d93f0b19952b2e27d705 /src/qml/qml
parent92562eacbc3c614a83a734f1108ed7df02415eae (diff)
Add type name to singleton (module api) implementations.
This change renames the previous module api implementation to singleton types. When a singleton type is registered, a type name must be provided that is used when accessing the API from QML. This makes the implementation more consistent with the rest of QML. Task-number: QTBUG-26549 Change-Id: Iab0bb1ccf516bd3ae20aee562a64d22976e0aecd Reviewed-by: Chris Adams <christopher.adams@nokia.com>
Diffstat (limited to 'src/qml/qml')
-rw-r--r--src/qml/qml/qqml.h16
-rw-r--r--src/qml/qml/qqmlengine.cpp26
-rw-r--r--src/qml/qml/qqmlengine_p.h4
-rw-r--r--src/qml/qml/qqmlimport.cpp19
-rw-r--r--src/qml/qml/qqmlmetatype.cpp124
-rw-r--r--src/qml/qml/qqmlmetatype_p.h25
-rw-r--r--src/qml/qml/qqmlprivate.h5
-rw-r--r--src/qml/qml/qqmltypenamecache.cpp26
-rw-r--r--src/qml/qml/qqmltypenamecache_p.h7
-rw-r--r--src/qml/qml/v4/qv4bindings.cpp16
-rw-r--r--src/qml/qml/v4/qv4compiler.cpp2
-rw-r--r--src/qml/qml/v4/qv4irbuilder.cpp14
-rw-r--r--src/qml/qml/v8/qv8typewrapper.cpp84
13 files changed, 228 insertions, 140 deletions
diff --git a/src/qml/qml/qqml.h b/src/qml/qml/qqml.h
index 528f8e6416..a10ed0c5e8 100644
--- a/src/qml/qml/qqml.h
+++ b/src/qml/qml/qqml.h
@@ -433,33 +433,33 @@ QObject *qmlAttachedPropertiesObject(const QObject *obj, bool create = true)
Q_QML_EXPORT void qmlRegisterBaseTypes(const char *uri, int versionMajor, int versionMinor);
-inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
+inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
QJSValue (*callback)(QQmlEngine *, QJSEngine *))
{
- QQmlPrivate::RegisterModuleApi api = {
+ QQmlPrivate::RegisterSingletonType api = {
0,
- uri, versionMajor, versionMinor,
+ uri, versionMajor, versionMinor, typeName,
callback, 0, 0
};
- return QQmlPrivate::qmlregister(QQmlPrivate::ModuleApiRegistration, &api);
+ return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
}
template <typename T>
-inline int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor,
+inline int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName,
QObject *(*callback)(QQmlEngine *, QJSEngine *))
{
- QQmlPrivate::RegisterModuleApi api = {
+ QQmlPrivate::RegisterSingletonType api = {
1,
- uri, versionMajor, versionMinor,
+ uri, versionMajor, versionMinor, typeName,
0, callback, &T::staticMetaObject
};
- return QQmlPrivate::qmlregister(QQmlPrivate::ModuleApiRegistration, &api);
+ return QQmlPrivate::qmlregister(QQmlPrivate::SingletonRegistration, &api);
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp
index 589d7b7c8a..bce5579f31 100644
--- a/src/qml/qml/qqmlengine.cpp
+++ b/src/qml/qml/qqmlengine.cpp
@@ -463,7 +463,7 @@ QQmlEnginePrivate::~QQmlEnginePrivate()
(*iter)->release();
for(QHash<QPair<QQmlType *, int>, QQmlPropertyCache *>::Iterator iter = typePropertyCache.begin(); iter != typePropertyCache.end(); ++iter)
(*iter)->release();
- for(QHash<QQmlMetaType::ModuleApi, QQmlMetaType::ModuleApiInstance *>::Iterator iter = moduleApiInstances.begin(); iter != moduleApiInstances.end(); ++iter) {
+ for (QHash<QQmlMetaType::SingletonType, QQmlMetaType::SingletonInstance *>::Iterator iter = singletonTypeInstances.begin(); iter != singletonTypeInstances.end(); ++iter) {
delete (*iter)->qobjectApi;
delete *iter;
}
@@ -735,23 +735,23 @@ QQmlEngine::~QQmlEngine()
}
// Emit onDestruction signals for the root context before
- // we destroy the contexts, engine, Module APIs etc. that
+ // we destroy the contexts, engine, Singleton Types etc. that
// may be required to handle the destruction signal.
QQmlContextData::get(rootContext())->emitDestruction();
- // if we are the parent of any of the qobject module api instances,
+ // if we are the parent of any of the qobject singleton type instances,
// we need to remove them from our internal list, in order to prevent
// a segfault in engine private dtor.
- QList<QQmlMetaType::ModuleApi> keys = d->moduleApiInstances.keys();
+ QList<QQmlMetaType::SingletonType> keys = d->singletonTypeInstances.keys();
QObject *currQObjectApi = 0;
- QQmlMetaType::ModuleApiInstance *currInstance = 0;
- foreach (const QQmlMetaType::ModuleApi &key, keys) {
- currInstance = d->moduleApiInstances.value(key);
+ QQmlMetaType::SingletonInstance *currInstance = 0;
+ foreach (const QQmlMetaType::SingletonType &key, keys) {
+ currInstance = d->singletonTypeInstances.value(key);
currQObjectApi = currInstance->qobjectApi;
if (this->children().contains(currQObjectApi)) {
delete currQObjectApi;
delete currInstance;
- d->moduleApiInstances.remove(key);
+ d->singletonTypeInstances.remove(key);
}
}
@@ -1881,18 +1881,18 @@ QQmlPropertyCache *QQmlEnginePrivate::createCache(QQmlType *type, int minorVersi
return raw;
}
-QQmlMetaType::ModuleApiInstance *
-QQmlEnginePrivate::moduleApiInstance(const QQmlMetaType::ModuleApi &module)
+QQmlMetaType::SingletonInstance *
+QQmlEnginePrivate::singletonTypeInstance(const QQmlMetaType::SingletonType &module)
{
Locker locker(this);
- QQmlMetaType::ModuleApiInstance *a = moduleApiInstances.value(module);
+ QQmlMetaType::SingletonInstance *a = singletonTypeInstances.value(module);
if (!a) {
- a = new QQmlMetaType::ModuleApiInstance;
+ a = new QQmlMetaType::SingletonInstance;
a->scriptCallback = module.script;
a->qobjectCallback = module.qobject;
a->instanceMetaObject = module.instanceMetaObject;
- moduleApiInstances.insert(module, a);
+ singletonTypeInstances.insert(module, a);
}
return a;
diff --git a/src/qml/qml/qqmlengine_p.h b/src/qml/qml/qqmlengine_p.h
index b90d597be6..f62e99b3ce 100644
--- a/src/qml/qml/qqmlengine_p.h
+++ b/src/qml/qml/qqmlengine_p.h
@@ -223,7 +223,7 @@ public:
inline static void deleteInEngineThread(QQmlEngine *, T *);
// These methods may be called from the loader thread
- QQmlMetaType::ModuleApiInstance *moduleApiInstance(const QQmlMetaType::ModuleApi &module);
+ QQmlMetaType::SingletonInstance *singletonTypeInstance(const QQmlMetaType::SingletonType &module);
// These methods may be called from the loader thread
inline QQmlPropertyCache *cache(QObject *obj);
@@ -305,7 +305,7 @@ private:
// These members must be protected by a QQmlEnginePrivate::Locker as they are required by
// the threaded loader. Only access them through their respective accessor methods.
- QHash<QQmlMetaType::ModuleApi, QQmlMetaType::ModuleApiInstance *> moduleApiInstances;
+ QHash<QQmlMetaType::SingletonType, QQmlMetaType::SingletonInstance *> singletonTypeInstances;
QHash<const QMetaObject *, QQmlPropertyCache *> propertyCache;
QHash<QPair<QQmlType *, int>, QQmlPropertyCache *> typePropertyCache;
QHash<int, int> m_qmlLists;
diff --git a/src/qml/qml/qqmlimport.cpp b/src/qml/qml/qqmlimport.cpp
index e7133992d9..6475621bee 100644
--- a/src/qml/qml/qqmlimport.cpp
+++ b/src/qml/qml/qqmlimport.cpp
@@ -299,6 +299,15 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache, QQmlEngine *engine) co
QQmlTypeModule *module = QQmlMetaType::typeModule(import->uri, import->majversion);
if (module)
cache->m_anonymousImports.append(QQmlTypeModuleVersion(module, import->minversion));
+
+ QQmlMetaType::SingletonType singletonType = QQmlMetaType::singletonType(import->uri, import->majversion,
+ import->minversion);
+ if (singletonType.script || singletonType.qobject) {
+ QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
+ QQmlMetaType::SingletonInstance *apiInstance = ep->singletonTypeInstance(singletonType);
+
+ cache->addSingletonType(singletonType.typeName, apiInstance);
+ }
}
for (QQmlImportNamespace *ns = d->qualifiedSets.first(); ns; ns = d->qualifiedSets.next(ns)) {
@@ -313,12 +322,14 @@ void QQmlImports::populateCache(QQmlTypeNameCache *cache, QQmlEngine *engine) co
typeimport.modules.append(QQmlTypeModuleVersion(module, import->minversion));
}
- QQmlMetaType::ModuleApi moduleApi = QQmlMetaType::moduleApi(import->uri, import->majversion,
+ QQmlMetaType::SingletonType singletonType = QQmlMetaType::singletonType(import->uri, import->majversion,
import->minversion);
- if (moduleApi.script || moduleApi.qobject) {
- QQmlTypeNameCache::Import &import = cache->m_namedImports[set.prefix];
+ if (singletonType.script || singletonType.qobject) {
QQmlEnginePrivate *ep = QQmlEnginePrivate::get(engine);
- import.moduleApi = ep->moduleApiInstance(moduleApi);
+ QQmlMetaType::SingletonInstance *apiInstance = ep->singletonTypeInstance(singletonType);
+
+ cache->add(set.prefix);
+ cache->addSingletonType(singletonType.typeName, apiInstance, set.prefix);
}
}
}
diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp
index b3a16b034c..35ff9fd5d1 100644
--- a/src/qml/qml/qqmlmetatype.cpp
+++ b/src/qml/qml/qqmlmetatype.cpp
@@ -94,14 +94,35 @@ struct QQmlMetaTypeData
typedef QHash<VersionedUri, QQmlTypeModule *> TypeModules;
TypeModules uriToModule;
- struct ModuleApiList {
- ModuleApiList() : sorted(true) {}
- QList<QQmlMetaType::ModuleApi> moduleApis;
+ struct SingletonTypeList {
+ SingletonTypeList() : sorted(true) {}
+ QList<QQmlMetaType::SingletonType> singletonTypes;
bool sorted;
};
- typedef QStringHash<ModuleApiList> ModuleApis;
- ModuleApis moduleApis;
- int moduleApiCount;
+ typedef QStringHash<SingletonTypeList> SingletonTypes;
+ SingletonTypes singletonTypes;
+ int singletonTypeCount;
+
+ bool singletonTypeExists(const QString &uri, const QString &typeName, int major, int minor)
+ {
+ QQmlMetaTypeData::SingletonTypeList *apiList = singletonTypes.value(uri);
+ if (apiList) {
+ for (int i=0 ; i < apiList->singletonTypes.size() ; ++i) {
+ const QQmlMetaType::SingletonType &import = apiList->singletonTypes.at(i);
+ if (import.major == major && import.minor == minor && typeName == import.typeName)
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ bool typeExists(const QString &uri, const QString &typeName, int major, int minor)
+ {
+ QQmlMetaTypeData::VersionedUri versionedUri(uri, major);
+ QQmlTypeModule *module = uriToModule.value(versionedUri);
+ return module && module->typeNoLock(typeName, minor) != 0;
+ }
QBitArray objects;
QBitArray interfaces;
@@ -141,7 +162,7 @@ static uint qHash(const QQmlMetaTypeData::VersionedUri &v)
}
QQmlMetaTypeData::QQmlMetaTypeData()
-: moduleApiCount(0)
+: singletonTypeCount(0)
{
}
@@ -779,6 +800,20 @@ void QQmlTypeModulePrivate::add(QQmlType *type)
list.append(type);
}
+QQmlType *QQmlTypeModule::typeNoLock(const QString &name, int minor)
+{
+ // Expected that the caller has already handled locking metaTypeDataLock
+
+ QList<QQmlType *> *types = d->typeHash.value(name);
+ if (!types) return 0;
+
+ for (int ii = 0; ii < types->count(); ++ii)
+ if (types->at(ii)->minorVersion() <= minor)
+ return types->at(ii);
+
+ return 0;
+}
+
QQmlType *QQmlTypeModule::type(const QHashedStringRef &name, int minor)
{
QReadLocker lock(metaTypeDataLock());
@@ -911,6 +946,11 @@ int registerType(const QQmlPrivate::RegisterType &type)
if (type.uri && type.elementName) {
QString nameSpace = moduleFromUtf8(type.uri);
+ if (data->singletonTypeExists(nameSpace, type.elementName, type.versionMajor, type.versionMinor)) {
+ qWarning("Cannot register type %s in uri %s %d.%d (a conflicting singleton type already exists)", qPrintable(type.elementName), qPrintable(nameSpace), type.versionMajor, type.versionMinor);
+ return -1;
+ }
+
if (!data->typeRegistrationNamespace.isEmpty()) {
// We can only install types into the registered namespace
if (nameSpace != data->typeRegistrationNamespace) {
@@ -966,28 +1006,38 @@ int registerType(const QQmlPrivate::RegisterType &type)
return index;
}
-int registerModuleApi(const QQmlPrivate::RegisterModuleApi &api)
+int registerSingletonType(const QQmlPrivate::RegisterSingletonType &api)
{
QWriteLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
QString uri = QString::fromUtf8(api.uri);
- QQmlMetaType::ModuleApi import;
+ QQmlMetaType::SingletonType import;
import.major = api.versionMajor;
import.minor = api.versionMinor;
import.script = api.scriptApi;
import.qobject = api.qobjectApi;
+ Q_ASSERT(api.typeName);
+ import.typeName = QString::fromUtf8(api.typeName);
import.instanceMetaObject = (api.qobjectApi && api.version >= 1) ? api.instanceMetaObject : 0; // BC with version 0.
- int index = data->moduleApiCount++;
+ if (data->singletonTypeExists(uri, import.typeName, import.major, import.minor)) {
+ qWarning("Cannot register singleton type %s in uri %s %d.%d (a conflicting singleton type already exists)", qPrintable(import.typeName), qPrintable(uri), import.major, import.minor);
+ return -1;
+ } else if (data->typeExists(uri, import.typeName, import.major, import.minor)) {
+ qWarning("Cannot register singleton type %s in uri %s %d.%d (a conflicting type already exists)", qPrintable(import.typeName), qPrintable(uri), import.major, import.minor);
+ return -1;
+ }
+
+ int index = data->singletonTypeCount++;
- QQmlMetaTypeData::ModuleApiList *apiList = data->moduleApis.value(uri);
+ QQmlMetaTypeData::SingletonTypeList *apiList = data->singletonTypes.value(uri);
if (!apiList) {
- QQmlMetaTypeData::ModuleApiList apis;
- apis.moduleApis << import;
- data->moduleApis.insert(uri, apis);
+ QQmlMetaTypeData::SingletonTypeList apis;
+ apis.singletonTypes << import;
+ data->singletonTypes.insert(uri, apis);
} else {
- apiList->moduleApis << import;
+ apiList->singletonTypes << import;
apiList->sorted = false;
}
@@ -1007,8 +1057,8 @@ int QQmlPrivate::qmlregister(RegistrationType type, void *data)
return registerInterface(*reinterpret_cast<RegisterInterface *>(data));
} else if (type == AutoParentRegistration) {
return registerAutoParentFunction(*reinterpret_cast<RegisterAutoParent *>(data));
- } else if (type == ModuleApiRegistration) {
- return registerModuleApi(*reinterpret_cast<RegisterModuleApi *>(data));
+ } else if (type == SingletonRegistration) {
+ return registerSingletonType(*reinterpret_cast<RegisterSingletonType *>(data));
}
return -1;
}
@@ -1068,8 +1118,8 @@ bool QQmlMetaType::isAnyModule(const QString &uri)
return true;
}
- // then, check ModuleApis
- QQmlMetaTypeData::ModuleApiList *apiList = data->moduleApis.value(uri);
+ // then, check SingletonTypes
+ QQmlMetaTypeData::SingletonTypeList *apiList = data->singletonTypes.value(uri);
if (apiList)
return true;
@@ -1096,10 +1146,10 @@ bool QQmlMetaType::isModule(const QString &module, int versionMajor, int version
if (tm && tm->minimumMinorVersion() <= versionMinor && tm->maximumMinorVersion() >= versionMinor)
return true;
- // then, check ModuleApis
- QQmlMetaTypeData::ModuleApiList *apiList = data->moduleApis.value(module);
+ // then, check SingletonTypes
+ QQmlMetaTypeData::SingletonTypeList *apiList = data->singletonTypes.value(module);
if (apiList) {
- foreach (const QQmlMetaType::ModuleApi &mApi, apiList->moduleApis) {
+ foreach (const QQmlMetaType::SingletonType &mApi, apiList->singletonTypes) {
if (mApi.major == versionMajor && mApi.minor == versionMinor) // XXX is this correct?
return true;
}
@@ -1122,46 +1172,46 @@ QList<QQmlPrivate::AutoParentFunction> QQmlMetaType::parentFunctions()
return data->parentFunctions;
}
-static bool operator<(const QQmlMetaType::ModuleApi &lhs, const QQmlMetaType::ModuleApi &rhs)
+static bool operator<(const QQmlMetaType::SingletonType &lhs, const QQmlMetaType::SingletonType &rhs)
{
return lhs.major < rhs.major || (lhs.major == rhs.major && lhs.minor < rhs.minor);
}
-QQmlMetaType::ModuleApi
-QQmlMetaType::moduleApi(const QString &uri, int versionMajor, int versionMinor)
+QQmlMetaType::SingletonType
+QQmlMetaType::singletonType(const QString &uri, int versionMajor, int versionMinor)
{
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QQmlMetaTypeData::ModuleApiList *apiList = data->moduleApis.value(uri);
+ QQmlMetaTypeData::SingletonTypeList *apiList = data->singletonTypes.value(uri);
if (!apiList)
- return ModuleApi();
+ return SingletonType();
if (apiList->sorted == false) {
- qSort(apiList->moduleApis.begin(), apiList->moduleApis.end());
+ qSort(apiList->singletonTypes.begin(), apiList->singletonTypes.end());
apiList->sorted = true;
}
- for (int ii = apiList->moduleApis.count() - 1; ii >= 0; --ii) {
- const ModuleApi &import = apiList->moduleApis.at(ii);
+ for (int ii = apiList->singletonTypes.count() - 1; ii >= 0; --ii) {
+ const SingletonType &import = apiList->singletonTypes.at(ii);
if (import.major == versionMajor && import.minor <= versionMinor)
return import;
}
- return ModuleApi();
+ return SingletonType();
}
-QHash<QString, QList<QQmlMetaType::ModuleApi> > QQmlMetaType::moduleApis()
+QHash<QString, QList<QQmlMetaType::SingletonType> > QQmlMetaType::singletonTypes()
{
QReadLocker lock(metaTypeDataLock());
QQmlMetaTypeData *data = metaTypeData();
- QHash<QString, QList<ModuleApi> > moduleApis;
- QStringHash<QQmlMetaTypeData::ModuleApiList>::ConstIterator it = data->moduleApis.begin();
- for (; it != data->moduleApis.end(); ++it)
- moduleApis[it.key()] = it.value().moduleApis;
+ QHash<QString, QList<SingletonType> > singletonTypes;
+ QStringHash<QQmlMetaTypeData::SingletonTypeList>::ConstIterator it = data->singletonTypes.begin();
+ for (; it != data->singletonTypes.end(); ++it)
+ singletonTypes[it.key()] = it.value().singletonTypes;
- return moduleApis;
+ return singletonTypes;
}
QObject *QQmlMetaType::toQObject(const QVariant &v, bool *ok)
diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h
index 6f76c95544..4e60c2d0d3 100644
--- a/src/qml/qml/qqmlmetatype_p.h
+++ b/src/qml/qml/qqmlmetatype_p.h
@@ -117,8 +117,8 @@ public:
static void setQQuickAnchorLineCompareFunction(CompareFunction);
static bool QQuickAnchorLineCompare(const void *p1, const void *p2);
- struct ModuleApiInstance {
- ModuleApiInstance()
+ struct SingletonInstance {
+ SingletonInstance()
: scriptCallback(0), qobjectCallback(0), qobjectApi(0), instanceMetaObject(0) {}
QJSValue (*scriptCallback)(QQmlEngine *, QJSEngine *);
@@ -128,17 +128,18 @@ public:
QJSValue scriptApi;
};
- struct ModuleApi {
- inline ModuleApi();
- inline bool operator==(const ModuleApi &) const;
+ struct SingletonType {
+ inline SingletonType();
+ inline bool operator==(const SingletonType &) const;
int major;
int minor;
+ QString typeName;
QObject *(*qobject)(QQmlEngine *, QJSEngine *);
const QMetaObject *instanceMetaObject;
QJSValue (*script)(QQmlEngine *, QJSEngine *);
};
- static ModuleApi moduleApi(const QString &, int, int);
- static QHash<QString, QList<ModuleApi> > moduleApis();
+ static SingletonType singletonType(const QString &, int, int);
+ static QHash<QString, QList<SingletonType> > singletonTypes();
static bool namespaceContainsRegistrations(const QString &);
@@ -232,7 +233,11 @@ public:
QQmlType *type(const QHashedV8String &, int);
private:
+ QQmlType *typeNoLock(const QString &name, int minor);
+
friend int registerType(const QQmlPrivate::RegisterType &);
+ friend struct QQmlMetaTypeData;
+
QQmlTypeModule();
~QQmlTypeModule();
QQmlTypeModulePrivate *d;
@@ -257,7 +262,7 @@ private:
int m_minor;
};
-QQmlMetaType::ModuleApi::ModuleApi()
+QQmlMetaType::SingletonType::SingletonType()
{
major = 0;
minor = 0;
@@ -266,12 +271,12 @@ QQmlMetaType::ModuleApi::ModuleApi()
script = 0;
}
-bool QQmlMetaType::ModuleApi::operator==(const ModuleApi &other) const
+bool QQmlMetaType::SingletonType::operator==(const SingletonType &other) const
{
return major == other.major && minor == other.minor && script == other.script && qobject == other.qobject;
}
-inline uint qHash(const QQmlMetaType::ModuleApi &import)
+inline uint qHash(const QQmlMetaType::SingletonType &import)
{
return import.major ^ import.minor ^ quintptr(import.script) ^ quintptr(import.qobject);
}
diff --git a/src/qml/qml/qqmlprivate.h b/src/qml/qml/qqmlprivate.h
index 82da62ff45..7ef24e9f37 100644
--- a/src/qml/qml/qqmlprivate.h
+++ b/src/qml/qml/qqmlprivate.h
@@ -237,12 +237,13 @@ namespace QQmlPrivate
AutoParentFunction function;
};
- struct RegisterModuleApi {
+ struct RegisterSingletonType {
int version;
const char *uri;
int versionMajor;
int versionMinor;
+ const char *typeName;
QJSValue (*scriptApi)(QQmlEngine *, QJSEngine *);
QObject *(*qobjectApi)(QQmlEngine *, QJSEngine *);
@@ -253,7 +254,7 @@ namespace QQmlPrivate
TypeRegistration = 0,
InterfaceRegistration = 1,
AutoParentRegistration = 2,
- ModuleApiRegistration = 3
+ SingletonRegistration = 3
};
int Q_QML_EXPORT qmlregister(RegistrationType, void *);
diff --git a/src/qml/qml/qqmltypenamecache.cpp b/src/qml/qml/qqmltypenamecache.cpp
index f9d3e7704c..bc75ca6636 100644
--- a/src/qml/qml/qqmltypenamecache.cpp
+++ b/src/qml/qml/qqmltypenamecache.cpp
@@ -71,6 +71,21 @@ void QQmlTypeNameCache::add(const QHashedString &name, int importedScriptIndex,
m_namedImports.insert(name, import);
}
+void QQmlTypeNameCache::addSingletonType(const QHashedString &name, QQmlMetaType::SingletonInstance *apiInstance, const QHashedString &nameSpace)
+{
+ Import import;
+ import.singletonType = apiInstance;
+
+ if (nameSpace.length() != 0) {
+ Import *i = m_namedImports.value(nameSpace);
+ Q_ASSERT(i != 0);
+ m_namespacedImports[i].insert(name, import);
+ } else {
+ if (!m_namedImports.contains(name))
+ m_namedImports.insert(name, import);
+ }
+}
+
QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedStringRef &name)
{
Result result = query(m_namedImports, name);
@@ -108,19 +123,22 @@ QQmlTypeNameCache::Result QQmlTypeNameCache::query(const QHashedV8String &name,
Q_ASSERT(i->scriptIndex == -1);
QMap<const Import *, QStringHash<Import> >::const_iterator it = m_namespacedImports.find(i);
- if (it != m_namespacedImports.constEnd())
- return query(*it, name);
+ if (it != m_namespacedImports.constEnd()) {
+ Result r = query(*it, name);
+ if (r.isValid())
+ return r;
+ }
return typeSearch(i->modules, name);
}
-QQmlMetaType::ModuleApiInstance *QQmlTypeNameCache::moduleApi(const void *importNamespace)
+QQmlMetaType::SingletonInstance *QQmlTypeNameCache::singletonType(const void *importNamespace)
{
Q_ASSERT(importNamespace);
const Import *i = static_cast<const Import *>(importNamespace);
Q_ASSERT(i->scriptIndex == -1);
- return i->moduleApi;
+ return i->singletonType;
}
QT_END_NAMESPACE
diff --git a/src/qml/qml/qqmltypenamecache_p.h b/src/qml/qml/qqmltypenamecache_p.h
index a9268db37a..841c5aef6b 100644
--- a/src/qml/qml/qqmltypenamecache_p.h
+++ b/src/qml/qml/qqmltypenamecache_p.h
@@ -74,6 +74,7 @@ public:
inline bool isEmpty() const;
void add(const QHashedString &name, int sciptIndex = -1, const QHashedString &nameSpace = QHashedString());
+ void addSingletonType(const QHashedString &name, QQmlMetaType::SingletonInstance *apiInstance, const QHashedString &nameSpace = QHashedString());
struct Result {
inline Result();
@@ -92,7 +93,7 @@ public:
Result query(const QHashedStringRef &, const void *importNamespace);
Result query(const QHashedV8String &);
Result query(const QHashedV8String &, const void *importNamespace);
- QQmlMetaType::ModuleApiInstance *moduleApi(const void *importNamespace);
+ QQmlMetaType::SingletonInstance *singletonType(const void *importNamespace);
private:
friend class QQmlImports;
@@ -100,7 +101,7 @@ private:
struct Import {
inline Import();
// Imported module
- QQmlMetaType::ModuleApiInstance *moduleApi;
+ QQmlMetaType::SingletonInstance *singletonType;
QVector<QQmlTypeModuleVersion> modules;
// Or, imported script
@@ -172,7 +173,7 @@ bool QQmlTypeNameCache::Result::isValid() const
}
QQmlTypeNameCache::Import::Import()
-: moduleApi(0), scriptIndex(-1)
+: singletonType(0), scriptIndex(-1)
{
}
diff --git a/src/qml/qml/v4/qv4bindings.cpp b/src/qml/qml/v4/qv4bindings.cpp
index c0e0f22fad..9b74c2aa72 100644
--- a/src/qml/qml/v4/qv4bindings.cpp
+++ b/src/qml/qml/v4/qv4bindings.cpp
@@ -949,15 +949,15 @@ void QV4Bindings::run(int instrIndex, quint32 &executedBlocks,
reg.cleanupString();
if (r.isValid() && r.importNamespace) {
- QQmlMetaType::ModuleApiInstance *moduleApi = context->imports->moduleApi(r.importNamespace);
- if (moduleApi) {
- if (moduleApi->qobjectCallback) {
- moduleApi->qobjectApi = moduleApi->qobjectCallback(context->engine, context->engine);
- moduleApi->qobjectCallback = 0;
- moduleApi->scriptCallback = 0;
+ QQmlMetaType::SingletonInstance *singletonType = context->imports->singletonType(r.importNamespace);
+ if (singletonType) {
+ if (singletonType->qobjectCallback) {
+ singletonType->qobjectApi = singletonType->qobjectCallback(context->engine, context->engine);
+ singletonType->qobjectCallback = 0;
+ singletonType->scriptCallback = 0;
}
- if (moduleApi->qobjectApi)
- reg.setQObject(moduleApi->qobjectApi);
+ if (singletonType->qobjectApi)
+ reg.setQObject(singletonType->qobjectApi);
}
}
}
diff --git a/src/qml/qml/v4/qv4compiler.cpp b/src/qml/qml/v4/qv4compiler.cpp
index 8f87583a94..b697204839 100644
--- a/src/qml/qml/v4/qv4compiler.cpp
+++ b/src/qml/qml/v4/qv4compiler.cpp
@@ -334,7 +334,7 @@ void QV4CompilerPrivate::visitName(IR::Name *e)
/*
Existing module object lookup methods include:
1. string -> module object (search via importCache->query(name))
- 2. QQmlMetaType::ModuleApi -> module object (via QQmlEnginePrivate::moduleApiInstance() cache)
+ 2. QQmlMetaType::SingletonType -> module object (via QQmlEnginePrivate::singletonTypeInstance() cache)
We currently use 1, which is not ideal for performance
*/
_subscribeName << *e->id;
diff --git a/src/qml/qml/v4/qv4irbuilder.cpp b/src/qml/qml/v4/qv4irbuilder.cpp
index 79090b4269..93c552173f 100644
--- a/src/qml/qml/v4/qv4irbuilder.cpp
+++ b/src/qml/qml/v4/qv4irbuilder.cpp
@@ -446,15 +446,15 @@ bool QV4IRBuilder::visit(AST::IdentifierExpression *ast)
if (r.type) {
_expr.code = _block->ATTACH_TYPE(name, r.type, IR::Name::ScopeStorage, line, column);
} else if (r.importNamespace) {
- QQmlMetaType::ModuleApiInstance *moduleApi = m_expression->importCache->moduleApi(r.importNamespace);
- 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,
+ QQmlMetaType::SingletonInstance *singletonType = m_expression->importCache->singletonType(r.importNamespace);
+ if (singletonType && singletonType->instanceMetaObject) {
+ // Note: we don't need to check singletonType->qobjectCallback here, since
+ // we did that check in registerSingletonType() in qqmlmetatype.cpp.
+ // We cannot create the QObject Singleton Type Instance here,
// as we might be running in a loader thread.
- // Thus, V4 can only handle bindings which use Module APIs which
+ // Thus, V4 can only handle bindings which use Singleton Types which
// were registered with the templated registration function.
- _expr.code = _block->MODULE_OBJECT(name, moduleApi->instanceMetaObject, IR::Name::MemberStorage, line, column);
+ _expr.code = _block->MODULE_OBJECT(name, singletonType->instanceMetaObject, IR::Name::MemberStorage, line, column);
}
}
// We don't support anything else
diff --git a/src/qml/qml/v8/qv8typewrapper.cpp b/src/qml/qml/v8/qv8typewrapper.cpp
index ff7e599995..4400d30abf 100644
--- a/src/qml/qml/v8/qv8typewrapper.cpp
+++ b/src/qml/qml/v8/qv8typewrapper.cpp
@@ -135,24 +135,24 @@ QVariant QV8TypeWrapper::toVariant(QV8ObjectResource *r)
QV8Engine *v8engine = resource->engine;
if (resource->typeNamespace) {
- if (QQmlMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) {
- if (moduleApi->scriptCallback) {
- moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine());
- moduleApi->scriptCallback = 0;
- moduleApi->qobjectCallback = 0;
- } else if (moduleApi->qobjectCallback) {
- moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine());
- moduleApi->scriptCallback = 0;
- moduleApi->qobjectCallback = 0;
+ if (QQmlMetaType::SingletonInstance *singletonType = resource->typeNamespace->singletonType(resource->importNamespace)) {
+ if (singletonType->scriptCallback) {
+ singletonType->scriptApi = singletonType->scriptCallback(v8engine->engine(), v8engine->engine());
+ singletonType->scriptCallback = 0;
+ singletonType->qobjectCallback = 0;
+ } else if (singletonType->qobjectCallback) {
+ singletonType->qobjectApi = singletonType->qobjectCallback(v8engine->engine(), v8engine->engine());
+ singletonType->scriptCallback = 0;
+ singletonType->qobjectCallback = 0;
}
- if (moduleApi->qobjectApi) {
- return QVariant::fromValue<QObject*>(moduleApi->qobjectApi);
+ if (singletonType->qobjectApi) {
+ return QVariant::fromValue<QObject*>(singletonType->qobjectApi);
}
}
}
- // only QObject Module API can be converted to a variant.
+ // only QObject Singleton Type can be converted to a variant.
return QVariant();
}
@@ -197,29 +197,31 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
resource->importNamespace);
if (r.isValid()) {
+ QQmlContextData *context = v8engine->callingContext();
if (r.type) {
return v8engine->typeWrapper()->newObject(object, r.type, resource->mode);
} else if (r.scriptIndex != -1) {
int index = r.scriptIndex;
- QQmlContextData *context = v8engine->callingContext();
if (index < context->importedScripts.count())
return context->importedScripts.at(index);
+ } else if (r.importNamespace) {
+ return v8engine->typeWrapper()->newObject(object, context->imports, r.importNamespace);
}
return v8::Undefined();
- } else if (QQmlMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) {
-
- if (moduleApi->scriptCallback) {
- moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine());
- moduleApi->scriptCallback = 0;
- moduleApi->qobjectCallback = 0;
- } else if (moduleApi->qobjectCallback) {
- moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine());
- moduleApi->scriptCallback = 0;
- moduleApi->qobjectCallback = 0;
+ } else if (QQmlMetaType::SingletonInstance *singletonType = resource->typeNamespace->singletonType(resource->importNamespace)) {
+
+ if (singletonType->scriptCallback) {
+ singletonType->scriptApi = singletonType->scriptCallback(v8engine->engine(), v8engine->engine());
+ singletonType->scriptCallback = 0;
+ singletonType->qobjectCallback = 0;
+ } else if (singletonType->qobjectCallback) {
+ singletonType->qobjectApi = singletonType->qobjectCallback(v8engine->engine(), v8engine->engine());
+ singletonType->scriptCallback = 0;
+ singletonType->qobjectCallback = 0;
}
- if (moduleApi->qobjectApi) {
+ if (singletonType->qobjectApi) {
// check for enum value
if (QV8Engine::startsWithUpper(property)) {
if (resource->mode == IncludeEnums) {
@@ -227,7 +229,7 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
// ### Optimize
QByteArray enumName = name.toUtf8();
- const QMetaObject *metaObject = moduleApi->qobjectApi->metaObject();
+ const QMetaObject *metaObject = singletonType->qobjectApi->metaObject();
for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) {
QMetaEnum e = metaObject->enumerator(ii);
bool ok;
@@ -239,11 +241,11 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property,
}
// check for property.
- v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(moduleApi->qobjectApi, propertystring, QV8QObjectWrapper::IgnoreRevision);
+ v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(singletonType->qobjectApi, propertystring, QV8QObjectWrapper::IgnoreRevision);
return rv;
- } else if (!moduleApi->scriptApi.isUndefined()) {
+ } else if (!singletonType->scriptApi.isUndefined()) {
// NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable.
- QJSValuePrivate *apiprivate = QJSValuePrivate::get(moduleApi->scriptApi);
+ QJSValuePrivate *apiprivate = QJSValuePrivate::get(singletonType->scriptApi);
QScopedPointer<QJSValuePrivate> propertyValue(apiprivate->property(property).give());
return propertyValue->asV8Value(v8engine);
} else {
@@ -281,23 +283,23 @@ v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property,
v8engine->qobjectWrapper()->setProperty(ao, propertystring, value,
QV8QObjectWrapper::IgnoreRevision);
} else if (resource->typeNamespace) {
- if (QQmlMetaType::ModuleApiInstance *moduleApi = resource->typeNamespace->moduleApi(resource->importNamespace)) {
- if (moduleApi->scriptCallback) {
- moduleApi->scriptApi = moduleApi->scriptCallback(v8engine->engine(), v8engine->engine());
- moduleApi->scriptCallback = 0;
- moduleApi->qobjectCallback = 0;
- } else if (moduleApi->qobjectCallback) {
- moduleApi->qobjectApi = moduleApi->qobjectCallback(v8engine->engine(), v8engine->engine());
- moduleApi->scriptCallback = 0;
- moduleApi->qobjectCallback = 0;
+ if (QQmlMetaType::SingletonInstance *singletonType = resource->typeNamespace->singletonType(resource->importNamespace)) {
+ if (singletonType->scriptCallback) {
+ singletonType->scriptApi = singletonType->scriptCallback(v8engine->engine(), v8engine->engine());
+ singletonType->scriptCallback = 0;
+ singletonType->qobjectCallback = 0;
+ } else if (singletonType->qobjectCallback) {
+ singletonType->qobjectApi = singletonType->qobjectCallback(v8engine->engine(), v8engine->engine());
+ singletonType->scriptCallback = 0;
+ singletonType->qobjectCallback = 0;
}
- if (moduleApi->qobjectApi) {
- v8engine->qobjectWrapper()->setProperty(moduleApi->qobjectApi, propertystring, value,
+ if (singletonType->qobjectApi) {
+ v8engine->qobjectWrapper()->setProperty(singletonType->qobjectApi, propertystring, value,
QV8QObjectWrapper::IgnoreRevision);
- } else if (!moduleApi->scriptApi.isUndefined()) {
+ } else if (!singletonType->scriptApi.isUndefined()) {
QScopedPointer<QJSValuePrivate> setvalp(new QJSValuePrivate(v8engine, value));
- QJSValuePrivate *apiprivate = QJSValuePrivate::get(moduleApi->scriptApi);
+ QJSValuePrivate *apiprivate = QJSValuePrivate::get(singletonType->scriptApi);
if (apiprivate->propertyFlags(property) & QJSValuePrivate::ReadOnly) {
QString error = QLatin1String("Cannot assign to read-only property \"") +
v8engine->toString(property) + QLatin1Char('\"');