diff options
author | Lars Knoll <lars.knoll@qt.io> | 2017-06-23 13:09:03 +0200 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@qt.io> | 2017-08-02 16:32:37 +0000 |
commit | a6633e41e7c6795bbbc016ce36e4ff91ec5248ad (patch) | |
tree | 084c03ead7bc38c146333e262637f3fd0a45881d | |
parent | ee1de29c2dcb16a4b0c691c7fc53310e175fa49f (diff) |
Use QQmlType by value in the type wrapper
Task-number: QTBUG-61536
Change-Id: Ie40cb3a6e170331b0ec7ab5deaf7c1d7ef0cdaeb
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
-rw-r--r-- | src/qml/jsruntime/qv4qmlcontext.cpp | 2 | ||||
-rw-r--r-- | src/qml/jsruntime/qv4qobjectwrapper.cpp | 2 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype.cpp | 19 | ||||
-rw-r--r-- | src/qml/qml/qqmlmetatype_p.h | 5 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper.cpp | 67 | ||||
-rw-r--r-- | src/qml/qml/qqmltypewrapper_p.h | 6 |
6 files changed, 65 insertions, 36 deletions
diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index 91d65a70c9..9411e2b8e0 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -143,7 +143,7 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr QV4::ScopedObject scripts(scope, context->importedScripts.valueRef()); return scripts->getIndexed(r.scriptIndex); } else if (r.type) { - return QmlTypeWrapper::create(v4, scopeObject, r.type); + return QmlTypeWrapper::create(v4, scopeObject, *r.type); } else if (r.importNamespace) { return QmlTypeWrapper::create(v4, scopeObject, context->imports, r.importNamespace); } diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index d7978cc212..73a6ab7503 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -251,7 +251,7 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String return QV4::Encode::undefined(); } else if (r.type) { return QmlTypeWrapper::create(v4, d()->object(), - r.type, Heap::QmlTypeWrapper::ExcludeEnums); + *r.type, Heap::QmlTypeWrapper::ExcludeEnums); } else if (r.importNamespace) { return QmlTypeWrapper::create(v4, d()->object(), qmlContext->imports, r.importNamespace, Heap::QmlTypeWrapper::ExcludeEnums); diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index 1959146388..2ff2cdc189 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -463,6 +463,13 @@ QQmlType &QQmlType::operator =(const QQmlType &other) return *this; } +QQmlType::QQmlType(QQmlTypePrivate *priv) + : d(priv) +{ + if (d) + d->refCount.ref(); +} + QQmlType::~QQmlType() { if (d && !d->refCount.deref()) @@ -1073,6 +1080,18 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool return -1; } +void QQmlType::refHandle(QQmlTypePrivate *priv) +{ + if (priv) + priv->refCount.ref(); +} + +void QQmlType::derefHandle(QQmlTypePrivate *priv) +{ + if (priv && !priv->refCount.deref()) + delete priv; +} + QQmlTypeModule::QQmlTypeModule() : d(new QQmlTypeModulePrivate) { diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index e3752b7bf8..08198340f3 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -141,6 +141,7 @@ public: QQmlType(); QQmlType(const QQmlType &other); QQmlType &operator =(const QQmlType &other); + explicit QQmlType(QQmlTypePrivate *priv); ~QQmlType(); bool isValid() const { return d != 0; } @@ -223,6 +224,10 @@ public: int enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &, bool *ok) const; int enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &, bool *ok) const; int enumValue(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const; + + QQmlTypePrivate *handle() const { return d; } + static void refHandle(QQmlTypePrivate *priv); + static void derefHandle(QQmlTypePrivate *priv); private: QQmlType *superType() const; QQmlType *resolveCompositeBaseType(QQmlEnginePrivate *engine) const; diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index be4ab68831..0656bd4c62 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -63,15 +63,22 @@ void Heap::QmlTypeWrapper::init() void Heap::QmlTypeWrapper::destroy() { + QQmlType::derefHandle(typePrivate); + typePrivate = nullptr; if (typeNamespace) typeNamespace->release(); object.destroy(); Object::destroy(); } +QQmlType Heap::QmlTypeWrapper::type() const +{ + return QQmlType(typePrivate); +} + bool QmlTypeWrapper::isSingleton() const { - return d()->type && d()->type->isSingleton(); + return d()->type().isSingleton(); } QObject* QmlTypeWrapper::singletonObject() const @@ -80,22 +87,16 @@ QObject* QmlTypeWrapper::singletonObject() const return 0; QQmlEngine *e = engine()->qmlEngine(); - QQmlType::SingletonInstanceInfo *siinfo = d()->type->singletonInstanceInfo(); + QQmlType::SingletonInstanceInfo *siinfo = d()->type().singletonInstanceInfo(); siinfo->init(e); return siinfo->qobjectApi(e); } QVariant QmlTypeWrapper::toVariant() const { - if (d()->type && d()->type->isSingleton()) { - QQmlEngine *e = engine()->qmlEngine(); - QQmlType::SingletonInstanceInfo *siinfo = d()->type->singletonInstanceInfo(); - siinfo->init(e); // note: this will also create QJSValue singleton which isn't strictly required. - QObject *qobjectSingleton = siinfo->qobjectApi(e); - if (qobjectSingleton) { - return QVariant::fromValue<QObject*>(qobjectSingleton); - } - } + QObject *qobjectSingleton = singletonObject(); + if (qobjectSingleton) + return QVariant::fromValue<QObject*>(qobjectSingleton); // only QObject Singleton Type can be converted to a variant. return QVariant(); @@ -103,14 +104,16 @@ QVariant QmlTypeWrapper::toVariant() const // Returns a type wrapper for type t on o. This allows access of enums, and attached properties. -ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlType *t, +ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, const QQmlType &t, Heap::QmlTypeWrapper::TypeNameMode mode) { - Q_ASSERT(t); + Q_ASSERT(t.isValid()); Scope scope(engine); Scoped<QmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QmlTypeWrapper>()); - w->d()->mode = mode; w->d()->object = o; w->d()->type = t; + w->d()->mode = mode; w->d()->object = o; + w->d()->typePrivate = t.handle(); + QQmlType::refHandle(w->d()->typePrivate); return w.asReturnedValue(); } @@ -130,10 +133,10 @@ ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, Q } static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, QObject *qobjectSingleton, - QQmlType *type) + const QQmlType &type) { bool ok; - int value = type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok); + int value = type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok); if (ok) return value; @@ -149,11 +152,11 @@ static int enumForSingleton(QV4::ExecutionEngine *v4, String *name, QObject *qob return -1; } -static ReturnedValue throwLowercaseEnumError(QV4::ExecutionEngine *v4, String *name, QQmlType *type) +static ReturnedValue throwLowercaseEnumError(QV4::ExecutionEngine *v4, String *name, const QQmlType &type) { const QString message = QStringLiteral("Cannot access enum value '%1' of '%2', enum values need to start with an uppercase letter.") - .arg(name->toQString()).arg(QLatin1String(type->typeName())); + .arg(name->toQString()).arg(QLatin1String(type.typeName())); return v4->throwTypeError(message); } @@ -172,14 +175,14 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope QQmlContextData *context = v4->callingQmlContext(); QObject *object = w->d()->object; - QQmlType *type = w->d()->type; + QQmlType type = w->d()->type(); - if (type) { + if (type.isValid()) { // singleton types are handled differently to other types. - if (type->isSingleton()) { + if (type.isSingleton()) { QQmlEngine *e = v4->qmlEngine(); - QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo(); + QQmlType::SingletonInstanceInfo *siinfo = type.singletonInstanceInfo(); siinfo->init(e); QObject *qobjectSingleton = siinfo->qobjectApi(e); @@ -220,14 +223,14 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope if (name->startsWithUpper()) { bool ok = false; - int value = type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok); + int value = type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok); if (ok) return QV4::Primitive::fromInt32(value).asReturnedValue(); // Fall through to base implementation } else if (w->d()->object) { - QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(QQmlEnginePrivate::get(v4->qmlEngine())), object); + QObject *ao = qmlAttachedPropertiesObjectById(type.attachedPropertiesId(QQmlEnginePrivate::get(v4->qmlEngine())), object); if (ao) return QV4::QObjectWrapper::getQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, hasProperty); @@ -245,7 +248,7 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope if (r.isValid()) { if (r.type) { - return create(scope.engine, object, r.type, w->d()->mode); + return create(scope.engine, object, *r.type, w->d()->mode); } else if (r.scriptIndex != -1) { QV4::ScopedObject scripts(scope, context->importedScripts.valueRef()); return scripts->getIndexed(r.scriptIndex); @@ -269,9 +272,9 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope *hasProperty = ok; // Warn when attempting to access a lowercased enum value, non-singleton case - if (!ok && type && !type->isSingleton() && !name->startsWithUpper()) { + if (!ok && type.isValid() && !type.isSingleton() && !name->startsWithUpper()) { bool enumOk = false; - type->enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &enumOk); + type.enumValue(QQmlEnginePrivate::get(v4->qmlEngine()), name, &enumOk); if (enumOk) return throwLowercaseEnumError(v4, name, type); } @@ -291,16 +294,16 @@ void QmlTypeWrapper::put(Managed *m, String *name, const Value &value) QV4::Scope scope(v4); QQmlContextData *context = v4->callingQmlContext(); - QQmlType *type = w->d()->type; - if (type && !type->isSingleton() && w->d()->object) { + QQmlType type = w->d()->type(); + if (type.isValid() && !type.isSingleton() && w->d()->object) { QObject *object = w->d()->object; QQmlEngine *e = scope.engine->qmlEngine(); - QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(QQmlEnginePrivate::get(e)), object); + QObject *ao = qmlAttachedPropertiesObjectById(type.attachedPropertiesId(QQmlEnginePrivate::get(e)), object); if (ao) QV4::QObjectWrapper::setQmlProperty(v4, context, ao, name, QV4::QObjectWrapper::IgnoreRevision, value); - } else if (type && type->isSingleton()) { + } else if (type.isValid() && type.isSingleton()) { QQmlEngine *e = scope.engine->qmlEngine(); - QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo(); + QQmlType::SingletonInstanceInfo *siinfo = type.singletonInstanceInfo(); siinfo->init(e); QObject *qobjectSingleton = siinfo->qobjectApi(e); diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index 3b0ae04cc1..c21a66424b 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -76,7 +76,9 @@ struct QmlTypeWrapper : Object { TypeNameMode mode; QQmlQPointer<QObject> object; - QQmlType *type; + QQmlType type() const; + + QQmlTypePrivate *typePrivate; QQmlTypeNameCache *typeNamespace; const void *importNamespace; }; @@ -93,7 +95,7 @@ struct Q_QML_EXPORT QmlTypeWrapper : Object QVariant toVariant() const; - static ReturnedValue create(ExecutionEngine *, QObject *, QQmlType *, + static ReturnedValue create(ExecutionEngine *, QObject *, const QQmlType &, Heap::QmlTypeWrapper::TypeNameMode = Heap::QmlTypeWrapper::IncludeEnums); static ReturnedValue create(ExecutionEngine *, QObject *, QQmlTypeNameCache *, const void *, Heap::QmlTypeWrapper::TypeNameMode = Heap::QmlTypeWrapper::IncludeEnums); |