diff options
author | Chris Adams <christopher.adams@nokia.com> | 2012-08-14 11:44:49 +1000 |
---|---|---|
committer | Qt by Nokia <qt-info@nokia.com> | 2012-08-28 04:32:48 +0200 |
commit | 70a2c0491d66aa05f9e9e67f8a845f4df84da857 (patch) | |
tree | 08d7828cfb6950926e1176ee420d5e15dedd9817 /src/qml/qml/v8/qv8typewrapper.cpp | |
parent | 3912bbaceab166eb116447311eb16453e4f26edf (diff) |
Refactor singleton type registration code
Previously each singleton type was registered as an implicit separate
import. This commit changes the code so that these types are treated
just like any other type in the registration sense.
It also ensures that singleton types are instantiated per-engine.
Change-Id: I5c81c4ca5bf65210f7125d74a62a282a21838068
Reviewed-by: Matthew Vogt <matthew.vogt@nokia.com>
Diffstat (limited to 'src/qml/qml/v8/qv8typewrapper.cpp')
-rw-r--r-- | src/qml/qml/v8/qv8typewrapper.cpp | 174 |
1 files changed, 80 insertions, 94 deletions
diff --git a/src/qml/qml/v8/qv8typewrapper.cpp b/src/qml/qml/v8/qv8typewrapper.cpp index 25695a9fbc..ab077543cd 100644 --- a/src/qml/qml/v8/qv8typewrapper.cpp +++ b/src/qml/qml/v8/qv8typewrapper.cpp @@ -134,21 +134,13 @@ QVariant QV8TypeWrapper::toVariant(QV8ObjectResource *r) QV8TypeResource *resource = static_cast<QV8TypeResource *>(r); QV8Engine *v8engine = resource->engine; - if (resource->typeNamespace) { - 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 (singletonType->qobjectApi) { - return QVariant::fromValue<QObject*>(singletonType->qobjectApi); - } + if (resource->type && resource->type->isSingleton()) { + QQmlEngine *e = v8engine->engine(); + QQmlType::SingletonInstanceInfo *siinfo = resource->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); } } @@ -174,19 +166,62 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, if (resource->type) { QQmlType *type = resource->type; - if (QV8Engine::startsWithUpper(property)) { - bool ok = false; - int value = type->enumValue(propertystring, &ok); - if (ok) - return v8::Integer::New(value); + // singleton types are handled differently to other types. + if (type->isSingleton()) { + QQmlEngine *e = v8engine->engine(); + QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo(); + siinfo->init(e); + + QObject *qobjectSingleton = siinfo->qobjectApi(e); + if (qobjectSingleton) { + // check for enum value + if (QV8Engine::startsWithUpper(property)) { + if (resource->mode == IncludeEnums) { + QString name = v8engine->toString(property); + + // ### Optimize + QByteArray enumName = name.toUtf8(); + const QMetaObject *metaObject = qobjectSingleton->metaObject(); + for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) { + QMetaEnum e = metaObject->enumerator(ii); + bool ok; + int value = e.keyToValue(enumName.constData(), &ok); + if (ok) + return v8::Integer::New(value); + } + } + } + + // check for property. + v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(qobjectSingleton, propertystring, context, QV8QObjectWrapper::IgnoreRevision); + return rv; + } else if (!siinfo->scriptApi(e).isUndefined()) { + // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. + QJSValuePrivate *apiprivate = QJSValuePrivate::get(siinfo->scriptApi(e)); + QScopedPointer<QJSValuePrivate> propertyValue(apiprivate->property(property).give()); + return propertyValue->asV8Value(v8engine); + } // Fall through to return empty handle - } else if (resource->object) { - QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); - if (ao) - return v8engine->qobjectWrapper()->getProperty(ao, propertystring, context, - QV8QObjectWrapper::IgnoreRevision); + } else { + + if (QV8Engine::startsWithUpper(property)) { + bool ok = false; + int value = type->enumValue(propertystring, &ok); + if (ok) + return v8::Integer::New(value); + + // Fall through to return empty handle + + } else if (resource->object) { + QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); + if (ao) + return v8engine->qobjectWrapper()->getProperty(ao, propertystring, context, + QV8QObjectWrapper::IgnoreRevision); + + // Fall through to return empty handle + } // Fall through to return empty handle } @@ -211,49 +246,7 @@ v8::Handle<v8::Value> QV8TypeWrapper::Getter(v8::Local<v8::String> property, } return v8::Undefined(); - } 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 (singletonType->qobjectApi) { - // check for enum value - if (QV8Engine::startsWithUpper(property)) { - if (resource->mode == IncludeEnums) { - QString name = v8engine->toString(property); - - // ### Optimize - QByteArray enumName = name.toUtf8(); - const QMetaObject *metaObject = singletonType->qobjectApi->metaObject(); - for (int ii = metaObject->enumeratorCount() - 1; ii >= 0; --ii) { - QMetaEnum e = metaObject->enumerator(ii); - bool ok; - int value = e.keyToValue(enumName.constData(), &ok); - if (ok) - return v8::Integer::New(value); - } - } - } - // check for property. - v8::Handle<v8::Value> rv = v8engine->qobjectWrapper()->getProperty(singletonType->qobjectApi, propertystring, - context, QV8QObjectWrapper::IgnoreRevision); - return rv; - } else if (!singletonType->scriptApi.isUndefined()) { - // NOTE: if used in a binding, changes will not trigger re-evaluation since non-NOTIFYable. - QJSValuePrivate *apiprivate = QJSValuePrivate::get(singletonType->scriptApi); - QScopedPointer<QJSValuePrivate> propertyValue(apiprivate->property(property).give()); - return propertyValue->asV8Value(v8engine); - } else { - return v8::Handle<v8::Value>(); - } } // Fall through to return empty handle @@ -279,38 +272,31 @@ v8::Handle<v8::Value> QV8TypeWrapper::Setter(v8::Local<v8::String> property, QHashedV8String propertystring(property); - if (resource->type && resource->object) { - QQmlType *type = resource->type; + QQmlType *type = resource->type; + if (type && !type->isSingleton() && resource->object) { QObject *object = resource->object; QObject *ao = qmlAttachedPropertiesObjectById(type->attachedPropertiesId(), object); if (ao) v8engine->qobjectWrapper()->setProperty(ao, propertystring, context, value, QV8QObjectWrapper::IgnoreRevision); - } else if (resource->typeNamespace) { - 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 (singletonType->qobjectApi) { - v8engine->qobjectWrapper()->setProperty(singletonType->qobjectApi, propertystring, context, value, - QV8QObjectWrapper::IgnoreRevision); - } else if (!singletonType->scriptApi.isUndefined()) { - QScopedPointer<QJSValuePrivate> setvalp(new QJSValuePrivate(v8engine, value)); - 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('\"'); - v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); - } else { - apiprivate->setProperty(property, setvalp.data()); - } + } else if (type && type->isSingleton()) { + QQmlEngine *e = v8engine->engine(); + QQmlType::SingletonInstanceInfo *siinfo = type->singletonInstanceInfo(); + siinfo->init(e); + + QObject *qobjectSingleton = siinfo->qobjectApi(e); + if (qobjectSingleton) { + v8engine->qobjectWrapper()->setProperty(qobjectSingleton, propertystring, context, value, + QV8QObjectWrapper::IgnoreRevision); + } else if (!siinfo->scriptApi(e).isUndefined()) { + QScopedPointer<QJSValuePrivate> setvalp(new QJSValuePrivate(v8engine, value)); + QJSValuePrivate *apiprivate = QJSValuePrivate::get(siinfo->scriptApi(e)); + if (apiprivate->propertyFlags(property) & QJSValuePrivate::ReadOnly) { + QString error = QLatin1String("Cannot assign to read-only property \"") + + v8engine->toString(property) + QLatin1Char('\"'); + v8::ThrowException(v8::Exception::Error(v8engine->toString(error))); + } else { + apiprivate->setProperty(property, setvalp.data()); } } } |