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>
This commit is contained in:
parent
92562eacbc
commit
6ebf215fda
|
@ -454,9 +454,9 @@ through the data.
|
|||
/*!
|
||||
\qmlmodule QtQuick.LocalStorage 2
|
||||
\title QML Module QtQuick.LocalStorage 2.0
|
||||
\brief Provides a JavaScript module API for accessing a local SQLite database
|
||||
\brief Provides a JavaScript object singleton type for accessing a local SQLite database
|
||||
|
||||
This is a module API for reading and writing to SQLite databases.
|
||||
This is a singleton type for reading and writing to SQLite databases.
|
||||
|
||||
|
||||
\section1 Methods
|
||||
|
@ -699,7 +699,7 @@ public:
|
|||
void registerTypes(const char *uri)
|
||||
{
|
||||
Q_ASSERT(QLatin1String(uri) == "QtQuick.LocalStorage");
|
||||
qmlRegisterModuleApi<QQuickLocalStorage>(uri, 2, 0, module_api_factory);
|
||||
qmlRegisterSingletonType<QQuickLocalStorage>(uri, 2, 0, "LocalStorage", module_api_factory);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -146,7 +146,7 @@ type name.
|
|||
instantiable but should be identifiable as a type to the QML type system. This
|
||||
is useful if a type's enums or attached properties should be accessible from QML
|
||||
but the type itself should not be instantiable.
|
||||
\li qmlRegisterModuleApi() registers a singleton instance that can be imported
|
||||
\li qmlRegisterSingletonType() registers a singleton type that can be imported
|
||||
from QML, as discussed below.
|
||||
\endlist
|
||||
|
||||
|
@ -154,29 +154,30 @@ Note that all C++ types registered with the QML type system must be
|
|||
QObject-derived, even if they are non-instantiable.
|
||||
|
||||
|
||||
\section3 Registering Singleton Objects with a Module API
|
||||
\section3 Registering Singleton Objects with a Singleton Type
|
||||
|
||||
A Module API enables properties, signals and methods to be exposed in
|
||||
A singleton type enables properties, signals and methods to be exposed in
|
||||
a namespace without requiring the client to manually instantiate an
|
||||
object instance. QObject module APIs in particular are an efficient and
|
||||
object instance. QObject singleton types in particular are an efficient and
|
||||
convenient way to provide functionality or global property values.
|
||||
|
||||
Note that module APIs do not have an associated QQmlContext as they are
|
||||
shared across all contexts in an engine. QObject module API instances
|
||||
Note that singleton types do not have an associated QQmlContext as they are
|
||||
shared across all contexts in an engine. QObject singleton type instances
|
||||
are constructed and owned by the QQmlEngine, and will be destroyed when
|
||||
the engine is destroyed.
|
||||
|
||||
A QObject module API can be interacted with in a manner simlar to any
|
||||
other QObject or instantiated element. That is, Q_PROPERTYs of QObject
|
||||
module APIs may be bound to, and Q_INVOKABLE functions of QObject module
|
||||
APIs may be used in signal handler expressions. This makes module APIs
|
||||
an ideal way to implement styling or theming, and they can also be used
|
||||
instead of ".pragma library" script imports to store global state or to
|
||||
provide global functionality.
|
||||
A QObject singleton type can be interacted with in a manner simlar to any
|
||||
other QObject or instantiated element, except that only one (engine constructed
|
||||
and owned) instance will exist, and it must be referenced by type name rather
|
||||
than id. Q_PROPERTYs of QObject singleton types may be bound to, and Q_INVOKABLE
|
||||
functions of QObject module APIs may be used in signal handler expressions.
|
||||
This makes singleton types an ideal way to implement styling or theming, and
|
||||
they can also be used instead of ".pragma library" script imports to store global
|
||||
state or to provide global functionality.
|
||||
|
||||
Once registered, a QObject module API may be imported and used like any
|
||||
Once registered, a QObject singleton type may be imported and used like any
|
||||
other QObject instance exposed to QML. The following example assumes that
|
||||
a QObject module API was registered into the "MyThemeModule" namespace
|
||||
a QObject singleton type was registered into the "MyThemeModule" namespace
|
||||
with version 1.0, where that QObject has a QColor "color" Q_PROPERTY:
|
||||
|
||||
\qml
|
||||
|
@ -187,11 +188,11 @@ Rectangle {
|
|||
}
|
||||
\endqml
|
||||
|
||||
A QJSValue may also be exposed as a module API, however clients should
|
||||
be aware that properties of such a module API cannot be bound to.
|
||||
A QJSValue may also be exposed as a singleton type, however clients should
|
||||
be aware that properties of such a singleton type cannot be bound to.
|
||||
|
||||
See \l{qmlRegisterModuleApi()} for more information on how implement and
|
||||
register a new module API, and how to use an existing module API.
|
||||
See \l{qmlRegisterSingletonType()} for more information on how implement and
|
||||
register a new singleton type, and how to use an existing singleton type.
|
||||
|
||||
|
||||
\section2 Type Revisions and Versions
|
||||
|
|
|
@ -61,8 +61,8 @@ required functionality is provided by such a class, it can be exposed to QML in
|
|||
registered as an instantiable QML type}, so that it can be instantiated and used like any ordinary
|
||||
\l{qtqml-typesystem-objecttypes.html}{QML object type} from QML code
|
||||
\li The class can be registered as a
|
||||
\l{qtqml-cppintegration-definetypes.html#registering-singleton-objects-with-a-module-api}
|
||||
{Module API} so that a single instance of the class may be imported from QML code, allowing the
|
||||
\l{qtqml-cppintegration-definetypes.html#registering-singleton-objects-with-a-singleton-type}
|
||||
{Singleton Type} so that a single instance of the class may be imported from QML code, allowing the
|
||||
instance's properties, methods and signals to be accessed from QML
|
||||
\li An instance of the class can be \l{qtqml-cppintegration-contextproperties.html}{embedded into
|
||||
QML code} as a \e {context property} or \e {context object}, allowing the instance's properties,
|
||||
|
@ -100,7 +100,7 @@ more information.
|
|||
QML types can be defined in C++ and then registered with the \l{qtqml-typesystem-topic.html}{QML
|
||||
type system}. This allows a C++ class to be instantiated as a \l {QML object type}, enabling custom
|
||||
object types to be implemented in C++ and integrated into existing QML code. A C++ class may be also
|
||||
registered for other purposes: for example, it could be registered as a \e {Module API} to enable a
|
||||
registered for other purposes: for example, it could be registered as a \e {Singleton Type} to enable a
|
||||
single class instance to be imported by QML code, or it could be registered to enable the
|
||||
enumeration values of a non-instantiable class to be accessible from QML.
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ For example:
|
|||
\endcode
|
||||
|
||||
In particular, this may be useful in order to access functionality provided
|
||||
via a module API; see qmlRegisterModuleApi() for more information.
|
||||
via a singleton type; see qmlRegisterSingletonType() for more information.
|
||||
|
||||
Due to the ability of a JavaScript file to import another script or QML module
|
||||
in this fashion in QtQuick 2.0, some extra semantics are defined:
|
||||
|
|
|
@ -205,25 +205,25 @@
|
|||
*/
|
||||
|
||||
/*!
|
||||
\fn int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, QJSValue (*callback)(QQmlEngine *, QJSEngine *))
|
||||
\fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QJSValue (*callback)(QQmlEngine *, QJSEngine *))
|
||||
\relates QQmlEngine
|
||||
|
||||
This function may be used to register a module API provider \a callback in a particular \a uri
|
||||
with a version specified in \a versionMajor and \a versionMinor.
|
||||
This function may be used to register a singleton type provider \a callback in a particular \a uri
|
||||
and \a typeName with a version specified in \a versionMajor and \a versionMinor.
|
||||
|
||||
Installing a module API into a uri allows developers to provide arbitrary functionality
|
||||
(methods and properties) in a namespace that doesn't necessarily contain elements.
|
||||
Installing a singleton type allows developers to provide arbitrary functionality
|
||||
(methods and properties) to a client without requiring individual instances of the type to
|
||||
be instantiated by the client.
|
||||
|
||||
A module API may be either a QObject or a QJSValue. Only one module API provider
|
||||
may be registered into any given namespace (combination of \a uri, \a versionMajor and \a versionMinor).
|
||||
This function should be used to register a module API provider function which returns a QJSValue as a module API.
|
||||
A singleton type may be either a QObject or a QJSValue.
|
||||
This function should be used to register a singleton type provider function which returns a QJSValue as a singleton type.
|
||||
|
||||
\b{NOTE:} QJSValue module API properties will \b{not} trigger binding re-evaluation if changed.
|
||||
\b{NOTE:} QJSValue singleton type properties will \b{not} trigger binding re-evaluation if changed.
|
||||
|
||||
Usage:
|
||||
\code
|
||||
// first, define the module API provider function (callback).
|
||||
static QJSValue *example_qjsvalue_module_api_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
// first, define the singleton type provider function (callback).
|
||||
static QJSValue *example_qjsvalue_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
|
||||
|
@ -233,19 +233,19 @@
|
|||
return example;
|
||||
}
|
||||
|
||||
// second, register the module API provider with QML by calling this function in an initialization function.
|
||||
// second, register the singleton type provider with QML by calling this function in an initialization function.
|
||||
...
|
||||
qmlRegisterModuleApi("Qt.example.qjsvalueApi", 1, 0, example_qjsvalue_module_api_provider);
|
||||
qmlRegisterSingletonType("Qt.example.qjsvalueApi", 1, 0, "MyApi", example_qjsvalue_singletontype_provider);
|
||||
...
|
||||
\endcode
|
||||
|
||||
In order to use the registered module API in QML, you must import the module API.
|
||||
In order to use the registered singleton type in QML, you must import the singleton type.
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import Qt.example.qjsvalueApi 1.0 as ExampleApi
|
||||
Item {
|
||||
id: root
|
||||
property int someValue: ExampleApi.someProperty
|
||||
property int someValue: ExampleApi.MyApi.someProperty
|
||||
}
|
||||
\endqml
|
||||
*/
|
||||
|
@ -274,44 +274,44 @@
|
|||
*/
|
||||
|
||||
/*!
|
||||
\fn int qmlRegisterModuleApi(const char *uri, int versionMajor, int versionMinor, QObject *(*callback)(QQmlEngine *, QJSEngine *))
|
||||
\fn int qmlRegisterSingletonType(const char *uri, int versionMajor, int versionMinor, const char *typeName, QObject *(*callback)(QQmlEngine *, QJSEngine *))
|
||||
\relates QQmlEngine
|
||||
|
||||
This function may be used to register a module API provider \a callback in a particular \a uri
|
||||
with a version specified in \a versionMajor and \a versionMinor.
|
||||
This function may be used to register a singleton type provider \a callback in a particular \a uri
|
||||
and \a typeName with a version specified in \a versionMajor and \a versionMinor.
|
||||
|
||||
Installing a module API into a uri allows developers to provide arbitrary functionality
|
||||
(methods and properties) in a namespace that doesn't necessarily contain elements.
|
||||
Installing a singleton type into a uri allows developers to provide arbitrary functionality
|
||||
(methods and properties) to clients without requiring individual instances ot the type to be
|
||||
instantiated by the client.
|
||||
|
||||
A module API may be either a QObject or a QJSValue. Only one module API provider
|
||||
may be registered into any given namespace (combination of \a uri, \a versionMajor and \a versionMinor).
|
||||
This function should be used to register a module API provider function which returns a QObject
|
||||
of the given type T as a module API.
|
||||
A singleton type may be either a QObject or a QJSValue.
|
||||
This function should be used to register a singleton type provider function which returns a QObject
|
||||
of the given type T as a singleton type.
|
||||
|
||||
A QObject module API must be imported with a qualifier, and that qualifier may be used as
|
||||
the target in a \l Connections element or otherwise used as any other element id would.
|
||||
One exception to this is that a QObject module API property may not be aliased (because the
|
||||
module API qualifier does not identify an object within the same component as any other item).
|
||||
A QObject singleton type may be referenced via the type name with which it was registered, and this
|
||||
typename may be used as the target in a \l Connections element or otherwise used as any other element id would.
|
||||
One exception to this is that a QObject singleton type property may not be aliased (because the
|
||||
singleton type name does not identify an object within the same component as any other item).
|
||||
|
||||
\b{NOTE:} A QObject module API instance returned from a module API provider is owned by the QML
|
||||
engine. For this reason, the module API provider function should \b{not} be implemented as a
|
||||
\b{NOTE:} A QObject singleton type instance returned from a singleton type provider is owned by the QML
|
||||
engine. For this reason, the singleton type provider function should \b{not} be implemented as a
|
||||
singleton factory.
|
||||
|
||||
Usage:
|
||||
\code
|
||||
// first, define your QObject which provides the functionality.
|
||||
class ModuleApiExample : public QObject
|
||||
class SingletonTypeExample : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY (int someProperty READ someProperty WRITE setSomeProperty NOTIFY somePropertyChanged)
|
||||
|
||||
public:
|
||||
ModuleApiExample(QObject* parent = 0)
|
||||
SingletonTypeExample(QObject* parent = 0)
|
||||
: QObject(parent), m_someProperty(0)
|
||||
{
|
||||
}
|
||||
|
||||
~ModuleApiExample() {}
|
||||
~SingletonTypeExample() {}
|
||||
|
||||
Q_INVOKABLE int doSomething() { setSomeProperty(5); return m_someProperty; }
|
||||
|
||||
|
@ -325,45 +325,45 @@
|
|||
int m_someProperty;
|
||||
};
|
||||
|
||||
// second, define the module API provider function (callback).
|
||||
static QObject *example_qobject_module_api_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
// second, define the singleton type provider function (callback).
|
||||
static QObject *example_qobject_singletontype_provider(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(scriptEngine)
|
||||
|
||||
ModuleApiExample *example = new ModuleApiExample();
|
||||
SingletonTypeExample *example = new SingletonTypeExample();
|
||||
return example;
|
||||
}
|
||||
|
||||
// third, register the module API provider with QML by calling this function in an initialization function.
|
||||
// third, register the singleton type provider with QML by calling this function in an initialization function.
|
||||
...
|
||||
qmlRegisterModuleApi<ModuleApiExample>("Qt.example.qobjectApi", 1, 0, example_qobject_module_api_provider);
|
||||
qmlRegisterSingletonType<SingletonTypeExample>("Qt.example.qobjectSingleton", 1, 0, "MyApi", example_qobject_singletontype_provider);
|
||||
...
|
||||
\endcode
|
||||
|
||||
In order to use the registered module API in QML, you must import the module API.
|
||||
In order to use the registered singleton type in QML, you must import the singleton type.
|
||||
\qml
|
||||
import QtQuick 2.0
|
||||
import Qt.example.qobjectApi 1.0 as ExampleApi
|
||||
import Qt.example.qobjectSingleton 1.0
|
||||
Item {
|
||||
id: root
|
||||
property int someValue: ExampleApi.someProperty
|
||||
property int someValue: MyApi.someProperty
|
||||
|
||||
Component.onCompleted: {
|
||||
someValue = ExampleApi.doSomething()
|
||||
someValue = MyApi.doSomething()
|
||||
}
|
||||
}
|
||||
\endqml
|
||||
|
||||
Since Module APIs do not have an associated QQmlContext object, then within the functions of a QObject-derived
|
||||
type that is registered as a module API implementation the QML context and engine information is not available.
|
||||
Since singleton types do not have an associated QQmlContext object, then within the functions of a QObject-derived
|
||||
type that is registered as a singleton type implementation the QML context and engine information is not available.
|
||||
The QQmlEngine::contextForObject() function returns NULL when supplied with a pointer to an QObject that
|
||||
implements a module API.
|
||||
implements a singleton type.
|
||||
|
||||
Extending the above example:
|
||||
|
||||
\code
|
||||
class ModuleApiExample : public QObject
|
||||
class SingletonTypeExample : public QObject
|
||||
{
|
||||
...
|
||||
|
||||
|
|
|
@ -175,7 +175,7 @@ types, animation classes, and canvas integration) for the QML language.
|
|||
|
||||
More information about the Qt QML module is contained within the class and
|
||||
function documentation of the \l{QtQml}
|
||||
{Qt QML Module API Reference}. The QML types provided by the Qt QML module
|
||||
{Qt QML Singleton Type Reference}. The QML types provided by the Qt QML module
|
||||
are listed in the \l{qtqml-typereference-topic.html}
|
||||
{Qt QML Module QML Type Reference} page.
|
||||
|
||||
|
|
|
@ -43,18 +43,16 @@ An import can be any one of:
|
|||
|
||||
\list
|
||||
\li a versioned namespace into which types have been registered (e.g., by a plugin)
|
||||
\li a versioned namespace which provides a module API
|
||||
\li a relative directory which contains type-definitions as QML documents
|
||||
\li a JavaScript file
|
||||
\endlist
|
||||
|
||||
Module API imports and JavaScript file imports must be qualified when
|
||||
imported, so that the properties and methods they provide can be accessed.
|
||||
JavaScript file imports must be qualified when imported, so that the properties and methods they provide can be accessed.
|
||||
|
||||
The generic form of the various imports are as follows:
|
||||
\list
|
||||
\li \tt{import Namespace VersionMajor.VersionMinor}
|
||||
\li \tt{import Namespace VersionMajor.VersionMinor as ModuleApiIdentifier}
|
||||
\li \tt{import Namespace VersionMajor.VersionMinor as SingletonTypeIdentifier}
|
||||
\li \tt{import "directory"}
|
||||
\li \tt{import "file.js" as ScriptIdentifier}
|
||||
\endlist
|
||||
|
|
|
@ -126,7 +126,7 @@ functions which each allow different use-cases to be fulfilled.
|
|||
\li qmlRegisterExtendedType
|
||||
\li qmlRegisterInterface
|
||||
\li qmlRegisterCustomType
|
||||
\li qmlRegisterModuleApi
|
||||
\li qmlRegisterSingletonType
|
||||
\endlist
|
||||
|
||||
For more information on this topic, see the documentation regarding
|
||||
|
|
|
@ -87,7 +87,7 @@ has now been replaced by the new QtQml and QtQuick C++ modules. See the
|
|||
\section2 Modules and Imports
|
||||
|
||||
\list
|
||||
\li Arbitrary functionality may be provided in a namespace through a Module API. See qmlRegisterModuleApi() for more information.
|
||||
\li Arbitrary functionality may be provided in a namespace through a singleton type. See qmlRegisterSingletonType() for more information.
|
||||
\li JavaScript (.js) files may now import QML modules and other JavaScript files using the ".import" syntax.
|
||||
\endlist
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
QQmlMetaTypeData::ModuleApiList *apiList = data->moduleApis.value(uri);
|
||||
int index = data->singletonTypeCount++;
|
||||
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)) {
|
||||
} else if (QQmlMetaType::SingletonInstance *singletonType = resource->typeNamespace->singletonType(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 (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('\"');
|
||||
|
|
|
@ -944,10 +944,10 @@ component doesn't already exist in the component set for your platform. Otherwi
|
|||
will be forcing the QML engine to generate and store type-data for a type which is
|
||||
essentially a duplicate of another pre-existing and potentially already loaded component.
|
||||
|
||||
\section3 Use module APIs instead of pragma library scripts
|
||||
\section3 Use singleton types instead of pragma library scripts
|
||||
|
||||
If you are using a pragma library script to store application-wide instance data,
|
||||
consider using a QObject module API instead. This should result in better performance,
|
||||
consider using a QObject singleton type instead. This should result in better performance,
|
||||
and will result in less JavaScript heap memory being used.
|
||||
|
||||
\section2 Memory Allocation in a QML Application
|
||||
|
|
|
@ -66,8 +66,8 @@ Qt.inputMethod.hide() to show and hide the virtual keyboard.
|
|||
\li XmlListModel has moved into its own module, QtQuick.XmlListModel. Any code that uses the
|
||||
XmlListModel and XmlRole types must import \e {QtQuick.XmlListModel} instead.
|
||||
\li The local storage API that enables SQL support has been moved from the \l {QML Global Object}
|
||||
into a \c QtQuick.LocalStorage module API. Any code that requires the local storage API must import
|
||||
\e {QtQuick.LocalStorage} with a namespaced import instead. See the \l \l{QtQuick.LocalStorage 2}{QtQuick.LocalStorage} documentation
|
||||
into a \c QtQuick.LocalStorage singleton type. Any code that requires the local storage API must import
|
||||
\e {QtQuick.LocalStorage} instead. See the \l \l{QtQuick.LocalStorage 2}{QtQuick.LocalStorage} documentation
|
||||
for examples.
|
||||
\li The \c LayoutItem type has been removed from the \c QtQuick module as it was specific to the
|
||||
Graphics View framework backend used in QtQuick 1.
|
||||
|
|
|
@ -231,7 +231,7 @@ Views
|
|||
|
||||
Data Storage
|
||||
\list
|
||||
\li \l {QtQuick.LocalStorage 2} - Module API providing simplified SQL access
|
||||
\li \l {QtQuick.LocalStorage 2} - Singleton type providing simplified SQL access
|
||||
\endlist
|
||||
|
||||
\section2 Graphical Effects
|
||||
|
|
|
@ -102,7 +102,7 @@ To find out more about using the QML language, see the \l{Qt QML Module Document
|
|||
|
||||
More information about the Qt Quick module is contained within the class and
|
||||
function documentation of the \l{qtquick-apireference.html}
|
||||
{Qt Quick Module API Reference}. The QML types provided by the Qt Quick module
|
||||
{Qt Quick Singleton Type Reference}. The QML types provided by the Qt Quick module
|
||||
are listed in the \l{qtquick-qmltypereference.html}
|
||||
{Qt Quick Module QML Type Reference} page.
|
||||
|
||||
|
|
|
@ -6,9 +6,9 @@ Rectangle {
|
|||
color: "red"
|
||||
|
||||
function flipOwnership() {
|
||||
ModApi.trackObject(base);
|
||||
ModApi.trackedObject(); // flip the ownership.
|
||||
if (!ModApi.trackedObjectHasJsOwnership())
|
||||
ModApi.QObject.trackObject(base);
|
||||
ModApi.QObject.trackedObject(); // flip the ownership.
|
||||
if (!ModApi.QObject.trackedObjectHasJsOwnership())
|
||||
derived.testConditionsMet = false;
|
||||
else
|
||||
derived.testConditionsMet = true;
|
||||
|
|
|
@ -6,10 +6,10 @@ Item {
|
|||
property var varCanary: 12
|
||||
|
||||
Component.onCompleted: {
|
||||
QObjectApi.qobjectTestWritableProperty = 42;
|
||||
QObjectApi.QObject.qobjectTestWritableProperty = 42;
|
||||
}
|
||||
|
||||
Component.onDestruction: {
|
||||
QObjectApi.qobjectTestWritableProperty = 43;
|
||||
QObjectApi.QObject.qobjectTestWritableProperty = 43;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,5 +5,5 @@ Item {
|
|||
id: sec
|
||||
|
||||
property int a: 10
|
||||
Component.onDestruction: ModApi.setSpecificProperty(sec, "a", 20);
|
||||
Component.onDestruction: ModApi.QObject.setSpecificProperty(sec, "a", 20);
|
||||
}
|
||||
|
|
|
@ -8,9 +8,9 @@ Rectangle {
|
|||
property bool testConditionsMet: false
|
||||
|
||||
onXChanged: {
|
||||
ModApi.trackObject(base);
|
||||
ModApi.trackedObject(); // flip the ownership.
|
||||
if (!ModApi.trackedObjectHasJsOwnership())
|
||||
ModApi.QObject.trackObject(base);
|
||||
ModApi.QObject.trackedObject(); // flip the ownership.
|
||||
if (!ModApi.QObject.trackedObjectHasJsOwnership())
|
||||
testConditionsMet = false;
|
||||
else
|
||||
testConditionsMet = true;
|
||||
|
|
|
@ -5,7 +5,7 @@ Item {
|
|||
id: sec
|
||||
property int a: 10
|
||||
Component.onDestruction: {
|
||||
ModApi.setSpecificProperty(sec, "a", 20);
|
||||
ModApi.QObject.setSpecificProperty(sec, "a", 20);
|
||||
}
|
||||
|
||||
function setSuccessPropertyOf(obj, val) {
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.fallbackBindingsObject 1.0 as ModuleAPI
|
||||
import Qt.test.fallbackBindingsObject 1.0 as SingletonType
|
||||
|
||||
Item {
|
||||
property bool success: false
|
||||
property string foo: ModuleAPI.test
|
||||
property string foo: SingletonType.Fallback.test
|
||||
|
||||
Component.onCompleted: success = (foo == '100')
|
||||
}
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.fallbackBindingsDerived 1.0 as ModuleAPI
|
||||
import Qt.test.fallbackBindingsDerived 1.0 as SingletonType
|
||||
|
||||
Item {
|
||||
property bool success: false
|
||||
property string foo: ModuleAPI.test
|
||||
property string foo: SingletonType.Fallback.test
|
||||
|
||||
Component.onCompleted: success = (foo == 'hello')
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ Item {
|
|||
if (testProp == null) success = false; // should not have triggered delete notify / zeroed testProp value
|
||||
if (testProp.variantCanary != 5) success = false; // should not have deleted vmemo of object referenced by testProp
|
||||
if (testProp.varCanary != 12) success = false; // should not have collected vmemo vmeProperties
|
||||
if (QObjectApi.qobjectTestWritableProperty != 42) success = false; // should not have been set to 43.
|
||||
if (QObjectApi.QObject.qobjectTestWritableProperty != 42) success = false; // should not have been set to 43.
|
||||
}
|
||||
|
||||
// then we remove the reference.
|
||||
|
@ -26,6 +26,6 @@ Item {
|
|||
|
||||
// after a gc (and deferred deletion process) the object should be gone
|
||||
function ensureDeletion() {
|
||||
if (QObjectApi.qobjectTestWritableProperty != 43) success = false; // should have been set to 43.
|
||||
if (QObjectApi.QObject.qobjectTestWritableProperty != 43) success = false; // should have been set to 43.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,13 +16,13 @@ Item {
|
|||
if (testProp == null) success = false; // should not have triggered delete notify / zeroed testProp value
|
||||
if (testProp.variantCanary != 5) success = false; // should not have deleted vmemo of object referenced by testProp
|
||||
if (testProp.varCanary != 12) success = false; // should not have collected vmemo vmeProperties
|
||||
if (QObjectApi.qobjectTestWritableProperty != 42) success = false; // should not have been set to 43.
|
||||
if (QObjectApi.QObject.qobjectTestWritableProperty != 42) success = false; // should not have been set to 43.
|
||||
}
|
||||
|
||||
// then we manually delete the item being referenced
|
||||
function manuallyDelete() {
|
||||
QObjectApi.deleteQObject(testProp);
|
||||
if (QObjectApi.qobjectTestWritableProperty != 43) success = false; // should have been set to 43.
|
||||
QObjectApi.QObject.deleteQObject(testProp);
|
||||
if (QObjectApi.QObject.qobjectTestWritableProperty != 43) success = false; // should have been set to 43.
|
||||
}
|
||||
|
||||
// after a gc (and deferred deletion process) the object should be gone
|
||||
|
|
|
@ -16,7 +16,7 @@ Item {
|
|||
if (testProp == null) success = false; // should not have triggered delete notify / zeroed testProp value
|
||||
if (testProp.variantCanary != 5) success = false; // should not have deleted vmemo of object referenced by testProp
|
||||
if (testProp.varCanary != 12) success = false; // should not have collected vmemo vmeProperties
|
||||
if (QObjectApi.qobjectTestWritableProperty != 42) success = false; // should not have been set to 43.
|
||||
if (QObjectApi.QObject.qobjectTestWritableProperty != 42) success = false; // should not have been set to 43.
|
||||
}
|
||||
|
||||
// then we remove the reference.
|
||||
|
@ -26,6 +26,6 @@ Item {
|
|||
|
||||
// after a gc (and deferred deletion process) the object should be gone
|
||||
function ensureDeletion() {
|
||||
if (QObjectApi.qobjectTestWritableProperty != 43) success = false; // should have been set to 43.
|
||||
if (QObjectApi.QObject.qobjectTestWritableProperty != 43) success = false; // should have been set to 43.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
.import Qt.test 1.0 as QObjectModuleApi
|
||||
|
||||
function testFunc() {
|
||||
return QObjectModuleApi.qobjectTestProperty
|
||||
}
|
|
@ -0,0 +1,5 @@
|
|||
.import Qt.test 1.0 as QObjectSingletonType
|
||||
|
||||
function testFunc() {
|
||||
return QObjectSingletonType.QObject.qobjectTestProperty
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
import "importModuleApi.js" as Script
|
||||
import "importSingletonType.js" as Script
|
||||
|
||||
Item {
|
||||
property variant testValue: 5
|
|
@ -1,21 +0,0 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import Qt.test 1.0 as QtTest // module API installed into existing uri
|
||||
import Qt.test.qobjectApi 1.0 as QtTestQObjectApi // qobject module API installed into new uri
|
||||
import Qt.test.qobjectApi 1.3 as QtTestMinorVersionQObjectApi // qobject module API installed into existing uri with new minor version
|
||||
import Qt.test.qobjectApi 2.0 as QtTestMajorVersionQObjectApi // qobject module API installed into existing uri with new major version
|
||||
import Qt.test.qobjectApiParented 1.0 as QtTestParentedQObjectApi // qobject (with parent) module API installed into a new uri
|
||||
|
||||
QtObject {
|
||||
property int existingUriTest: QtTest.qobjectTestProperty
|
||||
property int qobjectTest: QtTestQObjectApi.qobjectTestProperty
|
||||
property int qobjectMethodTest: 2
|
||||
property int qobjectMinorVersionTest: QtTestMinorVersionQObjectApi.qobjectTestProperty
|
||||
property int qobjectMajorVersionTest: QtTestMajorVersionQObjectApi.qobjectTestProperty
|
||||
property int qobjectParentedTest: QtTestParentedQObjectApi.qobjectTestProperty
|
||||
|
||||
Component.onCompleted: {
|
||||
qobjectMethodTest = QtTestQObjectApi.qobjectTestMethod();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +0,0 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import Qt.test 1.0 as QtTest // module API installed into existing uri
|
||||
import Qt.test.qobjectApiParented 1.0 as QtTestParentedQObjectApi // qobject (with parent) module API installed into a new uri
|
||||
|
||||
QtObject {
|
||||
property int existingUriTest: QtTest.qobjectTestProperty
|
||||
property int qobjectParentedTest: QtTestParentedQObjectApi.qobjectTestProperty
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.qobjectApi 1.0 as QtTestQObjectApi // qobject module API installed into new uri
|
||||
|
||||
QtObject {
|
||||
property int enumValue: QtTestQObjectApi.EnumValue2;
|
||||
property int enumMethod: QtTestQObjectApi.qobjectEnumTestMethod(QtTestQObjectApi.EnumValue1);
|
||||
}
|
||||
|
|
@ -1,30 +0,0 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test 1.0 as QtTest // qobject module API installed into existing uri
|
||||
|
||||
QtObject {
|
||||
property int firstProperty: 1
|
||||
property int secondProperty: 2
|
||||
property int readOnlyProperty: QtTest.qobjectTestProperty
|
||||
property int writableProperty: QtTest.qobjectTestWritableProperty
|
||||
property int writableFinalProperty: QtTest.qobjectTestWritableFinalProperty
|
||||
|
||||
onFirstPropertyChanged: {
|
||||
// In this case, we want to attempt to set the module API property.
|
||||
// This should fail, as the module API property is read only.
|
||||
if (firstProperty != QtTest.qobjectTestProperty) {
|
||||
QtTest.qobjectTestProperty = firstProperty; // should silently fail.
|
||||
}
|
||||
}
|
||||
|
||||
onSecondPropertyChanged: {
|
||||
// In this case, we want to attempt to set the module API properties.
|
||||
// This should succeed, as the module API properties are writable.
|
||||
if (secondProperty != QtTest.qobjectTestWritableProperty) {
|
||||
QtTest.qobjectTestWritableProperty = secondProperty; // should succeed.
|
||||
}
|
||||
if (secondProperty != QtTest.qobjectTestWritableFinalProperty) {
|
||||
QtTest.qobjectTestWritableFinalProperty = secondProperty; // should succeed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +0,0 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri
|
||||
|
||||
QtObject {
|
||||
property int scriptTest: QtTestScriptApi.scriptTestProperty // script module api's only provide properties.
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.scriptApi 1.0 as QtTestScriptApi // script module API installed into new uri
|
||||
|
||||
QtObject {
|
||||
property int scriptTest: QtTestScriptApi.scriptTestProperty
|
||||
}
|
|
@ -1,32 +0,0 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.scriptApi 1.0 as QtTestScriptApi
|
||||
import Qt.test.scriptApi 2.0 as QtTestScriptApi2
|
||||
|
||||
QtObject {
|
||||
property int firstProperty
|
||||
property int readBack
|
||||
|
||||
property int secondProperty
|
||||
property int unchanged
|
||||
|
||||
onFirstPropertyChanged: {
|
||||
if (QtTestScriptApi.scriptTestProperty != firstProperty) {
|
||||
QtTestScriptApi.scriptTestProperty = firstProperty;
|
||||
readBack = QtTestScriptApi.scriptTestProperty;
|
||||
}
|
||||
}
|
||||
|
||||
onSecondPropertyChanged: {
|
||||
if (QtTestScriptApi2.scriptTestProperty != secondProperty) {
|
||||
QtTestScriptApi2.scriptTestProperty = secondProperty;
|
||||
unchanged = QtTestScriptApi2.scriptTestProperty;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
firstProperty = QtTestScriptApi.scriptTestProperty;
|
||||
readBack = QtTestScriptApi.scriptTestProperty;
|
||||
secondProperty = QtTestScriptApi2.scriptTestProperty;
|
||||
unchanged = QtTestScriptApi2.scriptTestProperty;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test 1.0 as ModuleApi
|
||||
import Qt.test 1.0 as SingletonType
|
||||
|
||||
Item {
|
||||
id: testOwnership
|
||||
|
@ -14,13 +14,13 @@ Item {
|
|||
return; // failed to create component.
|
||||
}
|
||||
o.varprop = true; // causes initialization of varProperties.
|
||||
ModuleApi.trackObject(o); // stores QObject ptr
|
||||
if (ModuleApi.trackedObject() == null) return; // is still valid, should have a valid v8object.
|
||||
SingletonType.QObject.trackObject(o); // stores QObject ptr
|
||||
if (SingletonType.QObject.trackedObject() == null) return; // is still valid, should have a valid v8object.
|
||||
o = new Date(); // causes object to be gc-able.
|
||||
gc(); // collect object's v8object + varProperties, queues deleteLater.
|
||||
if (ModuleApi.trackedObject() != null) return; // v8object was previously collected.
|
||||
ModuleApi.setTrackedObjectProperty("varprop"); // deferences varProperties of object.
|
||||
test = !(ModuleApi.trackedObjectProperty("varprop")); // deferences varProperties of object.
|
||||
if (SingletonType.QObject.trackedObject() != null) return; // v8object was previously collected.
|
||||
SingletonType.QObject.setTrackedObjectProperty("varprop"); // deferences varProperties of object.
|
||||
test = !(SingletonType.QObject.trackedObjectProperty("varprop")); // deferences varProperties of object.
|
||||
// if we didn't crash, success.
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,8 +37,8 @@ Item {
|
|||
property bool enumTypeHasOwnProperty
|
||||
property bool typenameHasOwnProperty
|
||||
property bool typenameHasOwnProperty2
|
||||
property bool moduleApiTypeHasOwnProperty
|
||||
property bool moduleApiPropertyTypeHasOwnProperty
|
||||
property bool singletonTypeTypeHasOwnProperty
|
||||
property bool singletonTypePropertyTypeHasOwnProperty
|
||||
function testHasOwnPropertySuccess() {
|
||||
valueTypeHasOwnProperty = !typeObj.pointProperty.hasOwnProperty("nonexistentpropertyname");
|
||||
valueTypeHasOwnProperty2 = typeObj.pointProperty.hasOwnProperty("x"); // should be true
|
||||
|
@ -50,8 +50,8 @@ Item {
|
|||
enumTypeHasOwnProperty = !MyTypeObject.EnumVal1.hasOwnProperty("nonexistentpropertyname");
|
||||
typenameHasOwnProperty = !MyTypeObject.hasOwnProperty("nonexistentpropertyname");
|
||||
typenameHasOwnProperty2 = MyTypeObject.hasOwnProperty("EnumVal1"); // should be true.
|
||||
moduleApiTypeHasOwnProperty = !QtTestQObjectApi.hasOwnProperty("nonexistentpropertyname");
|
||||
moduleApiPropertyTypeHasOwnProperty = !QtTestQObjectApi.qobjectTestProperty.hasOwnProperty("nonexistentpropertyname");
|
||||
singletonTypeTypeHasOwnProperty = !QtTestQObjectApi.QObject.hasOwnProperty("nonexistentpropertyname");
|
||||
singletonTypePropertyTypeHasOwnProperty = !QtTestQObjectApi.QObject.qobjectTestProperty.hasOwnProperty("nonexistentpropertyname");
|
||||
}
|
||||
|
||||
property bool enumNonValueHasOwnProperty
|
||||
|
@ -59,9 +59,9 @@ Item {
|
|||
enumNonValueHasOwnProperty = !MyTypeObject.NonexistentEnumVal.hasOwnProperty("nonexistentpropertyname");
|
||||
}
|
||||
|
||||
property bool moduleApiNonPropertyHasOwnProperty
|
||||
property bool singletonTypeNonPropertyHasOwnProperty
|
||||
function testHasOwnPropertyFailureTwo() {
|
||||
moduleApiNonPropertyHasOwnProperty = !QtTestQObjectApi.someNonexistentProperty.hasOwnProperty("nonexistentpropertyname");
|
||||
singletonTypeNonPropertyHasOwnProperty = !QtTestQObjectApi.QObject.someNonexistentProperty.hasOwnProperty("nonexistentpropertyname");
|
||||
}
|
||||
|
||||
property bool listAtInvalidHasOwnProperty
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import Qt.test 1.0 as QtTest // singleton Type installed into existing uri
|
||||
import Qt.test.qobjectApi 1.0 as QtTestQObjectApi // qobject singleton Type installed into new uri
|
||||
import Qt.test.qobjectApi 1.3 as QtTestMinorVersionQObjectApi // qobject singleton Type installed into existing uri with new minor version
|
||||
import Qt.test.qobjectApi 2.0 as QtTestMajorVersionQObjectApi // qobject singleton Type installed into existing uri with new major version
|
||||
import Qt.test.qobjectApiParented 1.0 as QtTestParentedQObjectApi // qobject (with parent) singleton Type installed into a new uri
|
||||
|
||||
QtObject {
|
||||
property int existingUriTest: QtTest.QObject.qobjectTestProperty
|
||||
property int qobjectTest: QtTestQObjectApi.QObject.qobjectTestProperty
|
||||
property int qobjectMethodTest: 3
|
||||
property int qobjectMinorVersionTest: QtTestMinorVersionQObjectApi.QObject.qobjectTestProperty
|
||||
property int qobjectMajorVersionTest: QtTestMajorVersionQObjectApi.QObject.qobjectTestProperty
|
||||
property int qobjectParentedTest: QtTestParentedQObjectApi.QObject.qobjectTestProperty
|
||||
|
||||
Component.onCompleted: {
|
||||
qobjectMethodTest = QtTestQObjectApi.QObject.qobjectTestMethod();
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
import Qt.test 1.0 as QtTest // singleton Type installed into existing uri
|
||||
import Qt.test.qobjectApiParented 1.0 as QtTestParentedQObjectApi // qobject (with parent) singleton Type installed into a new uri
|
||||
|
||||
QtObject {
|
||||
property int existingUriTest: QtTest.QObject.qobjectTestProperty
|
||||
property int qobjectParentedTest: QtTestParentedQObjectApi.QObject.qobjectTestProperty
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.qobjectApi 1.0 as QtTestQObjectApi // qobject singleton Type installed into new uri
|
||||
|
||||
QtObject {
|
||||
property int enumValue: QtTestQObjectApi.QObject.EnumValue2;
|
||||
property int enumMethod: QtTestQObjectApi.QObject.qobjectEnumTestMethod(QtTestQObjectApi.QObject.EnumValue1);
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test 1.0
|
||||
|
||||
QtObject {
|
||||
property int qobjectPropertyTest: QObject.qobjectTestProperty
|
||||
property int qobjectMethodTest: 2
|
||||
|
||||
Component.onCompleted: {
|
||||
qobjectMethodTest = QObject.qobjectTestMethod();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test 1.0 as QtTest // qobject singleton Type installed into existing uri
|
||||
|
||||
QtObject {
|
||||
property int firstProperty: 1
|
||||
property int secondProperty: 2
|
||||
property int readOnlyProperty: QtTest.QObject.qobjectTestProperty
|
||||
property int writableProperty: QtTest.QObject.qobjectTestWritableProperty
|
||||
property int writableFinalProperty: QtTest.QObject.qobjectTestWritableFinalProperty
|
||||
|
||||
onFirstPropertyChanged: {
|
||||
// In this case, we want to attempt to set the singleton Type property.
|
||||
// This should fail, as the singleton Type property is read only.
|
||||
if (firstProperty != QtTest.QObject.qobjectTestProperty) {
|
||||
QtTest.QObject.qobjectTestProperty = firstProperty; // should silently fail.
|
||||
}
|
||||
}
|
||||
|
||||
onSecondPropertyChanged: {
|
||||
// In this case, we want to attempt to set the singleton Type properties.
|
||||
// This should succeed, as the singleton Type properties are writable.
|
||||
if (secondProperty != QtTest.QObject.qobjectTestWritableProperty) {
|
||||
QtTest.QObject.qobjectTestWritableProperty = secondProperty; // should succeed.
|
||||
}
|
||||
if (secondProperty != QtTest.QObject.qobjectTestWritableFinalProperty) {
|
||||
QtTest.QObject.qobjectTestWritableFinalProperty = secondProperty; // should succeed.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.scriptApi 1.0 as QtTestScriptApi // script singleton Type installed into new uri
|
||||
|
||||
QtObject {
|
||||
property int scriptTest: QtTestScriptApi.Script.scriptTestProperty // script singleton type's only provide properties.
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.scriptApi 1.0 as QtTestScriptApi // script singleton Type installed into new uri
|
||||
|
||||
QtObject {
|
||||
property int scriptTest: QtTestScriptApi.Script.scriptTestProperty
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.scriptApi 1.0
|
||||
|
||||
QtObject {
|
||||
property int scriptTest: Script.scriptTestProperty // script singleton type's only provide properties.
|
||||
}
|
|
@ -0,0 +1,32 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.scriptApi 1.0 as QtTestScriptApi
|
||||
import Qt.test.scriptApi 2.0 as QtTestScriptApi2
|
||||
|
||||
QtObject {
|
||||
property int firstProperty
|
||||
property int readBack
|
||||
|
||||
property int secondProperty
|
||||
property int unchanged
|
||||
|
||||
onFirstPropertyChanged: {
|
||||
if (QtTestScriptApi.Script.scriptTestProperty != firstProperty) {
|
||||
QtTestScriptApi.Script.scriptTestProperty = firstProperty;
|
||||
readBack = QtTestScriptApi.Script.scriptTestProperty;
|
||||
}
|
||||
}
|
||||
|
||||
onSecondPropertyChanged: {
|
||||
if (QtTestScriptApi2.Script.scriptTestProperty != secondProperty) {
|
||||
QtTestScriptApi2.Script.scriptTestProperty = secondProperty;
|
||||
unchanged = QtTestScriptApi2.Script.scriptTestProperty;
|
||||
}
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
firstProperty = QtTestScriptApi.Script.scriptTestProperty;
|
||||
readBack = QtTestScriptApi.Script.scriptTestProperty;
|
||||
secondProperty = QtTestScriptApi2.Script.scriptTestProperty;
|
||||
unchanged = QtTestScriptApi2.Script.scriptTestProperty;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.importOrderApi1 1.0
|
||||
import Qt.test.importOrderApi2 1.0
|
||||
|
||||
QtObject {
|
||||
property int v: Data.value
|
||||
}
|
|
@ -1,8 +1,8 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
// this qml file attempts to import an invalid version of a qobject module API.
|
||||
// this qml file attempts to import an invalid version of a qobject singleton Type.
|
||||
|
||||
import Qt.test.qobjectApi 4.0 as QtTestMajorVersionQObjectApi // qobject module API installed into existing uri with nonexistent major version
|
||||
import Qt.test.qobjectApi 4.0 as QtTestMajorVersionQObjectApi // qobject singleton Type installed into existing uri with nonexistent major version
|
||||
|
||||
QtObject {
|
||||
property int qobjectMajorVersionTest: QtTestMajorVersionQObjectApi.qobjectTestProperty
|
|
@ -1,8 +1,8 @@
|
|||
import QtQuick 2.0
|
||||
|
||||
// this qml file attempts to import an invalid version of a qobject module API.
|
||||
// this qml file attempts to import an invalid version of a qobject singleton Type.
|
||||
|
||||
import Qt.test.qobjectApi 1.2 as QtTestMinorVersionQObjectApi // qobject module API installed into existing uri with nonexistent minor version
|
||||
import Qt.test.qobjectApi 1.2 as QtTestMinorVersionQObjectApi // qobject singleton Type installed into existing uri with nonexistent minor version
|
||||
|
||||
QtObject {
|
||||
property int qobjectMinorVersionTest: QtTestMinorVersionedQObjectApi.qobjectTestProperty
|
|
@ -0,0 +1,17 @@
|
|||
import QtQuick 2.0
|
||||
import Qt.test.importOrderApi 1.0
|
||||
import Qt.test.importOrderApi 1.0 as Namespace
|
||||
import NamespaceAndType 1.0
|
||||
import NamespaceAndType 1.0 as NamespaceAndType
|
||||
|
||||
QtObject {
|
||||
property bool success: false
|
||||
|
||||
Component.onCompleted: {
|
||||
var s0 = Data.value === 37 && Namespace.Data.value === 37 && Data.value === Namespace.Data.value;
|
||||
var s1 = NamespaceAndType.value === NamespaceAndType.NamespaceAndType.value &&
|
||||
NamespaceAndType.value === 37 &&
|
||||
NamespaceAndType.NamespaceAndType.value === 37;
|
||||
success = (s0 === true) && (s1 === true);
|
||||
}
|
||||
}
|
|
@ -135,6 +135,33 @@ static QJSValue readonly_script_api(QQmlEngine *engine, QJSEngine *scriptEngine)
|
|||
return v;
|
||||
}
|
||||
|
||||
static QObject *testImportOrder_api(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(scriptEngine)
|
||||
|
||||
testImportOrderApi *o = new testImportOrderApi(37);
|
||||
return o;
|
||||
}
|
||||
|
||||
static QObject *testImportOrder_api1(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(scriptEngine)
|
||||
|
||||
testImportOrderApi *o = new testImportOrderApi(1);
|
||||
return o;
|
||||
}
|
||||
|
||||
static QObject *testImportOrder_api2(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(scriptEngine)
|
||||
|
||||
testImportOrderApi *o = new testImportOrderApi(2);
|
||||
return o;
|
||||
}
|
||||
|
||||
static QObject *qobject_api(QQmlEngine *engine, QJSEngine *scriptEngine)
|
||||
{
|
||||
Q_UNUSED(engine)
|
||||
|
@ -266,14 +293,14 @@ void registerTypes()
|
|||
|
||||
qRegisterMetaType<MyQmlObject::MyType>("MyQmlObject::MyType");
|
||||
|
||||
qmlRegisterModuleApi("Qt.test",1,0,script_api); // register (script) module API for an existing uri which contains elements
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test",1,0,qobject_api); // register (qobject) for an existing uri for which another module API was previously regd. Should replace!
|
||||
qmlRegisterModuleApi("Qt.test.scriptApi",1,0,script_api); // register (script) module API for a uri which doesn't contain elements
|
||||
qmlRegisterModuleApi("Qt.test.scriptApi",2,0,readonly_script_api); // register (script) module API for a uri which doesn't contain elements - will be made read-only
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test.qobjectApi",1,0,qobject_api); // register (qobject) module API for a uri which doesn't contain elements
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test.qobjectApi",1,3,qobject_api); // register (qobject) module API for a uri which doesn't contain elements, minor version set
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test.qobjectApi",2,0,qobject_api); // register (qobject) module API for a uri which doesn't contain elements, major version set
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test.qobjectApiParented",1,0,qobject_api_engine_parent); // register (parented qobject) module API for a uri which doesn't contain elements
|
||||
qmlRegisterSingletonType("Qt.test",1,0,"Script",script_api); // register (script) singleton Type for an existing uri which contains elements
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test",1,0,"QObject",qobject_api); // register (qobject) for an existing uri for which another singleton Type was previously regd. Should replace!
|
||||
qmlRegisterSingletonType("Qt.test.scriptApi",1,0,"Script",script_api); // register (script) singleton Type for a uri which doesn't contain elements
|
||||
qmlRegisterSingletonType("Qt.test.scriptApi",2,0,"Script",readonly_script_api); // register (script) singleton Type for a uri which doesn't contain elements - will be made read-only
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",1,0,"QObject",qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",1,3,"QObject",qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements, minor version set
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",2,0,"QObject",qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements, major version set
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApiParented",1,0,"QObject",qobject_api_engine_parent); // register (parented qobject) singleton Type for a uri which doesn't contain elements
|
||||
|
||||
qRegisterMetaType<MyQmlObject::MyEnum2>("MyEnum2");
|
||||
qRegisterMetaType<Qt::MouseButtons>("Qt::MouseButtons");
|
||||
|
@ -288,13 +315,18 @@ void registerTypes()
|
|||
|
||||
qmlRegisterType<MyUnregisteredEnumTypeObject>("Qt.test", 1, 0, "MyUnregisteredEnumTypeObject");
|
||||
|
||||
qmlRegisterModuleApi<FallbackBindingsObject>("Qt.test.fallbackBindingsObject", 1, 0, fallback_bindings_object);
|
||||
qmlRegisterModuleApi<FallbackBindingsObject>("Qt.test.fallbackBindingsDerived", 1, 0, fallback_bindings_derived);
|
||||
qmlRegisterSingletonType<FallbackBindingsObject>("Qt.test.fallbackBindingsObject", 1, 0, "Fallback", fallback_bindings_object);
|
||||
qmlRegisterSingletonType<FallbackBindingsObject>("Qt.test.fallbackBindingsDerived", 1, 0, "Fallback", fallback_bindings_derived);
|
||||
|
||||
qmlRegisterType<FallbackBindingsTypeObject>("Qt.test.fallbackBindingsObject", 1, 0, "FallbackBindingsType");
|
||||
qmlRegisterType<FallbackBindingsTypeDerived>("Qt.test.fallbackBindingsDerived", 1, 0, "FallbackBindingsType");
|
||||
|
||||
qmlRegisterType<MyStringClass>("Qt.test", 1, 0, "MyStringClass");
|
||||
|
||||
qmlRegisterSingletonType<testImportOrderApi>("Qt.test.importOrderApi",1,0,"Data",testImportOrder_api);
|
||||
qmlRegisterSingletonType<testImportOrderApi>("NamespaceAndType",1,0,"NamespaceAndType",testImportOrder_api);
|
||||
qmlRegisterSingletonType<testImportOrderApi>("Qt.test.importOrderApi1",1,0,"Data",testImportOrder_api1);
|
||||
qmlRegisterSingletonType<testImportOrderApi>("Qt.test.importOrderApi2",1,0,"Data",testImportOrder_api2);
|
||||
}
|
||||
|
||||
#include "testtypes.moc"
|
||||
|
|
|
@ -1129,6 +1129,21 @@ private:
|
|||
QObject *m_trackedObject;
|
||||
};
|
||||
|
||||
class testImportOrderApi : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
testImportOrderApi(int value, QObject *parent = 0) : QObject(parent), m_value(value) {}
|
||||
|
||||
Q_PROPERTY(int value READ value)
|
||||
|
||||
int value() const { return m_value; }
|
||||
|
||||
private:
|
||||
int m_value;
|
||||
};
|
||||
|
||||
class CircularReferenceObject : public QObject,
|
||||
public QV8GCCallback::Node
|
||||
{
|
||||
|
|
|
@ -150,8 +150,13 @@ private slots:
|
|||
void signalWithJSValueInVariant_twoEngines();
|
||||
void signalWithQJSValue_data();
|
||||
void signalWithQJSValue();
|
||||
void moduleApi_data();
|
||||
void moduleApi();
|
||||
void singletonType_data();
|
||||
void singletonType();
|
||||
void singletonTypeImportOrder();
|
||||
void singletonTypeResolution();
|
||||
void singletonTypeConflicts1();
|
||||
void singletonTypeConflicts2();
|
||||
void singletonTypeConflicts3();
|
||||
void importScripts_data();
|
||||
void importScripts();
|
||||
void scarceResources();
|
||||
|
@ -1632,15 +1637,15 @@ void tst_qqmlecmascript::objectHasOwnProperty()
|
|||
QCOMPARE(child->property("enumTypeHasOwnProperty").toBool(), true);
|
||||
QCOMPARE(child->property("typenameHasOwnProperty").toBool(), true);
|
||||
QCOMPARE(child->property("typenameHasOwnProperty2").toBool(), true);
|
||||
QCOMPARE(child->property("moduleApiTypeHasOwnProperty").toBool(), true);
|
||||
QCOMPARE(child->property("moduleApiPropertyTypeHasOwnProperty").toBool(), true);
|
||||
QCOMPARE(child->property("singletonTypeTypeHasOwnProperty").toBool(), true);
|
||||
QCOMPARE(child->property("singletonTypePropertyTypeHasOwnProperty").toBool(), true);
|
||||
|
||||
QTest::ignoreMessage(QtWarningMsg, warning1.toLatin1().constData());
|
||||
QMetaObject::invokeMethod(child, "testHasOwnPropertyFailureOne");
|
||||
QCOMPARE(child->property("enumNonValueHasOwnProperty").toBool(), false);
|
||||
QTest::ignoreMessage(QtWarningMsg, warning2.toLatin1().constData());
|
||||
QMetaObject::invokeMethod(child, "testHasOwnPropertyFailureTwo");
|
||||
QCOMPARE(child->property("moduleApiNonPropertyHasOwnProperty").toBool(), false);
|
||||
QCOMPARE(child->property("singletonTypeNonPropertyHasOwnProperty").toBool(), false);
|
||||
QTest::ignoreMessage(QtWarningMsg, warning3.toLatin1().constData());
|
||||
QMetaObject::invokeMethod(child, "testHasOwnPropertyFailureThree");
|
||||
QCOMPARE(child->property("listAtInvalidHasOwnProperty").toBool(), false);
|
||||
|
@ -3527,7 +3532,7 @@ void tst_qqmlecmascript::signalWithQJSValue()
|
|||
QVERIFY(object->qjsvalue().strictlyEquals(value));
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::moduleApi_data()
|
||||
void tst_qqmlecmascript::singletonType_data()
|
||||
{
|
||||
QTest::addColumn<QUrl>("testfile");
|
||||
QTest::addColumn<QString>("errorMessage");
|
||||
|
@ -3539,20 +3544,42 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
QTest::addColumn<QStringList>("readBackProperties");
|
||||
QTest::addColumn<QVariantList>("readBackExpectedValues");
|
||||
|
||||
QTest::newRow("qobject, register + read + method [no qualifier]")
|
||||
<< testFileUrl("singletontype/qobjectSingletonTypeNoQualifier.qml")
|
||||
<< QString()
|
||||
<< QStringList()
|
||||
<< (QStringList() << "qobjectPropertyTest" << "qobjectMethodTest")
|
||||
<< (QVariantList() << 20 << 1)
|
||||
<< QStringList()
|
||||
<< QVariantList()
|
||||
<< QStringList()
|
||||
<< QVariantList();
|
||||
|
||||
QTest::newRow("script, register + read [no qualifier]")
|
||||
<< testFileUrl("singletontype/scriptSingletonTypeNoQualifier.qml")
|
||||
<< QString()
|
||||
<< QStringList()
|
||||
<< (QStringList() << "scriptTest")
|
||||
<< (QVariantList() << 13)
|
||||
<< QStringList()
|
||||
<< QVariantList()
|
||||
<< QStringList()
|
||||
<< QVariantList();
|
||||
|
||||
QTest::newRow("qobject, register + read + method")
|
||||
<< testFileUrl("moduleapi/qobjectModuleApi.qml")
|
||||
<< testFileUrl("singletontype/qobjectSingletonType.qml")
|
||||
<< QString()
|
||||
<< QStringList()
|
||||
<< (QStringList() << "existingUriTest" << "qobjectTest" << "qobjectMethodTest"
|
||||
<< "qobjectMinorVersionTest" << "qobjectMajorVersionTest" << "qobjectParentedTest")
|
||||
<< (QVariantList() << 20 << 20 << 1 << 20 << 20 << 26)
|
||||
<< (QVariantList() << 20 << 20 << 2 << 20 << 20 << 26)
|
||||
<< QStringList()
|
||||
<< QVariantList()
|
||||
<< QStringList()
|
||||
<< QVariantList();
|
||||
|
||||
QTest::newRow("script, register + read")
|
||||
<< testFileUrl("moduleapi/scriptModuleApi.qml")
|
||||
<< testFileUrl("singletontype/scriptSingletonType.qml")
|
||||
<< QString()
|
||||
<< QStringList()
|
||||
<< (QStringList() << "scriptTest")
|
||||
|
@ -3563,7 +3590,7 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
<< QVariantList();
|
||||
|
||||
QTest::newRow("qobject, caching + read")
|
||||
<< testFileUrl("moduleapi/qobjectModuleApiCaching.qml")
|
||||
<< testFileUrl("singletontype/qobjectSingletonTypeCaching.qml")
|
||||
<< QString()
|
||||
<< QStringList()
|
||||
<< (QStringList() << "existingUriTest" << "qobjectParentedTest")
|
||||
|
@ -3574,7 +3601,7 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
<< QVariantList();
|
||||
|
||||
QTest::newRow("script, caching + read")
|
||||
<< testFileUrl("moduleapi/scriptModuleApiCaching.qml")
|
||||
<< testFileUrl("singletontype/scriptSingletonTypeCaching.qml")
|
||||
<< QString()
|
||||
<< QStringList()
|
||||
<< (QStringList() << "scriptTest")
|
||||
|
@ -3585,9 +3612,9 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
<< QVariantList();
|
||||
|
||||
QTest::newRow("qobject, writing + readonly constraints")
|
||||
<< testFileUrl("moduleapi/qobjectModuleApiWriting.qml")
|
||||
<< testFileUrl("singletontype/qobjectSingletonTypeWriting.qml")
|
||||
<< QString()
|
||||
<< (QStringList() << QString(testFileUrl("moduleapi/qobjectModuleApiWriting.qml").toString() + QLatin1String(":15: Error: Cannot assign to read-only property \"qobjectTestProperty\"")))
|
||||
<< (QStringList() << QString(testFileUrl("singletontype/qobjectSingletonTypeWriting.qml").toString() + QLatin1String(":15: Error: Cannot assign to read-only property \"qobjectTestProperty\"")))
|
||||
<< (QStringList() << "readOnlyProperty" << "writableProperty" << "writableFinalProperty")
|
||||
<< (QVariantList() << 20 << 50 << 10)
|
||||
<< (QStringList() << "firstProperty" << "secondProperty")
|
||||
|
@ -3596,9 +3623,9 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
<< (QVariantList() << 20 << 30 << 30);
|
||||
|
||||
QTest::newRow("script, writing + readonly constraints")
|
||||
<< testFileUrl("moduleapi/scriptModuleApiWriting.qml")
|
||||
<< testFileUrl("singletontype/scriptSingletonTypeWriting.qml")
|
||||
<< QString()
|
||||
<< (QStringList() << QString(testFileUrl("moduleapi/scriptModuleApiWriting.qml").toString() + QLatin1String(":21: Error: Cannot assign to read-only property \"scriptTestProperty\"")))
|
||||
<< (QStringList() << QString(testFileUrl("singletontype/scriptSingletonTypeWriting.qml").toString() + QLatin1String(":21: Error: Cannot assign to read-only property \"scriptTestProperty\"")))
|
||||
<< (QStringList() << "readBack" << "unchanged")
|
||||
<< (QVariantList() << 13 << 42)
|
||||
<< (QStringList() << "firstProperty" << "secondProperty")
|
||||
|
@ -3606,8 +3633,8 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
<< (QStringList() << "readBack" << "unchanged")
|
||||
<< (QVariantList() << 30 << 42);
|
||||
|
||||
QTest::newRow("qobject module API enum values in JS")
|
||||
<< testFileUrl("moduleapi/qobjectModuleApiEnums.qml")
|
||||
QTest::newRow("qobject singleton Type enum values in JS")
|
||||
<< testFileUrl("singletontype/qobjectSingletonTypeEnums.qml")
|
||||
<< QString()
|
||||
<< QStringList()
|
||||
<< (QStringList() << "enumValue" << "enumMethod")
|
||||
|
@ -3618,7 +3645,7 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
<< QVariantList();
|
||||
|
||||
QTest::newRow("qobject, invalid major version fail")
|
||||
<< testFileUrl("moduleapi/moduleApiMajorVersionFail.qml")
|
||||
<< testFileUrl("singletontype/singletonTypeMajorVersionFail.qml")
|
||||
<< QString("QQmlComponent: Component is not ready")
|
||||
<< QStringList()
|
||||
<< QStringList()
|
||||
|
@ -3629,7 +3656,7 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
<< QVariantList();
|
||||
|
||||
QTest::newRow("qobject, invalid minor version fail")
|
||||
<< testFileUrl("moduleapi/moduleApiMinorVersionFail.qml")
|
||||
<< testFileUrl("singletontype/singletonTypeMinorVersionFail.qml")
|
||||
<< QString("QQmlComponent: Component is not ready")
|
||||
<< QStringList()
|
||||
<< QStringList()
|
||||
|
@ -3640,7 +3667,7 @@ void tst_qqmlecmascript::moduleApi_data()
|
|||
<< QVariantList();
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::moduleApi()
|
||||
void tst_qqmlecmascript::singletonType()
|
||||
{
|
||||
QFETCH(QUrl, testfile);
|
||||
QFETCH(QString, errorMessage);
|
||||
|
@ -3676,6 +3703,90 @@ void tst_qqmlecmascript::moduleApi()
|
|||
}
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::singletonTypeImportOrder()
|
||||
{
|
||||
QQmlComponent component(&engine, testFileUrl("singletontype/singletonTypeImportOrder.qml"));
|
||||
QObject *object = component.create();
|
||||
QVERIFY(object);
|
||||
QVERIFY(object->property("v") == 1);
|
||||
delete object;
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::singletonTypeResolution()
|
||||
{
|
||||
QQmlComponent component(&engine, testFileUrl("singletontype/singletonTypeResolution.qml"));
|
||||
QObject *object = component.create();
|
||||
QVERIFY(object);
|
||||
QVERIFY(object->property("success") == true);
|
||||
delete object;
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::singletonTypeConflicts1()
|
||||
{
|
||||
const char *warning = "Cannot register singleton type TypeName in uri Test.Conflict1 1.5 (a conflicting singleton type already exists)";
|
||||
QTest::ignoreMessage(QtWarningMsg, warning);
|
||||
|
||||
int i0 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict1", 1, 5, "TypeName", 0);
|
||||
QVERIFY(i0 != -1);
|
||||
|
||||
int i1 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict1", 2, 0, "TypeName", 0);
|
||||
QVERIFY(i1 != -1);
|
||||
|
||||
int i2 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict1", 1, 5, "TypeName", 0);
|
||||
QVERIFY(i2 == -1);
|
||||
|
||||
int i3 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict1", 1, 2, "TypeName", 0);
|
||||
QVERIFY(i3 != -1);
|
||||
|
||||
int i4 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict1", 1, 8, "TypeName", 0);
|
||||
QVERIFY(i4 != -1);
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::singletonTypeConflicts2()
|
||||
{
|
||||
int i0 = qmlRegisterType<MyQmlObject>("Test.Conflict2", 1, 5, "TypeName");
|
||||
QVERIFY(i0 != -1);
|
||||
|
||||
int i2 = qmlRegisterType<MyQmlObject>("Test.Conflict2", 1, 8, "TypeName");
|
||||
QVERIFY(i2 != -1);
|
||||
|
||||
int i3 = qmlRegisterType<MyQmlObject>("Test.Conflict2", 2, 0, "TypeName");
|
||||
QVERIFY(i3 != -1);
|
||||
|
||||
int i4 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict2", 1, 0, "TypeName", 0);
|
||||
QVERIFY(i4 != -1);
|
||||
|
||||
const char *warning2 = "Cannot register singleton type TypeName in uri Test.Conflict2 1.9 (a conflicting type already exists)";
|
||||
QTest::ignoreMessage(QtWarningMsg, warning2);
|
||||
|
||||
int i5 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict2", 1, 9, "TypeName", 0);
|
||||
QVERIFY(i5 == -1);
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::singletonTypeConflicts3()
|
||||
{
|
||||
int i0 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict3", 1, 0, "TypeName", 0);
|
||||
QVERIFY(i0 != -1);
|
||||
|
||||
int i1 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict3", 1, 5, "TypeName", 0);
|
||||
QVERIFY(i1 != -1);
|
||||
|
||||
int i2 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict3", 1, 8, "TypeName", 0);
|
||||
QVERIFY(i2 != -1);
|
||||
|
||||
int i3 = qmlRegisterSingletonType<testImportOrderApi>("Test.Conflict3", 2, 0, "TypeName", 0);
|
||||
QVERIFY(i3 != -1);
|
||||
|
||||
const char *warning = "Cannot register type TypeName in uri Test.Conflict3 1.0 (a conflicting singleton type already exists)";
|
||||
QTest::ignoreMessage(QtWarningMsg, warning);
|
||||
|
||||
int i4 = qmlRegisterType<MyQmlObject>("Test.Conflict3", 1, 0, "TypeName");
|
||||
QVERIFY(i4 == -1);
|
||||
|
||||
int i5 = qmlRegisterType<MyQmlObject>("Test.Conflict3", 1, 3, "TypeName");
|
||||
QVERIFY(i5 != -1);
|
||||
}
|
||||
|
||||
void tst_qqmlecmascript::importScripts_data()
|
||||
{
|
||||
QTest::addColumn<QUrl>("testfile");
|
||||
|
@ -3767,8 +3878,8 @@ void tst_qqmlecmascript::importScripts_data()
|
|||
<< (QStringList() << QLatin1String("testValue"))
|
||||
<< (QVariantList() << QVariant(18));
|
||||
|
||||
QTest::newRow("import module api into js import")
|
||||
<< testFileUrl("jsimport/testImportModuleApi.qml")
|
||||
QTest::newRow("import singleton type into js import")
|
||||
<< testFileUrl("jsimport/testImportSingletonType.qml")
|
||||
<< QString()
|
||||
<< QStringList()
|
||||
<< (QStringList() << QLatin1String("testValue"))
|
||||
|
@ -7106,8 +7217,8 @@ void tst_qqmlecmascript::fallbackBindings_data()
|
|||
|
||||
QTest::newRow("Property without fallback") << "fallbackBindings.1.qml";
|
||||
QTest::newRow("Property fallback") << "fallbackBindings.2.qml";
|
||||
QTest::newRow("ModuleAPI without fallback") << "fallbackBindings.3.qml";
|
||||
QTest::newRow("ModuleAPI fallback") << "fallbackBindings.4.qml";
|
||||
QTest::newRow("SingletonType without fallback") << "fallbackBindings.3.qml";
|
||||
QTest::newRow("SingletonType fallback") << "fallbackBindings.4.qml";
|
||||
QTest::newRow("Attached without fallback") << "fallbackBindings.5.qml";
|
||||
QTest::newRow("Attached fallback") << "fallbackBindings.6.qml";
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
function test() {
|
||||
var r="transaction_not_finished";
|
||||
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-changeversion", "", "Test database from Qt autotests", 1000000,
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-changeversion", "", "Test database from Qt autotests", 1000000,
|
||||
function(db) {
|
||||
db.changeVersion("","1.0")
|
||||
db.transaction(function(tx){
|
||||
|
@ -17,7 +17,7 @@ function test() {
|
|||
});
|
||||
|
||||
|
||||
db = Sql.openDatabaseSync("QmlTestDB-changeversion", "", "Test database from Qt autotests", 1000000);
|
||||
db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-changeversion", "", "Test database from Qt autotests", 1000000);
|
||||
|
||||
if (db.version == "1.0")
|
||||
db.changeVersion("1.0","2.0",function(tx)
|
||||
|
@ -37,7 +37,7 @@ function test() {
|
|||
else
|
||||
return "db.version should be 1.0, but is " + db.version;
|
||||
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-changeversion", "2.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-changeversion", "2.0", "Test database from Qt autotests", 1000000);
|
||||
|
||||
db.transaction(function(tx){
|
||||
var rs = tx.executeSql('SELECT * FROM Utterance');
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
function test() {
|
||||
var r="transaction_not_finished";
|
||||
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-creation-a", "1.0", "Test database from Qt autotests", 1000000,
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-creation-a", "1.0", "Test database from Qt autotests", 1000000,
|
||||
function(db) {
|
||||
db.transaction(function(tx){
|
||||
tx.executeSql('CREATE TABLE Greeting(salutation TEXT, salutee TEXT)');
|
||||
|
@ -11,7 +11,7 @@ function test() {
|
|||
})
|
||||
});
|
||||
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-creation-a", "1.0", "Test database from Qt autotests", 1000000,
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-creation-a", "1.0", "Test database from Qt autotests", 1000000,
|
||||
function(db) {
|
||||
r = "FAILED: should have already been created";
|
||||
});
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
function test() {
|
||||
var r="transaction_not_finished";
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-creation", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-creation", "1.0", "Test database from Qt autotests", 1000000);
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
tx.executeSql('CREATE TABLE IF NOT EXISTS Greeting(salutation TEXT, salutee TEXT)');
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.import QtQuick.LocalStorage 2.0 as Sql
|
||||
|
||||
function test() {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-error-a", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-error-a", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var r="transaction_not_finished";
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.import QtQuick.LocalStorage 2.0 as Sql
|
||||
|
||||
function test() {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-error-b", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-error-b", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var r="transaction_not_finished";
|
||||
|
||||
db.transaction(
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
function test() {
|
||||
var r="transaction_not_finished";
|
||||
try {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-creation", "2.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-creation", "2.0", "Test database from Qt autotests", 1000000);
|
||||
} catch (err) {
|
||||
if (err.code != SQLException.VERSION_ERR)
|
||||
r = "WRONG ERROR CODE="+err.code;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.import QtQuick.LocalStorage 2.0 as Sql
|
||||
|
||||
function test() {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-data/error-notransaction", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-data/error-notransaction", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var r="transaction_not_finished";
|
||||
|
||||
try {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.import QtQuick.LocalStorage 2.0 as Sql
|
||||
|
||||
function test() {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-data/error-notransaction", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-data/error-notransaction", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var r="transaction_not_finished";
|
||||
var v;
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.import QtQuick.LocalStorage 2.0 as Sql
|
||||
|
||||
function test() {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-iteration-forwardonly", "", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-iteration-forwardonly", "", "Test database from Qt autotests", 1000000);
|
||||
var r="transaction_not_finished";
|
||||
|
||||
db.transaction(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.import QtQuick.LocalStorage 2.0 as Sql
|
||||
|
||||
function test() {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-iteration", "", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-iteration", "", "Test database from Qt autotests", 1000000);
|
||||
var r="transaction_not_finished";
|
||||
|
||||
db.transaction(
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
function test() {
|
||||
var r="transaction_not_finished";
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-readonly-error", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-readonly-error", "1.0", "Test database from Qt autotests", 1000000);
|
||||
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
function test() {
|
||||
var r="transaction_not_finished";
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-readonly", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-readonly", "1.0", "Test database from Qt autotests", 1000000);
|
||||
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
function test() {
|
||||
var r="transaction_not_finished";
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-reopen", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-reopen", "1.0", "Test database from Qt autotests", 1000000);
|
||||
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
function test() {
|
||||
var r="transaction_not_finished";
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-reopen", "1.0", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-reopen", "1.0", "Test database from Qt autotests", 1000000);
|
||||
|
||||
db.transaction(
|
||||
function(tx) {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.import QtQuick.LocalStorage 2.0 as Sql
|
||||
|
||||
function test() {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-bindnames", "", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-bindnames", "", "Test database from Qt autotests", 1000000);
|
||||
var r="transaction_not_finished";
|
||||
|
||||
db.transaction(
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
.import QtQuick.LocalStorage 2.0 as Sql
|
||||
|
||||
function test() {
|
||||
var db = Sql.openDatabaseSync("QmlTestDB-selection", "", "Test database from Qt autotests", 1000000);
|
||||
var db = Sql.LocalStorage.openDatabaseSync("QmlTestDB-selection", "", "Test database from Qt autotests", 1000000);
|
||||
var r="transaction_not_finished";
|
||||
|
||||
db.transaction(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import QtQuick 2.0
|
||||
import MyTestModuleApi 1.0 as MyTestModuleApi
|
||||
import MyTestSingletonType 1.0 as MyTestSingletonType
|
||||
|
||||
Item {
|
||||
id: rootObject
|
||||
|
@ -10,12 +10,12 @@ Item {
|
|||
property int moduleOtherSignalCount: 0
|
||||
|
||||
function setModuleIntProp() {
|
||||
MyTestModuleApi.intProp = newIntPropValue;
|
||||
MyTestSingletonType.Api.intProp = newIntPropValue;
|
||||
newIntPropValue = newIntPropValue + 1;
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: MyTestModuleApi
|
||||
target: MyTestSingletonType.Api
|
||||
onIntPropChanged: moduleIntPropChangedCount = moduleIntPropChangedCount + 1;
|
||||
onOtherSignal: moduleOtherSignalCount = moduleOtherSignalCount + 1;
|
||||
}
|
|
@ -62,7 +62,7 @@ private slots:
|
|||
void unknownSignals();
|
||||
void errors_data();
|
||||
void errors();
|
||||
void moduleApiTarget();
|
||||
void singletonTypeTarget();
|
||||
|
||||
private:
|
||||
QQmlEngine engine;
|
||||
|
@ -225,14 +225,14 @@ void tst_qquickconnection::errors()
|
|||
}
|
||||
|
||||
|
||||
class MyTestModuleApi : public QObject
|
||||
class MyTestSingletonType : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int intProp READ intProp WRITE setIntProp NOTIFY intPropChanged)
|
||||
|
||||
public:
|
||||
MyTestModuleApi(QObject *parent = 0) : QObject(parent), m_intProp(0), m_changeCount(0) {}
|
||||
~MyTestModuleApi() {}
|
||||
MyTestSingletonType(QObject *parent = 0) : QObject(parent), m_intProp(0), m_changeCount(0) {}
|
||||
~MyTestSingletonType() {}
|
||||
|
||||
Q_INVOKABLE int otherMethod(int val) { return val + 4; }
|
||||
|
||||
|
@ -256,15 +256,15 @@ static QObject *module_api_factory(QQmlEngine *engine, QJSEngine *scriptEngine)
|
|||
{
|
||||
Q_UNUSED(engine)
|
||||
Q_UNUSED(scriptEngine)
|
||||
MyTestModuleApi *api = new MyTestModuleApi();
|
||||
MyTestSingletonType *api = new MyTestSingletonType();
|
||||
return api;
|
||||
}
|
||||
|
||||
// QTBUG-20937
|
||||
void tst_qquickconnection::moduleApiTarget()
|
||||
void tst_qquickconnection::singletonTypeTarget()
|
||||
{
|
||||
qmlRegisterModuleApi<MyTestModuleApi>("MyTestModuleApi", 1, 0, module_api_factory);
|
||||
QQmlComponent component(&engine, testFileUrl("moduleapi-target.qml"));
|
||||
qmlRegisterSingletonType<MyTestSingletonType>("MyTestSingletonType", 1, 0, "Api", module_api_factory);
|
||||
QQmlComponent component(&engine, testFileUrl("singletontype-target.qml"));
|
||||
QObject *object = component.create();
|
||||
QVERIFY(object != 0);
|
||||
|
||||
|
@ -279,7 +279,7 @@ void tst_qquickconnection::moduleApiTarget()
|
|||
QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 2);
|
||||
QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 0);
|
||||
|
||||
// the module API emits otherSignal every 3 times the int property changes.
|
||||
// the singleton Type emits otherSignal every 3 times the int property changes.
|
||||
QMetaObject::invokeMethod(object, "setModuleIntProp");
|
||||
QCOMPARE(object->property("moduleIntPropChangedCount").toInt(), 3);
|
||||
QCOMPARE(object->property("moduleOtherSignalCount").toInt(), 1);
|
||||
|
|
|
@ -2,11 +2,11 @@ import Qt.test 1.0 as ModApi
|
|||
import QtQuick 2.0
|
||||
|
||||
Item {
|
||||
property int testProp: ModApi.ip
|
||||
property int testProp: ModApi.V4.ip
|
||||
property int testProp2: 2
|
||||
|
||||
function getRandom() {
|
||||
testProp2 = ModApi.random();
|
||||
testProp2 = ModApi.V4.random();
|
||||
// testProp should also have changed.
|
||||
}
|
||||
}
|
|
@ -82,7 +82,7 @@ private slots:
|
|||
void mathCeil();
|
||||
void mathMax();
|
||||
void mathMin();
|
||||
void moduleApi();
|
||||
void singletonType();
|
||||
|
||||
void conversions_data();
|
||||
void conversions();
|
||||
|
@ -607,13 +607,13 @@ void tst_v4::mathMin()
|
|||
delete o;
|
||||
}
|
||||
|
||||
class V4ModuleApi : public QObject
|
||||
class V4SingletonType : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(int ip READ ip WRITE setIp NOTIFY ipChanged FINAL)
|
||||
public:
|
||||
V4ModuleApi() : m_ip(12) {}
|
||||
~V4ModuleApi() {}
|
||||
V4SingletonType() : m_ip(12) {}
|
||||
~V4SingletonType() {}
|
||||
|
||||
Q_INVOKABLE int random() { static int prng = 3; prng++; m_ip++; emit ipChanged(); return prng; }
|
||||
|
||||
|
@ -629,14 +629,14 @@ private:
|
|||
|
||||
static QObject *v4_module_api_factory(QQmlEngine*, QJSEngine*)
|
||||
{
|
||||
return new V4ModuleApi;
|
||||
return new V4SingletonType;
|
||||
}
|
||||
|
||||
void tst_v4::moduleApi()
|
||||
void tst_v4::singletonType()
|
||||
{
|
||||
// register module api, providing typeinfo via template
|
||||
qmlRegisterModuleApi<V4ModuleApi>("Qt.test", 1, 0, v4_module_api_factory);
|
||||
QQmlComponent component(&engine, testFileUrl("moduleApi.qml"));
|
||||
// register singleton type, providing typeinfo via template
|
||||
qmlRegisterSingletonType<V4SingletonType>("Qt.test", 1, 0, "V4", v4_module_api_factory);
|
||||
QQmlComponent component(&engine, testFileUrl("singletonType.qml"));
|
||||
QObject *o = component.create();
|
||||
QVERIFY(o != 0);
|
||||
QCOMPARE(o->property("testProp").toInt(), 12);
|
||||
|
|
|
@ -82,13 +82,13 @@ void registerTypes()
|
|||
qmlRegisterType<ScarceResourceProvider>("Qt.test", 1,0, "MyScarceResourceProvider");
|
||||
qmlRegisterType<ArbitraryVariantProvider>("Qt.test", 1,0, "MyArbitraryVariantProvider");
|
||||
|
||||
qmlRegisterModuleApi("Qt.test",1,0,script_api); // register (script) module API for an existing uri which contains elements
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test",1,0,qobject_api); // register (qobject) for an existing uri for which another module API was previously regd. Should replace!
|
||||
qmlRegisterModuleApi("Qt.test.scriptApi",1,0,script_api); // register (script) module API for a uri which doesn't contain elements
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test.qobjectApi",1,0,qobject_api); // register (qobject) module API for a uri which doesn't contain elements
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test.qobjectApi",1,3,qobject_api); // register (qobject) module API for a uri which doesn't contain elements, minor version set
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test.qobjectApi",2,0,qobject_api); // register (qobject) module API for a uri which doesn't contain elements, major version set
|
||||
qmlRegisterModuleApi<testQObjectApi>("Qt.test.qobjectApiParented",1,0,qobject_api_engine_parent); // register (parented qobject) module API for a uri which doesn't contain elements
|
||||
qmlRegisterSingletonType("Qt.test",1,0,script_api); // register (script) singleton Type for an existing uri which contains elements
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test",1,0,qobject_api); // register (qobject) for an existing uri for which another singleton Type was previously regd. Should replace!
|
||||
qmlRegisterSingletonType("Qt.test.scriptApi",1,0,script_api); // register (script) singleton Type for a uri which doesn't contain elements
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",1,0,qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",1,3,qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements, minor version set
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApi",2,0,qobject_api); // register (qobject) singleton Type for a uri which doesn't contain elements, major version set
|
||||
qmlRegisterSingletonType<testQObjectApi>("Qt.test.qobjectApiParented",1,0,qobject_api_engine_parent); // register (parented qobject) singleton Type for a uri which doesn't contain elements
|
||||
}
|
||||
|
||||
//#include "testtypes.moc"
|
||||
|
|
|
@ -177,15 +177,16 @@ QByteArray convertToId(const QMetaObject *mo)
|
|||
return className;
|
||||
}
|
||||
|
||||
/* All exported module APIs are collected into this list */
|
||||
class ModuleApi {
|
||||
/* All exported singleton Types are collected into this list */
|
||||
class SingletonType {
|
||||
public:
|
||||
QString uri;
|
||||
int majorVersion;
|
||||
int minorVersion;
|
||||
QByteArray objectId;
|
||||
QString typeName;
|
||||
};
|
||||
QList<ModuleApi> moduleApis;
|
||||
QList<SingletonType> singletonTypes;
|
||||
|
||||
QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, const QList<QQmlType *> &skip = QList<QQmlType *>())
|
||||
{
|
||||
|
@ -260,30 +261,31 @@ QSet<const QMetaObject *> collectReachableMetaObjects(QQmlEngine *engine, const
|
|||
qWarning() << "Could not create" << tyName;
|
||||
}
|
||||
|
||||
// extract exported module api
|
||||
QHashIterator<QString, QList<QQmlMetaType::ModuleApi> > moduleApiIt(QQmlMetaType::moduleApis());
|
||||
while (moduleApiIt.hasNext()) {
|
||||
moduleApiIt.next();
|
||||
foreach (const QQmlMetaType::ModuleApi &api, moduleApiIt.value()) {
|
||||
ModuleApi moduleApi;
|
||||
moduleApi.uri = moduleApiIt.key();
|
||||
moduleApi.majorVersion = api.major;
|
||||
moduleApi.minorVersion = api.minor;
|
||||
// extract exported singleton type
|
||||
QHashIterator<QString, QList<QQmlMetaType::SingletonType> > singletonTypeIt(QQmlMetaType::singletonTypes());
|
||||
while (singletonTypeIt.hasNext()) {
|
||||
singletonTypeIt.next();
|
||||
foreach (const QQmlMetaType::SingletonType &api, singletonTypeIt.value()) {
|
||||
SingletonType singletonType;
|
||||
singletonType.uri = singletonTypeIt.key();
|
||||
singletonType.majorVersion = api.major;
|
||||
singletonType.minorVersion = api.minor;
|
||||
singletonType.typeName = api.typeName;
|
||||
|
||||
if (api.qobject) {
|
||||
if (QObject *object = (*api.qobject)(engine, engine)) {
|
||||
collectReachableMetaObjects(object, &metas);
|
||||
moduleApi.objectId = convertToId(object->metaObject()->className());
|
||||
singletonType.objectId = convertToId(object->metaObject()->className());
|
||||
delete object;
|
||||
}
|
||||
} else if (api.script) {
|
||||
qWarning() << "Can't dump the module api in " << moduleApi.uri << ". QJSValue based module API is not supported.";
|
||||
qWarning() << "Can't dump the singleton type in " << singletonType.uri << ". QJSValue based singleton Type is not supported.";
|
||||
// QJSValue value = (*api.script)(engine, engine);
|
||||
// IdToObjectHash jsObjects;
|
||||
// collectReachableJSObjects(value, &jsObjects, &metas);
|
||||
}
|
||||
|
||||
moduleApis += moduleApi;
|
||||
singletonTypes += singletonType;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -416,15 +418,16 @@ public:
|
|||
qml->writeEndObject();
|
||||
}
|
||||
|
||||
void dump(const ModuleApi &api)
|
||||
void dump(const SingletonType &api)
|
||||
{
|
||||
qml->writeStartObject(QLatin1String("ModuleApi"));
|
||||
qml->writeStartObject(QLatin1String("SingletonType"));
|
||||
if (api.uri != relocatableModuleUri)
|
||||
qml->writeScriptBinding(QLatin1String("uri"), enquote(api.uri));
|
||||
qml->writeScriptBinding(QLatin1String("version"), QString("%1.%2").arg(
|
||||
QString::number(api.majorVersion),
|
||||
QString::number(api.minorVersion)));
|
||||
qml->writeScriptBinding(QLatin1String("name"), enquote(api.objectId));
|
||||
qml->writeScriptBinding(QLatin1String("typeName"), enquote(api.typeName));
|
||||
qml->writeEndObject();
|
||||
}
|
||||
|
||||
|
@ -789,8 +792,8 @@ int main(int argc, char *argv[])
|
|||
if (pluginImportUri.isEmpty())
|
||||
dumper.writeEasingCurve();
|
||||
|
||||
// write out module api elements
|
||||
foreach (const ModuleApi &api, moduleApis) {
|
||||
// write out singleton type elements
|
||||
foreach (const SingletonType &api, singletonTypes) {
|
||||
dumper.dump(api);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue