diff options
Diffstat (limited to 'src')
248 files changed, 1645 insertions, 734 deletions
diff --git a/src/imports/layouts/qquicklinearlayout.cpp b/src/imports/layouts/qquicklinearlayout.cpp index 887b9b1fa1..4410723f3d 100644 --- a/src/imports/layouts/qquicklinearlayout.cpp +++ b/src/imports/layouts/qquicklinearlayout.cpp @@ -850,3 +850,5 @@ void QQuickLinearLayout::insertLayoutItems() } QT_END_NAMESPACE + +#include "moc_qquicklinearlayout_p.cpp" diff --git a/src/imports/layouts/qquickstacklayout.cpp b/src/imports/layouts/qquickstacklayout.cpp index 0bfe63816d..9a7ec71473 100644 --- a/src/imports/layouts/qquickstacklayout.cpp +++ b/src/imports/layouts/qquickstacklayout.cpp @@ -341,3 +341,5 @@ bool QQuickStackLayout::shouldIgnoreItem(QQuickItem *item) const d_func()->m_ignoredItems << item; return ignored; } + +#include "moc_qquickstacklayout_p.cpp" diff --git a/src/imports/sharedimage/plugin.cpp b/src/imports/sharedimage/plugin.cpp index f20edc641c..53e95ef21a 100644 --- a/src/imports/sharedimage/plugin.cpp +++ b/src/imports/sharedimage/plugin.cpp @@ -43,7 +43,7 @@ /*! - \qmlmodule QtQuick.SharedImage 1 + \qmlmodule Qt.labs.sharedimage 1 \title Qt Quick Shared Image Provider \ingroup qmlmodules \brief Adds an image provider which utilizes shared CPU memory @@ -62,7 +62,7 @@ To use this module, import it like this: \code - import QtQuick.SharedImage 1.0 + import Qt.labs.sharedimage 1.0 \endcode The sharing functionality is provided through a QQuickImageProvider. Use @@ -99,13 +99,6 @@ The shared image module does not provide any directly usable QML types. */ -static void initResources() -{ -#ifdef QT_STATIC - Q_INIT_RESOURCE(qmake_QtQuick_SharedImage); -#endif -} - QT_BEGIN_NAMESPACE class QtQuickSharedImagePlugin : public QQmlExtensionPlugin @@ -113,13 +106,12 @@ class QtQuickSharedImagePlugin : public QQmlExtensionPlugin Q_OBJECT Q_PLUGIN_METADATA(IID QQmlExtensionInterface_iid) public: - QtQuickSharedImagePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) { initResources(); } + QtQuickSharedImagePlugin(QObject *parent = 0) : QQmlExtensionPlugin(parent) {} - void registerTypes(const char *uri) Q_DECL_OVERRIDE + void registerTypes(const char *uri) override { - Q_ASSERT(uri == QStringLiteral("QtQuick.SharedImage")); - // Need to register *something* to let our version number be known: - qmlRegisterTypeNotAvailable(uri, 1, 0, "nosuchtype", QStringLiteral("Just a dummy type, do not use")); + Q_ASSERT(uri == QStringLiteral("Qt.labs.sharedimage")); + qmlRegisterModule(uri, 1, 0); } void initializeEngine(QQmlEngine *engine, const char *uri) override diff --git a/src/imports/sharedimage/qmldir b/src/imports/sharedimage/qmldir index 64a5aa8ac1..079399dc4e 100644 --- a/src/imports/sharedimage/qmldir +++ b/src/imports/sharedimage/qmldir @@ -1,3 +1,3 @@ -module QtQuick.SharedImage +module Qt.labs.sharedimage plugin sharedimageplugin classname QtQuickSharedImagePlugin diff --git a/src/imports/sharedimage/qsharedimageloader.cpp b/src/imports/sharedimage/qsharedimageloader.cpp index 65cbd92bb4..fb96a79187 100644 --- a/src/imports/sharedimage/qsharedimageloader.cpp +++ b/src/imports/sharedimage/qsharedimageloader.cpp @@ -58,7 +58,7 @@ struct SharedImageHeader { }; Q_STATIC_ASSERT(sizeof(SharedImageHeader) % 4 == 0); -#ifndef QT_NO_SHAREDMEMORY +#if QT_CONFIG(sharedmemory) struct SharedImageInfo { QString path; QPointer<QSharedMemory> shmp; @@ -160,7 +160,7 @@ QImage QSharedImageLoaderPrivate::createImageFromMem(const void *data, void *cle QImage QSharedImageLoaderPrivate::load(const QString &path, QSharedImageLoader::ImageParameters *params) { -#ifndef QT_NO_SHAREDMEMORY +#if QT_CONFIG(sharedmemory) Q_Q(QSharedImageLoader); QImage nil; diff --git a/src/imports/sharedimage/qsharedimageloader_p.h b/src/imports/sharedimage/qsharedimageloader_p.h index afb50e5088..38e2bd4d54 100644 --- a/src/imports/sharedimage/qsharedimageloader_p.h +++ b/src/imports/sharedimage/qsharedimageloader_p.h @@ -56,11 +56,6 @@ class QSharedImageLoader : public QObject Q_DECLARE_PRIVATE(QSharedImageLoader) public: - enum ImageParameter { - OriginalSize = 0, - RequestedSize, - NumImageParameters - }; typedef QVector<QVariant> ImageParameters; QSharedImageLoader(QObject *parent = Q_NULLPTR); diff --git a/src/imports/sharedimage/sharedimage.pro b/src/imports/sharedimage/sharedimage.pro index 523de66ac1..46a6a56ca5 100644 --- a/src/imports/sharedimage/sharedimage.pro +++ b/src/imports/sharedimage/sharedimage.pro @@ -1,9 +1,9 @@ CXX_MODULE = qml TARGET = sharedimageplugin -TARGETPATH = QtQuick/SharedImage +TARGETPATH = Qt/labs/sharedimage IMPORT_VERSION = 1.0 -QT *= quick qml gui-private core-private +QT *= quick-private qml gui-private core-private SOURCES += \ plugin.cpp \ diff --git a/src/imports/sharedimage/sharedimageprovider.cpp b/src/imports/sharedimage/sharedimageprovider.cpp index 2dd3a130e9..f33057936d 100644 --- a/src/imports/sharedimage/sharedimageprovider.cpp +++ b/src/imports/sharedimage/sharedimageprovider.cpp @@ -39,18 +39,27 @@ #include <sharedimageprovider.h> #include <qsharedimageloader_p.h> -#include <qquickimageprovider.h> +#include <private/qquickpixmapcache_p.h> #include <private/qimage_p.h> #include <QImageReader> #include <QFileInfo> #include <QDir> +Q_DECLARE_METATYPE(QQuickImageProviderOptions) + class QuickSharedImageLoader : public QSharedImageLoader { Q_OBJECT friend class SharedImageProvider; public: + enum ImageParameter { + OriginalSize = 0, + RequestedSize, + ProviderOptions, + NumImageParameters + }; + QuickSharedImageLoader(QObject *parent = Q_NULLPTR) : QSharedImageLoader(parent) { @@ -61,29 +70,17 @@ protected: { QImageReader imgio(path); QSize realSize = imgio.size(); - QSize requestSize = params ? params->value(RequestedSize).toSize() : QSize(); + QSize requestSize; + QQuickImageProviderOptions options; + if (params) { + requestSize = params->value(RequestedSize).toSize(); + options = params->value(ProviderOptions).value<QQuickImageProviderOptions>(); + } - // Following qquickpixmapcache's readImage, from here... - const bool force_scale = imgio.format() == "svg" || imgio.format() == "svgz"; + QSize scSize = QQuickImageProviderWithOptions::loadSize(imgio.size(), requestSize, imgio.format(), options); - if (requestSize.width() > 0 || requestSize.height() > 0) { - QSize s = realSize; - qreal ratio = 0.0; - if (requestSize.width() && (force_scale || requestSize.width() < s.width())) { - ratio = qreal(requestSize.width())/s.width(); - } - if (requestSize.height() && (force_scale || requestSize.height() < s.height())) { - qreal hr = qreal(requestSize.height())/s.height(); - if (ratio == 0.0 || hr < ratio) - ratio = hr; - } - if (ratio > 0.0) { - s.setHeight(qRound(s.height() * ratio)); - s.setWidth(qRound(s.width() * ratio)); - imgio.setScaledSize(s); - } - } - // ... to here + if (scSize.isValid()) + imgio.setScaledSize(scSize); QImage image; if (imgio.read(&image)) { @@ -108,11 +105,17 @@ protected: QString key(const QString &path, ImageParameters *params) override { - QSize reqSz = params->value(RequestedSize).toSize(); + QSize reqSz; + QQuickImageProviderOptions opts; + if (params) { + reqSz = params->value(RequestedSize).toSize(); + opts = params->value(ProviderOptions).value<QQuickImageProviderOptions>(); + } if (!reqSz.isValid()) return path; + int aspect = opts.preserveAspectRatioCrop() || opts.preserveAspectRatioFit() ? 1 : 0; - QString key = path + QStringLiteral("_%1x%2").arg(reqSz.width()).arg(reqSz.height()); + QString key = path + QStringLiteral("_%1x%2_%3").arg(reqSz.width()).arg(reqSz.height()).arg(aspect); qCDebug(lcSharedImage) << "KEY:" << key; return key; } @@ -120,19 +123,20 @@ protected: SharedImageProvider::SharedImageProvider() - : QQuickImageProvider(QQuickImageProvider::Image), loader(new QuickSharedImageLoader) + : QQuickImageProviderWithOptions(QQuickImageProvider::Image), loader(new QuickSharedImageLoader) { } -QImage SharedImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize) +QImage SharedImageProvider::requestImage(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options) { QFileInfo fi(QDir::root(), id); QString path = fi.canonicalFilePath(); if (path.isEmpty()) return QImage(); - QSharedImageLoader::ImageParameters params(QSharedImageLoader::NumImageParameters); - params[QSharedImageLoader::RequestedSize].setValue(requestedSize); + QSharedImageLoader::ImageParameters params(QuickSharedImageLoader::NumImageParameters); + params[QuickSharedImageLoader::RequestedSize].setValue(requestedSize); + params[QuickSharedImageLoader::ProviderOptions].setValue(options); QImage img = loader->load(path, ¶ms); if (img.isNull()) { diff --git a/src/imports/sharedimage/sharedimageprovider.h b/src/imports/sharedimage/sharedimageprovider.h index a2f6b6ef2f..e6b6c77134 100644 --- a/src/imports/sharedimage/sharedimageprovider.h +++ b/src/imports/sharedimage/sharedimageprovider.h @@ -41,16 +41,17 @@ #define SHAREDIMAGEPROVIDER_H #include <QQuickImageProvider> +#include <private/qquickpixmapcache_p.h> #include <QScopedPointer> class QuickSharedImageLoader; -class SharedImageProvider : public QQuickImageProvider +class SharedImageProvider : public QQuickImageProviderWithOptions { public: SharedImageProvider(); - QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize) override; + QImage requestImage(const QString &id, QSize *size, const QSize &requestedSize, const QQuickImageProviderOptions &options) override; protected: QScopedPointer<QuickSharedImageLoader> loader; diff --git a/src/imports/statemachine/signaltransition.cpp b/src/imports/statemachine/signaltransition.cpp index 44fbf69431..0f88ec641b 100644 --- a/src/imports/statemachine/signaltransition.cpp +++ b/src/imports/statemachine/signaltransition.cpp @@ -343,3 +343,5 @@ void SignalTransitionParser::applyBindings(QObject *object, QV4::CompiledData::C \sa signal */ + +#include "moc_signaltransition.cpp" diff --git a/src/imports/statemachine/state.cpp b/src/imports/statemachine/state.cpp index f1294b0de0..2467039d01 100644 --- a/src/imports/statemachine/state.cpp +++ b/src/imports/statemachine/state.cpp @@ -242,3 +242,4 @@ QQmlListProperty<QObject> State::children() \endlist */ +#include "moc_state.cpp" diff --git a/src/imports/statemachine/statemachine.cpp b/src/imports/statemachine/statemachine.cpp index a9ea5f7a95..7c8dcbc6b6 100644 --- a/src/imports/statemachine/statemachine.cpp +++ b/src/imports/statemachine/statemachine.cpp @@ -219,3 +219,5 @@ QQmlListProperty<QObject> StateMachine::children() \sa running, stop(), State::finished */ + +#include "moc_statemachine.cpp" diff --git a/src/imports/statemachine/timeouttransition.cpp b/src/imports/statemachine/timeouttransition.cpp index 0d208b919b..b0400b7d00 100644 --- a/src/imports/statemachine/timeouttransition.cpp +++ b/src/imports/statemachine/timeouttransition.cpp @@ -110,3 +110,5 @@ void TimeoutTransition::componentComplete() \brief The timeout interval in milliseconds. */ + +#include "moc_timeouttransition.cpp" diff --git a/src/particles/qquickage.cpp b/src/particles/qquickage.cpp index 578207531d..bf3d042e32 100644 --- a/src/particles/qquickage.cpp +++ b/src/particles/qquickage.cpp @@ -113,3 +113,5 @@ bool QQuickAgeAffector::affectParticle(QQuickParticleData *d, qreal dt) return false; } QT_END_NAMESPACE + +#include "moc_qquickage_p.cpp" diff --git a/src/particles/qquickangledirection.cpp b/src/particles/qquickangledirection.cpp index 6f30e24a26..debf52e49b 100644 --- a/src/particles/qquickangledirection.cpp +++ b/src/particles/qquickangledirection.cpp @@ -116,3 +116,5 @@ QPointF QQuickAngleDirection::sample(const QPointF &from) } QT_END_NAMESPACE + +#include "moc_qquickangledirection_p.cpp" diff --git a/src/particles/qquickcumulativedirection.cpp b/src/particles/qquickcumulativedirection.cpp index 6fbd53df48..447baf01d4 100644 --- a/src/particles/qquickcumulativedirection.cpp +++ b/src/particles/qquickcumulativedirection.cpp @@ -68,3 +68,5 @@ QPointF QQuickCumulativeDirection::sample(const QPointF &from) } QT_END_NAMESPACE + +#include "moc_qquickcumulativedirection_p.cpp" diff --git a/src/particles/qquickcustomaffector.cpp b/src/particles/qquickcustomaffector.cpp index b95810bb62..e152c436db 100644 --- a/src/particles/qquickcustomaffector.cpp +++ b/src/particles/qquickcustomaffector.cpp @@ -238,3 +238,5 @@ void QQuickCustomAffector::affectProperties(const QList<QQuickParticleData*> par } QT_END_NAMESPACE + +#include "moc_qquickcustomaffector_p.cpp" diff --git a/src/particles/qquickcustomparticle.cpp b/src/particles/qquickcustomparticle.cpp index babf13a93c..a9645461a5 100644 --- a/src/particles/qquickcustomparticle.cpp +++ b/src/particles/qquickcustomparticle.cpp @@ -460,3 +460,5 @@ void QQuickCustomParticle::itemChange(ItemChange change, const ItemChangeData &v QT_END_NAMESPACE + +#include "moc_qquickcustomparticle_p.cpp" diff --git a/src/particles/qquickdirection.cpp b/src/particles/qquickdirection.cpp index fd94c8945c..5439930a0e 100644 --- a/src/particles/qquickdirection.cpp +++ b/src/particles/qquickdirection.cpp @@ -63,3 +63,5 @@ QPointF QQuickDirection::sample(const QPointF &from) } QT_END_NAMESPACE + +#include "moc_qquickdirection_p.cpp" diff --git a/src/particles/qquickellipseextruder.cpp b/src/particles/qquickellipseextruder.cpp index 6e59ae452a..bd3a95d684 100644 --- a/src/particles/qquickellipseextruder.cpp +++ b/src/particles/qquickellipseextruder.cpp @@ -86,3 +86,5 @@ bool QQuickEllipseExtruder::contains(const QRectF &bounds, const QPointF &point) } QT_END_NAMESPACE + +#include "moc_qquickellipseextruder_p.cpp" diff --git a/src/particles/qquickfriction.cpp b/src/particles/qquickfriction.cpp index 401f4cd8c9..718c1a0bf9 100644 --- a/src/particles/qquickfriction.cpp +++ b/src/particles/qquickfriction.cpp @@ -111,3 +111,5 @@ bool QQuickFrictionAffector::affectParticle(QQuickParticleData *d, qreal dt) return true; } QT_END_NAMESPACE + +#include "moc_qquickfriction_p.cpp" diff --git a/src/particles/qquickgravity.cpp b/src/particles/qquickgravity.cpp index a2a2ad7e0e..5ca126e64e 100644 --- a/src/particles/qquickgravity.cpp +++ b/src/particles/qquickgravity.cpp @@ -134,3 +134,5 @@ bool QQuickGravityAffector::affectParticle(QQuickParticleData *d, qreal dt) QT_END_NAMESPACE + +#include "moc_qquickgravity_p.cpp" diff --git a/src/particles/qquickgroupgoal.cpp b/src/particles/qquickgroupgoal.cpp index 65c54411ec..02cbe5a621 100644 --- a/src/particles/qquickgroupgoal.cpp +++ b/src/particles/qquickgroupgoal.cpp @@ -110,3 +110,5 @@ bool QQuickGroupGoalAffector::affectParticle(QQuickParticleData *d, qreal dt) } QT_END_NAMESPACE + +#include "moc_qquickgroupgoal_p.cpp" diff --git a/src/particles/qquickimageparticle.cpp b/src/particles/qquickimageparticle.cpp index fde491b1ef..1b3d2eed6b 100644 --- a/src/particles/qquickimageparticle.cpp +++ b/src/particles/qquickimageparticle.cpp @@ -1323,6 +1323,7 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) getState<ImageMaterialData>(m_material)->animSheetSize = QSizeF(image.size()); if (m_spriteEngine) m_spriteEngine->setCount(m_count); + Q_FALLTHROUGH(); case Tabled: if (!m_material) m_material = TabledMaterial::createMaterial(); @@ -1355,12 +1356,15 @@ void QQuickImageParticle::finishBuildParticleNodes(QSGNode** node) getState<ImageMaterialData>(m_material)->colorTable = QSGPlainTexture::fromImage(colortable); fillUniformArrayFromImage(getState<ImageMaterialData>(m_material)->sizeTable, sizetable, UNIFORM_ARRAY_SIZE); fillUniformArrayFromImage(getState<ImageMaterialData>(m_material)->opacityTable, opacitytable, UNIFORM_ARRAY_SIZE); + Q_FALLTHROUGH(); case Deformable: if (!m_material) m_material = DeformableMaterial::createMaterial(); + Q_FALLTHROUGH(); case Colored: if (!m_material) m_material = ColoredMaterial::createMaterial(); + Q_FALLTHROUGH(); default://Also Simple if (!m_material) m_material = SimpleMaterial::createMaterial(); @@ -1530,6 +1534,7 @@ void QQuickImageParticle::prepareNextFrame(QSGNode **node) if (m_spriteEngine) m_spriteEngine->updateSprites(timeStamp);//fires signals if anim changed spritesUpdate(time); + Q_FALLTHROUGH(); case Tabled: case Deformable: case Colored: @@ -1691,6 +1696,7 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx) writeTo->animWidth = getState<ImageMaterialData>(m_material)->animSheetSize.width(); writeTo->animHeight = getState<ImageMaterialData>(m_material)->animSheetSize.height(); } + Q_FALLTHROUGH(); case Tabled: case Deformable: //Initial Rotation @@ -1737,6 +1743,7 @@ void QQuickImageParticle::initialize(int gIdx, int pIdx) getShadowDatum(datum)->autoRotate = autoRotate; } } + Q_FALLTHROUGH(); case Colored: //Color initialization // Particle color @@ -1920,3 +1927,5 @@ void QQuickImageParticle::commit(int gIdx, int pIdx) QT_END_NAMESPACE + +#include "moc_qquickimageparticle_p.cpp" diff --git a/src/particles/qquickitemparticle.cpp b/src/particles/qquickitemparticle.cpp index 15cf19181e..50b66a4d15 100644 --- a/src/particles/qquickitemparticle.cpp +++ b/src/particles/qquickitemparticle.cpp @@ -313,3 +313,5 @@ QQuickItemParticleAttached *QQuickItemParticle::qmlAttachedProperties(QObject *o } QT_END_NAMESPACE + +#include "moc_qquickitemparticle_p.cpp" diff --git a/src/particles/qquicklineextruder.cpp b/src/particles/qquicklineextruder.cpp index 00cf5e348c..4bcd63543c 100644 --- a/src/particles/qquicklineextruder.cpp +++ b/src/particles/qquicklineextruder.cpp @@ -83,3 +83,5 @@ QPointF QQuickLineExtruder::extrude(const QRectF &r) } return QPointF(x,y); } + +#include "moc_qquicklineextruder_p.cpp" diff --git a/src/particles/qquickmaskextruder.cpp b/src/particles/qquickmaskextruder.cpp index 7564fa6739..93eaaf1a6f 100644 --- a/src/particles/qquickmaskextruder.cpp +++ b/src/particles/qquickmaskextruder.cpp @@ -153,3 +153,5 @@ void QQuickMaskExtruder::ensureInitialized(const QRectF &rf) } } QT_END_NAMESPACE + +#include "moc_qquickmaskextruder_p.cpp" diff --git a/src/particles/qquickparticleaffector.cpp b/src/particles/qquickparticleaffector.cpp index 31bcfb82af..30716ecb80 100644 --- a/src/particles/qquickparticleaffector.cpp +++ b/src/particles/qquickparticleaffector.cpp @@ -267,3 +267,5 @@ bool QQuickParticleAffector::isColliding(QQuickParticleData *d) const } QT_END_NAMESPACE + +#include "moc_qquickparticleaffector_p.cpp" diff --git a/src/particles/qquickparticleemitter.cpp b/src/particles/qquickparticleemitter.cpp index 6e116d450c..9bed25dba6 100644 --- a/src/particles/qquickparticleemitter.cpp +++ b/src/particles/qquickparticleemitter.cpp @@ -508,3 +508,5 @@ void QQuickParticleEmitter::emitWindow(int timeStamp) QT_END_NAMESPACE + +#include "moc_qquickparticleemitter_p.cpp" diff --git a/src/particles/qquickparticleextruder.cpp b/src/particles/qquickparticleextruder.cpp index 5c033a4f8c..f1fef58884 100644 --- a/src/particles/qquickparticleextruder.cpp +++ b/src/particles/qquickparticleextruder.cpp @@ -69,3 +69,5 @@ bool QQuickParticleExtruder::contains(const QRectF &bounds, const QPointF &point } QT_END_NAMESPACE + +#include "moc_qquickparticleextruder_p.cpp" diff --git a/src/particles/qquickparticlegroup.cpp b/src/particles/qquickparticlegroup.cpp index 7ff79186ac..2ee2a1d0a3 100644 --- a/src/particles/qquickparticlegroup.cpp +++ b/src/particles/qquickparticlegroup.cpp @@ -141,3 +141,5 @@ void QQuickParticleGroup::componentComplete(){ if (!m_system && qobject_cast<QQuickParticleSystem*>(parent())) setSystem(qobject_cast<QQuickParticleSystem*>(parent())); } + +#include "moc_qquickparticlegroup_p.cpp" diff --git a/src/particles/qquickparticlepainter.cpp b/src/particles/qquickparticlepainter.cpp index 0c2521cd9e..70fc2d59e3 100644 --- a/src/particles/qquickparticlepainter.cpp +++ b/src/particles/qquickparticlepainter.cpp @@ -194,3 +194,5 @@ void QQuickParticlePainter::performPendingCommits() } QT_END_NAMESPACE + +#include "moc_qquickparticlepainter_p.cpp" diff --git a/src/particles/qquickparticlesystem.cpp b/src/particles/qquickparticlesystem.cpp index 6f134f08df..cc7d9edbc8 100644 --- a/src/particles/qquickparticlesystem.cpp +++ b/src/particles/qquickparticlesystem.cpp @@ -1092,3 +1092,5 @@ int QQuickParticleSystem::systemSync(QQuickParticlePainter* p) QT_END_NAMESPACE + +#include "moc_qquickparticlesystem_p.cpp" diff --git a/src/particles/qquickpointattractor.cpp b/src/particles/qquickpointattractor.cpp index 779b2915f0..d7446842f2 100644 --- a/src/particles/qquickpointattractor.cpp +++ b/src/particles/qquickpointattractor.cpp @@ -160,3 +160,5 @@ bool QQuickAttractorAffector::affectParticle(QQuickParticleData *d, qreal dt) return true; } QT_END_NAMESPACE + +#include "moc_qquickpointattractor_p.cpp" diff --git a/src/particles/qquickpointdirection.cpp b/src/particles/qquickpointdirection.cpp index 9038ce0aa0..8d602204b5 100644 --- a/src/particles/qquickpointdirection.cpp +++ b/src/particles/qquickpointdirection.cpp @@ -84,3 +84,5 @@ QPointF QQuickPointDirection::sample(const QPointF &) } QT_END_NAMESPACE + +#include "moc_qquickpointdirection_p.cpp" diff --git a/src/particles/qquickrectangleextruder.cpp b/src/particles/qquickrectangleextruder.cpp index 26b99e675a..cb166f1d50 100644 --- a/src/particles/qquickrectangleextruder.cpp +++ b/src/particles/qquickrectangleextruder.cpp @@ -85,3 +85,5 @@ bool QQuickRectangleExtruder::contains(const QRectF &bounds, const QPointF &poin } QT_END_NAMESPACE + +#include "moc_qquickrectangleextruder_p.cpp" diff --git a/src/particles/qquickspritegoal.cpp b/src/particles/qquickspritegoal.cpp index 5784f1402d..2e420a2840 100644 --- a/src/particles/qquickspritegoal.cpp +++ b/src/particles/qquickspritegoal.cpp @@ -151,3 +151,5 @@ bool QQuickSpriteGoalAffector::affectParticle(QQuickParticleData *d, qreal dt) } QT_END_NAMESPACE + +#include "moc_qquickspritegoal_p.cpp" diff --git a/src/particles/qquicktargetdirection.cpp b/src/particles/qquicktargetdirection.cpp index 012c9a151b..ee805b4e39 100644 --- a/src/particles/qquicktargetdirection.cpp +++ b/src/particles/qquicktargetdirection.cpp @@ -129,3 +129,5 @@ QPointF QQuickTargetDirection::sample(const QPointF &from) } QT_END_NAMESPACE + +#include "moc_qquicktargetdirection_p.cpp" diff --git a/src/particles/qquicktrailemitter.cpp b/src/particles/qquicktrailemitter.cpp index d4d2adcfb2..a5bf0e9d21 100644 --- a/src/particles/qquicktrailemitter.cpp +++ b/src/particles/qquicktrailemitter.cpp @@ -285,3 +285,5 @@ void QQuickTrailEmitter::emitWindow(int timeStamp) m_lastTimeStamp = time; } QT_END_NAMESPACE + +#include "moc_qquicktrailemitter_p.cpp" diff --git a/src/particles/qquickturbulence.cpp b/src/particles/qquickturbulence.cpp index 74558413a6..f916635358 100644 --- a/src/particles/qquickturbulence.cpp +++ b/src/particles/qquickturbulence.cpp @@ -203,3 +203,5 @@ void QQuickTurbulenceAffector::affectSystem(qreal dt) } QT_END_NAMESPACE + +#include "moc_qquickturbulence_p.cpp" diff --git a/src/particles/qquickwander.cpp b/src/particles/qquickwander.cpp index 09d36ab2e8..099b453808 100644 --- a/src/particles/qquickwander.cpp +++ b/src/particles/qquickwander.cpp @@ -179,3 +179,5 @@ bool QQuickWanderAffector::affectParticle(QQuickParticleData* data, qreal dt) return true; } QT_END_NAMESPACE + +#include "moc_qquickwander_p.cpp" diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp index 3fb0522cd1..f0bb4de016 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlenginedebugservice.cpp @@ -819,3 +819,5 @@ void QQmlEngineDebugServiceImpl::setStatesDelegate(QQmlDebugStatesDelegate *dele } QT_END_NAMESPACE + +#include "moc_qqmlenginedebugservice.cpp" diff --git a/src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp b/src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp index 1214212727..cbbbb2ceb7 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qqmlwatcher.cpp @@ -186,3 +186,5 @@ void QQmlWatcher::addPropertyWatch(int id, QObject *object, quint32 debugId, con QT_END_NAMESPACE #include <qqmlwatcher.moc> + +#include "moc_qqmlwatcher.cpp" diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp index 75cbc9eba1..9e8be84c33 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugger.cpp @@ -332,3 +332,5 @@ void QV4Debugger::runInEngine_havingLock(QV4DebugJob *job) } QT_END_NAMESPACE + +#include "moc_qv4debugger.cpp" diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp index 773bc937f5..9a34d5770a 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debuggeragent.cpp @@ -230,3 +230,5 @@ void QV4DebuggerAgent::clearAllPauseRequests() } QT_END_NAMESPACE + +#include "moc_qv4debuggeragent.cpp" diff --git a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp index 68cdb57a44..168a08865c 100644 --- a/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp +++ b/src/plugins/qmltooling/qmldbg_debugger/qv4debugservice.cpp @@ -873,3 +873,5 @@ int QV4DebugServiceImpl::selectedFrame() const } QT_END_NAMESPACE + +#include "moc_qv4debugservice.cpp" diff --git a/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp b/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp index 88a6ea6b6d..c7307db240 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp +++ b/src/plugins/qmltooling/qmldbg_inspector/highlight.cpp @@ -201,3 +201,5 @@ void SelectionHighlight::disableNameDisplay() } // namespace QmlJSDebugger QT_END_NAMESPACE + +#include "moc_highlight.cpp" diff --git a/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp b/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp index 7527bc41c7..bc146b176c 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp +++ b/src/plugins/qmltooling/qmldbg_inspector/inspecttool.cpp @@ -206,3 +206,5 @@ GlobalInspector *InspectTool::globalInspector() const } // namespace QmlJSDebugger QT_END_NAMESPACE + +#include "moc_inspecttool.cpp" diff --git a/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp b/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp index 7d260a4d2a..16056addbd 100644 --- a/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp +++ b/src/plugins/qmltooling/qmldbg_inspector/qquickwindowinspector.cpp @@ -230,3 +230,5 @@ QQuickItem *QQuickWindowInspector::topVisibleItemAt(const QPointF &pos) const } // namespace QmlJSDebugger QT_END_NAMESPACE + +#include "moc_qquickwindowinspector.cpp" diff --git a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.cpp b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.cpp index a066237e77..860d654128 100644 --- a/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.cpp +++ b/src/plugins/qmltooling/qmldbg_messages/qdebugmessageservicefactory.cpp @@ -52,3 +52,5 @@ QQmlDebugService *QDebugMessageServiceFactory::create(const QString &key) } QT_END_NAMESPACE + +#include "moc_qdebugmessageservicefactory.cpp" diff --git a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp index 1a318b3ca2..388d2e3b22 100644 --- a/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp +++ b/src/plugins/qmltooling/qmldbg_native/qqmlnativedebugconnector.cpp @@ -364,3 +364,5 @@ QQmlDebugConnector *QQmlNativeDebugConnectorFactory::create(const QString &key) } QT_END_NAMESPACE + +#include "moc_qqmlnativedebugconnector.cpp" diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp index c1f6f93ef1..edeb364f60 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservice.cpp @@ -468,3 +468,5 @@ void QQmlProfilerServiceImpl::flush() } QT_END_NAMESPACE + +#include "moc_qqmlprofilerservice.cpp" diff --git a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp index 19100b6e8f..0cd3e0b4ab 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qqmlprofilerservicefactory.cpp @@ -55,3 +55,5 @@ QQmlDebugService *QQmlProfilerServiceFactory::create(const QString &key) } QT_END_NAMESPACE + +#include "moc_qqmlprofilerservicefactory.cpp" diff --git a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp index eae5e0a795..f1ac8ef998 100644 --- a/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp +++ b/src/plugins/qmltooling/qmldbg_profiler/qv4profileradapter.cpp @@ -210,3 +210,5 @@ void QV4ProfilerAdapter::forwardEnabledWhileWaiting(quint64 features) } QT_END_NAMESPACE + +#include "moc_qv4profileradapter.cpp" diff --git a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp index c85bca0ac7..f38307b1f7 100644 --- a/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp +++ b/src/plugins/qmltooling/qmldbg_quickprofiler/qquickprofileradapterfactory.cpp @@ -52,3 +52,5 @@ QQmlAbstractProfilerAdapter *QQuickProfilerAdapterFactory::create(const QString } QT_END_NAMESPACE + +#include "moc_qquickprofileradapterfactory.cpp" diff --git a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp index bcfb3b8a75..0a7421842a 100644 --- a/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp +++ b/src/plugins/qmltooling/qmldbg_server/qqmldebugserver.cpp @@ -767,3 +767,4 @@ QQmlDebugConnector *QQmlDebugServerFactory::create(const QString &key) QT_END_NAMESPACE #include "qqmldebugserver.moc" +#include "moc_qqmldebugserver.cpp" diff --git a/src/plugins/qmltooling/qmltooling.pro b/src/plugins/qmltooling/qmltooling.pro index 8123e2999e..27c51b53c8 100644 --- a/src/plugins/qmltooling/qmltooling.pro +++ b/src/plugins/qmltooling/qmltooling.pro @@ -1,5 +1,5 @@ TEMPLATE = subdirs -QT_FOR_CONFIG += qml +QT_FOR_CONFIG += qml-private # Utilities SUBDIRS += \ @@ -10,25 +10,28 @@ SUBDIRS += \ qmldbg_native \ qmldbg_server +qmldbg_native.depends = packetprotocol +qmldbg_server.depends = packetprotocol + qtConfig(qml-network) { SUBDIRS += \ qmldbg_local \ qmldbg_tcp } -# Services -SUBDIRS += \ - qmldbg_debugger \ - qmldbg_profiler \ - qmldbg_messages \ - qmldbg_nativedebugger +qtConfig(qml-interpreter) { + # Services + SUBDIRS += \ + qmldbg_debugger \ + qmldbg_profiler \ + qmldbg_messages \ + qmldbg_nativedebugger -qmldbg_server.depends = packetprotocol -qmldbg_native.depends = packetprotocol -qmldbg_debugger.depends = packetprotocol -qmldbg_profiler.depends = packetprotocol -qmldbg_messages.depends = packetprotocol -qmldbg_nativedebugger.depends = packetprotocol + qmldbg_debugger.depends = packetprotocol + qmldbg_profiler.depends = packetprotocol + qmldbg_messages.depends = packetprotocol + qmldbg_nativedebugger.depends = packetprotocol +} qtHaveModule(quick) { SUBDIRS += \ diff --git a/src/qml/animations/qabstractanimationjob.cpp b/src/qml/animations/qabstractanimationjob.cpp index f7f6939e4b..1ac4925ed3 100644 --- a/src/qml/animations/qabstractanimationjob.cpp +++ b/src/qml/animations/qabstractanimationjob.cpp @@ -672,3 +672,4 @@ QDebug operator<<(QDebug d, const QAbstractAnimationJob *job) QT_END_NAMESPACE //#include "moc_qabstractanimation2_p.cpp" +#include "moc_qabstractanimationjob_p.cpp" diff --git a/src/qml/compiler/compiler.pri b/src/qml/compiler/compiler.pri index 871f28f2d0..31ee917b39 100644 --- a/src/qml/compiler/compiler.pri +++ b/src/qml/compiler/compiler.pri @@ -41,7 +41,7 @@ SOURCES += \ unix: SOURCES += $$PWD/qv4compilationunitmapper_unix.cpp else: SOURCES += $$PWD/qv4compilationunitmapper_win.cpp -qtConfig(private_tests): LIBS_PRIVATE += $$QMAKE_LIBS_DYNLOAD +qtConfig(private_tests):unix: QMAKE_USE_PRIVATE += libdl } qmldevtools_build|qtConfig(qml-interpreter) { @@ -52,4 +52,3 @@ qmldevtools_build|qtConfig(qml-interpreter) { $$PWD/qv4instr_moth.cpp \ $$PWD/qv4isel_moth.cpp } - diff --git a/src/qml/compiler/qqmlirbuilder.cpp b/src/qml/compiler/qqmlirbuilder.cpp index 218f5675dc..de04116a6b 100644 --- a/src/qml/compiler/qqmlirbuilder.cpp +++ b/src/qml/compiler/qqmlirbuilder.cpp @@ -1687,6 +1687,7 @@ enum MetaObjectResolverFlags { }; static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlPropertyCache *metaObject); +static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlType *qmlType, int index); static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine, const QV4::IR::MemberExpressionResolver *resolver, @@ -1702,6 +1703,14 @@ static QV4::IR::DiscoveredType resolveQmlType(QQmlEnginePrivate *qmlEngine, if (ok) { member->setEnumValue(value); return QV4::IR::SInt32Type; + } else { + int index = type->scopedEnumIndex(qmlEngine, *member->name, &ok); + if (ok) { + auto newResolver = resolver->owner->New<QV4::IR::MemberExpressionResolver>(); + newResolver->owner = resolver->owner; + initScopedEnumResolver(newResolver, type, index); + return QV4::IR::DiscoveredType(newResolver); + } } } @@ -1885,6 +1894,34 @@ static void initMetaObjectResolver(QV4::IR::MemberExpressionResolver *resolver, resolver->flags = 0; } +static QV4::IR::DiscoveredType resolveScopedEnum(QQmlEnginePrivate *qmlEngine, + const QV4::IR::MemberExpressionResolver *resolver, + QV4::IR::Member *member) +{ + if (!member->name->constData()->isUpper()) + return QV4::IR::VarType; + + QQmlType *type = static_cast<QQmlType*>(resolver->data); + int index = resolver->flags; + + bool ok = false; + int value = type->scopedEnumValue(qmlEngine, index, *member->name, &ok); + if (!ok) + return QV4::IR::VarType; + member->setEnumValue(value); + return QV4::IR::SInt32Type; +} + +static void initScopedEnumResolver(QV4::IR::MemberExpressionResolver *resolver, QQmlType *qmlType, int index) +{ + Q_ASSERT(resolver); + + resolver->resolveMember = &resolveScopedEnum; + resolver->data = qmlType; + resolver->extraData = 0; + resolver->flags = index; +} + #endif // V4_BOOTSTRAP void JSCodeGen::beginFunctionBodyHook() diff --git a/src/qml/compiler/qqmltypecompiler.cpp b/src/qml/compiler/qqmltypecompiler.cpp index d1d22be0ac..c09fde86f1 100644 --- a/src/qml/compiler/qqmltypecompiler.cpp +++ b/src/qml/compiler/qqmltypecompiler.cpp @@ -591,21 +591,32 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj, if (!string.constData()->isUpper()) return true; + // we support one or two '.' in the enum phrase: + // * <TypeName>.<EnumValue> + // * <TypeName>.<ScopedEnumName>.<EnumValue> + int dot = string.indexOf(QLatin1Char('.')); if (dot == -1 || dot == string.length()-1) return true; - if (string.indexOf(QLatin1Char('.'), dot+1) != -1) - return true; + int dot2 = string.indexOf(QLatin1Char('.'), dot+1); + if (dot2 != -1 && dot2 != string.length()-1) { + if (!string.at(dot+1).isUpper()) + return true; + if (string.indexOf(QLatin1Char('.'), dot2+1) != -1) + return true; + } QHashedStringRef typeName(string.constData(), dot); const bool isQtObject = (typeName == QLatin1String("Qt")); - const QStringRef enumValue = string.midRef(dot + 1); + const QStringRef scopedEnumName = (dot2 != -1 ? string.midRef(dot + 1, dot2 - dot - 1) : QStringRef()); + // ### consider supporting scoped enums in Qt namespace + const QStringRef enumValue = string.midRef(!isQtObject && dot2 != -1 ? dot2 + 1 : dot + 1); - if (isIntProp) { + if (isIntProp) { // ### C++11 allows enums to be other integral types. Should we support other integral types here? // Allow enum assignment to ints. bool ok; - int enumval = evaluateEnum(typeName.toString(), enumValue.toUtf8(), &ok); + int enumval = evaluateEnum(typeName.toString(), scopedEnumName, enumValue, &ok); if (ok) { if (!assignEnumToBinding(binding, enumValue, enumval, isQtObject)) return false; @@ -623,18 +634,25 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj, auto *tr = resolvedTypes->value(obj->inheritedTypeNameIndex); if (type && tr && tr->type == type) { + // When these two match, we can short cut the search QMetaProperty mprop = propertyCache->firstCppMetaObject()->property(prop->coreIndex()); + QMetaEnum menum = mprop.enumerator(); + QByteArray enumName = enumValue.toUtf8(); + if (menum.isScoped() && !scopedEnumName.isEmpty() && enumName != scopedEnumName.toUtf8()) + return true; - // When these two match, we can short cut the search if (mprop.isFlagType()) { - value = mprop.enumerator().keysToValue(enumValue.toUtf8().constData(), &ok); + value = menum.keysToValue(enumName.constData(), &ok); } else { - value = mprop.enumerator().keyToValue(enumValue.toUtf8().constData(), &ok); + value = menum.keyToValue(enumName.constData(), &ok); } } else { // Otherwise we have to search the whole type if (type) { - value = type->enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok); + if (!scopedEnumName.isEmpty()) + value = type->scopedEnumValue(compiler->enginePrivate(), scopedEnumName, enumValue, &ok); + else + value = type->enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue), &ok); } else { QByteArray enumName = enumValue.toUtf8(); const QMetaObject *metaObject = StaticQtMetaObject::get(); @@ -651,7 +669,7 @@ bool QQmlEnumTypeResolver::tryQualifiedEnumAssignment(const QmlIR::Object *obj, return assignEnumToBinding(binding, enumValue, value, isQtObject); } -int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &enumValue, bool *ok) const +int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QStringRef &enumName, const QStringRef &enumValue, bool *ok) const { Q_ASSERT_X(ok, "QQmlEnumTypeResolver::evaluateEnum", "ok must not be a null pointer"); *ok = false; @@ -661,13 +679,16 @@ int QQmlEnumTypeResolver::evaluateEnum(const QString &scope, const QByteArray &e imports->resolveType(scope, &type, 0, 0, 0); if (!type) return -1; - return type->enumValue(compiler->enginePrivate(), QHashedCStringRef(enumValue.constData(), enumValue.length()), ok); + if (!enumName.isEmpty()) + return type->scopedEnumValue(compiler->enginePrivate(), enumName, enumValue, ok); + return type->enumValue(compiler->enginePrivate(), QHashedStringRef(enumValue.constData(), enumValue.length()), ok); } const QMetaObject *mo = StaticQtMetaObject::get(); int i = mo->enumeratorCount(); + const QByteArray ba = enumValue.toUtf8(); while (i--) { - int v = mo->enumerator(i).keyToValue(enumValue.constData(), ok); + int v = mo->enumerator(i).keyToValue(ba.constData(), ok); if (*ok) return v; } diff --git a/src/qml/compiler/qqmltypecompiler_p.h b/src/qml/compiler/qqmltypecompiler_p.h index 79fc073d8b..76aa422fc5 100644 --- a/src/qml/compiler/qqmltypecompiler_p.h +++ b/src/qml/compiler/qqmltypecompiler_p.h @@ -209,7 +209,7 @@ private: bool tryQualifiedEnumAssignment(const QmlIR::Object *obj, const QQmlPropertyCache *propertyCache, const QQmlPropertyData *prop, QmlIR::Binding *binding); - int evaluateEnum(const QString &scope, const QByteArray &enumValue, bool *ok) const; + int evaluateEnum(const QString &scope, const QStringRef &enumName, const QStringRef &enumValue, bool *ok) const; const QVector<QmlIR::Object*> &qmlObjects; diff --git a/src/qml/compiler/qv4jsir.cpp b/src/qml/compiler/qv4jsir.cpp index cc2f9b7cf2..5a58380005 100644 --- a/src/qml/compiler/qv4jsir.cpp +++ b/src/qml/compiler/qv4jsir.cpp @@ -444,10 +444,6 @@ void Function::setScheduledBlocks(const QVector<BasicBlock *> &scheduled) Q_ASSERT(!_allBasicBlocks); _allBasicBlocks = new QVector<BasicBlock *>(basicBlocks()); _basicBlocks = scheduled; -} - -void Function::renumberBasicBlocks() -{ for (int i = 0, ei = basicBlockCount(); i != ei; ++i) basicBlock(i)->changeIndex(i); } diff --git a/src/qml/compiler/qv4jsir_p.h b/src/qml/compiler/qv4jsir_p.h index 35cf0fc174..b534eaa54f 100644 --- a/src/qml/compiler/qv4jsir_p.h +++ b/src/qml/compiler/qv4jsir_p.h @@ -1348,7 +1348,6 @@ struct Function { { return hasDirectEval || !nestedFunctions.isEmpty() || module->debugMode; } void setScheduledBlocks(const QVector<BasicBlock *> &scheduled); - void renumberBasicBlocks(); int getNewStatementId() { return _statementCount++; } int statementCount() const { return _statementCount; } diff --git a/src/qml/compiler/qv4ssa.cpp b/src/qml/compiler/qv4ssa.cpp index cc542e94e7..731c6ad38f 100644 --- a/src/qml/compiler/qv4ssa.cpp +++ b/src/qml/compiler/qv4ssa.cpp @@ -2345,6 +2345,7 @@ private: case OpIncrement: case OpDecrement: Q_ASSERT(!"Inplace operators should have been removed!"); + Q_UNREACHABLE(); default: Q_UNIMPLEMENTED(); Q_UNREACHABLE(); @@ -2645,6 +2646,7 @@ private: case OpMul: if (!targetTemp || !knownOk.contains(*targetTemp)) return false; + Q_FALLTHROUGH(); case OpBitAnd: case OpBitOr: case OpBitXor: @@ -3023,14 +3025,19 @@ void splitCriticalEdges(IR::Function *f, DominatorTree &df, StatementWorklist &w // add newBB to the correct loop group if (toBB->isGroupStart()) { - BasicBlock *container; - for (container = fromBB->containingGroup(); container; container = container->containingGroup()) - if (container == toBB) - break; - if (container == toBB) // if we were already inside the toBB loop + if (fromBB == toBB) { + // special case: the loop header points back to itself (so it's a small loop). newBB->setContainingGroup(toBB); - else - newBB->setContainingGroup(toBB->containingGroup()); + } else { + BasicBlock *container; + for (container = fromBB->containingGroup(); container; container = container->containingGroup()) + if (container == toBB) + break; + if (container == toBB) // if we were already inside the toBB loop + newBB->setContainingGroup(toBB); + else + newBB->setContainingGroup(toBB->containingGroup()); + } } else { newBB->setContainingGroup(toBB->containingGroup()); } @@ -3061,7 +3068,7 @@ void splitCriticalEdges(IR::Function *f, DominatorTree &df, StatementWorklist &w bool toNeedsNewIdom = true; for (BasicBlock *bb : toBB->in) { - if (bb != newBB && !df.dominates(toBB, bb)) { + if (bb != newBB && bb != toBB && !df.dominates(toBB, bb)) { toNeedsNewIdom = false; break; } @@ -3172,7 +3179,7 @@ public: backedges.clear(); for (BasicBlock *in : bb->in) - if (dt.dominates(bb, in)) + if (bb == in || dt.dominates(bb, in)) backedges.push_back(in); if (!backedges.empty()) { @@ -3189,6 +3196,7 @@ public: if (!DebugLoopDetection) return; + qDebug() << "Found" << loopInfos.size() << "loops"; for (const LoopInfo *info : loopInfos) { qDebug() << "Loop header:" << info->loopHeader->index() << "for loop" << quint64(info); @@ -3222,6 +3230,9 @@ private: void subLoop(BasicBlock *loopHead, const std::vector<BasicBlock *> &backedges) { loopHead->markAsGroupStart(); + LoopInfo *info = new LoopInfo; + info->loopHeader = loopHead; + loopInfos.append(info); std::vector<BasicBlock *> worklist; worklist.reserve(backedges.size() + 8); @@ -3291,10 +3302,8 @@ private: return info; } - LoopInfo *info = new LoopInfo; - info->loopHeader = loopHeader; - loopInfos.append(info); - return info; + Q_UNREACHABLE(); + return nullptr; } }; @@ -3324,6 +3333,8 @@ private: // the same reason. class BlockScheduler { + enum { DebugBlockScheduler = 0 }; + IR::Function *function; const DominatorTree &dominatorTree; @@ -3439,6 +3450,14 @@ class BlockScheduler Q_UNREACHABLE(); } + void dumpLoopStartsEnds() const + { + qDebug() << "Found" << loopsStartEnd.size() << "loops:"; + for (auto key : loopsStartEnd.keys()) + qDebug("Loop starting at L%d ends at L%d.", key->index(), + loopsStartEnd.value(key)->index()); + } + public: BlockScheduler(IR::Function *function, const DominatorTree &dominatorTree) : function(function) @@ -3450,11 +3469,15 @@ public: QHash<BasicBlock *, BasicBlock *> go() { showMeTheCode(function, "Before block scheduling"); + if (DebugBlockScheduler) + dominatorTree.dumpImmediateDominators(); + schedule(function->basicBlock(0)); Q_ASSERT(function->liveBasicBlocksCount() == sequence.size()); function->setScheduledBlocks(sequence); - function->renumberBasicBlocks(); + if (DebugBlockScheduler) + dumpLoopStartsEnds(); return loopsStartEnd; } }; @@ -4590,7 +4613,6 @@ void removeUnreachleBlocks(IR::Function *function) if (!bb->isRemoved()) newSchedule.append(bb); function->setScheduledBlocks(newSchedule); - function->renumberBasicBlocks(); } class ConvertArgLocals @@ -4764,6 +4786,137 @@ private: IR::Stmt *clonedStmt; }; +static void verifyCFG(IR::Function *function) +{ + if (!DoVerification) + return; + + for (BasicBlock *bb : function->basicBlocks()) { + if (bb->isRemoved()) { + Q_ASSERT(bb->in.isEmpty()); + Q_ASSERT(bb->out.isEmpty()); + continue; + } + + Q_ASSERT(function->basicBlock(bb->index()) == bb); + + // Check the terminators: + Stmt *terminator = bb->terminator(); + if (terminator == nullptr) { + Stmt *last = bb->statements().last(); + Call *call = last->asExp()->expr->asCall(); + Name *baseName = call->base->asName(); + Q_ASSERT(baseName->builtin == Name::builtin_rethrow); + Q_UNUSED(baseName); + } else if (Jump *jump = terminator->asJump()) { + Q_UNUSED(jump); + Q_ASSERT(jump->target); + Q_ASSERT(!jump->target->isRemoved()); + Q_ASSERT(bb->out.size() == 1); + Q_ASSERT(bb->out.first() == jump->target); + } else if (CJump *cjump = terminator->asCJump()) { + Q_UNUSED(cjump); + Q_ASSERT(bb->out.size() == 2); + Q_ASSERT(cjump->iftrue); + Q_ASSERT(!cjump->iftrue->isRemoved()); + Q_ASSERT(cjump->iftrue == bb->out[0]); + Q_ASSERT(cjump->iffalse); + Q_ASSERT(!cjump->iffalse->isRemoved()); + Q_ASSERT(cjump->iffalse == bb->out[1]); + } else if (terminator->asRet()) { + Q_ASSERT(bb->out.size() == 0); + } else { + Q_UNREACHABLE(); + } + + // Check the outgoing edges: + for (BasicBlock *out : bb->out) { + Q_UNUSED(out); + Q_ASSERT(!out->isRemoved()); + Q_ASSERT(out->in.contains(bb)); + } + + // Check the incoming edges: + for (BasicBlock *in : bb->in) { + Q_UNUSED(in); + Q_ASSERT(!in->isRemoved()); + Q_ASSERT(in->out.contains(bb)); + } + } +} + +static void verifyImmediateDominators(const DominatorTree &dt, IR::Function *function) +{ + if (!DoVerification) + return; + + cfg2dot(function); + dt.dumpImmediateDominators(); + DominatorTree referenceTree(function); + + for (BasicBlock *bb : function->basicBlocks()) { + if (bb->isRemoved()) + continue; + + BasicBlock *idom = dt.immediateDominator(bb); + BasicBlock *referenceIdom = referenceTree.immediateDominator(bb); + Q_UNUSED(idom); + Q_UNUSED(referenceIdom); + Q_ASSERT(idom == referenceIdom); + } +} + +static void verifyNoPointerSharing(IR::Function *function) +{ + if (!DoVerification) + return; + + class { + public: + void operator()(IR::Function *f) + { + for (BasicBlock *bb : f->basicBlocks()) { + if (bb->isRemoved()) + continue; + + for (Stmt *s : bb->statements()) { + visit(s); + } + } + } + + private: + void visit(Stmt *s) + { + check(s); + STMT_VISIT_ALL_KINDS(s); + } + + void visit(Expr *e) + { + check(e); + EXPR_VISIT_ALL_KINDS(e); + } + + private: + void check(Stmt *s) + { + Q_ASSERT(!stmts.contains(s)); + stmts.insert(s); + } + + void check(Expr *e) + { + Q_ASSERT(!exprs.contains(e)); + exprs.insert(e); + } + + QSet<Stmt *> stmts; + QSet<Expr *> exprs; + } V; + V(function); +} + // Loop-peeling is done by unfolding the loop once. The "original" loop basic blocks stay where they // are, and a copy of the loop is placed after it. Special care is taken while copying the loop body: // by having the copies of the basic-blocks point to the same nodes as the "original" basic blocks, @@ -4824,12 +4977,14 @@ private: void peelLoop(LoopDetection::LoopInfo *loop) { + IR::Function *f = loop->loopHeader->function; CloneBasicBlock clone; LoopDetection::LoopInfo unpeeled(*loop); unpeeled.loopHeader = clone(unpeeled.loopHeader); unpeeled.loopHeader->setContainingGroup(loop->loopHeader->containingGroup()); unpeeled.loopHeader->markAsGroupStart(true); + f->addBasicBlock(unpeeled.loopHeader); for (int i = 0, ei = unpeeled.loopBody.size(); i != ei; ++i) { BasicBlock *&bodyBlock = unpeeled.loopBody[i]; bodyBlock = clone(bodyBlock); @@ -4843,8 +4998,8 @@ private: BasicBlock::IncomingEdges inCopy = loop->loopHeader->in; for (BasicBlock *in : inCopy) { - if (unpeeled.loopHeader != in // this can happen for really tight loops (where there are no body blocks). This is a back-edge in that case. - && !unpeeled.loopBody.contains(in) // if the edge is not coming from within the copied set, leave it alone + if (loop->loopHeader != in // this can happen for really tight loops (where there are no body blocks). This is a back-edge in that case. + && unpeeled.loopHeader != in && !unpeeled.loopBody.contains(in) // if the edge is not coming from within the copied set, leave it alone && !dt.dominates(loop->loopHeader, in)) // an edge coming from within the loop (so a back-edge): this is handled when rewiring all outgoing edges continue; @@ -4874,9 +5029,7 @@ private: loopExits.reserve(8); loopExits.append(unpeeled.loopHeader); - IR::Function *f = unpeeled.loopHeader->function; rewire(unpeeled.loopHeader, loop->loopBody, unpeeled.loopBody, loopExits); - f->addBasicBlock(unpeeled.loopHeader); for (int i = 0, ei = unpeeled.loopBody.size(); i != ei; ++i) { BasicBlock *bodyBlock = unpeeled.loopBody.at(i); rewire(bodyBlock, loop->loopBody, unpeeled.loopBody, loopExits); @@ -4889,6 +5042,9 @@ private: for (BasicBlock *bb : qAsConst(loop->loopBody)) bb->setContainingGroup(loop->loopHeader->containingGroup()); + // Set the immediate dominator of the new loop header to the old one. The real immediate + // dominator will be calculated later. + dt.setImmediateDominator(unpeeled.loopHeader, loop->loopHeader); // calculate the idoms in a separate loop, because addBasicBlock in the previous loop will // set the block index, which in turn is used by the dominator tree. for (int i = 0, ei = unpeeled.loopBody.size(); i != ei; ++i) { @@ -4907,141 +5063,13 @@ private: for (BasicBlock *bb : qAsConst(loopExits)) dt.collectSiblings(bb, siblings); + siblings.insert(unpeeled.loopHeader); dt.recalculateIDoms(siblings, loop->loopHeader); + dt.dumpImmediateDominators(); + verifyImmediateDominators(dt, f); } }; -static void verifyCFG(IR::Function *function) -{ - if (!DoVerification) - return; - - for (BasicBlock *bb : function->basicBlocks()) { - if (bb->isRemoved()) { - Q_ASSERT(bb->in.isEmpty()); - Q_ASSERT(bb->out.isEmpty()); - continue; - } - - Q_ASSERT(function->basicBlock(bb->index()) == bb); - - // Check the terminators: - Stmt *terminator = bb->terminator(); - if (terminator == nullptr) { - Stmt *last = bb->statements().last(); - Call *call = last->asExp()->expr->asCall(); - Name *baseName = call->base->asName(); - Q_ASSERT(baseName->builtin == Name::builtin_rethrow); - Q_UNUSED(baseName); - } else if (Jump *jump = terminator->asJump()) { - Q_UNUSED(jump); - Q_ASSERT(jump->target); - Q_ASSERT(!jump->target->isRemoved()); - Q_ASSERT(bb->out.size() == 1); - Q_ASSERT(bb->out.first() == jump->target); - } else if (CJump *cjump = terminator->asCJump()) { - Q_UNUSED(cjump); - Q_ASSERT(bb->out.size() == 2); - Q_ASSERT(cjump->iftrue); - Q_ASSERT(!cjump->iftrue->isRemoved()); - Q_ASSERT(cjump->iftrue == bb->out[0]); - Q_ASSERT(cjump->iffalse); - Q_ASSERT(!cjump->iffalse->isRemoved()); - Q_ASSERT(cjump->iffalse == bb->out[1]); - } else if (terminator->asRet()) { - Q_ASSERT(bb->out.size() == 0); - } else { - Q_UNREACHABLE(); - } - - // Check the outgoing edges: - for (BasicBlock *out : bb->out) { - Q_UNUSED(out); - Q_ASSERT(!out->isRemoved()); - Q_ASSERT(out->in.contains(bb)); - } - - // Check the incoming edges: - for (BasicBlock *in : bb->in) { - Q_UNUSED(in); - Q_ASSERT(!in->isRemoved()); - Q_ASSERT(in->out.contains(bb)); - } - } -} - -static void verifyImmediateDominators(const DominatorTree &dt, IR::Function *function) -{ - if (!DoVerification) - return; - - cfg2dot(function); - dt.dumpImmediateDominators(); - DominatorTree referenceTree(function); - - for (BasicBlock *bb : function->basicBlocks()) { - if (bb->isRemoved()) - continue; - - BasicBlock *idom = dt.immediateDominator(bb); - BasicBlock *referenceIdom = referenceTree.immediateDominator(bb); - Q_UNUSED(idom); - Q_UNUSED(referenceIdom); - Q_ASSERT(idom == referenceIdom); - } -} - -static void verifyNoPointerSharing(IR::Function *function) -{ - if (!DoVerification) - return; - - class { - public: - void operator()(IR::Function *f) - { - for (BasicBlock *bb : f->basicBlocks()) { - if (bb->isRemoved()) - continue; - - for (Stmt *s : bb->statements()) { - visit(s); - } - } - } - - private: - void visit(Stmt *s) - { - check(s); - STMT_VISIT_ALL_KINDS(s); - } - - void visit(Expr *e) - { - check(e); - EXPR_VISIT_ALL_KINDS(e); - } - - private: - void check(Stmt *s) - { - Q_ASSERT(!stmts.contains(s)); - stmts.insert(s); - } - - void check(Expr *e) - { - Q_ASSERT(!exprs.contains(e)); - exprs.insert(e); - } - - QSet<Stmt *> stmts; - QSet<Expr *> exprs; - } V; - V(function); -} - class RemoveLineNumbers: private SideEffectsChecker { public: @@ -5450,6 +5478,9 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee verifyNoPointerSharing(function); mergeBasicBlocks(function, &defUses, &df); + verifyImmediateDominators(df, function); + verifyCFG(function); + // Basic-block cycles that are unreachable (i.e. for loops in a then-part where the // condition is calculated to be always false) are not yet removed. This will choke the // block scheduling, so remove those now. @@ -5457,10 +5488,13 @@ void Optimizer::run(QQmlEnginePrivate *qmlEngine, bool doTypeInference, bool pee cleanupBasicBlocks(function); // showMeTheCode(function); + verifyImmediateDominators(df, function); + verifyCFG(function); + // Transform the CFG into edge-split SSA. -// qout << "Starting edge splitting..." << endl; + showMeTheCode(function, "Before edge splitting"); splitCriticalEdges(function, df, worklist, defUses); -// showMeTheCode(function); + showMeTheCode(function, "After edge splitting"); verifyImmediateDominators(df, function); verifyCFG(function); diff --git a/src/qml/debugger/qqmlabstractprofileradapter.cpp b/src/qml/debugger/qqmlabstractprofileradapter.cpp index cfc40e8c2a..68b45ec6bf 100644 --- a/src/qml/debugger/qqmlabstractprofileradapter.cpp +++ b/src/qml/debugger/qqmlabstractprofileradapter.cpp @@ -179,3 +179,5 @@ void QQmlAbstractProfilerAdapter::stopProfiling() { */ QT_END_NAMESPACE + +#include "moc_qqmlabstractprofileradapter_p.cpp" diff --git a/src/qml/debugger/qqmldebugconnector.cpp b/src/qml/debugger/qqmldebugconnector.cpp index 8a16d56c45..01f74f08be 100644 --- a/src/qml/debugger/qqmldebugconnector.cpp +++ b/src/qml/debugger/qqmldebugconnector.cpp @@ -174,3 +174,5 @@ QQmlDebugConnectorFactory::~QQmlDebugConnectorFactory() } QT_END_NAMESPACE + +#include "moc_qqmldebugconnector_p.cpp" diff --git a/src/qml/debugger/qqmldebugservice.cpp b/src/qml/debugger/qqmldebugservice.cpp index b576c3bb85..4b77bee2c9 100644 --- a/src/qml/debugger/qqmldebugservice.cpp +++ b/src/qml/debugger/qqmldebugservice.cpp @@ -178,3 +178,4 @@ const QHash<int, QObject *> &QQmlDebugService::objectsForIds() QT_END_NAMESPACE #include "qqmldebugservice.moc" +#include "moc_qqmldebugservice_p.cpp" diff --git a/src/qml/debugger/qqmldebugserviceinterfaces.cpp b/src/qml/debugger/qqmldebugserviceinterfaces.cpp index 48184da4d2..76205c7760 100644 --- a/src/qml/debugger/qqmldebugserviceinterfaces.cpp +++ b/src/qml/debugger/qqmldebugserviceinterfaces.cpp @@ -50,3 +50,5 @@ const QString QQmlEngineControlService::s_key = QStringLiteral("EngineControl"); const QString QQmlNativeDebugService::s_key = QStringLiteral("NativeQmlDebugger"); QT_END_NAMESPACE + +#include "moc_qqmldebugserviceinterfaces_p.cpp" diff --git a/src/qml/debugger/qqmlprofiler.cpp b/src/qml/debugger/qqmlprofiler.cpp index ffba731b13..8c0bd73822 100644 --- a/src/qml/debugger/qqmlprofiler.cpp +++ b/src/qml/debugger/qqmlprofiler.cpp @@ -81,3 +81,5 @@ void QQmlProfiler::reportData(bool trackLocations) } QT_END_NAMESPACE + +#include "moc_qqmlprofiler_p.cpp" diff --git a/src/qml/doc/src/cppintegration/data.qdoc b/src/qml/doc/src/cppintegration/data.qdoc index 4523ee39d8..9cc7291583 100644 --- a/src/qml/doc/src/cppintegration/data.qdoc +++ b/src/qml/doc/src/cppintegration/data.qdoc @@ -273,10 +273,17 @@ In particular, QML currently supports: \li \c {QList<qreal>} \li \c {QList<bool>} \li \c {QList<QString>} and \c{QStringList} + \li \c {QVector<QString>} + \li \c {std::vector<QString>} \li \c {QList<QUrl>} + \li \c {QVector<QUrl>} + \li \c {std::vector<QUrl>} \li \c {QVector<int>} \li \c {QVector<qreal>} \li \c {QVector<bool>} + \li \c {std::vector<int>} + \li \c {std::vector<qreal>} + \li \c {std::vector<bool>} \endlist These sequence types are implemented directly in terms of the underlying C++ @@ -296,6 +303,10 @@ If the sequence is returned from a Q_INVOKABLE function, access and mutation is much cheaper, as no QObject property read or write occurs; instead, the C++ sequence data is accessed and modified directly. +In both the Q_PROPERTY and return from Q_INVOKABLE cases, the elements +of a std::vector are copied. This copying may be an expensive operation, +so std::vector should be used judiciously. + Other sequence types are not supported transparently, and instead an instance of any other sequence type will be passed between QML and C++ as an opaque QVariantList. @@ -318,10 +329,17 @@ The default-constructed values for each sequence type are as follows: \row \li QList<qreal> \li real value 0.0 \row \li QList<bool> \li boolean value \c {false} \row \li QList<QString> and QStringList \li empty QString +\row \li QVector<QString> \li empty QString +\row \li std::vector<QString> \li empty QString \row \li QList<QUrl> \li empty QUrl +\row \li QVector<QUrl> \li empty QUrl +\row \li std::vector<QUrl> \li empty QUrl \row \li QVector<int> \li integer value 0 \row \li QVector<qreal> \li real value 0.0 \row \li QVector<bool> \li boolean value \c {false} +\row \li std::vector<int> \li integer value 0 +\row \li std::vector<qreal> \li real value 0.0 +\row \li std::vector<bool> \li boolean value \c {false} \endtable If you wish to remove elements from a sequence rather than simply replace diff --git a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc index 201cee16e6..f4046c91ac 100644 --- a/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc +++ b/src/qml/doc/src/qmllanguageref/modules/qmldir.qdoc @@ -35,9 +35,9 @@ There are two distinct types of \c qmldir files: \li QML module definition files \endlist -This documentation covers only the second form of \c qmldir file. For more -information about the first form of \c qmldir file, please see the -documentation about +This documentation covers only the second form of \c qmldir file, which +lists the QML types, JavaScript files, and plugins that are available under a +module. For more information about the first form of \c qmldir file, see \l{qtqml-syntax-directoryimports.html#directory-listing-qmldir-files} {directory listing qmldir files}. @@ -280,22 +280,33 @@ Each command in a \c qmldir file must be on a separate line. \section1 Versioning Semantics -Types which are exported for a particular version are still made available if a -later version is imported. If a module provides a \c MyButton type in version -1.0 and a \c MyWindow type in version 1.1, clients which import version 1.1 of -the module will be able to use the \c MyButton type and the \c MyWindow type. -However, the reverse is not true: a type exported for a particular version -cannot be used if an earlier version is imported. If the client had imported -version 1.0 of the module, they can use the \c MyButton type but \b not the +All QML types that are exported for a particular major version are available +with the latest version of the same major version. For example, if a module +provides a \c MyButton type in version 1.0 and \c MyWindow type in version 1.1, +clients importing version \c 1.1 of the module get to use the \c MyButton and +\c MyWindow types. However, the reverse is not true: a type exported for a +particular minor version cannot be used by importing an older or earlier minor +version. In the example mentioned earlier, if the client had imported version +\c 1.0 of the module, they can use the \c MyButton type only but not the \c MyWindow type. +A module can offer multiple major versions but the clients have access +to one major version only at a time. For example, importing +\c{MyExampleModule 2.0} provides access to that major version only and not +the previous major version. Although you can organize the artifacts that belong +to different major versions under a sigle directory and a \c qmldir file, it is +recommended to use different directories for each major version. If you +choose to go with the earlier approach (one directory and a \c qmldir file), +try to use the version suffix for the file names. For example, artifacts +that belong to \c{MyExampleModule 2.0} can use \c .2 suffix in their file name. + A version cannot be imported if no types have been explicitly exported for that version. If a module provides a \c MyButton type in version 1.0 and a \c MyWindow type in version 1.1, you cannot import version 1.2 or version 2.0 of that module. -A type can be defined by different files in different versions. In this case, -the most closely matching version will be used when imported by clients. +A type can be defined by different files in different minor versions. In this case, +the most closely matching version is used when imported by clients. For example, if a module had specified the following types via its \c qmldir file: @@ -304,17 +315,15 @@ module ExampleModule MyButton 1.0 MyButton.qml MyButton 1.1 MyButton11.qml MyButton 1.3 MyButton13.qml -MyButton 2.0 MyButton20.qml MyRectangle 1.2 MyRectangle12.qml \endcode -a client who imports version 1.2 of ExampleModule will get the \c MyButton -type definition provided by \c MyButton11.qml as it is the most closely -matching (i.e., latest while not being greater than the import) version of the +a client who imports version \c 1.2 of \c ExampleModule can use the \c MyButton +type definition provided by \c MyButton11.qml as it is the latest version of that type, and the \c MyRectangle type definition provided by \c MyRectangle12.qml. -The versioning system ensures that a given QML file will work regardless of the -version of installed software, since a versioned import \e only imports types +The version system ensures that a given QML file works regardless of the +version of installed software, as a versioned import only imports types for that version, leaving other identifiers available, even if the actual installed version might otherwise provide those identifiers. @@ -324,7 +333,6 @@ One example of a \c qmldir file follows: \code module ExampleModule -CustomButton 1.0 CustomButton.qml CustomButton 2.0 CustomButton20.qml CustomButton 2.1 CustomButton21.qml plugin examplemodule @@ -332,16 +340,16 @@ MathFunctions 2.0 mathfuncs.js \endcode The above \c qmldir file defines a module called "ExampleModule". It defines -the \c CustomButton QML object type in versions 1.1, 2.0 and 2.1 of the -module, with different implementations in each version. It specifies a plugin -which must be loaded by the engine when the module is imported by clients, and +the \c CustomButton QML object type in versions 2.0 and 2.1 of the +module, with different implementations for each version. It specifies a plugin +that must be loaded by the engine when the module is imported by clients, and that plugin may register various C++-defined types with the QML type system. -On Unix-like systems the QML engine will attempt to load \c libexamplemodule.so -as a QQmlExtensionPlugin, and on Windows it will attempt to load -\c examplemodule.dll as a QQmlExtensionPlugin. Finally, the \c qmldir file -specifies a \l{qtqml-javascript-resources.html}{JavaScript resource} which is -only available if version 2.0 or greater of the module is imported, accessible -via the \c MathFunctions identifier. +On Unix-like systems the QML engine attempts to load \c libexamplemodule.so +as a QQmlExtensionPlugin, and on Windows it loads \c examplemodule.dll as a +QQmlExtensionPlugin. Finally, the \c qmldir file specifies a +\l{qtqml-javascript-resources.html}{JavaScript resource}, which is +only available if version 2.0 or a later version (under the same major version) +of the module is imported. If the module is \l{qtqml-modules-identifiedmodules.html}{installed} into the QML import path, clients could import and use the module in the following @@ -368,7 +376,6 @@ The \c CustomButton type used above would come from the definition specified in the \c CustomButton21.qml file, and the JavaScript resource identified by the \c MathFunctions identifier would be defined in the \c mathfuncs.js file. - \section1 Writing a qmltypes File QML modules may refer to one or more type information files in their diff --git a/src/qml/jit/qv4isel_masm.cpp b/src/qml/jit/qv4isel_masm.cpp index 599370f73d..c2853a39d2 100644 --- a/src/qml/jit/qv4isel_masm.cpp +++ b/src/qml/jit/qv4isel_masm.cpp @@ -1002,6 +1002,7 @@ void InstructionSelection<JITAssembler>::convertTypeToBool(IR::Expr *source, IR: generateRuntimeCall(_as, JITTargetPlatform::ReturnValueRegister, toBoolean, PointerToValue(source)); _as->storeBool(JITTargetPlatform::ReturnValueRegister, target); + Q_FALLTHROUGH(); case IR::VarType: default: Pointer addr = _as->loadAddressForReading(JITTargetPlatform::ScratchRegister, source); diff --git a/src/qml/jit/qv4regalloc.cpp b/src/qml/jit/qv4regalloc.cpp index 8eafaaaa8a..d418b050c4 100644 --- a/src/qml/jit/qv4regalloc.cpp +++ b/src/qml/jit/qv4regalloc.cpp @@ -125,6 +125,7 @@ protected: *out << ri->prettyName(); break; } + Q_FALLTHROUGH(); } default: IRPrinterWithPositions::visitTemp(e); @@ -662,6 +663,7 @@ protected: // IRDecoder addUses(rightSource->asTemp(), Use::MustHaveRegister); break; } + Q_FALLTHROUGH(); #endif case OpBitAnd: case OpBitOr: diff --git a/src/qml/jsruntime/qv4context_p.h b/src/qml/jsruntime/qv4context_p.h index 3b37ea69dc..625d9ed424 100644 --- a/src/qml/jsruntime/qv4context_p.h +++ b/src/qml/jsruntime/qv4context_p.h @@ -72,7 +72,7 @@ struct SimpleCallContext; struct CatchContext; struct WithContext; struct QmlContext; -struct QmlContextWrapper; +struct QQmlContextWrapper; // Attention: Make sure that this structure is the same size on 32-bit and 64-bit // architecture or you'll have to change the JIT code. diff --git a/src/qml/jsruntime/qv4engine.cpp b/src/qml/jsruntime/qv4engine.cpp index 806a614e95..6465b15d5a 100644 --- a/src/qml/jsruntime/qv4engine.cpp +++ b/src/qml/jsruntime/qv4engine.cpp @@ -183,7 +183,7 @@ ExecutionEngine::ExecutionEngine(EvalISelFactory *factory) "solutions for your platform."); } #else - factory = new JIT::ISelFactory; + factory = new JIT::ISelFactory<>; #endif } iselFactory.reset(factory); @@ -1147,9 +1147,9 @@ static QVariant toVariant(QV4::ExecutionEngine *e, const QV4::Value &value, int return QVariant::fromValue(QV4::JsonObject::toJsonObject(object)); } else if (QV4::QObjectWrapper *wrapper = object->as<QV4::QObjectWrapper>()) { return qVariantFromValue<QObject *>(wrapper->object()); - } else if (object->as<QV4::QmlContextWrapper>()) { + } else if (object->as<QV4::QQmlContextWrapper>()) { return QVariant(); - } else if (QV4::QmlTypeWrapper *w = object->as<QV4::QmlTypeWrapper>()) { + } else if (QV4::QQmlTypeWrapper *w = object->as<QV4::QQmlTypeWrapper>()) { return w->toVariant(); } else if (QV4::QQmlValueTypeWrapper *v = object->as<QV4::QQmlValueTypeWrapper>()) { return v->toVariant(); diff --git a/src/qml/jsruntime/qv4global_p.h b/src/qml/jsruntime/qv4global_p.h index 0665295287..8769519a59 100644 --- a/src/qml/jsruntime/qv4global_p.h +++ b/src/qml/jsruntime/qv4global_p.h @@ -51,10 +51,6 @@ // We mean it. // -#if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB) -#define V4_BOOTSTRAP -#endif - #include <QtCore/qglobal.h> #include <QString> @@ -64,11 +60,11 @@ #define QML_NEARLY_ALWAYS_INLINE inline #endif -#ifdef V4_BOOTSTRAP -#include <private/qtqmldevtoolsglobal_p.h> -#else #include <qtqmlglobal.h> #include <private/qtqmlglobal_p.h> + +#ifdef QT_QML_BOOTSTRAPPED +#define V4_BOOTSTRAP #endif #if defined(Q_CC_MSVC) diff --git a/src/qml/jsruntime/qv4include.cpp b/src/qml/jsruntime/qv4include.cpp index f033eb2d2d..1edb7d3914 100644 --- a/src/qml/jsruntime/qv4include.cpp +++ b/src/qml/jsruntime/qv4include.cpp @@ -270,3 +270,5 @@ void QV4Include::method_include(const QV4::BuiltinFunction *, QV4::Scope &scope, } QT_END_NAMESPACE + +#include "moc_qv4include_p.cpp" diff --git a/src/qml/jsruntime/qv4profiling.cpp b/src/qml/jsruntime/qv4profiling.cpp index 8862cbef8e..bedcb5b164 100644 --- a/src/qml/jsruntime/qv4profiling.cpp +++ b/src/qml/jsruntime/qv4profiling.cpp @@ -141,3 +141,5 @@ void Profiler::startProfiling(quint64 features) } // namespace QV4 QT_END_NAMESPACE + +#include "moc_qv4profiling_p.cpp" diff --git a/src/qml/jsruntime/qv4qmlcontext.cpp b/src/qml/jsruntime/qv4qmlcontext.cpp index 56ecc9f682..c08dd7baa3 100644 --- a/src/qml/jsruntime/qv4qmlcontext.cpp +++ b/src/qml/jsruntime/qv4qmlcontext.cpp @@ -59,10 +59,10 @@ QT_BEGIN_NAMESPACE using namespace QV4; -DEFINE_OBJECT_VTABLE(QmlContextWrapper); +DEFINE_OBJECT_VTABLE(QQmlContextWrapper); DEFINE_MANAGED_VTABLE(QmlContext); -void Heap::QmlContextWrapper::init(QQmlContextData *context, QObject *scopeObject, bool ownsContext) +void Heap::QQmlContextWrapper::init(QQmlContextData *context, QObject *scopeObject, bool ownsContext) { Object::init(); readOnly = true; @@ -72,7 +72,7 @@ void Heap::QmlContextWrapper::init(QQmlContextData *context, QObject *scopeObjec this->scopeObject.init(scopeObject); } -void Heap::QmlContextWrapper::destroy() +void Heap::QQmlContextWrapper::destroy() { if (*context && ownsContext) (*context)->destroy(); @@ -81,10 +81,10 @@ void Heap::QmlContextWrapper::destroy() Object::destroy(); } -ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasProperty) +ReturnedValue QQmlContextWrapper::get(const Managed *m, String *name, bool *hasProperty) { - Q_ASSERT(m->as<QmlContextWrapper>()); - const QmlContextWrapper *resource = static_cast<const QmlContextWrapper *>(m); + Q_ASSERT(m->as<QQmlContextWrapper>()); + const QQmlContextWrapper *resource = static_cast<const QQmlContextWrapper *>(m); QV4::ExecutionEngine *v4 = resource->engine(); QV4::Scope scope(v4); @@ -143,9 +143,9 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr QV4::ScopedObject scripts(scope, context->importedScripts.valueRef()); return scripts->getIndexed(r.scriptIndex); } else if (r.type) { - return QmlTypeWrapper::create(v4, scopeObject, r.type); + return QQmlTypeWrapper::create(v4, scopeObject, r.type); } else if (r.importNamespace) { - return QmlTypeWrapper::create(v4, scopeObject, context->imports, r.importNamespace); + return QQmlTypeWrapper::create(v4, scopeObject, context->imports, r.importNamespace); } Q_ASSERT(!"Unreachable"); } @@ -225,15 +225,15 @@ ReturnedValue QmlContextWrapper::get(const Managed *m, String *name, bool *hasPr return Encode::undefined(); } -bool QmlContextWrapper::put(Managed *m, String *name, const Value &value) +bool QQmlContextWrapper::put(Managed *m, String *name, const Value &value) { - Q_ASSERT(m->as<QmlContextWrapper>()); - QmlContextWrapper *resource = static_cast<QmlContextWrapper *>(m); + Q_ASSERT(m->as<QQmlContextWrapper>()); + QQmlContextWrapper *resource = static_cast<QQmlContextWrapper *>(m); ExecutionEngine *v4 = resource->engine(); QV4::Scope scope(v4); if (scope.hasException()) return false; - QV4::Scoped<QmlContextWrapper> wrapper(scope, resource); + QV4::Scoped<QQmlContextWrapper> wrapper(scope, resource); uint member = wrapper->internalClass()->find(name); if (member < UINT_MAX) @@ -295,7 +295,7 @@ bool QmlContextWrapper::put(Managed *m, String *name, const Value &value) return Object::put(m, name, value); } -void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml) +void Heap::QmlContext::init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml) { Heap::ExecutionContext::init(outerContext->engine(), Heap::ExecutionContext::Type_QmlContext); outer.set(engine, outerContext->d()); @@ -318,7 +318,7 @@ Heap::QmlContext *QmlContext::createWorkerContext(ExecutionContext *parent, cons context->isInternal = true; context->isJSContext = true; - Scoped<QmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QmlContextWrapper>(context, (QObject*)0, true)); + Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QQmlContextWrapper>(context, (QObject*)0, true)); qml->d()->isNullWrapper = true; qml->setReadOnly(false); @@ -335,7 +335,7 @@ Heap::QmlContext *QmlContext::create(ExecutionContext *parent, QQmlContextData * { Scope scope(parent); - Scoped<QmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QmlContextWrapper>(context, scopeObject)); + Scoped<QQmlContextWrapper> qml(scope, scope.engine->memoryManager->allocObject<QQmlContextWrapper>(context, scopeObject)); Heap::QmlContext *c = parent->d()->engine->memoryManager->alloc<QmlContext>(parent, qml); return c; } diff --git a/src/qml/jsruntime/qv4qmlcontext_p.h b/src/qml/jsruntime/qv4qmlcontext_p.h index 835c9236fe..2f1dbabaf2 100644 --- a/src/qml/jsruntime/qv4qmlcontext_p.h +++ b/src/qml/jsruntime/qv4qmlcontext_p.h @@ -62,11 +62,11 @@ QT_BEGIN_NAMESPACE namespace QV4 { -struct QmlContextWrapper; +struct QQmlContextWrapper; namespace Heap { -struct QmlContextWrapper : Object { +struct QQmlContextWrapper : Object { void init(QQmlContextData *context, QObject *scopeObject, bool ownsContext = false); void destroy(); bool readOnly; @@ -78,19 +78,19 @@ struct QmlContextWrapper : Object { }; #define QmlContextMembers(class, Member) \ - Member(class, Pointer, QmlContextWrapper *, qml) + Member(class, Pointer, QQmlContextWrapper *, qml) DECLARE_HEAP_OBJECT(QmlContext, ExecutionContext) { DECLARE_MARK_TABLE(QmlContext); - void init(QV4::ExecutionContext *outerContext, QV4::QmlContextWrapper *qml); + void init(QV4::ExecutionContext *outerContext, QV4::QQmlContextWrapper *qml); }; } -struct Q_QML_EXPORT QmlContextWrapper : Object +struct Q_QML_EXPORT QQmlContextWrapper : Object { - V4_OBJECT2(QmlContextWrapper, Object) + V4_OBJECT2(QQmlContextWrapper, Object) V4_NEEDS_DESTROY void takeContextOwnership() { diff --git a/src/qml/jsruntime/qv4qobjectwrapper.cpp b/src/qml/jsruntime/qv4qobjectwrapper.cpp index 2ac2b0b64d..e4fb54f0ff 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper.cpp +++ b/src/qml/jsruntime/qv4qobjectwrapper.cpp @@ -74,7 +74,9 @@ #include <QtCore/qtimer.h> #include <QtCore/qatomic.h> #include <QtCore/qmetaobject.h> +#include <QtCore/qabstractitemmodel.h> +#include <vector> QT_BEGIN_NAMESPACE // The code in this file does not violate strict aliasing, but GCC thinks it does @@ -202,19 +204,61 @@ void QObjectWrapper::initializeBindings(ExecutionEngine *engine) QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const { + QObject *o = d()->object(); + return findProperty(engine, o, qmlContext, name, revisionMode, local); +} + +QQmlPropertyData *QObjectWrapper::findProperty(ExecutionEngine *engine, QObject *o, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) +{ Q_UNUSED(revisionMode); - QQmlData *ddata = QQmlData::get(d()->object(), false); - if (!ddata) - return 0; + QQmlData *ddata = QQmlData::get(o, false); QQmlPropertyData *result = 0; if (ddata && ddata->propertyCache) - result = ddata->propertyCache->property(name, d()->object(), qmlContext); + result = ddata->propertyCache->property(name, o, qmlContext); else - result = QQmlPropertyCache::property(engine->jsEngine(), d()->object(), name, qmlContext, *local); + result = QQmlPropertyCache::property(engine->jsEngine(), o, name, qmlContext, *local); return result; } +ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property, bool captureRequired) +{ + QQmlData::flushPendingBinding(object, QQmlPropertyIndex(property->coreIndex())); + + if (property->isFunction() && !property->isVarProperty()) { + if (property->isVMEFunction()) { + QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object); + Q_ASSERT(vmemo); + return vmemo->vmeMethod(property->coreIndex()); + } else if (property->isV4Function()) { + Scope scope(engine); + ScopedContext global(scope, engine->qmlContext()); + if (!global) + global = engine->rootContext(); + return QV4::QObjectMethod::create(global, object, property->coreIndex()); + } else if (property->isSignalHandler()) { + QmlSignalHandler::initProto(engine); + return engine->memoryManager->allocObject<QV4::QmlSignalHandler>(object, property->coreIndex())->asReturnedValue(); + } else { + ExecutionContext *global = engine->rootContext(); + return QV4::QObjectMethod::create(global, object, property->coreIndex()); + } + } + + QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0; + + if (captureRequired && ep && ep->propertyCapture && !property->isConstant()) + ep->propertyCapture->captureProperty(object, property->coreIndex(), property->notifyIndex()); + + if (property->isVarProperty()) { + QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object); + Q_ASSERT(vmemo); + return vmemo->vmeProperty(property->coreIndex()); + } else { + return loadProperty(engine, object, *property); + } +} + ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty, bool includeImports) const { @@ -250,11 +294,11 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String if (r.scriptIndex != -1) { return QV4::Encode::undefined(); } else if (r.type) { - return QmlTypeWrapper::create(v4, d()->object(), - r.type, Heap::QmlTypeWrapper::ExcludeEnums); + return QQmlTypeWrapper::create(v4, d()->object(), + r.type, Heap::QQmlTypeWrapper::ExcludeEnums); } else if (r.importNamespace) { - return QmlTypeWrapper::create(v4, d()->object(), - qmlContext->imports, r.importNamespace, Heap::QmlTypeWrapper::ExcludeEnums); + return QQmlTypeWrapper::create(v4, d()->object(), + qmlContext->imports, r.importNamespace, Heap::QQmlTypeWrapper::ExcludeEnums); } Q_ASSERT(!"Unreachable"); } @@ -279,42 +323,19 @@ ReturnedValue QObjectWrapper::getQmlProperty(QQmlContextData *qmlContext, String return getProperty(v4, d()->object(), result); } -ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, QQmlPropertyData *property, bool captureRequired) +ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, bool captureRequired) { - QQmlData::flushPendingBinding(object, QQmlPropertyIndex(property->coreIndex())); - - if (property->isFunction() && !property->isVarProperty()) { - if (property->isVMEFunction()) { - QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object); - Q_ASSERT(vmemo); - return vmemo->vmeMethod(property->coreIndex()); - } else if (property->isV4Function()) { - Scope scope(engine); - ScopedContext global(scope, engine->qmlContext()); - if (!global) - global = engine->rootContext(); - return QV4::QObjectMethod::create(global, object, property->coreIndex()); - } else if (property->isSignalHandler()) { - QmlSignalHandler::initProto(engine); - return engine->memoryManager->allocObject<QV4::QmlSignalHandler>(object, property->coreIndex())->asReturnedValue(); - } else { - ExecutionContext *global = engine->rootContext(); - return QV4::QObjectMethod::create(global, object, property->coreIndex()); - } - } - - QQmlEnginePrivate *ep = engine->qmlEngine() ? QQmlEnginePrivate::get(engine->qmlEngine()) : 0; - - if (captureRequired && ep && ep->propertyCapture && !property->isConstant()) - ep->propertyCapture->captureProperty(object, property->coreIndex(), property->notifyIndex()); + if (QQmlData::wasDeleted(object)) + return QV4::Encode::null(); + QQmlData *ddata = QQmlData::get(object, /*create*/false); + if (!ddata) + return QV4::Encode::undefined(); - if (property->isVarProperty()) { - QQmlVMEMetaObject *vmemo = QQmlVMEMetaObject::get(object); - Q_ASSERT(vmemo); - return vmemo->vmeProperty(property->coreIndex()); - } else { - return loadProperty(engine, object, *property); - } + QQmlPropertyCache *cache = ddata->propertyCache; + Q_ASSERT(cache); + QQmlPropertyData *property = cache->property(propertyIndex); + Q_ASSERT(property); // We resolved this property earlier, so it better exist! + return getProperty(engine, object, property, captureRequired); } ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, bool *hasProperty) @@ -325,12 +346,49 @@ ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlC return QV4::Encode::null(); } - if (!QQmlData::get(object, true)) { + if (name->equals(engine->id_destroy()) || name->equals(engine->id_toString())) { + int index = name->equals(engine->id_destroy()) ? QV4::QObjectMethod::DestroyMethod : QV4::QObjectMethod::ToStringMethod; if (hasProperty) - *hasProperty = false; - return QV4::Encode::null(); + *hasProperty = true; + ExecutionContext *global = engine->rootContext(); + return QV4::QObjectMethod::create(global, object, index); } + QQmlData *ddata = QQmlData::get(object, false); + QQmlPropertyData local; + QQmlPropertyData *result = findProperty(engine, object, qmlContext, name, revisionMode, &local); + + if (result) { + if (revisionMode == QV4::QObjectWrapper::CheckRevision && result->hasRevision()) { + if (ddata && ddata->propertyCache && !ddata->propertyCache->isAllowedInRevision(result)) { + if (hasProperty) + *hasProperty = false; + return QV4::Encode::undefined(); + } + } + + if (hasProperty) + *hasProperty = true; + + return getProperty(engine, object, result); + } else { + // Check if this object is already wrapped. + if (!ddata || (ddata->jsWrapper.isUndefined() && + (ddata->jsEngineId == 0 || // Nobody owns the QObject + !ddata->hasTaintedV4Object))) { // Someone else has used the QObject, but it isn't tainted + + // Not wrapped. Last chance: try query QObjectWrapper's prototype. + // If it can't handle this, then there is no point + // to wrap the QObject just to look at an empty set of JS props. + QV4::Object *proto = QObjectWrapper::defaultPrototype(engine); + return proto->get(name, hasProperty); + } + } + + // If we get here, we must already be wrapped (which implies a ddata). + // There's no point wrapping again, as there wouldn't be any new props. + Q_ASSERT(ddata); + QV4::Scope scope(engine); QV4::Scoped<QObjectWrapper> wrapper(scope, wrap(engine, object)); if (!wrapper) { @@ -341,6 +399,7 @@ ReturnedValue QObjectWrapper::getQmlProperty(QV4::ExecutionEngine *engine, QQmlC return wrapper->getQmlProperty(qmlContext, name, revisionMode, hasProperty); } + bool QObjectWrapper::setQmlProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, QObject *object, String *name, QObjectWrapper::RevisionMode revisionMode, const Value &value) { @@ -554,21 +613,6 @@ void QObjectWrapper::markWrapper(QObject *object, MarkStack *markStack) markStack->engine->m_multiplyWrappedQObjects->mark(object, markStack); } -ReturnedValue QObjectWrapper::getProperty(ExecutionEngine *engine, QObject *object, int propertyIndex, bool captureRequired) -{ - if (QQmlData::wasDeleted(object)) - return QV4::Encode::null(); - QQmlData *ddata = QQmlData::get(object, /*create*/false); - if (!ddata) - return QV4::Encode::undefined(); - - QQmlPropertyCache *cache = ddata->propertyCache; - Q_ASSERT(cache); - QQmlPropertyData *property = cache->property(propertyIndex); - Q_ASSERT(property); // We resolved this property earlier, so it better exist! - return getProperty(engine, object, property, captureRequired); -} - void QObjectWrapper::setProperty(ExecutionEngine *engine, int propertyIndex, const Value &value) { setProperty(engine, d()->object(), propertyIndex, value); @@ -598,7 +642,7 @@ bool QObjectWrapper::isEqualTo(Managed *a, Managed *b) QV4::QObjectWrapper *qobjectWrapper = static_cast<QV4::QObjectWrapper *>(a); QV4::Object *o = b->as<Object>(); if (o) { - if (QV4::QmlTypeWrapper *qmlTypeWrapper = o->as<QV4::QmlTypeWrapper>()) + if (QV4::QQmlTypeWrapper *qmlTypeWrapper = o->as<QV4::QQmlTypeWrapper>()) return qmlTypeWrapper->toVariant().value<QObject*>() == qobjectWrapper->object(); } @@ -992,6 +1036,10 @@ void QObjectWrapper::destroyObject(bool lastCall) // If the object is C++-owned, we still have to release the weak reference we have // to it. ddata->jsWrapper.clear(); + if (lastCall && ddata->propertyCache) { + ddata->propertyCache->release(); + ddata->propertyCache = nullptr; + } } } } @@ -1030,12 +1078,21 @@ private: inline void cleanup(); + template <class T, class M> + void fromContainerValue(const QV4::Object *object, int type, M CallArgument::*member, bool &queryEngine); + union { float floatValue; double doubleValue; quint32 intValue; bool boolValue; QObject *qobjectPtr; + std::vector<int> *stdVectorIntPtr; + std::vector<qreal> *stdVectorRealPtr; + std::vector<bool> *stdVectorBoolPtr; + std::vector<QString> *stdVectorQStringPtr; + std::vector<QUrl> *stdVectorQUrlPtr; + std::vector<QModelIndex> *stdVectorQModelIndexPtr; char allocData[MaxSizeOf8<QVariant, QString, @@ -1465,6 +1522,18 @@ void *CallArgument::dataPtr() { if (type == -1) return qvariantPtr->data(); + else if (type == qMetaTypeId<std::vector<int>>()) + return stdVectorIntPtr; + else if (type == qMetaTypeId<std::vector<qreal>>()) + return stdVectorRealPtr; + else if (type == qMetaTypeId<std::vector<bool>>()) + return stdVectorBoolPtr; + else if (type == qMetaTypeId<std::vector<QString>>()) + return stdVectorQStringPtr; + else if (type == qMetaTypeId<std::vector<QUrl>>()) + return stdVectorQUrlPtr; + else if (type == qMetaTypeId<std::vector<QModelIndex>>()) + return stdVectorQModelIndexPtr; else if (type != 0) return (void *)&allocData; return 0; @@ -1514,6 +1583,19 @@ void CallArgument::initAsType(int callType) } } +template <class T, class M> +void CallArgument::fromContainerValue(const QV4::Object *object, int callType, M CallArgument::*member, bool &queryEngine) +{ + if (object && object->isListType()) { + T* ptr = static_cast<T*>(QV4::SequencePrototype::getRawContainerPtr(object, callType)); + if (ptr) { + (this->*member) = ptr; + type = callType; + queryEngine = false; + } + } +} + void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const QV4::Value &value) { if (type != 0) { @@ -1552,7 +1634,7 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q qobjectPtr = 0; if (const QV4::QObjectWrapper *qobjectWrapper = value.as<QV4::QObjectWrapper>()) qobjectPtr = qobjectWrapper->object(); - else if (const QV4::QmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QmlTypeWrapper>()) + else if (const QV4::QQmlTypeWrapper *qmlTypeWrapper = value.as<QV4::QQmlTypeWrapper>()) queryEngine = qmlTypeWrapper->isSingleton(); type = callType; } else if (callType == qMetaTypeId<QVariant>()) { @@ -1595,6 +1677,33 @@ void CallArgument::fromValue(int callType, QV4::ExecutionEngine *engine, const Q type = callType; } else if (callType == QMetaType::Void) { *qvariantPtr = QVariant(); + } else if (callType == qMetaTypeId<std::vector<int>>() + || callType == qMetaTypeId<std::vector<qreal>>() + || callType == qMetaTypeId<std::vector<bool>>() + || callType == qMetaTypeId<std::vector<QString>>() + || callType == qMetaTypeId<std::vector<QUrl>>() + || callType == qMetaTypeId<std::vector<QModelIndex>>()) { + queryEngine = true; + const QV4::Object* object = value.as<Object>(); + if (callType == qMetaTypeId<std::vector<int>>()) { + stdVectorIntPtr = nullptr; + fromContainerValue<std::vector<int>>(object, callType, &CallArgument::stdVectorIntPtr, queryEngine); + } else if (callType == qMetaTypeId<std::vector<qreal>>()) { + stdVectorRealPtr = nullptr; + fromContainerValue<std::vector<qreal>>(object, callType, &CallArgument::stdVectorRealPtr, queryEngine); + } else if (callType == qMetaTypeId<std::vector<bool>>()) { + stdVectorBoolPtr = nullptr; + fromContainerValue<std::vector<bool>>(object, callType, &CallArgument::stdVectorBoolPtr, queryEngine); + } else if (callType == qMetaTypeId<std::vector<QString>>()) { + stdVectorQStringPtr = nullptr; + fromContainerValue<std::vector<QString>>(object, callType, &CallArgument::stdVectorQStringPtr, queryEngine); + } else if (callType == qMetaTypeId<std::vector<QUrl>>()) { + stdVectorQUrlPtr = nullptr; + fromContainerValue<std::vector<QUrl>>(object, callType, &CallArgument::stdVectorQUrlPtr, queryEngine); + } else if (callType == qMetaTypeId<std::vector<QModelIndex>>()) { + stdVectorQModelIndexPtr = nullptr; + fromContainerValue<std::vector<QModelIndex>>(object, callType, &CallArgument::stdVectorQModelIndexPtr, queryEngine); + } } else { queryEngine = true; } @@ -2081,3 +2190,4 @@ void MultiplyWrappedQObjectMap::removeDestroyedObject(QObject *object) QT_END_NAMESPACE +#include "moc_qv4qobjectwrapper_p.cpp" diff --git a/src/qml/jsruntime/qv4qobjectwrapper_p.h b/src/qml/jsruntime/qv4qobjectwrapper_p.h index 55700d17c1..018e444f7c 100644 --- a/src/qml/jsruntime/qv4qobjectwrapper_p.h +++ b/src/qml/jsruntime/qv4qobjectwrapper_p.h @@ -189,6 +189,7 @@ protected: static ReturnedValue create(ExecutionEngine *engine, QObject *object); + static QQmlPropertyData *findProperty(ExecutionEngine *engine, QObject *o, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local); QQmlPropertyData *findProperty(ExecutionEngine *engine, QQmlContextData *qmlContext, String *name, RevisionMode revisionMode, QQmlPropertyData *local) const; static ReturnedValue get(const Managed *m, String *name, bool *hasProperty); diff --git a/src/qml/jsruntime/qv4runtime.cpp b/src/qml/jsruntime/qv4runtime.cpp index b28a5f9000..610db8ec00 100644 --- a/src/qml/jsruntime/qv4runtime.cpp +++ b/src/qml/jsruntime/qv4runtime.cpp @@ -472,6 +472,7 @@ Heap::String *RuntimeHelpers::convertToString(ExecutionEngine *engine, const Val switch (value.type()) { case Value::Empty_Type: Q_ASSERT(!"empty Value encountered"); + Q_UNREACHABLE(); case Value::Undefined_Type: return engine->id_undefined()->d(); case Value::Null_Type: @@ -504,6 +505,7 @@ static Heap::String *convert_to_string_add(ExecutionEngine *engine, const Value switch (value.type()) { case Value::Empty_Type: Q_ASSERT(!"empty Value encountered"); + Q_UNREACHABLE(); case Value::Undefined_Type: return engine->id_undefined()->d(); case Value::Null_Type: @@ -1460,7 +1462,7 @@ ReturnedValue Runtime::method_getQmlContextObjectProperty(ExecutionEngine *engin ReturnedValue Runtime::method_getQmlSingletonQObjectProperty(ExecutionEngine *engine, const Value &object, int propertyIndex, bool captureRequired) { Scope scope(engine); - QV4::Scoped<QmlTypeWrapper> wrapper(scope, object); + QV4::Scoped<QQmlTypeWrapper> wrapper(scope, object); if (!wrapper) { scope.engine->throwTypeError(QStringLiteral("Cannot read property of null")); return Encode::undefined(); diff --git a/src/qml/jsruntime/qv4scopedvalue_p.h b/src/qml/jsruntime/qv4scopedvalue_p.h index e9dcc9172f..bc882bbd95 100644 --- a/src/qml/jsruntime/qv4scopedvalue_p.h +++ b/src/qml/jsruntime/qv4scopedvalue_p.h @@ -366,7 +366,7 @@ struct Scoped struct ScopedCallData { ScopedCallData(const Scope &scope, int argc = 0) { - int size = qMax(argc, QV4::Global::ReservedArgumentCount + int(offsetof(QV4::CallData, args)/sizeof(QV4::Value))); + int size = int(offsetof(QV4::CallData, args)/sizeof(QV4::Value)) + qMax(argc , int(QV4::Global::ReservedArgumentCount)); ptr = reinterpret_cast<CallData *>(scope.alloc(size)); ptr->tag = quint32(QV4::Value::ValueTypeInternal::Integer); ptr->argc = argc; diff --git a/src/qml/jsruntime/qv4sequenceobject.cpp b/src/qml/jsruntime/qv4sequenceobject.cpp index 6d3110771e..8afc672aa2 100644 --- a/src/qml/jsruntime/qv4sequenceobject.cpp +++ b/src/qml/jsruntime/qv4sequenceobject.cpp @@ -78,13 +78,22 @@ static void generateWarning(QV4::ExecutionEngine *v4, const QString& description F(int, IntVector, QVector<int>, 0) \ F(qreal, RealVector, QVector<qreal>, 0.0) \ F(bool, BoolVector, QVector<bool>, false) \ + F(int, IntStdVector, std::vector<int>, 0) \ + F(qreal, RealStdVector, std::vector<qreal>, 0.0) \ + F(bool, BoolStdVector, std::vector<bool>, false) \ F(int, Int, QList<int>, 0) \ F(qreal, Real, QList<qreal>, 0.0) \ F(bool, Bool, QList<bool>, false) \ F(QString, String, QList<QString>, QString()) \ F(QString, QString, QStringList, QString()) \ + F(QString, StringVector, QVector<QString>, QString()) \ + F(QString, StringStdVector, std::vector<QString>, QString()) \ F(QUrl, Url, QList<QUrl>, QUrl()) \ + F(QUrl, UrlVector, QVector<QUrl>, QUrl()) \ + F(QUrl, UrlStdVector, std::vector<QUrl>, QUrl()) \ F(QModelIndex, QModelIndex, QModelIndexList, QModelIndex()) \ + F(QModelIndex, QModelIndexVector, QVector<QModelIndex>, QModelIndex()) \ + F(QModelIndex, QModelIndexStdVector, std::vector<QModelIndex>, QModelIndex()) \ F(QItemSelectionRange, QItemSelectionRange, QItemSelection, QItemSelectionRange()) static QV4::ReturnedValue convertElementToValue(QV4::ExecutionEngine *engine, const QString &element) @@ -263,11 +272,10 @@ public: } loadReference(); } - qint32 signedIdx = static_cast<qint32>(index); - if (signedIdx < d()->container->count()) { + if (index < size_t(d()->container->size())) { if (hasProperty) *hasProperty = true; - return convertElementToValue(engine(), d()->container->at(signedIdx)); + return convertElementToValue(engine(), qAsConst(*(d()->container))[index]); } if (hasProperty) *hasProperty = false; @@ -291,24 +299,22 @@ public: loadReference(); } - qint32 signedIdx = static_cast<qint32>(index); - - int count = d()->container->count(); + size_t count = size_t(d()->container->size()); typename Container::value_type element = convertValueToElement<typename Container::value_type>(value); - if (signedIdx == count) { - d()->container->append(element); - } else if (signedIdx < count) { - (*d()->container)[signedIdx] = element; + if (index == count) { + d()->container->push_back(element); + } else if (index < count) { + (*d()->container)[index] = element; } else { /* according to ECMA262r3 we need to insert */ /* the value at the given index, increasing length to index+1. */ - d()->container->reserve(signedIdx + 1); - while (signedIdx > count++) { - d()->container->append(typename Container::value_type()); + d()->container->reserve(index + 1); + while (index > count++) { + d()->container->push_back(typename Container::value_type()); } - d()->container->append(element); + d()->container->push_back(element); } if (d()->isReference) @@ -328,8 +334,7 @@ public: return QV4::Attr_Invalid; loadReference(); } - qint32 signedIdx = static_cast<qint32>(index); - return (signedIdx < d()->container->count()) ? QV4::Attr_Data : QV4::Attr_Invalid; + return (index < size_t(d()->container->size())) ? QV4::Attr_Data : QV4::Attr_Invalid; } void containerAdvanceIterator(ObjectIterator *it, Value *name, uint *index, Property *p, PropertyAttributes *attrs) @@ -345,7 +350,7 @@ public: loadReference(); } - if (it->arrayIndex < static_cast<uint>(d()->container->count())) { + if (it->arrayIndex < static_cast<uint>(d()->container->size())) { *index = it->arrayIndex; ++it->arrayIndex; *attrs = QV4::Attr_Data; @@ -365,14 +370,13 @@ public: return false; loadReference(); } - qint32 signedIdx = static_cast<qint32>(index); - if (signedIdx >= d()->container->count()) + if (index >= size_t(d()->container->size())) return false; /* according to ECMA262r3 it should be Undefined, */ /* but we cannot, so we insert a default-value instead. */ - d()->container->replace(signedIdx, typename Container::value_type()); + (*d()->container)[index] = typename Container::value_type(); if (d()->isReference) storeReference(); @@ -457,7 +461,7 @@ public: RETURN_RESULT(Encode(0)); This->loadReference(); } - RETURN_RESULT(Encode(This->d()->container->count())); + RETURN_RESULT(Encode(qint32(This->d()->container->size()))); } static void method_set_length(const BuiltinFunction *, Scope &scope, CallData *callData) @@ -479,8 +483,8 @@ public: This->loadReference(); } /* Determine whether we need to modify the sequence */ - qint32 newCount = static_cast<qint32>(newLength); - qint32 count = This->d()->container->count(); + quint32 newCount = static_cast<quint32>(newLength); + quint32 count = static_cast<quint32>(This->d()->container->size()); if (newCount == count) { RETURN_UNDEFINED(); } else if (newCount > count) { @@ -489,14 +493,13 @@ public: /* We cannot, so we insert default-values instead. */ This->d()->container->reserve(newCount); while (newCount > count++) { - This->d()->container->append(typename Container::value_type()); + This->d()->container->push_back(typename Container::value_type()); } } else { /* according to ECMA262r3 we need to remove */ /* elements until the sequence is the required length. */ - while (newCount < count) { - count--; - This->d()->container->removeAt(count); + if (newCount < count) { + This->d()->container->erase(This->d()->container->begin() + newCount, This->d()->container->end()); } } /* write back if required. */ @@ -517,10 +520,13 @@ public: quint32 length = array->getLength(); QV4::ScopedValue v(scope); for (quint32 i = 0; i < length; ++i) - result << convertValueToElement<typename Container::value_type>((v = array->getIndexed(i))); + result.push_back(convertValueToElement<typename Container::value_type>((v = array->getIndexed(i)))); return QVariant::fromValue(result); } + void* getRawContainerPtr() const + { return d()->container; } + void loadReference() const { Q_ASSERT(d()->object); @@ -595,16 +601,34 @@ typedef QQmlSequence<QVector<qreal> > QQmlRealVectorList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlRealVectorList); typedef QQmlSequence<QVector<bool> > QQmlBoolVectorList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlBoolVectorList); +typedef QQmlSequence<std::vector<int> > QQmlIntStdVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntStdVectorList); +typedef QQmlSequence<std::vector<qreal> > QQmlRealStdVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlRealStdVectorList); +typedef QQmlSequence<std::vector<bool> > QQmlBoolStdVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlBoolStdVectorList); typedef QQmlSequence<QStringList> QQmlQStringList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQStringList); typedef QQmlSequence<QList<QString> > QQmlStringList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringList); +typedef QQmlSequence<QVector<QString> > QQmlStringVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringVectorList); +typedef QQmlSequence<std::vector<QString> > QQmlStringStdVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlStringStdVectorList); typedef QQmlSequence<QList<int> > QQmlIntList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlIntList); typedef QQmlSequence<QList<QUrl> > QQmlUrlList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlList); +typedef QQmlSequence<QVector<QUrl> > QQmlUrlVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlVectorList); +typedef QQmlSequence<std::vector<QUrl> > QQmlUrlStdVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlUrlStdVectorList); typedef QQmlSequence<QModelIndexList> QQmlQModelIndexList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexList); +typedef QQmlSequence<QVector<QModelIndex> > QQmlQModelIndexVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexVectorList); +typedef QQmlSequence<std::vector<QModelIndex> > QQmlQModelIndexStdVectorList; +DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQModelIndexStdVectorList); typedef QQmlSequence<QItemSelection> QQmlQItemSelectionRangeList; DEFINE_OBJECT_TEMPLATE_VTABLE(QQmlQItemSelectionRangeList); typedef QQmlSequence<QList<bool> > QQmlBoolList; @@ -725,6 +749,19 @@ QVariant SequencePrototype::toVariant(const QV4::Value &array, int typeHint, boo #undef SEQUENCE_TO_VARIANT +#define SEQUENCE_GET_RAWCONTAINERPTR(ElementType, ElementTypeName, SequenceType, unused) \ + if (const QQml##ElementTypeName##List *list = [&]() -> const QQml##ElementTypeName##List* \ + { if (typeHint == qMetaTypeId<SequenceType>()) return object->as<QQml##ElementTypeName##List>(); return nullptr;}()) \ + return list->getRawContainerPtr(); \ + else + +void* SequencePrototype::getRawContainerPtr(const Object *object, int typeHint) +{ + FOREACH_QML_SEQUENCE_TYPE(SEQUENCE_GET_RAWCONTAINERPTR) { /* else */ return nullptr; } +} + +#undef SEQUENCE_GET_RAWCONTAINERPTR + #define MAP_META_TYPE(ElementType, ElementTypeName, SequenceType, unused) \ if (object->as<QQml##ElementTypeName##List>()) { \ return qMetaTypeId<SequenceType>(); \ diff --git a/src/qml/jsruntime/qv4sequenceobject_p.h b/src/qml/jsruntime/qv4sequenceobject_p.h index 6f96b9f760..dcab34d092 100644 --- a/src/qml/jsruntime/qv4sequenceobject_p.h +++ b/src/qml/jsruntime/qv4sequenceobject_p.h @@ -80,6 +80,7 @@ struct SequencePrototype : public QV4::Object static int metaTypeForSequence(const Object *object); static QVariant toVariant(Object *object); static QVariant toVariant(const Value &array, int typeHint, bool *succeeded); + static void* getRawContainerPtr(const Object *object, int typeHint); }; } diff --git a/src/qml/jsruntime/qv4value.cpp b/src/qml/jsruntime/qv4value.cpp index e34ac9c764..f41442df7a 100644 --- a/src/qml/jsruntime/qv4value.cpp +++ b/src/qml/jsruntime/qv4value.cpp @@ -113,6 +113,7 @@ double Value::toNumberImpl() const case QV4::Value::Managed_Type: #ifdef V4_BOOTSTRAP Q_UNIMPLEMENTED(); + Q_FALLTHROUGH(); #else if (String *s = stringValue()) return RuntimeHelpers::stringToNumber(s->toQString()); @@ -140,6 +141,7 @@ QString Value::toQStringNoThrow() const switch (type()) { case Value::Empty_Type: Q_ASSERT(!"empty Value encountered"); + Q_UNREACHABLE(); case Value::Undefined_Type: return QStringLiteral("undefined"); case Value::Null_Type: @@ -193,6 +195,7 @@ QString Value::toQString() const switch (type()) { case Value::Empty_Type: Q_ASSERT(!"empty Value encountered"); + Q_UNREACHABLE(); case Value::Undefined_Type: return QStringLiteral("undefined"); case Value::Null_Type: diff --git a/src/qml/memory/qv4mm.cpp b/src/qml/memory/qv4mm.cpp index 7c57b93d9b..64b07153cc 100644 --- a/src/qml/memory/qv4mm.cpp +++ b/src/qml/memory/qv4mm.cpp @@ -165,6 +165,13 @@ struct MemorySegment { size_t pageSize = WTF::pageSize(); size = (size + pageSize - 1) & ~(pageSize - 1); +#if !defined(Q_OS_LINUX) && !defined(Q_OS_WIN) + // Linux and Windows zero out pages that have been decommitted and get committed again. + // unfortunately that's not true on other OSes (e.g. BSD based ones), so zero out the + // memory before decommit, so that we can be sure that all chunks we allocate will be + // zero initialized. + memset(chunk, 0, size); +#endif pageReservation.decommit(chunk, size); } @@ -259,6 +266,18 @@ void ChunkAllocator::free(Chunk *chunk, size_t size) Q_ASSERT(false); } +#ifdef DUMP_SWEEP +QString binary(quintptr n) { + QString s = QString::number(n, 2); + while (s.length() < 64) + s.prepend(QChar::fromLatin1('0')); + return s; +} +#define SDUMP qDebug +#else +QString binary(quintptr) { return QString(); } +#define SDUMP if (1) ; else qDebug +#endif void Heap::Base::markChildren(MarkStack *markStack) { @@ -318,11 +337,22 @@ void Heap::Base::markChildren(MarkStack *markStack) } } +// Stores a classname -> freed count mapping. +typedef QHash<const char*, int> MMStatsHash; +Q_GLOBAL_STATIC(MMStatsHash, freedObjectStatsGlobal) -void Chunk::sweep() +// This indirection avoids sticking QHash code in each of the call sites, which +// shaves off some instructions in the case that it's unused. +static void increaseFreedCountForClass(const char *className) { - // DEBUG << "sweeping chunk" << this << (*freeList); + (*freedObjectStatsGlobal())[className]++; +} + +void Chunk::sweep(ClassDestroyStatsCallback classCountPtr) +{ + SDUMP() << "sweeping chunk" << this; HeapItem *o = realBase(); + bool lastSlotFree = false; for (uint i = 0; i < Chunk::EntriesInBitmap; ++i) { #if WRITEBARRIER(none) Q_ASSERT((grayBitmap[i] | blackBitmap[i]) == blackBitmap[i]); // check that we don't have gray only objects @@ -330,7 +360,13 @@ void Chunk::sweep() quintptr toFree = objectBitmap[i] ^ blackBitmap[i]; Q_ASSERT((toFree & objectBitmap[i]) == toFree); // check all black objects are marked as being used quintptr e = extendsBitmap[i]; - // DEBUG << hex << " index=" << i << toFree; + SDUMP() << " index=" << i; + SDUMP() << " toFree =" << binary(toFree); + SDUMP() << " black =" << binary(blackBitmap[i]); + SDUMP() << " object =" << binary(objectBitmap[i]); + SDUMP() << " extends =" << binary(e); + if (lastSlotFree) + e &= (e + 1); // clear all lowest extent bits while (toFree) { uint index = qCountTrailingZeroBits(toFree); quintptr bit = (static_cast<quintptr>(1) << index); @@ -349,14 +385,21 @@ void Chunk::sweep() HeapItem *itemToFree = o + index; Heap::Base *b = *itemToFree; - if (b->vtable()->destroy) { - b->vtable()->destroy(b); + const VTable *v = b->vtable(); + if (Q_UNLIKELY(classCountPtr)) + classCountPtr(v->className); + if (v->destroy) { + v->destroy(b); b->_checkIsDestroyed(); } } objectBitmap[i] = blackBitmap[i]; grayBitmap[i] = 0; extendsBitmap[i] = e; + lastSlotFree = !((objectBitmap[i]|extendsBitmap[i]) >> (sizeof(quintptr)*8 - 1)); + SDUMP() << " new extends =" << binary(e); + SDUMP() << " lastSlotFree" << lastSlotFree; + Q_ASSERT((objectBitmap[i] & extendsBitmap[i]) == 0); o += Chunk::Bits; } // DEBUG << "swept chunk" << this << "freed" << slotsFreed << "slots."; @@ -649,7 +692,7 @@ done: return m; } -void BlockAllocator::sweep() +void BlockAllocator::sweep(ClassDestroyStatsCallback classCountPtr) { nextFree = 0; nFree = 0; @@ -658,7 +701,7 @@ void BlockAllocator::sweep() // qDebug() << "BlockAlloc: sweep"; usedSlotsAfterLastSweep = 0; for (auto c : chunks) { - c->sweep(); + c->sweep(classCountPtr); c->sortIntoBins(freeBins, NumBins); // qDebug() << "used slots in chunk" << c << ":" << c->nUsedSlots(); usedSlotsAfterLastSweep += c->nUsedSlots(); @@ -724,22 +767,27 @@ HeapItem *HugeItemAllocator::allocate(size_t size) { return c->first(); } -static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocator::HugeChunk &c) +static void freeHugeChunk(ChunkAllocator *chunkAllocator, const HugeItemAllocator::HugeChunk &c, ClassDestroyStatsCallback classCountPtr) { HeapItem *itemToFree = c.chunk->first(); Heap::Base *b = *itemToFree; - if (b->vtable()->destroy) { - b->vtable()->destroy(b); + const VTable *v = b->vtable(); + if (Q_UNLIKELY(classCountPtr)) + classCountPtr(v->className); + + if (v->destroy) { + v->destroy(b); b->_checkIsDestroyed(); } chunkAllocator->free(c.chunk, c.size); } -void HugeItemAllocator::sweep() { - auto isBlack = [this] (const HugeChunk &c) { +void HugeItemAllocator::sweep(ClassDestroyStatsCallback classCountPtr) +{ + auto isBlack = [this, classCountPtr] (const HugeChunk &c) { bool b = c.chunk->first()->isBlack(); if (!b) - freeHugeChunk(chunkAllocator, c); + freeHugeChunk(chunkAllocator, c, classCountPtr); return !b; }; @@ -768,7 +816,7 @@ void HugeItemAllocator::collectGrayItems(MarkStack *markStack) void HugeItemAllocator::freeAll() { for (auto &c : chunks) { - freeHugeChunk(chunkAllocator, c); + freeHugeChunk(chunkAllocator, c, nullptr); } } @@ -984,7 +1032,7 @@ void MemoryManager::mark() markStack.drain(); } -void MemoryManager::sweep(bool lastSweep) +void MemoryManager::sweep(bool lastSweep, ClassDestroyStatsCallback classCountPtr) { for (PersistentValueStorage::Iterator it = m_weakValues->begin(); it != m_weakValues->end(); ++it) { Managed *m = (*it).managed(); @@ -1031,8 +1079,8 @@ void MemoryManager::sweep(bool lastSweep) } } - blockAllocator.sweep(); - hugeItemAllocator.sweep(); + blockAllocator.sweep(classCountPtr); + hugeItemAllocator.sweep(classCountPtr); } bool MemoryManager::shouldRunGC() const @@ -1059,6 +1107,13 @@ size_t dumpBins(BlockAllocator *b, bool printOutput = true) if (printOutput) qDebug() << " number of entries in slot" << i << ":" << nEntries; } + SDUMP() << " large slot map"; + HeapItem *h = b->freeBins[BlockAllocator::NumBins - 1]; + while (h) { + SDUMP() << " " << hex << (quintptr(h)/32) << h->freeData.availableSlots; + h = h->freeData.next; + } + if (printOutput) qDebug() << " total mem in bins" << totalSlotMem*Chunk::SlotSize; return totalSlotMem*Chunk::SlotSize; @@ -1105,7 +1160,7 @@ void MemoryManager::runGC() mark(); qint64 markTime = t.nsecsElapsed()/1000; t.restart(); - sweep(); + sweep(false, increaseFreedCountForClass); const size_t usedAfter = getUsedMem(); const size_t largeItemsAfter = getLargeItemsMem(); qint64 sweepTime = t.nsecsElapsed()/1000; @@ -1120,6 +1175,20 @@ void MemoryManager::runGC() qDebug() << "Marked object in" << markTime << "us."; qDebug() << " " << markStackSize << "objects marked"; qDebug() << "Sweeped object in" << sweepTime << "us."; + + // sort our object types by number of freed instances + MMStatsHash freedObjectStats; + std::swap(freedObjectStats, *freedObjectStatsGlobal()); + typedef std::pair<const char*, int> ObjectStatInfo; + std::vector<ObjectStatInfo> freedObjectsSorted; + freedObjectsSorted.reserve(freedObjectStats.count()); + for (auto it = freedObjectStats.constBegin(); it != freedObjectStats.constEnd(); ++it) { + freedObjectsSorted.push_back(std::make_pair(it.key(), it.value())); + } + std::sort(freedObjectsSorted.begin(), freedObjectsSorted.end(), [](const ObjectStatInfo &a, const ObjectStatInfo &b) { + return a.second > b.second && strcmp(a.first, b.first) < 0; + }); + qDebug() << "Used memory before GC:" << usedBefore; qDebug() << "Used memory after GC :" << usedAfter; qDebug() << "Freed up bytes :" << (usedBefore - usedAfter); @@ -1131,6 +1200,11 @@ void MemoryManager::runGC() qDebug() << "Large item memory after GC:" << largeItemsAfter; qDebug() << "Large item memory freed up:" << (largeItemsBefore - largeItemsAfter); } + + for (auto it = freedObjectsSorted.cbegin(); it != freedObjectsSorted.cend(); ++it) { + qDebug().noquote() << QString::fromLatin1("Freed JS type: %1 (%2 instances)").arg(QString::fromLatin1(it->first), QString::number(it->second)); + } + qDebug() << "======== End GC ========"; } diff --git a/src/qml/memory/qv4mm_p.h b/src/qml/memory/qv4mm_p.h index 76ffec42de..df7d09dce0 100644 --- a/src/qml/memory/qv4mm_p.h +++ b/src/qml/memory/qv4mm_p.h @@ -86,7 +86,7 @@ struct StackAllocator { } else { nextFree += requiredSlots; } -#if MM_DEBUG || !defined(QT_NO_DEBUG) +#if MM_DEBUG || !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) Chunk *c = m->chunk(); Chunk::setBit(c->objectBitmap, m - c->realBase()); #endif @@ -98,7 +98,7 @@ struct StackAllocator { } else { nextFree -= requiredSlots; } -#if MM_DEBUG || !defined(QT_NO_DEBUG) +#if MM_DEBUG || !defined(QT_NO_DEBUG) || defined(QT_FORCE_ASSERTS) Chunk *c = nextFree->chunk(); Chunk::clearBit(c->objectBitmap, nextFree - c->realBase()); #endif @@ -153,7 +153,7 @@ struct BlockAllocator { return used; } - void sweep(); + void sweep(ClassDestroyStatsCallback classCountPtr); void freeAll(); void resetBlackBits(); void collectGrayItems(MarkStack *markStack); @@ -176,7 +176,7 @@ struct HugeItemAllocator { {} HeapItem *allocate(size_t size); - void sweep(); + void sweep(ClassDestroyStatsCallback classCountPtr); void freeAll(); void resetBlackBits(); void collectGrayItems(MarkStack *markStack); @@ -446,7 +446,7 @@ protected: private: void collectFromJSStack(MarkStack *markStack) const; void mark(); - void sweep(bool lastSweep = false); + void sweep(bool lastSweep = false, ClassDestroyStatsCallback classCountPtr = nullptr); bool shouldRunGC() const; void collectRoots(MarkStack *markStack); diff --git a/src/qml/memory/qv4mmdefs_p.h b/src/qml/memory/qv4mmdefs_p.h index 9512722782..bf29b44a2c 100644 --- a/src/qml/memory/qv4mmdefs_p.h +++ b/src/qml/memory/qv4mmdefs_p.h @@ -61,6 +61,8 @@ namespace QV4 { struct MarkStack; +typedef void(*ClassDestroyStatsCallback)(const char *); + /* * Chunks are the basic structure containing GC managed objects. * @@ -184,7 +186,7 @@ struct Chunk { return usedSlots; } - void sweep(); + void sweep(ClassDestroyStatsCallback classCountPtr); void freeAll(); void resetBlackBits(); void collectGrayItems(QV4::MarkStack *markStack); diff --git a/src/qml/qml/qqmlapplicationengine.cpp b/src/qml/qml/qqmlapplicationengine.cpp index a10dda166c..faab8bf926 100644 --- a/src/qml/qml/qqmlapplicationengine.cpp +++ b/src/qml/qml/qqmlapplicationengine.cpp @@ -57,6 +57,10 @@ QQmlApplicationEnginePrivate::~QQmlApplicationEnginePrivate() void QQmlApplicationEnginePrivate::cleanUp() { + Q_Q(QQmlApplicationEngine); + for (auto obj : qAsConst(objects)) + obj->disconnect(q); + qDeleteAll(objects); #if QT_CONFIG(translation) qDeleteAll(translators); @@ -126,9 +130,12 @@ void QQmlApplicationEnginePrivate::finishLoad(QQmlComponent *c) qWarning() << qPrintable(c->errorString()); q->objectCreated(0, c->url()); break; - case QQmlComponent::Ready: - objects << c->create(); + case QQmlComponent::Ready: { + auto newObj = c->create(); + objects << newObj; + QObject::connect(newObj, &QObject::destroyed, q, [&](QObject *obj) { objects.removeAll(obj); }); q->objectCreated(objects.constLast(), c->url()); + } break; case QQmlComponent::Loading: case QQmlComponent::Null: diff --git a/src/qml/qml/qqmlcomponent.cpp b/src/qml/qml/qqmlcomponent.cpp index 75968ffc43..e7a45482e6 100644 --- a/src/qml/qml/qqmlcomponent.cpp +++ b/src/qml/qml/qqmlcomponent.cpp @@ -1040,6 +1040,35 @@ void QQmlComponent::create(QQmlIncubator &incubator, QQmlContext *context, enginePriv->incubate(incubator, forContextData); } +/* + This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData + arguments instead of QQmlContext which means we don't have to construct the rather weighty + wrapper class for every delegate item. + + This is used by QQmlDelegateModel. +*/ +void QQmlComponentPrivate::incubateObject( + QQmlIncubator *incubationTask, + QQmlComponent *component, + QQmlEngine *engine, + QQmlContextData *context, + QQmlContextData *forContext) +{ + QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubationTask); + QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine); + QQmlComponentPrivate *componentPriv = QQmlComponentPrivate::get(component); + + incubatorPriv->compilationUnit = componentPriv->compilationUnit; + incubatorPriv->compilationUnit->addref(); + incubatorPriv->enginePriv = enginePriv; + incubatorPriv->creator.reset(new QQmlObjectCreator(context, componentPriv->compilationUnit, componentPriv->creationContext)); + incubatorPriv->subComponentToCreate = componentPriv->start; + + enginePriv->incubate(*incubationTask, forContext); +} + + + class QQmlComponentIncubator; namespace QV4 { @@ -1527,3 +1556,5 @@ void QV4::QmlIncubatorObject::statusChanged(QQmlIncubator::Status s) #undef INITIALPROPERTIES_SOURCE QT_END_NAMESPACE + +#include "moc_qqmlcomponent.cpp" diff --git a/src/qml/qml/qqmlcomponent_p.h b/src/qml/qml/qqmlcomponent_p.h index d01a987acc..6414025574 100644 --- a/src/qml/qml/qqmlcomponent_p.h +++ b/src/qml/qml/qqmlcomponent_p.h @@ -88,6 +88,13 @@ public: void initializeObjectWithInitialProperties(QV4::QmlContext *qmlContext, const QV4::Value &valuemap, QObject *toCreate); static void setInitialProperties(QV4::ExecutionEngine *engine, QV4::QmlContext *qmlContext, const QV4::Value &o, const QV4::Value &v); + void incubateObject( + QQmlIncubator *incubationTask, + QQmlComponent *component, + QQmlEngine *engine, + QQmlContextData *context, + QQmlContextData *forContext); + QQmlTypeData *typeData; void typeDataReady(QQmlTypeData *) override; void typeDataProgress(QQmlTypeData *, qreal) override; diff --git a/src/qml/qml/qqmlcontext.cpp b/src/qml/qml/qqmlcontext.cpp index 018841b9b1..1476c276f4 100644 --- a/src/qml/qml/qqmlcontext.cpp +++ b/src/qml/qml/qqmlcontext.cpp @@ -834,3 +834,5 @@ QString QQmlContextData::urlString() const } QT_END_NAMESPACE + +#include "moc_qqmlcontext.cpp" diff --git a/src/qml/qml/qqmlcustomparser.cpp b/src/qml/qml/qqmlcustomparser.cpp index 0b0bbef795..6ad641b8b1 100644 --- a/src/qml/qml/qqmlcustomparser.cpp +++ b/src/qml/qml/qqmlcustomparser.cpp @@ -121,13 +121,16 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const { Q_ASSERT_X(ok, "QQmlCustomParser::evaluateEnum", "ok must not be a null pointer"); *ok = false; + + // we support one or two '.' in the enum phrase: + // * <TypeName>.<EnumValue> + // * <TypeName>.<ScopedEnumName>.<EnumValue> + int dot = script.indexOf('.'); - if (dot == -1) + if (dot == -1 || dot == script.length()-1) return -1; - QString scope = QString::fromUtf8(script.left(dot)); - QByteArray enumValue = script.mid(dot+1); if (scope != QLatin1String("Qt")) { if (imports.isNull()) @@ -142,9 +145,20 @@ int QQmlCustomParser::evaluateEnum(const QByteArray& script, bool *ok) const type = result.type; } - return type ? type->enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok) : -1; + if (!type) + return -1; + + int dot2 = script.indexOf('.', dot+1); + const bool dot2Valid = dot2 != -1 && dot2 != script.length()-1; + QByteArray enumValue = script.mid(dot2Valid ? dot2 + 1 : dot + 1); + QByteArray scopedEnumName = (dot2Valid ? script.mid(dot + 1, dot2 - dot - 1) : QByteArray()); + if (!scopedEnumName.isEmpty()) + return type->scopedEnumValue(engine, scopedEnumName, enumValue, ok); + else + return type->enumValue(engine, QHashedCStringRef(enumValue.constData(), enumValue.length()), ok); } + QByteArray enumValue = script.mid(dot + 1); const QMetaObject *mo = StaticQtMetaObject::get(); int i = mo->enumeratorCount(); while (i--) { diff --git a/src/qml/qml/qqmldelayedcallqueue.cpp b/src/qml/qml/qqmldelayedcallqueue.cpp index d5d2c9a28d..13e62ec696 100644 --- a/src/qml/qml/qqmldelayedcallqueue.cpp +++ b/src/qml/qml/qqmldelayedcallqueue.cpp @@ -210,3 +210,5 @@ void QQmlDelayedCallQueue::ticked() } QT_END_NAMESPACE + +#include "moc_qqmldelayedcallqueue_p.cpp" diff --git a/src/qml/qml/qqmlengine.cpp b/src/qml/qml/qqmlengine.cpp index 9ff76d7b24..4a21acb050 100644 --- a/src/qml/qml/qqmlengine.cpp +++ b/src/qml/qml/qqmlengine.cpp @@ -1492,9 +1492,9 @@ QQmlEngine *qmlEngine(const QObject *obj) QObject *qmlAttachedPropertiesObjectById(int id, const QObject *object, bool create) { - QQmlData *data = QQmlData::get(object); + QQmlData *data = QQmlData::get(object, create); if (!data) - return 0; // Attached properties are only on objects created by QML + return 0; // Attached properties are only on objects created by QML, unless explicitly requested (create==true) QObject *rv = data->hasExtendedData()?data->attachedProperties()->value(id):0; if (rv || !create) @@ -2177,7 +2177,7 @@ QString QQmlEngine::offlineStoragePath() const Returns the file path where a \l{QtQuick.LocalStorage}{Local Storage} database with the identifier \a databaseName is (or would be) located. - \sa LocalStorage.openDatabaseSync() + \sa {openDatabaseSync}{LocalStorage.openDatabaseSync()} \since 5.9 */ QString QQmlEngine::offlineStorageDatabaseFilePath(const QString &databaseName) const @@ -2553,3 +2553,5 @@ bool QQml_isFileCaseCorrect(const QString &fileName, int lengthIn /* = -1 */) */ QT_END_NAMESPACE + +#include "moc_qqmlengine.cpp" diff --git a/src/qml/qml/qqmlerror.cpp b/src/qml/qml/qqmlerror.cpp index 7a1e02eec6..64f008cd32 100644 --- a/src/qml/qml/qqmlerror.cpp +++ b/src/qml/qml/qqmlerror.cpp @@ -44,6 +44,7 @@ #include <QtCore/qfile.h> #include <QtCore/qstringlist.h> #include <QtCore/qvector.h> +#include <QtCore/qpointer.h> #include <private/qv4errorobject_p.h> @@ -86,7 +87,7 @@ public: quint16 line; quint16 column; QtMsgType messageType; - QObject *object; + QPointer<QObject> object; }; QQmlErrorPrivate::QQmlErrorPrivate() diff --git a/src/qml/qml/qqmlextensionplugin.cpp b/src/qml/qml/qqmlextensionplugin.cpp index 097fa71200..b0e6a24616 100644 --- a/src/qml/qml/qqmlextensionplugin.cpp +++ b/src/qml/qml/qqmlextensionplugin.cpp @@ -128,3 +128,5 @@ void QQmlExtensionPlugin::initializeEngine(QQmlEngine *engine, const char *uri) */ QT_END_NAMESPACE + +#include "moc_qqmlextensionplugin.cpp" diff --git a/src/qml/qml/qqmlfileselector.cpp b/src/qml/qml/qqmlfileselector.cpp index 461ca33b3e..be6216d3ff 100644 --- a/src/qml/qml/qqmlfileselector.cpp +++ b/src/qml/qml/qqmlfileselector.cpp @@ -222,3 +222,5 @@ QUrl QQmlFileSelectorInterceptor::intercept(const QUrl &path, DataType type) } QT_END_NAMESPACE + +#include "moc_qqmlfileselector.cpp" diff --git a/src/qml/qml/qqmlglobal.cpp b/src/qml/qml/qqmlglobal.cpp index f967dacd34..7939656107 100644 --- a/src/qml/qml/qqmlglobal.cpp +++ b/src/qml/qml/qqmlglobal.cpp @@ -450,3 +450,5 @@ void QQmlApplication::setDomain(const QString &arg) } QT_END_NAMESPACE + +#include "moc_qqmlglobal_p.cpp" diff --git a/src/qml/qml/qqmllocale.cpp b/src/qml/qml/qqmllocale.cpp index 712da78807..326b36c5cd 100644 --- a/src/qml/qml/qqmllocale.cpp +++ b/src/qml/qml/qqmllocale.cpp @@ -1090,3 +1090,5 @@ void QQmlLocale::method_localeCompare(const BuiltinFunction *b, Scope &scope, Ca */ QT_END_NAMESPACE + +#include "moc_qqmllocale_p.cpp" diff --git a/src/qml/qml/qqmlloggingcategory.cpp b/src/qml/qml/qqmlloggingcategory.cpp index 764b874131..08f8552ab6 100644 --- a/src/qml/qml/qqmlloggingcategory.cpp +++ b/src/qml/qml/qqmlloggingcategory.cpp @@ -126,3 +126,5 @@ void QQmlLoggingCategory::setName(const QString &name) QScopedPointer<QLoggingCategory> category(new QLoggingCategory(m_name.constData())); m_category.swap(category); } + +#include "moc_qqmlloggingcategory_p.cpp" diff --git a/src/qml/qml/qqmlmetatype.cpp b/src/qml/qml/qqmlmetatype.cpp index bb9b69c479..0672618225 100644 --- a/src/qml/qml/qqmlmetatype.cpp +++ b/src/qml/qml/qqmlmetatype.cpp @@ -216,6 +216,8 @@ public: mutable bool haveSuperType:1; mutable QList<QQmlProxyMetaObject::ProxyData> metaObjects; mutable QStringHash<int> enums; + mutable QStringHash<int> scopedEnumIndex; // maps from enum name to index in scopedEnums + mutable QList<QStringHash<int>*> scopedEnums; static QHash<const QMetaObject *, int> attachedPropertyIds; }; @@ -313,6 +315,7 @@ QQmlTypePrivate::QQmlTypePrivate(QQmlType::RegistrationType type) QQmlTypePrivate::~QQmlTypePrivate() { + qDeleteAll(scopedEnums); switch (regType) { case QQmlType::CppType: delete extraData.cd->customParser; @@ -507,6 +510,67 @@ int QQmlType::resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString return type->enumValue(engine, name, ok); } +int QQmlType::resolveCompositeScopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *name, bool *ok) const +{ + Q_ASSERT(isComposite()); + *ok = false; + QQmlType *type = resolveCompositeBaseType(engine); + if (!type) + return -1; + return type->scopedEnumIndex(engine, name, ok); +} + +int QQmlType::resolveCompositeScopedEnumIndex(QQmlEnginePrivate *engine, const QString &name, bool *ok) const +{ + Q_ASSERT(isComposite()); + *ok = false; + QQmlType *type = resolveCompositeBaseType(engine); + if (!type) + return -1; + return type->scopedEnumIndex(engine, name, ok); +} + + +int QQmlType::resolveCompositeScopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::String *name, bool *ok) const +{ + Q_ASSERT(isComposite()); + *ok = false; + QQmlType *type = resolveCompositeBaseType(engine); + if (!type) + return -1; + return type->scopedEnumValue(engine, index, name, ok); +} + +int QQmlType::resolveCompositeScopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &name, bool *ok) const +{ + Q_ASSERT(isComposite()); + *ok = false; + QQmlType *type = resolveCompositeBaseType(engine); + if (!type) + return -1; + return type->scopedEnumValue(engine, index, name, ok); +} + +int QQmlType::resolveCompositeScopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scopedName, const QByteArray &name, bool *ok) const +{ + Q_ASSERT(isComposite()); + *ok = false; + QQmlType *type = resolveCompositeBaseType(engine); + if (!type) + return -1; + return type->scopedEnumValue(engine, scopedName, name, ok); +} + +int QQmlType::resolveCompositeScopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scopedName, const QStringRef &name, bool *ok) const +{ + Q_ASSERT(isComposite()); + *ok = false; + QQmlType *type = resolveCompositeBaseType(engine); + if (!type) + return -1; + return type->scopedEnumValue(engine, scopedName, name, ok); +} + static void clone(QMetaObjectBuilder &builder, const QMetaObject *mo, const QMetaObject *ignoreStart, const QMetaObject *ignoreEnd) { @@ -702,8 +766,21 @@ void QQmlTypePrivate::insertEnums(const QMetaObject *metaObject) const // Add any enum values defined by this class, overwriting any inherited values for (int ii = 0; ii < metaObject->enumeratorCount(); ++ii) { QMetaEnum e = metaObject->enumerator(ii); - for (int jj = 0; jj < e.keyCount(); ++jj) - enums.insert(QString::fromUtf8(e.key(jj)), e.value(jj)); + const bool isScoped = e.isScoped(); + QStringHash<int> *scoped = isScoped ? new QStringHash<int>() : 0; + + for (int jj = 0; jj < e.keyCount(); ++jj) { + const QString key = QString::fromUtf8(e.key(jj)); + const int value = e.value(jj); + enums.insert(key, value); + if (isScoped) + scoped->insert(key, value); + } + + if (isScoped) { + scopedEnums << scoped; + scopedEnumIndex.insert(QString::fromUtf8(e.name()), scopedEnums.count()-1); + } } } @@ -1004,6 +1081,116 @@ int QQmlType::enumValue(QQmlEnginePrivate *engine, const QV4::String *name, bool return -1; } +int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *name, bool *ok) const +{ + Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeScopedEnumIndex(engine, name, ok); + *ok = true; + + d->initEnums(); + + int *rv = d->scopedEnumIndex.value(name); + if (rv) + return *rv; + + *ok = false; + return -1; +} + +int QQmlType::scopedEnumIndex(QQmlEnginePrivate *engine, const QString &name, bool *ok) const +{ + Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeScopedEnumIndex(engine, name, ok); + *ok = true; + + d->initEnums(); + + int *rv = d->scopedEnumIndex.value(name); + if (rv) + return *rv; + + *ok = false; + return -1; +} + +int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::String *name, bool *ok) const +{ + Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeScopedEnumValue(engine, index, name, ok); + *ok = true; + + Q_ASSERT(index > -1 && index < d->scopedEnums.count()); + int *rv = d->scopedEnums.at(index)->value(name); + if (rv) + return *rv; + + *ok = false; + return -1; +} + +int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &name, bool *ok) const +{ + Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeScopedEnumValue(engine, index, name, ok); + *ok = true; + + Q_ASSERT(index > -1 && index < d->scopedEnums.count()); + int *rv = d->scopedEnums.at(index)->value(name); + if (rv) + return *rv; + + *ok = false; + return -1; +} + +int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scopedEnumName, const QByteArray &name, bool *ok) const +{ + Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeScopedEnumValue(engine, scopedEnumName, name, ok); + *ok = true; + + d->initEnums(); + + int *rv = d->scopedEnumIndex.value(QHashedCStringRef(scopedEnumName.constData(), scopedEnumName.length())); + if (rv) { + int index = *rv; + Q_ASSERT(index > -1 && index < d->scopedEnums.count()); + rv = d->scopedEnums.at(index)->value(QHashedCStringRef(name.constData(), name.length())); + if (rv) + return *rv; + } + + *ok = false; + return -1; +} + +int QQmlType::scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scopedEnumName, const QStringRef &name, bool *ok) const +{ + Q_ASSERT(ok); + if (isComposite()) + return resolveCompositeScopedEnumValue(engine, scopedEnumName, name, ok); + *ok = true; + + d->initEnums(); + + int *rv = d->scopedEnumIndex.value(QHashedStringRef(scopedEnumName)); + if (rv) { + int index = *rv; + Q_ASSERT(index > -1 && index < d->scopedEnums.count()); + rv = d->scopedEnums.at(index)->value(QHashedStringRef(name)); + if (rv) + return *rv; + } + + *ok = false; + return -1; +} + QQmlTypeModule::QQmlTypeModule() : d(new QQmlTypeModulePrivate) { diff --git a/src/qml/qml/qqmlmetatype_p.h b/src/qml/qml/qqmlmetatype_p.h index 2b615e645a..4dd28bbd36 100644 --- a/src/qml/qml/qqmlmetatype_p.h +++ b/src/qml/qml/qqmlmetatype_p.h @@ -216,10 +216,24 @@ public: int enumValue(QQmlEnginePrivate *engine, const QHashedStringRef &, bool *ok) const; int enumValue(QQmlEnginePrivate *engine, const QHashedCStringRef &, bool *ok) const; int enumValue(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const; + + int scopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const; + int scopedEnumIndex(QQmlEnginePrivate *engine, const QString &, bool *ok) const; + int scopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::String *, bool *ok) const; + int scopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &, bool *ok) const; + int scopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &, const QByteArray &, bool *ok) const; + int scopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &, const QStringRef &, bool *ok) const; + private: QQmlType *superType() const; QQmlType *resolveCompositeBaseType(QQmlEnginePrivate *engine) const; int resolveCompositeEnumValue(QQmlEnginePrivate *engine, const QString &name, bool *ok) const; + int resolveCompositeScopedEnumIndex(QQmlEnginePrivate *engine, const QV4::String *, bool *ok) const; + int resolveCompositeScopedEnumIndex(QQmlEnginePrivate *engine, const QString &name, bool *ok) const; + int resolveCompositeScopedEnumValue(QQmlEnginePrivate *engine, int index, const QV4::String *, bool *ok) const; + int resolveCompositeScopedEnumValue(QQmlEnginePrivate *engine, int index, const QString &name, bool *ok) const; + int resolveCompositeScopedEnumValue(QQmlEnginePrivate *engine, const QByteArray &scopedName, const QByteArray &name, bool *ok) const; + int resolveCompositeScopedEnumValue(QQmlEnginePrivate *engine, const QStringRef &scopedName, const QStringRef &name, bool *ok) const; friend class QQmlTypePrivate; friend struct QQmlMetaTypeData; diff --git a/src/qml/qml/qqmlplatform.cpp b/src/qml/qml/qqmlplatform.cpp index 64ca208f1b..165cde5eb3 100644 --- a/src/qml/qml/qqmlplatform.cpp +++ b/src/qml/qml/qqmlplatform.cpp @@ -79,3 +79,5 @@ QString QQmlPlatform::os() } QT_END_NAMESPACE + +#include "moc_qqmlplatform_p.cpp" diff --git a/src/qml/qml/qqmltypenotavailable.cpp b/src/qml/qml/qqmltypenotavailable.cpp index b10a7c62b9..ffa4472e4b 100644 --- a/src/qml/qml/qqmltypenotavailable.cpp +++ b/src/qml/qml/qqmltypenotavailable.cpp @@ -49,3 +49,5 @@ int qmlRegisterTypeNotAvailable(const char *uri, int versionMajor, int versionMi QQmlTypeNotAvailable::QQmlTypeNotAvailable() { } QT_END_NAMESPACE + +#include "moc_qqmltypenotavailable_p.cpp" diff --git a/src/qml/qml/qqmltypewrapper.cpp b/src/qml/qml/qqmltypewrapper.cpp index 7b98096a7f..7a06077c11 100644 --- a/src/qml/qml/qqmltypewrapper.cpp +++ b/src/qml/qml/qqmltypewrapper.cpp @@ -52,16 +52,17 @@ QT_BEGIN_NAMESPACE using namespace QV4; -DEFINE_OBJECT_VTABLE(QmlTypeWrapper); +DEFINE_OBJECT_VTABLE(QQmlTypeWrapper); +DEFINE_OBJECT_VTABLE(QQmlScopedEnumWrapper); -void Heap::QmlTypeWrapper::init() +void Heap::QQmlTypeWrapper::init() { Object::init(); mode = IncludeEnums; object.init(); } -void Heap::QmlTypeWrapper::destroy() +void Heap::QQmlTypeWrapper::destroy() { if (typeNamespace) typeNamespace->release(); @@ -69,12 +70,12 @@ void Heap::QmlTypeWrapper::destroy() Object::destroy(); } -bool QmlTypeWrapper::isSingleton() const +bool QQmlTypeWrapper::isSingleton() const { return d()->type && d()->type->isSingleton(); } -QObject* QmlTypeWrapper::singletonObject() const +QObject* QQmlTypeWrapper::singletonObject() const { if (!isSingleton()) return 0; @@ -85,7 +86,7 @@ QObject* QmlTypeWrapper::singletonObject() const return siinfo->qobjectApi(e); } -QVariant QmlTypeWrapper::toVariant() const +QVariant QQmlTypeWrapper::toVariant() const { if (d()->type && d()->type->isSingleton()) { QQmlEngine *e = engine()->qmlEngine(); @@ -103,27 +104,27 @@ QVariant QmlTypeWrapper::toVariant() const // Returns a type wrapper for type t on o. This allows access of enums, and attached properties. -ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlType *t, - Heap::QmlTypeWrapper::TypeNameMode mode) +ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlType *t, + Heap::QQmlTypeWrapper::TypeNameMode mode) { Q_ASSERT(t); Scope scope(engine); - Scoped<QmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QmlTypeWrapper>()); + Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QQmlTypeWrapper>()); w->d()->mode = mode; w->d()->object = o; w->d()->type = t; return w.asReturnedValue(); } // Returns a type wrapper for importNamespace (of t) on o. This allows nested resolution of a type in a // namespace. -ReturnedValue QmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, - Heap::QmlTypeWrapper::TypeNameMode mode) +ReturnedValue QQmlTypeWrapper::create(QV4::ExecutionEngine *engine, QObject *o, QQmlTypeNameCache *t, const void *importNamespace, + Heap::QQmlTypeWrapper::TypeNameMode mode) { Q_ASSERT(t); Q_ASSERT(importNamespace); Scope scope(engine); - Scoped<QmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QmlTypeWrapper>()); + Scoped<QQmlTypeWrapper> w(scope, engine->memoryManager->allocObject<QQmlTypeWrapper>()); w->d()->mode = mode; w->d()->object = o; w->d()->typeNamespace = t; w->d()->importNamespace = importNamespace; t->addref(); return w.asReturnedValue(); @@ -157,14 +158,14 @@ static ReturnedValue throwLowercaseEnumError(QV4::ExecutionEngine *v4, String *n return v4->throwTypeError(message); } -ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasProperty) +ReturnedValue QQmlTypeWrapper::get(const Managed *m, String *name, bool *hasProperty) { - Q_ASSERT(m->as<QmlTypeWrapper>()); + Q_ASSERT(m->as<QQmlTypeWrapper>()); - QV4::ExecutionEngine *v4 = static_cast<const QmlTypeWrapper *>(m)->engine(); + QV4::ExecutionEngine *v4 = static_cast<const QQmlTypeWrapper *>(m)->engine(); QV4::Scope scope(v4); - Scoped<QmlTypeWrapper> w(scope, static_cast<const QmlTypeWrapper *>(m)); + Scoped<QQmlTypeWrapper> w(scope, static_cast<const QQmlTypeWrapper *>(m)); if (hasProperty) *hasProperty = true; @@ -186,7 +187,7 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope if (qobjectSingleton) { // check for enum value - const bool includeEnums = w->d()->mode == Heap::QmlTypeWrapper::IncludeEnums; + const bool includeEnums = w->d()->mode == Heap::QQmlTypeWrapper::IncludeEnums; if (includeEnums && name->startsWithUpper()) { const int value = enumForSingleton(v4, name, qobjectSingleton, type); if (value != -1) @@ -224,6 +225,14 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope if (ok) return QV4::Primitive::fromInt32(value).asReturnedValue(); + value = type->scopedEnumIndex(QQmlEnginePrivate::get(v4->qmlEngine()), name, &ok); + if (ok) { + Scoped<QQmlScopedEnumWrapper> enumWrapper(scope, v4->memoryManager->allocObject<QQmlScopedEnumWrapper>()); + enumWrapper->d()->type = type; + enumWrapper->d()->scopeEnumIndex = value; + return enumWrapper.asReturnedValue(); + } + // Fall through to base implementation } else if (w->d()->object) { @@ -280,10 +289,10 @@ ReturnedValue QmlTypeWrapper::get(const Managed *m, String *name, bool *hasPrope } -bool QmlTypeWrapper::put(Managed *m, String *name, const Value &value) +bool QQmlTypeWrapper::put(Managed *m, String *name, const Value &value) { - Q_ASSERT(m->as<QmlTypeWrapper>()); - QmlTypeWrapper *w = static_cast<QmlTypeWrapper *>(m); + Q_ASSERT(m->as<QQmlTypeWrapper>()); + QQmlTypeWrapper *w = static_cast<QQmlTypeWrapper *>(m); QV4::ExecutionEngine *v4 = w->engine(); if (v4->hasException) return false; @@ -322,7 +331,7 @@ bool QmlTypeWrapper::put(Managed *m, String *name, const Value &value) return false; } -PropertyAttributes QmlTypeWrapper::query(const Managed *m, String *name) +PropertyAttributes QQmlTypeWrapper::query(const Managed *m, String *name) { // ### Implement more efficiently. bool hasProperty = false; @@ -330,11 +339,11 @@ PropertyAttributes QmlTypeWrapper::query(const Managed *m, String *name) return hasProperty ? Attr_Data : Attr_Invalid; } -bool QmlTypeWrapper::isEqualTo(Managed *a, Managed *b) +bool QQmlTypeWrapper::isEqualTo(Managed *a, Managed *b) { - Q_ASSERT(a->as<QV4::QmlTypeWrapper>()); - QV4::QmlTypeWrapper *qmlTypeWrapperA = static_cast<QV4::QmlTypeWrapper *>(a); - if (QV4::QmlTypeWrapper *qmlTypeWrapperB = b->as<QV4::QmlTypeWrapper>()) + Q_ASSERT(a->as<QV4::QQmlTypeWrapper>()); + QV4::QQmlTypeWrapper *qmlTypeWrapperA = static_cast<QV4::QQmlTypeWrapper *>(a); + if (QV4::QQmlTypeWrapper *qmlTypeWrapperB = b->as<QV4::QQmlTypeWrapper>()) return qmlTypeWrapperA->toVariant() == qmlTypeWrapperB->toVariant(); else if (QV4::QObjectWrapper *qobjectWrapper = b->as<QV4::QObjectWrapper>()) return qmlTypeWrapperA->toVariant().value<QObject*>() == qobjectWrapper->object(); @@ -342,10 +351,10 @@ bool QmlTypeWrapper::isEqualTo(Managed *a, Managed *b) return false; } -ReturnedValue QmlTypeWrapper::instanceOf(const Object *typeObject, const Value &var) +ReturnedValue QQmlTypeWrapper::instanceOf(const Object *typeObject, const Value &var) { - Q_ASSERT(typeObject->as<QV4::QmlTypeWrapper>()); - const QV4::QmlTypeWrapper *typeWrapper = static_cast<const QV4::QmlTypeWrapper *>(typeObject); + Q_ASSERT(typeObject->as<QV4::QQmlTypeWrapper>()); + const QV4::QQmlTypeWrapper *typeWrapper = static_cast<const QV4::QQmlTypeWrapper *>(typeObject); QV4::ExecutionEngine *engine = typeObject->internalClass()->engine; QQmlEnginePrivate *qenginepriv = QQmlEnginePrivate::get(engine->qmlEngine()); @@ -382,4 +391,24 @@ ReturnedValue QmlTypeWrapper::instanceOf(const Object *typeObject, const Value & return QV4::Encode(QQmlMetaObject::canConvert(theirType, myQmlType)); } +ReturnedValue QQmlScopedEnumWrapper::get(const Managed *m, String *name, bool *hasProperty) +{ + Q_ASSERT(m->as<QQmlScopedEnumWrapper>()); + const QQmlScopedEnumWrapper *resource = static_cast<const QQmlScopedEnumWrapper *>(m); + QV4::ExecutionEngine *v4 = resource->engine(); + QV4::Scope scope(v4); + + QQmlType *type = resource->d()->type; + int index = resource->d()->scopeEnumIndex; + + bool ok = false; + int value = type->scopedEnumValue(QQmlEnginePrivate::get(v4->qmlEngine()), index, name, &ok); + if (hasProperty) + *hasProperty = ok; + if (ok) + return QV4::Primitive::fromInt32(value).asReturnedValue(); + + return Encode::undefined(); +} + QT_END_NAMESPACE diff --git a/src/qml/qml/qqmltypewrapper_p.h b/src/qml/qml/qqmltypewrapper_p.h index c584458ed4..730bfd6d12 100644 --- a/src/qml/qml/qqmltypewrapper_p.h +++ b/src/qml/qml/qqmltypewrapper_p.h @@ -65,7 +65,7 @@ namespace QV4 { namespace Heap { -struct QmlTypeWrapper : Object { +struct QQmlTypeWrapper : Object { enum TypeNameMode { IncludeEnums, ExcludeEnums @@ -81,11 +81,18 @@ struct QmlTypeWrapper : Object { const void *importNamespace; }; +struct QQmlScopedEnumWrapper : Object { + void init() { Object::init(); } + void destroy() { Object::destroy(); } + int scopeEnumIndex; + QQmlType *type; +}; + } -struct Q_QML_EXPORT QmlTypeWrapper : Object +struct Q_QML_EXPORT QQmlTypeWrapper : Object { - V4_OBJECT2(QmlTypeWrapper, Object) + V4_OBJECT2(QQmlTypeWrapper, Object) V4_NEEDS_DESTROY bool isSingleton() const; @@ -94,9 +101,9 @@ struct Q_QML_EXPORT QmlTypeWrapper : Object QVariant toVariant() const; static ReturnedValue create(ExecutionEngine *, QObject *, QQmlType *, - Heap::QmlTypeWrapper::TypeNameMode = Heap::QmlTypeWrapper::IncludeEnums); + Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums); static ReturnedValue create(ExecutionEngine *, QObject *, QQmlTypeNameCache *, const void *, - Heap::QmlTypeWrapper::TypeNameMode = Heap::QmlTypeWrapper::IncludeEnums); + Heap::QQmlTypeWrapper::TypeNameMode = Heap::QQmlTypeWrapper::IncludeEnums); static ReturnedValue get(const Managed *m, String *name, bool *hasProperty); @@ -106,6 +113,14 @@ struct Q_QML_EXPORT QmlTypeWrapper : Object static ReturnedValue instanceOf(const Object *typeObject, const Value &var); }; +struct Q_QML_EXPORT QQmlScopedEnumWrapper : Object +{ + V4_OBJECT2(QQmlScopedEnumWrapper, Object) + V4_NEEDS_DESTROY + + static ReturnedValue get(const Managed *m, String *name, bool *hasProperty); +}; + } QT_END_NAMESPACE diff --git a/src/qml/qml/qqmlvaluetype.cpp b/src/qml/qml/qqmlvaluetype.cpp index bcefad0ee3..520f512b1a 100644 --- a/src/qml/qml/qqmlvaluetype.cpp +++ b/src/qml/qml/qqmlvaluetype.cpp @@ -566,3 +566,5 @@ QVariantList QQmlEasingValueType::bezierCurve() const } QT_END_NAMESPACE + +#include "moc_qqmlvaluetype_p.cpp" diff --git a/src/qml/qtqmlglobal.h b/src/qml/qtqmlglobal.h index 89228b7777..6704e55b52 100644 --- a/src/qml/qtqmlglobal.h +++ b/src/qml/qtqmlglobal.h @@ -48,7 +48,11 @@ QT_BEGIN_NAMESPACE -#ifndef QT_STATIC +#if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB) +# define QT_QML_BOOTSTRAPPED +#endif + +#if !defined(QT_QML_BOOTSTRAPPED) && !defined(QT_STATIC) # if defined(QT_BUILD_QML_LIB) # define Q_QML_EXPORT Q_DECL_EXPORT # else diff --git a/src/qml/qtqmlglobal_p.h b/src/qml/qtqmlglobal_p.h index 026be5a703..6547274d09 100644 --- a/src/qml/qtqmlglobal_p.h +++ b/src/qml/qtqmlglobal_p.h @@ -63,7 +63,7 @@ Q_ALLOCA_DECLARE(type, name); \ Q_ALLOCA_ASSIGN(type, name, size) -#if QT_CONFIG(alloca) +#if defined(QT_BOOTSTRAPPED) || QT_CONFIG(alloca) #define Q_ALLOCA_DECLARE(type, name) \ type *name = 0 @@ -95,10 +95,6 @@ QT_END_NAMESPACE #endif -#if defined(QT_BUILD_QMLDEVTOOLS_LIB) || defined(QT_QMLDEVTOOLS_LIB) -# define Q_QML_PRIVATE_EXPORT -#else -# define Q_QML_PRIVATE_EXPORT Q_QML_EXPORT -#endif +#define Q_QML_PRIVATE_EXPORT Q_QML_EXPORT #endif // QTQMLGLOBAL_P_H diff --git a/src/qml/types/qqmlbind.cpp b/src/qml/types/qqmlbind.cpp index 2ded9c13c8..da644becc2 100644 --- a/src/qml/types/qqmlbind.cpp +++ b/src/qml/types/qqmlbind.cpp @@ -386,3 +386,5 @@ void QQmlBind::eval() } QT_END_NAMESPACE + +#include "moc_qqmlbind_p.cpp" diff --git a/src/qml/types/qqmlconnections.cpp b/src/qml/types/qqmlconnections.cpp index 870aeaa6e2..6e9cb5f1fe 100644 --- a/src/qml/types/qqmlconnections.cpp +++ b/src/qml/types/qqmlconnections.cpp @@ -235,14 +235,13 @@ void QQmlConnectionsParser::verifyBindings(const QV4::CompiledData::Unit *qmlUni { for (int ii = 0; ii < props.count(); ++ii) { const QV4::CompiledData::Binding *binding = props.at(ii); - QString propName = qmlUnit->stringAt(binding->propertyNameIndex); + const QString &propName = qmlUnit->stringAt(binding->propertyNameIndex); - if (!propName.startsWith(QLatin1String("on")) || !propName.at(2).isUpper()) { + if (!propName.startsWith(QLatin1String("on")) || (propName.length() < 3 || !propName.at(2).isUpper())) { error(props.at(ii), QQmlConnections::tr("Cannot assign to non-existent property \"%1\"").arg(propName)); return; } - if (binding->type >= QV4::CompiledData::Binding::Type_Object) { const QV4::CompiledData::Object *target = qmlUnit->objectAt(binding->value.objectIndex); if (!qmlUnit->stringAt(target->inheritedTypeNameIndex).isEmpty()) @@ -314,3 +313,5 @@ void QQmlConnections::componentComplete() } QT_END_NAMESPACE + +#include "moc_qqmlconnections_p.cpp" diff --git a/src/qml/types/qqmldelegatemodel.cpp b/src/qml/types/qqmldelegatemodel.cpp index f26e5f6cdb..9620df6af9 100644 --- a/src/qml/types/qqmldelegatemodel.cpp +++ b/src/qml/types/qqmldelegatemodel.cpp @@ -988,7 +988,9 @@ QObject *QQmlDelegateModelPrivate::object(Compositor::Group group, int index, bo } } - cacheItem->incubateObject( + QQmlComponentPrivate *cp = QQmlComponentPrivate::get(m_delegate); + cp->incubateObject( + cacheItem->incubationTask, m_delegate, m_context->engine(), ctxt, @@ -1935,30 +1937,6 @@ void QQmlDelegateModelItem::Dispose() delete this; } -/* - This is essentially a copy of QQmlComponent::create(); except it takes the QQmlContextData - arguments instead of QQmlContext which means we don't have to construct the rather weighty - wrapper class for every delegate item. -*/ -void QQmlDelegateModelItem::incubateObject( - QQmlComponent *component, - QQmlEngine *engine, - QQmlContextData *context, - QQmlContextData *forContext) -{ - QQmlIncubatorPrivate *incubatorPriv = QQmlIncubatorPrivate::get(incubationTask); - QQmlEnginePrivate *enginePriv = QQmlEnginePrivate::get(engine); - QQmlComponentPrivate *componentPriv = QQmlComponentPrivate::get(component); - - incubatorPriv->compilationUnit = componentPriv->compilationUnit; - incubatorPriv->compilationUnit->addref(); - incubatorPriv->enginePriv = enginePriv; - incubatorPriv->creator.reset(new QQmlObjectCreator(context, componentPriv->compilationUnit, componentPriv->creationContext)); - incubatorPriv->subComponentToCreate = componentPriv->start; - - enginePriv->incubate(*incubationTask, forContext); -} - void QQmlDelegateModelItem::destroyObject() { Q_ASSERT(object); @@ -3346,3 +3324,5 @@ QV4::ReturnedValue QQmlDelegateModelEngineData::array(QV8Engine *engine, const Q } QT_END_NAMESPACE + +#include "moc_qqmldelegatemodel_p.cpp" diff --git a/src/qml/types/qqmldelegatemodel_p_p.h b/src/qml/types/qqmldelegatemodel_p_p.h index cb4a1f79ba..4ebfd9b938 100644 --- a/src/qml/types/qqmldelegatemodel_p_p.h +++ b/src/qml/types/qqmldelegatemodel_p_p.h @@ -112,11 +112,6 @@ public: QObject *modelObject() { return this; } - void incubateObject( - QQmlComponent *component, - QQmlEngine *engine, - QQmlContextData *context, - QQmlContextData *forContext); void destroyObject(); static QQmlDelegateModelItem *dataForObject(QObject *object); diff --git a/src/qml/types/qqmllistmodel.cpp b/src/qml/types/qqmllistmodel.cpp index efc2828dc5..eebf0f74d8 100644 --- a/src/qml/types/qqmllistmodel.cpp +++ b/src/qml/types/qqmllistmodel.cpp @@ -359,7 +359,7 @@ int ListModel::appendElement() void ListModel::insertElement(int index) { newElement(index); - updateCacheIndices(); + updateCacheIndices(index); } void ListModel::move(int from, int to, int n) @@ -381,7 +381,7 @@ void ListModel::move(int from, int to, int n) for (int i=0 ; i < store.count() ; ++i) elements[from+i] = store[i]; - updateCacheIndices(); + updateCacheIndices(from, to + n); } void ListModel::newElement(int index) @@ -390,9 +390,14 @@ void ListModel::newElement(int index) elements.insert(index, e); } -void ListModel::updateCacheIndices() +void ListModel::updateCacheIndices(int start, int end) { - for (int i=0 ; i < elements.count() ; ++i) { + int count = elements.count(); + + if (end < 0 || end > count) + end = count; + + for (int i = start; i < end; ++i) { ListElement *e = elements.at(i); if (ModelNodeMetaObject *mo = e->objectCache()) mo->m_elementIndex = i; @@ -574,7 +579,7 @@ void ListModel::remove(int index, int count) delete elements[index+i]; } elements.remove(index, count); - updateCacheIndices(); + updateCacheIndices(index); } void ListModel::insert(int elementIndex, QV4::Object *object) @@ -2606,3 +2611,5 @@ bool QQmlListModelParser::definesEmptyList(const QString &s) */ QT_END_NAMESPACE + +#include "moc_qqmllistmodel_p.cpp" diff --git a/src/qml/types/qqmllistmodel_p_p.h b/src/qml/types/qqmllistmodel_p_p.h index 44583df2a6..e2653c220d 100644 --- a/src/qml/types/qqmllistmodel_p_p.h +++ b/src/qml/types/qqmllistmodel_p_p.h @@ -397,7 +397,7 @@ private: void newElement(int index); - void updateCacheIndices(); + void updateCacheIndices(int start = 0, int end = -1); friend class ListElement; friend class QQmlListModelWorkerAgent; diff --git a/src/qml/types/qqmllistmodelworkeragent.cpp b/src/qml/types/qqmllistmodelworkeragent.cpp index 963459cc55..0a5adbf292 100644 --- a/src/qml/types/qqmllistmodelworkeragent.cpp +++ b/src/qml/types/qqmllistmodelworkeragent.cpp @@ -253,3 +253,4 @@ bool QQmlListModelWorkerAgent::event(QEvent *e) QT_END_NAMESPACE +#include "moc_qqmllistmodelworkeragent_p.cpp" diff --git a/src/qml/types/qqmlmodelindexvaluetype.cpp b/src/qml/types/qqmlmodelindexvaluetype.cpp index 0b05210ce5..cbf2fef348 100644 --- a/src/qml/types/qqmlmodelindexvaluetype.cpp +++ b/src/qml/types/qqmlmodelindexvaluetype.cpp @@ -64,3 +64,5 @@ QString QQmlItemSelectionRangeValueType::toString() const } QT_END_NAMESPACE + +#include "moc_qqmlmodelindexvaluetype_p.cpp" diff --git a/src/qml/types/qqmlobjectmodel.cpp b/src/qml/types/qqmlobjectmodel.cpp index d926ecb6ce..2814b9d38f 100644 --- a/src/qml/types/qqmlobjectmodel.cpp +++ b/src/qml/types/qqmlobjectmodel.cpp @@ -439,3 +439,5 @@ void QQmlObjectModel::clear() } QT_END_NAMESPACE + +#include "moc_qqmlobjectmodel_p.cpp" diff --git a/src/qml/types/qqmltimer.cpp b/src/qml/types/qqmltimer.cpp index 7efdac4c22..2037c4f6cd 100644 --- a/src/qml/types/qqmltimer.cpp +++ b/src/qml/types/qqmltimer.cpp @@ -355,3 +355,5 @@ void QQmlTimerPrivate::animationFinished(QAbstractAnimationJob *) } QT_END_NAMESPACE + +#include "moc_qqmltimer_p.cpp" diff --git a/src/qml/types/qquickpackage.cpp b/src/qml/types/qquickpackage.cpp index 17eff5ac40..e0d1888f33 100644 --- a/src/qml/types/qquickpackage.cpp +++ b/src/qml/types/qquickpackage.cpp @@ -194,3 +194,5 @@ QQuickPackageAttached *QQuickPackage::qmlAttachedProperties(QObject *o) QT_END_NAMESPACE + +#include "moc_qquickpackage_p.cpp" diff --git a/src/qml/types/qquickworkerscript.cpp b/src/qml/types/qquickworkerscript.cpp index f35e17c34d..6159355afc 100644 --- a/src/qml/types/qquickworkerscript.cpp +++ b/src/qml/types/qquickworkerscript.cpp @@ -758,3 +758,4 @@ QT_END_NAMESPACE #include <qquickworkerscript.moc> +#include "moc_qquickworkerscript_p.cpp" diff --git a/src/qmldebug/qqmldebugconnection.cpp b/src/qmldebug/qqmldebugconnection.cpp index b5db71557f..73ccd7c854 100644 --- a/src/qmldebug/qqmldebugconnection.cpp +++ b/src/qmldebug/qqmldebugconnection.cpp @@ -467,3 +467,5 @@ void QQmlDebugConnectionPrivate::createProtocol() QT_END_NAMESPACE #include <qqmldebugconnection.moc> + +#include "moc_qqmldebugconnection_p.cpp" diff --git a/src/qmldebug/qqmlenginecontrolclient.cpp b/src/qmldebug/qqmlenginecontrolclient.cpp index c95ae5c6ee..3f75298e51 100644 --- a/src/qmldebug/qqmlenginecontrolclient.cpp +++ b/src/qmldebug/qqmlenginecontrolclient.cpp @@ -151,3 +151,5 @@ void QQmlEngineControlClientPrivate::sendCommand( } QT_END_NAMESPACE + +#include "moc_qqmlenginecontrolclient_p.cpp" diff --git a/src/qmldebug/qqmlprofilerclient.cpp b/src/qmldebug/qqmlprofilerclient.cpp index 29ccbb33b6..3676bd933c 100644 --- a/src/qmldebug/qqmlprofilerclient.cpp +++ b/src/qmldebug/qqmlprofilerclient.cpp @@ -375,3 +375,5 @@ void QQmlProfilerClient::messageReceived(const QByteArray &data) unknownData(stream); } QT_END_NAMESPACE + +#include "moc_qqmlprofilerclient_p.cpp" diff --git a/src/qmldevtools/qmldevtools.pro b/src/qmldevtools/qmldevtools.pro index ec5d73044f..a21988b915 100644 --- a/src/qmldevtools/qmldevtools.pro +++ b/src/qmldevtools/qmldevtools.pro @@ -1,11 +1,9 @@ option(host_build) TARGET = QtQmlDevTools QT = core-private -CONFIG += static internal_module qmldevtools_build +CONFIG += minimal_syncqt internal_module qmldevtools_build -# Don't use pch because the auto-generated header refers to QtBootstrap, -# which doesn't exist -CONFIG -= precompile_header +MODULE_INCNAME = QtQml # 2415: variable "xx" of static storage duration was declared but never referenced # unused variable 'xx' [-Werror,-Wunused-const-variable] diff --git a/src/qmldevtools/qtqmldevtoolsglobal_p.h b/src/qmldevtools/qtqmldevtoolsglobal_p.h deleted file mode 100644 index 5cb8a9275a..0000000000 --- a/src/qmldevtools/qtqmldevtoolsglobal_p.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2016 The Qt Company Ltd. -** Contact: https://www.qt.io/licensing/ -** -** This file is part of the QtQml module of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL$ -** Commercial License Usage -** Licensees holding valid commercial Qt licenses may use this file in -** accordance with the commercial license agreement provided with the -** Software or, alternatively, in accordance with the terms contained in -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see https://www.qt.io/terms-conditions. For further -** information use the contact form at https://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 3 as published by the Free Software -** Foundation and appearing in the file LICENSE.LGPL3 included in the -** packaging of this file. Please review the following information to -** ensure the GNU Lesser General Public License version 3 requirements -** will be met: https://www.gnu.org/licenses/lgpl-3.0.html. -** -** GNU General Public License Usage -** Alternatively, this file may be used under the terms of the GNU -** General Public License version 2.0 or (at your option) the GNU General -** Public license version 3 or any later version approved by the KDE Free -** Qt Foundation. The licenses are as published by the Free Software -** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 -** included in the packaging of this file. Please review the following -** information to ensure the GNU General Public License requirements will -** be met: https://www.gnu.org/licenses/gpl-2.0.html and -** https://www.gnu.org/licenses/gpl-3.0.html. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -#ifndef QTQMLGLOBAL_P_H -#define QTQMLGLOBAL_P_H - -// -// W A R N I N G -// ------------- -// -// This file is not part of the Qt API. It exists purely as an -// implementation detail. This header file may change from version to -// version without notice, or even be removed. -// -// We mean it. -// - -#include <QtCore/qglobal.h> - -// All host systems are assumed to have alloca(). -#define Q_ALLOCA_VAR(type, name, size) \ - type *name = static_cast<type*>(alloca(size)) - -QT_BEGIN_NAMESPACE - -#define Q_QML_EXPORT -#define Q_QML_PRIVATE_EXPORT - -/* Some classes built into QtQmlDevTools are marked Q_AUTOTEST_EXPORT but we - have nothing to export in this static library */ -#if defined(Q_AUTOTEST_EXPORT) -#undef Q_AUTOTEST_EXPORT -#endif -#define Q_AUTOTEST_EXPORT - -QT_END_NAMESPACE -#endif // QTQMLGLOBAL_P_H diff --git a/src/qmltest/quicktestresult.cpp b/src/qmltest/quicktestresult.cpp index 02d925d37d..dc6caf505b 100644 --- a/src/qmltest/quicktestresult.cpp +++ b/src/qmltest/quicktestresult.cpp @@ -759,5 +759,6 @@ int QuickTestResult::exitCode() } #include "quicktestresult.moc" +#include "moc_quicktestresult_p.cpp" QT_END_NAMESPACE diff --git a/src/quick/accessible/qaccessiblequickitem.cpp b/src/quick/accessible/qaccessiblequickitem.cpp index fbde5d354d..2d6bb02af4 100644 --- a/src/quick/accessible/qaccessiblequickitem.cpp +++ b/src/quick/accessible/qaccessiblequickitem.cpp @@ -142,9 +142,6 @@ QAccessibleInterface *QAccessibleQuickItem::child(int index) const return 0; QQuickItem *child = children.at(index); - if (!child) // FIXME can this happen? - return 0; - return QAccessible::queryAccessibleInterface(child); } diff --git a/src/quick/designer/qquickdesignercustomparserobject.cpp b/src/quick/designer/qquickdesignercustomparserobject.cpp index b785abe361..9145b1367a 100644 --- a/src/quick/designer/qquickdesignercustomparserobject.cpp +++ b/src/quick/designer/qquickdesignercustomparserobject.cpp @@ -57,3 +57,5 @@ void QQuickDesignerCustomParser::applyBindings(QObject *, QV4::CompiledData::Com } QT_END_NAMESPACE + +#include "moc_qquickdesignercustomparserobject_p.cpp" diff --git a/src/quick/designer/qquickdesignersupport.cpp b/src/quick/designer/qquickdesignersupport.cpp index 749ece8221..88971e3172 100644 --- a/src/quick/designer/qquickdesignersupport.cpp +++ b/src/quick/designer/qquickdesignersupport.cpp @@ -90,10 +90,11 @@ void QQuickDesignerSupport::refFromEffectItem(QQuickItem *referencedItem, bool h QSGRenderContext *rc = QQuickWindowPrivate::get(referencedItem->window())->context; QSGLayer *texture = rc->sceneGraphContext()->createLayer(rc); + QSizeF itemSize = referencedItem->size(); texture->setLive(true); texture->setItem(QQuickItemPrivate::get(referencedItem)->rootNode()); - texture->setRect(referencedItem->boundingRect()); - texture->setSize(referencedItem->boundingRect().size().toSize()); + texture->setRect(QRectF(QPointF(0, 0), itemSize)); + texture->setSize(itemSize.toSize()); texture->setRecursive(true); #if QT_CONFIG(opengl) #ifndef QT_OPENGL_ES diff --git a/src/quick/designer/qquickdesignerwindowmanager.cpp b/src/quick/designer/qquickdesignerwindowmanager.cpp index e2d7b98c33..093559a572 100644 --- a/src/quick/designer/qquickdesignerwindowmanager.cpp +++ b/src/quick/designer/qquickdesignerwindowmanager.cpp @@ -115,3 +115,4 @@ void QQuickDesignerWindowManager::update(QQuickWindow *window) QT_END_NAMESPACE +#include "moc_qquickdesignerwindowmanager_p.cpp" diff --git a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc index d80c72e0f1..76f863d07f 100644 --- a/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc +++ b/src/quick/doc/src/concepts/visualcanvas/adaptations.qdoc @@ -96,8 +96,7 @@ The OpenVG adaptation is an alternative renderer for \l {Qt Quick} 2 that will renderer the contents of the scene graph using OpenVG commands to provide hardware-acclerated 2D vector and raster graphics. The details for this adaptation are available here: -\l{qtquick-visualcanvas-scenegraph-openvg.html}{OpenVG Adaptation} - +\l{qtquick-visualcanvas-adaptations-openvg.html}{OpenVG Adaptation} */ diff --git a/src/quick/items/context2d/qquickcanvascontext.cpp b/src/quick/items/context2d/qquickcanvascontext.cpp index 300f0489f4..1d61cacb7c 100644 --- a/src/quick/items/context2d/qquickcanvascontext.cpp +++ b/src/quick/items/context2d/qquickcanvascontext.cpp @@ -68,3 +68,4 @@ void QQuickCanvasContext::flush() QT_END_NAMESPACE +#include "moc_qquickcanvascontext_p.cpp" diff --git a/src/quick/items/context2d/qquickcanvasitem.cpp b/src/quick/items/context2d/qquickcanvasitem.cpp index dab35f2a54..670dc6d032 100644 --- a/src/quick/items/context2d/qquickcanvasitem.cpp +++ b/src/quick/items/context2d/qquickcanvasitem.cpp @@ -640,6 +640,10 @@ void QQuickCanvasItem::releaseResources() QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider); d->textureProvider = 0; } + if (d->nodeTexture) { + QQuickWindowQObjectCleanupJob::schedule(window(), d->nodeTexture); + d->nodeTexture = 0; + } } bool QQuickCanvasItem::event(QEvent *event) @@ -662,6 +666,8 @@ void QQuickCanvasItem::invalidateSceneGraph() d->node = 0; // managed by the scene graph, just reset the pointer delete d->textureProvider; d->textureProvider = 0; + delete d->nodeTexture; + d->nodeTexture = 0; } void QQuickCanvasItem::schedulePolish() @@ -889,7 +895,7 @@ void QQuickCanvasItem::getContext(QQmlV4Function *args) } /*! - \qmlmethod long QtQuick::Canvas::requestAnimationFrame(callback) + \qmlmethod int QtQuick::Canvas::requestAnimationFrame(callback) This function schedules callback to be invoked before composing the Qt Quick scene. @@ -919,7 +925,7 @@ void QQuickCanvasItem::requestAnimationFrame(QQmlV4Function *args) } /*! - \qmlmethod QtQuick::Canvas::cancelRequestAnimationFrame(long handle) + \qmlmethod QtQuick::Canvas::cancelRequestAnimationFrame(int handle) This function will cancel the animation callback referenced by \a handle. */ @@ -1246,3 +1252,5 @@ QRect QQuickCanvasItem::tiledRect(const QRectF &window, const QSize &tileSize) */ QT_END_NAMESPACE + +#include "moc_qquickcanvasitem_p.cpp" diff --git a/src/quick/items/context2d/qquickcontext2d.cpp b/src/quick/items/context2d/qquickcontext2d.cpp index 1a6f530bfa..ebfa6deb6f 100644 --- a/src/quick/items/context2d/qquickcontext2d.cpp +++ b/src/quick/items/context2d/qquickcontext2d.cpp @@ -4324,3 +4324,5 @@ void QQuickContext2D::setV4Engine(QV4::ExecutionEngine *engine) } QT_END_NAMESPACE + +#include "moc_qquickcontext2d_p.cpp" diff --git a/src/quick/items/context2d/qquickcontext2dtexture.cpp b/src/quick/items/context2d/qquickcontext2dtexture.cpp index d90f527486..df6dd9dba2 100644 --- a/src/quick/items/context2d/qquickcontext2dtexture.cpp +++ b/src/quick/items/context2d/qquickcontext2dtexture.cpp @@ -751,3 +751,5 @@ void QQuickContext2DImageTexture::compositeTile(QQuickContext2DTile* tile) } QT_END_NAMESPACE + +#include "moc_qquickcontext2dtexture_p.cpp" diff --git a/src/quick/items/qquickaccessibleattached.cpp b/src/quick/items/qquickaccessibleattached.cpp index 4e918802d1..c559ee8887 100644 --- a/src/quick/items/qquickaccessibleattached.cpp +++ b/src/quick/items/qquickaccessibleattached.cpp @@ -462,4 +462,6 @@ void QQuickAccessibleAttached::availableActions(QStringList *actions) const QT_END_NAMESPACE +#include "moc_qquickaccessibleattached_p.cpp" + #endif diff --git a/src/quick/items/qquickanimatedimage.cpp b/src/quick/items/qquickanimatedimage.cpp index 22ea4774be..adf460886a 100644 --- a/src/quick/items/qquickanimatedimage.cpp +++ b/src/quick/items/qquickanimatedimage.cpp @@ -491,3 +491,5 @@ void QQuickAnimatedImage::componentComplete() } QT_END_NAMESPACE + +#include "moc_qquickanimatedimage_p.cpp" diff --git a/src/quick/items/qquickanimatedsprite.cpp b/src/quick/items/qquickanimatedsprite.cpp index 76c2146ddb..4e71b0c65f 100644 --- a/src/quick/items/qquickanimatedsprite.cpp +++ b/src/quick/items/qquickanimatedsprite.cpp @@ -815,3 +815,5 @@ void QQuickAnimatedSprite::prepareNextFrame(QSGSpriteNode *node) } QT_END_NAMESPACE + +#include "moc_qquickanimatedsprite_p.cpp" diff --git a/src/quick/items/qquickborderimage.cpp b/src/quick/items/qquickborderimage.cpp index 28d834f9e2..75e3a3dbed 100644 --- a/src/quick/items/qquickborderimage.cpp +++ b/src/quick/items/qquickborderimage.cpp @@ -684,3 +684,5 @@ void QQuickBorderImage::pixmapChange() } QT_END_NAMESPACE + +#include "moc_qquickborderimage_p.cpp" diff --git a/src/quick/items/qquickdrag.cpp b/src/quick/items/qquickdrag.cpp index e5969eed7f..41847e5f01 100644 --- a/src/quick/items/qquickdrag.cpp +++ b/src/quick/items/qquickdrag.cpp @@ -995,4 +995,6 @@ QQuickDragAttached *QQuickDrag::qmlAttachedProperties(QObject *obj) QT_END_NAMESPACE +#include "moc_qquickdrag_p.cpp" + #endif // draganddrop diff --git a/src/quick/items/qquickdroparea.cpp b/src/quick/items/qquickdroparea.cpp index b314390915..c7606f90e1 100644 --- a/src/quick/items/qquickdroparea.cpp +++ b/src/quick/items/qquickdroparea.cpp @@ -618,4 +618,6 @@ void QQuickDropEvent::accept(QQmlV4Function *args) QT_END_NAMESPACE +#include "moc_qquickdroparea_p.cpp" + #endif // draganddrop diff --git a/src/quick/items/qquickflickable.cpp b/src/quick/items/qquickflickable.cpp index 40719c6324..a631512877 100644 --- a/src/quick/items/qquickflickable.cpp +++ b/src/quick/items/qquickflickable.cpp @@ -565,18 +565,6 @@ void QQuickFlickablePrivate::updateBeginningEnd() visibleArea->updateVisible(); } -/* -XXXTODO add docs describing moving, dragging, flicking properties, e.g. - -When the user starts dragging the Flickable, the dragging and moving properties -will be true. - -If the velocity is sufficient when the drag is ended, flicking may begin. - -The moving properties will remain true until all dragging and flicking -is finished. -*/ - /*! \qmlsignal QtQuick::Flickable::dragStarted() @@ -2801,3 +2789,5 @@ void QQuickFlickable::setBoundsMovement(BoundsMovement movement) } QT_END_NAMESPACE + +#include "moc_qquickflickable_p.cpp" diff --git a/src/quick/items/qquickflipable.cpp b/src/quick/items/qquickflipable.cpp index f452893528..a960cd8b80 100644 --- a/src/quick/items/qquickflipable.cpp +++ b/src/quick/items/qquickflipable.cpp @@ -314,3 +314,4 @@ void QQuickFlipablePrivate::setBackTransform() QT_END_NAMESPACE #include "qquickflipable.moc" +#include "moc_qquickflipable_p.cpp" diff --git a/src/quick/items/qquickfocusscope.cpp b/src/quick/items/qquickfocusscope.cpp index f6c3a4a58f..de4494a521 100644 --- a/src/quick/items/qquickfocusscope.cpp +++ b/src/quick/items/qquickfocusscope.cpp @@ -67,3 +67,5 @@ QQuickFocusScope::~QQuickFocusScope() } QT_END_NAMESPACE + +#include "moc_qquickfocusscope_p.cpp" diff --git a/src/quick/items/qquickframebufferobject.cpp b/src/quick/items/qquickframebufferobject.cpp index 18a6a58467..52b19d994c 100644 --- a/src/quick/items/qquickframebufferobject.cpp +++ b/src/quick/items/qquickframebufferobject.cpp @@ -536,5 +536,6 @@ void QQuickFramebufferObject::Renderer::update() #include "qquickframebufferobject.moc" +#include "moc_qquickframebufferobject.cpp" QT_END_NAMESPACE diff --git a/src/quick/items/qquickgenericshadereffect.cpp b/src/quick/items/qquickgenericshadereffect.cpp index 2f8d71fc11..b366071962 100644 --- a/src/quick/items/qquickgenericshadereffect.cpp +++ b/src/quick/items/qquickgenericshadereffect.cpp @@ -656,3 +656,5 @@ void QQuickGenericShaderEffect::markGeometryDirtyAndUpdateIfSupportsAtlas() } QT_END_NAMESPACE + +#include "moc_qquickgenericshadereffect_p.cpp" diff --git a/src/quick/items/qquickgraphicsinfo.cpp b/src/quick/items/qquickgraphicsinfo.cpp index f735f17a4d..a36133874b 100644 --- a/src/quick/items/qquickgraphicsinfo.cpp +++ b/src/quick/items/qquickgraphicsinfo.cpp @@ -301,3 +301,5 @@ void QQuickGraphicsInfo::setWindow(QQuickWindow *window) } QT_END_NAMESPACE + +#include "moc_qquickgraphicsinfo_p.cpp" diff --git a/src/quick/items/qquickgridview.cpp b/src/quick/items/qquickgridview.cpp index e6a7a0acd0..fd78c46a16 100644 --- a/src/quick/items/qquickgridview.cpp +++ b/src/quick/items/qquickgridview.cpp @@ -2658,3 +2658,5 @@ QQuickGridViewAttached *QQuickGridView::qmlAttachedProperties(QObject *obj) } QT_END_NAMESPACE + +#include "moc_qquickgridview_p.cpp" diff --git a/src/quick/items/qquickimage.cpp b/src/quick/items/qquickimage.cpp index bf982117e8..7e13e5e0e1 100644 --- a/src/quick/items/qquickimage.cpp +++ b/src/quick/items/qquickimage.cpp @@ -87,6 +87,7 @@ public: }; #include "qquickimage.moc" +#include "moc_qquickimage_p.cpp" QQuickImagePrivate::QQuickImagePrivate() : fillMode(QQuickImage::Stretch) diff --git a/src/quick/items/qquickimagebase.cpp b/src/quick/items/qquickimagebase.cpp index 33d69f5032..74ee859f77 100644 --- a/src/quick/items/qquickimagebase.cpp +++ b/src/quick/items/qquickimagebase.cpp @@ -328,18 +328,18 @@ void QQuickImageBase::requestProgress(qint64 received, qint64 total) void QQuickImageBase::itemChange(ItemChange change, const ItemChangeData &value) { - if (change == ItemSceneChange && value.window) - connect(value.window, &QQuickWindow::screenChanged, this, &QQuickImageBase::handleScreenChanged); + Q_D(QQuickImageBase); + // If the screen DPI changed, reload image. + if (change == ItemDevicePixelRatioHasChanged && value.realValue != d->devicePixelRatio) { + // ### how can we get here with !qmlEngine(this)? that implies + // itemChange() on an item pending deletion, which seems strange. + if (qmlEngine(this) && isComponentComplete() && d->url.isValid()) { + load(); + } + } QQuickItem::itemChange(change, value); } -void QQuickImageBase::handleScreenChanged(QScreen* screen) -{ - // Screen DPI might have changed, reload images on screen change. - if (qmlEngine(this) && screen && isComponentComplete()) - load(); -} - void QQuickImageBase::componentComplete() { Q_D(QQuickImageBase); @@ -406,3 +406,5 @@ void QQuickImageBase::setAutoTransform(bool transform) } QT_END_NAMESPACE + +#include "moc_qquickimagebase_p.cpp" diff --git a/src/quick/items/qquickimagebase_p.h b/src/quick/items/qquickimagebase_p.h index 532f6ce683..54b1f789c9 100644 --- a/src/quick/items/qquickimagebase_p.h +++ b/src/quick/items/qquickimagebase_p.h @@ -123,7 +123,6 @@ protected: private Q_SLOTS: virtual void requestFinished(); void requestProgress(qint64,qint64); - void handleScreenChanged(QScreen *screen); private: Q_DISABLE_COPY(QQuickImageBase) diff --git a/src/quick/items/qquickimplicitsizeitem.cpp b/src/quick/items/qquickimplicitsizeitem.cpp index 08886329fd..1996fb9489 100644 --- a/src/quick/items/qquickimplicitsizeitem.cpp +++ b/src/quick/items/qquickimplicitsizeitem.cpp @@ -75,3 +75,5 @@ QQuickImplicitSizeItem::QQuickImplicitSizeItem(QQuickImplicitSizeItemPrivate &dd } QT_END_NAMESPACE + +#include "moc_qquickimplicitsizeitem_p.cpp" diff --git a/src/quick/items/qquickitem.cpp b/src/quick/items/qquickitem.cpp index ad3c46a8c9..bdf60e7ea0 100644 --- a/src/quick/items/qquickitem.cpp +++ b/src/quick/items/qquickitem.cpp @@ -164,7 +164,7 @@ void QQuickTransform::update() } QQuickContents::QQuickContents(QQuickItem *item) -: m_item(item), m_x(0), m_y(0), m_width(0), m_height(0) +: m_item(item) { } @@ -177,8 +177,8 @@ QQuickContents::~QQuickContents() bool QQuickContents::calcHeight(QQuickItem *changed) { - qreal oldy = m_y; - qreal oldheight = m_height; + qreal oldy = m_contents.y(); + qreal oldheight = m_contents.height(); if (changed) { qreal top = oldy; @@ -188,8 +188,8 @@ bool QQuickContents::calcHeight(QQuickItem *changed) bottom = y + changed->height(); if (y < top) top = y; - m_y = top; - m_height = bottom - top; + m_contents.setY(top); + m_contents.setHeight(bottom - top); } else { qreal top = std::numeric_limits<qreal>::max(); qreal bottom = -std::numeric_limits<qreal>::max(); @@ -202,17 +202,17 @@ bool QQuickContents::calcHeight(QQuickItem *changed) top = y; } if (!children.isEmpty()) - m_y = top; - m_height = qMax(bottom - top, qreal(0.0)); + m_contents.setY(top); + m_contents.setHeight(qMax(bottom - top, qreal(0.0))); } - return (m_height != oldheight || m_y != oldy); + return (m_contents.height() != oldheight || m_contents.y() != oldy); } bool QQuickContents::calcWidth(QQuickItem *changed) { - qreal oldx = m_x; - qreal oldwidth = m_width; + qreal oldx = m_contents.x(); + qreal oldwidth = m_contents.width(); if (changed) { qreal left = oldx; @@ -222,8 +222,8 @@ bool QQuickContents::calcWidth(QQuickItem *changed) right = x + changed->width(); if (x < left) left = x; - m_x = left; - m_width = right - left; + m_contents.setX(left); + m_contents.setWidth(right - left); } else { qreal left = std::numeric_limits<qreal>::max(); qreal right = -std::numeric_limits<qreal>::max(); @@ -236,11 +236,11 @@ bool QQuickContents::calcWidth(QQuickItem *changed) left = x; } if (!children.isEmpty()) - m_x = left; - m_width = qMax(right - left, qreal(0.0)); + m_contents.setX(left); + m_contents.setWidth(qMax(right - left, qreal(0.0))); } - return (m_width != oldwidth || m_x != oldx); + return (m_contents.width() != oldwidth || m_contents.x() != oldx); } void QQuickContents::complete() @@ -7237,6 +7237,8 @@ void QQuickItemPrivate::setHasCursorInChild(bool hasCursor) QQuickItemPrivate *parentPrivate = QQuickItemPrivate::get(parent); parentPrivate->setHasCursorInChild(hasCursor); } +#else + Q_UNUSED(hasCursor); #endif } @@ -8522,3 +8524,5 @@ quint64 QQuickItemPrivate::_q_createJSWrapper(QV4::ExecutionEngine *engine) QT_END_NAMESPACE #include <moc_qquickitem.cpp> + +#include "moc_qquickitem_p.cpp" diff --git a/src/quick/items/qquickitem_p.h b/src/quick/items/qquickitem_p.h index 6b010fc24d..069f0ee541 100644 --- a/src/quick/items/qquickitem_p.h +++ b/src/quick/items/qquickitem_p.h @@ -95,7 +95,7 @@ public: QQuickContents(QQuickItem *item); ~QQuickContents(); - QRectF rectF() const { return QRectF(m_x, m_y, m_width, m_height); } + QRectF rectF() const { return m_contents; } inline void calcGeometry(QQuickItem *changed = 0); void complete(); @@ -113,10 +113,7 @@ private: void updateRect(); QQuickItem *m_item; - qreal m_x; - qreal m_y; - qreal m_width; - qreal m_height; + QRectF m_contents; }; void QQuickContents::calcGeometry(QQuickItem *changed) diff --git a/src/quick/items/qquickitemanimation.cpp b/src/quick/items/qquickitemanimation.cpp index 874130b137..d4d346def9 100644 --- a/src/quick/items/qquickitemanimation.cpp +++ b/src/quick/items/qquickitemanimation.cpp @@ -1051,3 +1051,5 @@ QQuickPathAnimationAnimator::~QQuickPathAnimationAnimator() #endif // quick_path QT_END_NAMESPACE + +#include "moc_qquickitemanimation_p.cpp" diff --git a/src/quick/items/qquickitemgrabresult.cpp b/src/quick/items/qquickitemgrabresult.cpp index 12bcd43076..c3f8d4f024 100644 --- a/src/quick/items/qquickitemgrabresult.cpp +++ b/src/quick/items/qquickitemgrabresult.cpp @@ -415,3 +415,5 @@ bool QQuickItem::grabToImage(const QJSValue &callback, const QSize &targetSize) } QT_END_NAMESPACE + +#include "moc_qquickitemgrabresult.cpp" diff --git a/src/quick/items/qquickitemview.cpp b/src/quick/items/qquickitemview.cpp index a8bac633cc..555db03962 100644 --- a/src/quick/items/qquickitemview.cpp +++ b/src/quick/items/qquickitemview.cpp @@ -2507,3 +2507,5 @@ void QQuickItemViewPrivate::updateVisibleIndex() } QT_END_NAMESPACE + +#include "moc_qquickitemview_p.cpp" diff --git a/src/quick/items/qquickitemviewtransition.cpp b/src/quick/items/qquickitemviewtransition.cpp index 700c4cc620..04d93937eb 100644 --- a/src/quick/items/qquickitemviewtransition.cpp +++ b/src/quick/items/qquickitemviewtransition.cpp @@ -942,3 +942,5 @@ QQuickViewTransitionAttached *QQuickViewTransitionAttached::qmlAttachedPropertie } QT_END_NAMESPACE + +#include "moc_qquickitemviewtransition_p.cpp" diff --git a/src/quick/items/qquicklistview.cpp b/src/quick/items/qquicklistview.cpp index 0351077f20..f739115e6b 100644 --- a/src/quick/items/qquicklistview.cpp +++ b/src/quick/items/qquicklistview.cpp @@ -3442,3 +3442,5 @@ QQuickListViewAttached *QQuickListView::qmlAttachedProperties(QObject *obj) } QT_END_NAMESPACE + +#include "moc_qquicklistview_p.cpp" diff --git a/src/quick/items/qquickmousearea.cpp b/src/quick/items/qquickmousearea.cpp index c662efe40e..d8bad7d793 100644 --- a/src/quick/items/qquickmousearea.cpp +++ b/src/quick/items/qquickmousearea.cpp @@ -1429,3 +1429,5 @@ QSGNode *QQuickMouseArea::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData } QT_END_NAMESPACE + +#include "moc_qquickmousearea_p.cpp" diff --git a/src/quick/items/qquickmultipointtoucharea.cpp b/src/quick/items/qquickmultipointtoucharea.cpp index 9b2b4daa58..54136b1bbf 100644 --- a/src/quick/items/qquickmultipointtoucharea.cpp +++ b/src/quick/items/qquickmultipointtoucharea.cpp @@ -176,8 +176,6 @@ void QQuickTouchPoint::setVelocity(const QVector2D &velocity) It is deprecated because a touch point is more correctly modeled as an ellipse, whereas this rectangle represents the outer bounds of the ellipse after \l rotation. - - \sa horizontalDiameter, verticalDiameter */ void QQuickTouchPoint::setArea(const QRectF &area) { @@ -1009,3 +1007,5 @@ QSGNode *QQuickMultiPointTouchArea::updatePaintNode(QSGNode *oldNode, UpdatePain } QT_END_NAMESPACE + +#include "moc_qquickmultipointtoucharea_p.cpp" diff --git a/src/quick/items/qquickopenglinfo.cpp b/src/quick/items/qquickopenglinfo.cpp index 4bb13b84aa..7f5364031a 100644 --- a/src/quick/items/qquickopenglinfo.cpp +++ b/src/quick/items/qquickopenglinfo.cpp @@ -200,3 +200,5 @@ void QQuickOpenGLInfo::setWindow(QQuickWindow *window) } QT_END_NAMESPACE + +#include "moc_qquickopenglinfo_p.cpp" diff --git a/src/quick/items/qquickopenglshadereffect.cpp b/src/quick/items/qquickopenglshadereffect.cpp index 4f4c403483..4fcfe04b55 100644 --- a/src/quick/items/qquickopenglshadereffect.cpp +++ b/src/quick/items/qquickopenglshadereffect.cpp @@ -973,3 +973,5 @@ void QQuickOpenGLShaderEffect::handleItemChange(QQuickItem::ItemChange change, c } QT_END_NAMESPACE + +#include "moc_qquickopenglshadereffect_p.cpp" diff --git a/src/quick/items/qquickopenglshadereffectnode.cpp b/src/quick/items/qquickopenglshadereffectnode.cpp index 2d2cffbeed..e1ea98641d 100644 --- a/src/quick/items/qquickopenglshadereffectnode.cpp +++ b/src/quick/items/qquickopenglshadereffectnode.cpp @@ -510,5 +510,6 @@ void QQuickOpenGLShaderEffectNode::preprocess() } #include "qquickopenglshadereffectnode.moc" +#include "moc_qquickopenglshadereffectnode_p.cpp" QT_END_NAMESPACE diff --git a/src/quick/items/qquickpainteditem.cpp b/src/quick/items/qquickpainteditem.cpp index 3911bb0f28..34d71f00e8 100644 --- a/src/quick/items/qquickpainteditem.cpp +++ b/src/quick/items/qquickpainteditem.cpp @@ -683,3 +683,5 @@ void QQuickPaintedItem::itemChange(ItemChange change, const ItemChangeData &valu } QT_END_NAMESPACE + +#include "moc_qquickpainteditem.cpp" diff --git a/src/quick/items/qquickpathview.cpp b/src/quick/items/qquickpathview.cpp index 53e547fe98..aac2b0296a 100644 --- a/src/quick/items/qquickpathview.cpp +++ b/src/quick/items/qquickpathview.cpp @@ -2428,3 +2428,4 @@ QQuickPathViewAttached *QQuickPathView::qmlAttachedProperties(QObject *obj) QT_END_NAMESPACE +#include "moc_qquickpathview_p.cpp" diff --git a/src/quick/items/qquickpincharea.cpp b/src/quick/items/qquickpincharea.cpp index 171b98cd31..476acd3a3e 100644 --- a/src/quick/items/qquickpincharea.cpp +++ b/src/quick/items/qquickpincharea.cpp @@ -797,3 +797,4 @@ QQuickPinch *QQuickPinchArea::pinch() QT_END_NAMESPACE +#include "moc_qquickpincharea_p.cpp" diff --git a/src/quick/items/qquickpositioners.cpp b/src/quick/items/qquickpositioners.cpp index 05882d0464..e752e2538f 100644 --- a/src/quick/items/qquickpositioners.cpp +++ b/src/quick/items/qquickpositioners.cpp @@ -2215,3 +2215,5 @@ void QQuickFlow::reportConflictingAnchors() } QT_END_NAMESPACE + +#include "moc_qquickpositioners_p.cpp" diff --git a/src/quick/items/qquickrectangle.cpp b/src/quick/items/qquickrectangle.cpp index 7ba2421d62..0c532bcd4c 100644 --- a/src/quick/items/qquickrectangle.cpp +++ b/src/quick/items/qquickrectangle.cpp @@ -1,5 +1,6 @@ /**************************************************************************** ** +** Copyright (C) 2017 Crimson AS <info@crimson.no> ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** @@ -90,6 +91,7 @@ void QQuickPen::setWidth(qreal w) m_width = w; m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0)); + static_cast<QQuickItem*>(parent())->update(); emit penChanged(); } @@ -102,6 +104,7 @@ void QQuickPen::setColor(const QColor &c) { m_color = c; m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0)); + static_cast<QQuickItem*>(parent())->update(); emit penChanged(); } @@ -116,6 +119,7 @@ void QQuickPen::setPixelAligned(bool aligned) return; m_aligned = aligned; m_valid = m_color.alpha() && (qRound(m_width) >= 1 || (!m_aligned && m_width > 0)); + static_cast<QQuickItem*>(parent())->update(); emit penChanged(); } @@ -266,11 +270,9 @@ QGradientStops QQuickGradient::gradientStops() const void QQuickGradient::doUpdate() { - emit updated(); + static_cast<QQuickItem*>(parent())->update(); } -int QQuickRectanglePrivate::doUpdateSlotIdx = -1; - /*! \qmltype Rectangle \instantiates QQuickRectangle @@ -324,11 +326,6 @@ QQuickRectangle::QQuickRectangle(QQuickItem *parent) setFlag(ItemHasContents); } -void QQuickRectangle::doUpdate() -{ - update(); -} - /*! \qmlproperty bool QtQuick::Rectangle::antialiasing @@ -356,7 +353,11 @@ void QQuickRectangle::doUpdate() QQuickPen *QQuickRectangle::border() { Q_D(QQuickRectangle); - return d->getPen(); + if (!d->pen) { + d->pen = new QQuickPen; + QQml_setParent_noEvent(d->pen, this); + } + return d->pen; } /*! @@ -389,16 +390,7 @@ void QQuickRectangle::setGradient(QQuickGradient *gradient) Q_D(QQuickRectangle); if (d->gradient == gradient) return; - static int updatedSignalIdx = -1; - if (updatedSignalIdx < 0) - updatedSignalIdx = QMetaMethod::fromSignal(&QQuickGradient::updated).methodIndex(); - if (d->doUpdateSlotIdx < 0) - d->doUpdateSlotIdx = QQuickRectangle::staticMetaObject.indexOfSlot("doUpdate()"); - if (d->gradient) - QMetaObject::disconnect(d->gradient, updatedSignalIdx, this, d->doUpdateSlotIdx); d->gradient = gradient; - if (d->gradient) - QMetaObject::connect(d->gradient, updatedSignalIdx, this, d->doUpdateSlotIdx); update(); } @@ -511,3 +503,5 @@ QSGNode *QQuickRectangle::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData } QT_END_NAMESPACE + +#include "moc_qquickrectangle_p.cpp" diff --git a/src/quick/items/qquickrectangle_p.h b/src/quick/items/qquickrectangle_p.h index 724a06013c..627f778e44 100644 --- a/src/quick/items/qquickrectangle_p.h +++ b/src/quick/items/qquickrectangle_p.h @@ -129,9 +129,6 @@ public: QGradientStops gradientStops() const; -Q_SIGNALS: - void updated(); - private: void doUpdate(); @@ -172,9 +169,6 @@ Q_SIGNALS: protected: QSGNode *updatePaintNode(QSGNode *, UpdatePaintNodeData *) Q_DECL_OVERRIDE; -private Q_SLOTS: - void doUpdate(); - private: Q_DISABLE_COPY(QQuickRectangle) Q_DECLARE_PRIVATE(QQuickRectangle) diff --git a/src/quick/items/qquickrectangle_p_p.h b/src/quick/items/qquickrectangle_p_p.h index 50d5817951..e771beec87 100644 --- a/src/quick/items/qquickrectangle_p_p.h +++ b/src/quick/items/qquickrectangle_p_p.h @@ -70,28 +70,12 @@ public: ~QQuickRectanglePrivate() { - delete pen; } QColor color; QQuickGradient *gradient; QQuickPen *pen; qreal radius; - static int doUpdateSlotIdx; - - QQuickPen *getPen() { - if (!pen) { - Q_Q(QQuickRectangle); - pen = new QQuickPen; - static int penChangedSignalIdx = -1; - if (penChangedSignalIdx < 0) - penChangedSignalIdx = QMetaMethod::fromSignal(&QQuickPen::penChanged).methodIndex(); - if (doUpdateSlotIdx < 0) - doUpdateSlotIdx = QQuickRectangle::staticMetaObject.indexOfSlot("doUpdate()"); - QMetaObject::connect(pen, penChangedSignalIdx, q, doUpdateSlotIdx); - } - return pen; - } }; QT_END_NAMESPACE diff --git a/src/quick/items/qquickrendercontrol.cpp b/src/quick/items/qquickrendercontrol.cpp index e2a20f9e7e..f2828bbedd 100644 --- a/src/quick/items/qquickrendercontrol.cpp +++ b/src/quick/items/qquickrendercontrol.cpp @@ -457,3 +457,5 @@ QWindow *QQuickRenderControl::renderWindowFor(QQuickWindow *win, QPoint *offset) } QT_END_NAMESPACE + +#include "moc_qquickrendercontrol.cpp" diff --git a/src/quick/items/qquickrepeater.cpp b/src/quick/items/qquickrepeater.cpp index a7254464ed..9ad7d27b18 100644 --- a/src/quick/items/qquickrepeater.cpp +++ b/src/quick/items/qquickrepeater.cpp @@ -509,3 +509,5 @@ void QQuickRepeater::modelUpdated(const QQmlChangeSet &changeSet, bool reset) } QT_END_NAMESPACE + +#include "moc_qquickrepeater_p.cpp" diff --git a/src/quick/items/qquickscreen.cpp b/src/quick/items/qquickscreen.cpp index 20c6973ee1..9b54b7fba9 100644 --- a/src/quick/items/qquickscreen.cpp +++ b/src/quick/items/qquickscreen.cpp @@ -86,6 +86,20 @@ QT_BEGIN_NAMESPACE The name of the screen. */ /*! + \qmlattachedproperty int Screen::virtualX + \readonly + \since 5.9 + + The x coordinate of the screen within the virtual desktop. +*/ +/*! + \qmlattachedproperty int Screen::virtualY + \readonly + \since 5.9 + + The y coordinate of the screen within the virtual desktop. +*/ +/*! \qmlattachedproperty int Screen::width \readonly @@ -435,3 +449,5 @@ void QQuickScreenAttached::screenChanged(QScreen *screen) } QT_END_NAMESPACE + +#include "moc_qquickscreen_p.cpp" diff --git a/src/quick/items/qquickshadereffect.cpp b/src/quick/items/qquickshadereffect.cpp index d317c1d19b..a41e9324f3 100644 --- a/src/quick/items/qquickshadereffect.cpp +++ b/src/quick/items/qquickshadereffect.cpp @@ -881,3 +881,5 @@ bool QQuickShaderEffect::isOpenGLShaderEffect() const #endif QT_END_NAMESPACE + +#include "moc_qquickshadereffect_p.cpp" diff --git a/src/quick/items/qquickshadereffectmesh.cpp b/src/quick/items/qquickshadereffectmesh.cpp index d23b576d42..4ea976a272 100644 --- a/src/quick/items/qquickshadereffectmesh.cpp +++ b/src/quick/items/qquickshadereffectmesh.cpp @@ -434,3 +434,5 @@ void QQuickBorderImageMesh::setVerticalTileMode(TileMode t) } QT_END_NAMESPACE + +#include "moc_qquickshadereffectmesh_p.cpp" diff --git a/src/quick/items/qquickshadereffectsource.cpp b/src/quick/items/qquickshadereffectsource.cpp index c782ddb5f7..f61bad1179 100644 --- a/src/quick/items/qquickshadereffectsource.cpp +++ b/src/quick/items/qquickshadereffectsource.cpp @@ -796,5 +796,6 @@ void QQuickShaderEffectSource::itemChange(ItemChange change, const ItemChangeDat } #include "qquickshadereffectsource.moc" +#include "moc_qquickshadereffectsource_p.cpp" QT_END_NAMESPACE diff --git a/src/quick/items/qquicksprite.cpp b/src/quick/items/qquicksprite.cpp index 63d3180842..aae657b749 100644 --- a/src/quick/items/qquicksprite.cpp +++ b/src/quick/items/qquicksprite.cpp @@ -269,3 +269,5 @@ void QQuickSprite::startImageLoading() } QT_END_NAMESPACE + +#include "moc_qquicksprite_p.cpp" diff --git a/src/quick/items/qquickspriteengine.cpp b/src/quick/items/qquickspriteengine.cpp index d26a1f8a64..92b60a8e3a 100644 --- a/src/quick/items/qquickspriteengine.cpp +++ b/src/quick/items/qquickspriteengine.cpp @@ -773,3 +773,5 @@ void QQuickStochasticEngine::addToUpdateList(uint t, int idx) } QT_END_NAMESPACE + +#include "moc_qquickspriteengine_p.cpp" diff --git a/src/quick/items/qquickspritesequence.cpp b/src/quick/items/qquickspritesequence.cpp index 858a3c0576..ae466aa482 100644 --- a/src/quick/items/qquickspritesequence.cpp +++ b/src/quick/items/qquickspritesequence.cpp @@ -329,3 +329,5 @@ void QQuickSpriteSequence::prepareNextFrame(QSGSpriteNode *node) } QT_END_NAMESPACE + +#include "moc_qquickspritesequence_p.cpp" diff --git a/src/quick/items/qquicktext.cpp b/src/quick/items/qquicktext.cpp index 1720377046..09371db66d 100644 --- a/src/quick/items/qquicktext.cpp +++ b/src/quick/items/qquicktext.cpp @@ -274,15 +274,9 @@ void QQuickTextPrivate::updateLayout() elideLayout->clearFormats(); QString tmp = text; multilengthEos = tmp.indexOf(QLatin1Char('\x9c')); - if (multilengthEos != -1) { + if (multilengthEos != -1) tmp = tmp.mid(0, multilengthEos); - tmp.replace(QLatin1Char('\n'), QChar::LineSeparator); - } else if (tmp.contains(QLatin1Char('\n'))) { - // Replace always does a detach. Checking for the new line character first - // means iterating over those items again if found but prevents a realloc - // otherwise. - tmp.replace(QLatin1Char('\n'), QChar::LineSeparator); - } + tmp.replace(QLatin1Char('\n'), QChar::LineSeparator); layout.setText(tmp); } textHasChanged = false; @@ -365,8 +359,8 @@ void QQuickTextPrivate::updateSize() } if (!requireImplicitSize) { - emit q->implicitWidthChanged(); - emit q->implicitHeightChanged(); + implicitWidthChanged(); + implicitHeightChanged(); // if the implicitWidth is used, then updateSize() has already been called (recursively) if (requireImplicitSize) return; @@ -3062,3 +3056,5 @@ QJSValue QQuickText::fontInfo() const } QT_END_NAMESPACE + +#include "moc_qquicktext_p.cpp" diff --git a/src/quick/items/qquicktextcontrol.cpp b/src/quick/items/qquicktextcontrol.cpp index 2dce3e9ec8..2e23d69e5b 100644 --- a/src/quick/items/qquicktextcontrol.cpp +++ b/src/quick/items/qquicktextcontrol.cpp @@ -830,6 +830,9 @@ void QQuickTextControlPrivate::keyPressEvent(QKeyEvent *e) if (e == QKeySequence::SelectAll) { e->accept(); q->selectAll(); +#if QT_CONFIG(clipboard) + setClipboardSelection(); +#endif return; } #if QT_CONFIG(clipboard) @@ -955,6 +958,10 @@ process: accept: +#if QT_CONFIG(clipboard) + setClipboardSelection(); +#endif + e->accept(); cursorOn = true; diff --git a/src/quick/items/qquicktextdocument.cpp b/src/quick/items/qquicktextdocument.cpp index c272503480..5d2034defe 100644 --- a/src/quick/items/qquicktextdocument.cpp +++ b/src/quick/items/qquicktextdocument.cpp @@ -240,3 +240,6 @@ void QQuickTextDocumentWithImageResources::setText(const QString &text) QSet<QUrl> QQuickTextDocumentWithImageResources::errors; QT_END_NAMESPACE + +#include "moc_qquicktextdocument.cpp" +#include "moc_qquicktextdocument_p.cpp" diff --git a/src/quick/items/qquicktextedit.cpp b/src/quick/items/qquicktextedit.cpp index 075fd48a46..61d610520f 100644 --- a/src/quick/items/qquicktextedit.cpp +++ b/src/quick/items/qquicktextedit.cpp @@ -3056,3 +3056,5 @@ void QQuickTextEdit::clear() } QT_END_NAMESPACE + +#include "moc_qquicktextedit_p.cpp" diff --git a/src/quick/items/qquicktextinput.cpp b/src/quick/items/qquicktextinput.cpp index a023ad8a8c..a378359c95 100644 --- a/src/quick/items/qquicktextinput.cpp +++ b/src/quick/items/qquicktextinput.cpp @@ -3885,6 +3885,7 @@ void QQuickTextInputPrivate::parseInputMask(const QString &maskFields) break; case '\\': escape = true; + Q_FALLTHROUGH(); default: s = true; break; @@ -4403,7 +4404,9 @@ void QQuickTextInputPrivate::processKeyEvent(QKeyEvent* event) } bool unknown = false; +#if QT_CONFIG(shortcut) bool visual = cursorMoveStyle() == Qt::VisualMoveStyle; +#endif if (false) { } @@ -4776,3 +4779,4 @@ void QQuickTextInput::resetBottomPadding() QT_END_NAMESPACE +#include "moc_qquicktextinput_p.cpp" diff --git a/src/quick/items/qquicktextutil.cpp b/src/quick/items/qquicktextutil.cpp index b07289f4a3..6aa6c5cb4b 100644 --- a/src/quick/items/qquicktextutil.cpp +++ b/src/quick/items/qquicktextutil.cpp @@ -110,3 +110,5 @@ qreal QQuickTextUtil::alignedY(const qreal textHeight, const qreal itemHeight, i } QT_END_NAMESPACE + +#include "moc_qquicktextutil_p.cpp" diff --git a/src/quick/items/qquicktranslate.cpp b/src/quick/items/qquicktranslate.cpp index c4a3d458f8..9937c692a5 100644 --- a/src/quick/items/qquicktranslate.cpp +++ b/src/quick/items/qquicktranslate.cpp @@ -530,3 +530,5 @@ void QQuickMatrix4x4::applyTo(QMatrix4x4 *matrix) const } QT_END_NAMESPACE + +#include "moc_qquicktranslate_p.cpp" diff --git a/src/quick/items/qquickview.cpp b/src/quick/items/qquickview.cpp index d7171bf910..8313b53a7d 100644 --- a/src/quick/items/qquickview.cpp +++ b/src/quick/items/qquickview.cpp @@ -615,3 +615,5 @@ void QQuickView::mouseReleaseEvent(QMouseEvent *e) QT_END_NAMESPACE + +#include "moc_qquickview.cpp" diff --git a/src/quick/items/qquickwindow.cpp b/src/quick/items/qquickwindow.cpp index 9c9764005d..b536ae3804 100644 --- a/src/quick/items/qquickwindow.cpp +++ b/src/quick/items/qquickwindow.cpp @@ -170,6 +170,7 @@ private: }; #include "qquickwindow.moc" +#include "moc_qquickwindow_p.cpp" #if QT_CONFIG(accessibility) @@ -2918,6 +2919,8 @@ void QQuickWindowPrivate::contextCreationFailureMessage(const QSurfaceFormat &fo #endif // !Q_OS_WIN32 } +#if QT_DEPRECATED_SINCE(5, 8) + /*! Propagates an event \a e to a QQuickItem \a item on the window. @@ -2970,6 +2973,8 @@ bool QQuickWindow::sendEvent(QQuickItem *item, QEvent *e) return false; } +#endif + void QQuickWindowPrivate::cleanupNodes() { for (int ii = 0; ii < cleanupNodeList.count(); ++ii) @@ -4375,7 +4380,7 @@ void QQuickWindow::resetOpenGLState() \since 5.9 - \sa QWindow::setScreen(), QWindow::screen(), QScreen, Qt.application + \sa QWindow::setScreen(), QWindow::screen(), QScreen, {QtQml::Qt::application}{Qt.application} */ /*! @@ -4724,6 +4729,20 @@ void QQuickWindow::setSceneGraphBackend(const QString &backend) } /*! + Returns the requested Qt Quick scenegraph \a backend. + + \note The return value of this function may still be outdated by + subsequent calls to setSceneGraphBackend() until the first QQuickWindow in the + application has been constructed. + + \since 5.9 + */ +QString QQuickWindow::sceneGraphBackend() +{ + return QSGContext::backend(); +} + +/*! Creates a simple rectangle node. When the scenegraph is not initialized, the return value is null. This is cross-backend alternative to constructing a QSGSimpleRectNode directly. diff --git a/src/quick/items/qquickwindow.h b/src/quick/items/qquickwindow.h index 27a73988ae..d1a16fbeb6 100644 --- a/src/quick/items/qquickwindow.h +++ b/src/quick/items/qquickwindow.h @@ -112,7 +112,9 @@ public: QQuickItem *mouseGrabberItem() const; - bool sendEvent(QQuickItem *, QEvent *); +#if QT_DEPRECATED_SINCE(5, 8) + QT_DEPRECATED bool sendEvent(QQuickItem *, QEvent *); +#endif QImage grabWindow(); #if QT_CONFIG(opengl) @@ -162,6 +164,7 @@ public: static void setSceneGraphBackend(QSGRendererInterface::GraphicsApi api); static void setSceneGraphBackend(const QString &backend); + static QString sceneGraphBackend(); QSGRectangleNode *createRectangleNode() const; QSGImageNode *createImageNode() const; diff --git a/src/quick/items/qquickwindowattached.cpp b/src/quick/items/qquickwindowattached.cpp index c6380e2b9a..c8d71139ca 100644 --- a/src/quick/items/qquickwindowattached.cpp +++ b/src/quick/items/qquickwindowattached.cpp @@ -137,3 +137,5 @@ void QQuickWindowAttached::windowChange(QQuickWindow *window) } QT_END_NAMESPACE + +#include "moc_qquickwindowattached_p.cpp" diff --git a/src/quick/items/qquickwindowmodule.cpp b/src/quick/items/qquickwindowmodule.cpp index 6211b7802f..a5234d4f77 100644 --- a/src/quick/items/qquickwindowmodule.cpp +++ b/src/quick/items/qquickwindowmodule.cpp @@ -205,3 +205,5 @@ void QQuickWindowModule::defineModule() QT_END_NAMESPACE QML_DECLARE_TYPEINFO(QQuickWindowQmlImpl, QML_HAS_ATTACHED_PROPERTIES) + +#include "moc_qquickwindowmodule_p.cpp" diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp index d71b0c3e2a..aa850a80db 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarecontext.cpp @@ -222,3 +222,5 @@ void *QSGSoftwareContext::getResource(QQuickWindow *window, Resource resource) c } QT_END_NAMESPACE + +#include "moc_qsgsoftwarecontext_p.cpp" diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp index 7020283898..2954f591ad 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarelayer.cpp @@ -259,3 +259,5 @@ void QSGSoftwareLayer::grab() } QT_END_NAMESPACE + +#include "moc_qsgsoftwarelayer_p.cpp" diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp index 534a0a4ec6..16e3a111ae 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarepixmaptexture.cpp @@ -86,3 +86,5 @@ void QSGSoftwarePixmapTexture::bind() } QT_END_NAMESPACE + +#include "moc_qsgsoftwarepixmaptexture_p.cpp" diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp index b3b8274a73..962db20cbc 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarerenderloop.cpp @@ -269,3 +269,5 @@ void QSGSoftwareRenderLoop::handleUpdateRequest(QQuickWindow *window) } QT_END_NAMESPACE + +#include "moc_qsgsoftwarerenderloop_p.cpp" diff --git a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp index 682f89721e..d2186e7cf1 100644 --- a/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp +++ b/src/quick/scenegraph/adaptations/software/qsgsoftwarethreadedrenderloop.cpp @@ -1000,5 +1000,6 @@ void QSGSoftwareThreadedRenderLoop::polishAndSync(QSGSoftwareThreadedRenderLoop: } #include "qsgsoftwarethreadedrenderloop.moc" +#include "moc_qsgsoftwarethreadedrenderloop_p.cpp" QT_END_NAMESPACE diff --git a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp index eeed986939..3d4ce24716 100644 --- a/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgabstractrenderer.cpp @@ -314,3 +314,5 @@ QSGAbstractRenderer::ClearMode QSGAbstractRenderer::clearMode() const */ QT_END_NAMESPACE + +#include "moc_qsgabstractrenderer.cpp" diff --git a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp index d4324bc489..b8ebeaca63 100644 --- a/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp +++ b/src/quick/scenegraph/coreapi/qsgbatchrenderer.cpp @@ -299,7 +299,7 @@ void Updater::updateStates(QSGNode *n) qDebug() << " - transforms have changed"; if (sn->dirtyState & (QSGNode::DirtyOpacity << 16)) qDebug() << " - opacity has changed"; - if (sn->dirtyState & (QSGNode::DirtyForceUpdate << 16)) + if (uint(sn->dirtyState) & uint(QSGNode::DirtyForceUpdate << 16)) qDebug() << " - forceupdate"; } @@ -338,7 +338,7 @@ void Updater::visitNode(Node *n) case QSGNode::RenderNodeType: if (m_added) n->renderNodeElement()->root = m_roots.last(); - // Fall through to visit children. + Q_FALLTHROUGH(); // to visit children default: SHADOWNODE_TRAVERSE(n) visitNode(child); break; @@ -2029,6 +2029,15 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) GLuint vbo = 0; int vboSize = 0; + bool useVBO = false; + QOpenGLContext *ctx = QOpenGLContext::currentContext(); + QSurfaceFormat::OpenGLContextProfile profile = ctx->format().profile(); + + if (!ctx->isOpenGLES() && profile == QSurfaceFormat::CoreProfile) { + // VBO are more expensive, so only use them if we must. + useVBO = true; + } + glDisable(GL_SCISSOR_TEST); m_currentStencilValue = 0; @@ -2113,20 +2122,27 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) Q_ASSERT(g->attributeCount() > 0); const QSGGeometry::Attribute *a = g->attributes(); - if (!vbo) - glGenBuffers(1, &vbo); + const GLvoid *pointer; + if (!useVBO) { + pointer = g->vertexData(); + } else { + if (!vbo) + glGenBuffers(1, &vbo); - glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBindBuffer(GL_ARRAY_BUFFER, vbo); - const int vertexByteSize = g->sizeOfVertex() * g->vertexCount(); - if (vboSize < vertexByteSize) { - vboSize = vertexByteSize; - glBufferData(GL_ARRAY_BUFFER, vertexByteSize, g->vertexData(), GL_STATIC_DRAW); - } else { - glBufferSubData(GL_ARRAY_BUFFER, 0, vertexByteSize, g->vertexData()); + const int vertexByteSize = g->sizeOfVertex() * g->vertexCount(); + if (vboSize < vertexByteSize) { + vboSize = vertexByteSize; + glBufferData(GL_ARRAY_BUFFER, vertexByteSize, g->vertexData(), GL_STATIC_DRAW); + } else { + glBufferSubData(GL_ARRAY_BUFFER, 0, vertexByteSize, g->vertexData()); + } + + pointer = 0; } - glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), 0); + glVertexAttribPointer(0, a->tupleSize, a->type, GL_FALSE, g->sizeOfVertex(), pointer); m_clipProgram.setUniformValue(m_clipMatrixId, m); if (g->indexCount()) { @@ -2135,7 +2151,8 @@ Renderer::ClipType Renderer::updateStencilClip(const QSGClipNode *clip) glDrawArrays(g->drawingMode(), 0, g->vertexCount()); } - glBindBuffer(GL_ARRAY_BUFFER, 0); + if (useVBO) + glBindBuffer(GL_ARRAY_BUFFER, 0); ++m_currentStencilValue; } @@ -3204,3 +3221,5 @@ void Renderer::visualize() QT_END_NAMESPACE } + +#include "moc_qsgbatchrenderer_p.cpp" diff --git a/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp b/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp index 48ab1aa52f..1fdc1720f7 100644 --- a/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp +++ b/src/quick/scenegraph/coreapi/qsgshaderrewriter.cpp @@ -38,6 +38,7 @@ ****************************************************************************/ #include <QtCore/QByteArray> +#include <QtCore/QString> #include <QtGui/QSurfaceFormat> // Duct Tape tokenizer for the purpose of parsing and rewriting @@ -133,6 +134,7 @@ Tokenizer::Token Tokenizer::next() pos += 3; return Token_Void; } + Q_FALLTHROUGH(); } case ';': return Token_SemiColon; diff --git a/src/quick/scenegraph/qsgadaptationlayer.cpp b/src/quick/scenegraph/qsgadaptationlayer.cpp index f90706affe..c64360f955 100644 --- a/src/quick/scenegraph/qsgadaptationlayer.cpp +++ b/src/quick/scenegraph/qsgadaptationlayer.cpp @@ -567,3 +567,5 @@ QDebug operator<<(QDebug debug, const QSGShaderEffectNode::VariableData &vd) #endif QT_END_NAMESPACE + +#include "moc_qsgadaptationlayer_p.cpp" diff --git a/src/quick/scenegraph/qsgcontext.cpp b/src/quick/scenegraph/qsgcontext.cpp index ff2379ecb5..2be84f4aec 100644 --- a/src/quick/scenegraph/qsgcontext.cpp +++ b/src/quick/scenegraph/qsgcontext.cpp @@ -413,5 +413,6 @@ void QSGRenderContext::textureFactoryDestroyed(QObject *o) } #include "qsgcontext.moc" +#include "moc_qsgcontext_p.cpp" QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgcontext_p.h b/src/quick/scenegraph/qsgcontext_p.h index bd10453131..6ff8f4a76e 100644 --- a/src/quick/scenegraph/qsgcontext_p.h +++ b/src/quick/scenegraph/qsgcontext_p.h @@ -144,6 +144,7 @@ public: static QSGRenderLoop *createWindowManager(); static void setBackend(const QString &backend); + static QString backend(); }; class Q_QUICK_PRIVATE_EXPORT QSGRenderContext : public QObject diff --git a/src/quick/scenegraph/qsgcontextplugin.cpp b/src/quick/scenegraph/qsgcontextplugin.cpp index 635308c38a..b8b5141957 100644 --- a/src/quick/scenegraph/qsgcontextplugin.cpp +++ b/src/quick/scenegraph/qsgcontextplugin.cpp @@ -232,4 +232,15 @@ void QSGContext::setBackend(const QString &backend) backendData->quickWindowBackendRequest = backend; } +QString QSGContext::backend() +{ + QSGAdaptationBackendData *backendData = qsg_adaptation_data(); + if (backendData->tried) + return backendData->name; + + return backendData->quickWindowBackendRequest; +} + QT_END_NAMESPACE + +#include "moc_qsgcontextplugin_p.cpp" diff --git a/src/quick/scenegraph/qsgdefaultlayer.cpp b/src/quick/scenegraph/qsgdefaultlayer.cpp index 6fa9dd6359..86d74acf54 100644 --- a/src/quick/scenegraph/qsgdefaultlayer.cpp +++ b/src/quick/scenegraph/qsgdefaultlayer.cpp @@ -472,3 +472,5 @@ QRectF QSGDefaultLayer::normalizedTextureSubRect() const m_mirrorHorizontal ? -1 : 1, m_mirrorVertical ? 1 : -1); } + +#include "moc_qsgdefaultlayer_p.cpp" diff --git a/src/quick/scenegraph/qsgdefaultrendercontext.cpp b/src/quick/scenegraph/qsgdefaultrendercontext.cpp index 7542068a53..bffffc36ad 100644 --- a/src/quick/scenegraph/qsgdefaultrendercontext.cpp +++ b/src/quick/scenegraph/qsgdefaultrendercontext.cpp @@ -301,3 +301,5 @@ QSGDistanceFieldGlyphCache *QSGDefaultRenderContext::distanceFieldGlyphCache(con return cache; } + +#include "moc_qsgdefaultrendercontext_p.cpp" diff --git a/src/quick/scenegraph/qsgrenderloop.cpp b/src/quick/scenegraph/qsgrenderloop.cpp index 293a706c2e..c11b698a03 100644 --- a/src/quick/scenegraph/qsgrenderloop.cpp +++ b/src/quick/scenegraph/qsgrenderloop.cpp @@ -501,5 +501,6 @@ void QSGGuiThreadRenderLoop::handleUpdateRequest(QQuickWindow *window) #endif #include "qsgrenderloop.moc" +#include "moc_qsgrenderloop_p.cpp" QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgthreadedrenderloop.cpp b/src/quick/scenegraph/qsgthreadedrenderloop.cpp index 560fddd580..7d77e52b5f 100644 --- a/src/quick/scenegraph/qsgthreadedrenderloop.cpp +++ b/src/quick/scenegraph/qsgthreadedrenderloop.cpp @@ -1309,5 +1309,6 @@ void QSGThreadedRenderLoop::postJob(QQuickWindow *window, QRunnable *job) } #include "qsgthreadedrenderloop.moc" +#include "moc_qsgthreadedrenderloop_p.cpp" QT_END_NAMESPACE diff --git a/src/quick/scenegraph/qsgwindowsrenderloop.cpp b/src/quick/scenegraph/qsgwindowsrenderloop.cpp index eff6763a16..e16f7ea966 100644 --- a/src/quick/scenegraph/qsgwindowsrenderloop.cpp +++ b/src/quick/scenegraph/qsgwindowsrenderloop.cpp @@ -494,3 +494,5 @@ void QSGWindowsRenderLoop::renderWindow(QQuickWindow *window) } QT_END_NAMESPACE + +#include "moc_qsgwindowsrenderloop_p.cpp" diff --git a/src/quick/scenegraph/util/qsgatlastexture.cpp b/src/quick/scenegraph/util/qsgatlastexture.cpp index c864ea9496..22f0b13f46 100644 --- a/src/quick/scenegraph/util/qsgatlastexture.cpp +++ b/src/quick/scenegraph/util/qsgatlastexture.cpp @@ -140,7 +140,7 @@ Atlas::Atlas(const QSize &size) if (QOpenGLContext::currentContext()->isOpenGLES()) { #endif -#if defined(Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) QString *deviceName = static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName")); static bool wrongfullyReportsBgra8888Support = deviceName != 0 @@ -533,3 +533,5 @@ QSGTexture *Texture::removedFromAtlas() const } QT_END_NAMESPACE + +#include "moc_qsgatlastexture_p.cpp" diff --git a/src/quick/scenegraph/util/qsgengine.cpp b/src/quick/scenegraph/util/qsgengine.cpp index 259e45c978..dffe199224 100644 --- a/src/quick/scenegraph/util/qsgengine.cpp +++ b/src/quick/scenegraph/util/qsgengine.cpp @@ -265,3 +265,5 @@ QSGNinePatchNode *QSGEngine::createNinePatchNode() const } QT_END_NAMESPACE + +#include "moc_qsgengine.cpp" diff --git a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp index d8f92919cb..e134a5d4d3 100644 --- a/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp +++ b/src/quick/scenegraph/util/qsgshadersourcebuilder.cpp @@ -122,6 +122,7 @@ Tokenizer::Token Tokenizer::next() case '*': if (*pos == '/') return Token_MultiLineCommentEnd; + Q_FALLTHROUGH(); case '\n': return Token_NewLine; @@ -129,6 +130,7 @@ Tokenizer::Token Tokenizer::next() case '\r': if (*pos == '\n') return Token_NewLine; + Q_FALLTHROUGH(); case '#': { if (*pos == 'v' && pos[1] == 'e' && pos[2] == 'r' && pos[3] == 's' @@ -177,7 +179,7 @@ Tokenizer::Token Tokenizer::next() pos += 3; return Token_Void; } - // Fall-thru + Q_FALLTHROUGH(); } default: // Identifier... diff --git a/src/quick/scenegraph/util/qsgtexture.cpp b/src/quick/scenegraph/util/qsgtexture.cpp index 591b679ec4..1c19876a76 100644 --- a/src/quick/scenegraph/util/qsgtexture.cpp +++ b/src/quick/scenegraph/util/qsgtexture.cpp @@ -295,6 +295,8 @@ static void qt_debug_remove_texture(QSGTexture* texture) \value Anisotropy8x 8x anisotropic filtering. \value Anisotropy16x 16x anisotropic filtering. + + \since 5.9 */ /*! @@ -795,7 +797,7 @@ void QSGPlainTexture::bind() GLenum externalFormat = GL_RGBA; GLenum internalFormat = GL_RGBA; -#if defined(Q_OS_ANDROID) +#if defined(Q_OS_ANDROID) && !defined(Q_OS_ANDROID_EMBEDDED) QString *deviceName = static_cast<QString *>(QGuiApplication::platformNativeInterface()->nativeResourceForIntegration("AndroidDeviceName")); static bool wrongfullyReportsBgra8888Support = deviceName != 0 @@ -902,3 +904,6 @@ void QSGPlainTexture::bind() QT_END_NAMESPACE + +#include "moc_qsgtexture.cpp" +#include "moc_qsgtexture_p.cpp" diff --git a/src/quick/scenegraph/util/qsgtextureprovider.cpp b/src/quick/scenegraph/util/qsgtextureprovider.cpp index 2f6a789222..d67d9cfdbc 100644 --- a/src/quick/scenegraph/util/qsgtextureprovider.cpp +++ b/src/quick/scenegraph/util/qsgtextureprovider.cpp @@ -62,3 +62,5 @@ QT_BEGIN_NAMESPACE */ QT_END_NAMESPACE + +#include "moc_qsgtextureprovider.cpp" diff --git a/src/quick/util/qquickanimation.cpp b/src/quick/util/qquickanimation.cpp index 1a2441171d..bfac46adb9 100644 --- a/src/quick/util/qquickanimation.cpp +++ b/src/quick/util/qquickanimation.cpp @@ -2718,3 +2718,5 @@ QQuickAnimationPropertyUpdater::~QQuickAnimationPropertyUpdater() } QT_END_NAMESPACE + +#include "moc_qquickanimation_p.cpp" diff --git a/src/quick/util/qquickanimationcontroller.cpp b/src/quick/util/qquickanimationcontroller.cpp index fa1ade50d1..cebb0391ae 100644 --- a/src/quick/util/qquickanimationcontroller.cpp +++ b/src/quick/util/qquickanimationcontroller.cpp @@ -297,3 +297,4 @@ void QQuickAnimationController::completeToEnd() QT_END_NAMESPACE +#include "moc_qquickanimationcontroller_p.cpp" diff --git a/src/quick/util/qquickanimator.cpp b/src/quick/util/qquickanimator.cpp index c3b5865369..5608326f8a 100644 --- a/src/quick/util/qquickanimator.cpp +++ b/src/quick/util/qquickanimator.cpp @@ -585,3 +585,5 @@ QQuickAnimatorJob *QQuickUniformAnimator::createJob() const #endif QT_END_NAMESPACE + +#include "moc_qquickanimator_p.cpp" diff --git a/src/quick/util/qquickanimatorcontroller.cpp b/src/quick/util/qquickanimatorcontroller.cpp index 2f96c511c0..3f7347c01d 100644 --- a/src/quick/util/qquickanimatorcontroller.cpp +++ b/src/quick/util/qquickanimatorcontroller.cpp @@ -219,3 +219,5 @@ void QQuickAnimatorController::cancel(const QSharedPointer<QAbstractAnimationJob QT_END_NAMESPACE + +#include "moc_qquickanimatorcontroller_p.cpp" diff --git a/src/quick/util/qquickanimatorjob.cpp b/src/quick/util/qquickanimatorjob.cpp index 89007cff1f..a7950e2b33 100644 --- a/src/quick/util/qquickanimatorjob.cpp +++ b/src/quick/util/qquickanimatorjob.cpp @@ -140,6 +140,14 @@ QObject *QQuickAnimatorProxyJob::findAnimationContext(QQuickAbstractAnimation *a void QQuickAnimatorProxyJob::updateCurrentTime(int) { + if (m_internalState != State_Running) + return; + + // A proxy which is being ticked should be associated with a window, (see + // setWindow() below). If we get here when there is no more controller we + // have a problem. + Q_ASSERT(m_controller); + // We do a simple check here to see if the animator has run and stopped on // the render thread. isPendingStart() will perform a check against jobs // that have been scheduled for start, but that will not yet have entered @@ -150,8 +158,7 @@ void QQuickAnimatorProxyJob::updateCurrentTime(int) // we might get the wrong value for this update, but then we'll simply // pick it up on the next iterationm when the job is stopped and render // thread is no longer using it. - if (m_internalState == State_Running - && !m_controller->isPendingStart(m_job) + if (!m_controller->isPendingStart(m_job) && !m_job->isRunning()) { stop(); } @@ -167,9 +174,9 @@ void QQuickAnimatorProxyJob::updateState(QAbstractAnimationJob::State newState, } } else if (newState == Stopped) { - syncBackCurrentValues(); m_internalState = State_Stopped; if (m_controller) { + syncBackCurrentValues(); m_controller->cancel(m_job); } } @@ -193,6 +200,7 @@ void QQuickAnimatorProxyJob::setWindow(QQuickWindow *window) if (m_job && m_controller) m_controller->cancel(m_job); m_controller = nullptr; + stop(); } else if (!m_controller && m_job) { m_controller = QQuickWindowPrivate::get(window)->animationController; @@ -313,8 +321,10 @@ void QQuickTransformAnimatorJob::preSync() m_helper = nullptr; } - if (!m_target) + if (!m_target) { + invalidate(); return; + } if (!m_helper) { m_helper = qquick_transform_animatorjob_helper_store()->acquire(m_target); @@ -334,27 +344,6 @@ void QQuickTransformAnimatorJob::preSync() m_helper->sync(); } -void QQuickTransformAnimatorJob::postSync() -{ - Q_ASSERT((m_helper != nullptr) == (m_target != nullptr)); // If there is a target, there should also be a helper, ref: preSync - Q_ASSERT(!m_helper || m_helper->item == m_target); // If there is a helper, it should point to our target - - if (!m_target || !m_helper) { - invalidate(); - return; - } - - QQuickItemPrivate *d = QQuickItemPrivate::get(m_target); -#if QT_CONFIG(quick_shadereffect) - if (d->extra.isAllocated() - && d->extra->layer - && d->extra->layer->enabled()) { - d = QQuickItemPrivate::get(d->extra->layer->m_effectSource); - } -#endif - m_helper->node = d->itemNode(); -} - void QQuickTransformAnimatorJob::invalidate() { if (m_helper) @@ -694,3 +683,5 @@ void QQuickUniformAnimatorJob::writeBack() #endif QT_END_NAMESPACE + +#include "moc_qquickanimatorjob_p.cpp" diff --git a/src/quick/util/qquickanimatorjob_p.h b/src/quick/util/qquickanimatorjob_p.h index a3ced4c21b..777da2ee6c 100644 --- a/src/quick/util/qquickanimatorjob_p.h +++ b/src/quick/util/qquickanimatorjob_p.h @@ -235,7 +235,6 @@ public: protected: QQuickTransformAnimatorJob(); - void postSync() override; void invalidate() override; Helper *m_helper; diff --git a/src/quick/util/qquickapplication.cpp b/src/quick/util/qquickapplication.cpp index 5c89275c5a..e0d032b074 100644 --- a/src/quick/util/qquickapplication.cpp +++ b/src/quick/util/qquickapplication.cpp @@ -140,3 +140,5 @@ void QQuickApplication::updateScreens() } QT_END_NAMESPACE + +#include "moc_qquickapplication_p.cpp" diff --git a/src/quick/util/qquickbehavior.cpp b/src/quick/util/qquickbehavior.cpp index 1b2d9afb7c..a562ebd937 100644 --- a/src/quick/util/qquickbehavior.cpp +++ b/src/quick/util/qquickbehavior.cpp @@ -258,3 +258,5 @@ void QQuickBehavior::componentFinalized() } QT_END_NAMESPACE + +#include "moc_qquickbehavior_p.cpp" diff --git a/src/quick/util/qquickfontloader.cpp b/src/quick/util/qquickfontloader.cpp index 3761a37a6d..68e27c25fd 100644 --- a/src/quick/util/qquickfontloader.cpp +++ b/src/quick/util/qquickfontloader.cpp @@ -236,7 +236,7 @@ QQuickFontLoader::~QQuickFontLoader() /*! \qmlproperty url QtQuick::FontLoader::source - The url of the font to load. + The URL of the font to load. */ QUrl QQuickFontLoader::source() const { @@ -317,7 +317,7 @@ void QQuickFontLoader::updateFontInfo(const QString& name, QQuickFontLoader::Sta \qmlproperty string QtQuick::FontLoader::name This property holds the name of the font family. - It is set automatically when a font is loaded using the \c url property. + It is set automatically when a font is loaded using the \l source property. Use this to set the \c font.family property of a \c Text item. @@ -397,3 +397,5 @@ QQuickFontLoader::Status QQuickFontLoader::status() const QT_END_NAMESPACE #include <qquickfontloader.moc> + +#include "moc_qquickfontloader_p.cpp" diff --git a/src/quick/util/qquickfontmetrics.cpp b/src/quick/util/qquickfontmetrics.cpp index 4609e638c2..8c44150486 100644 --- a/src/quick/util/qquickfontmetrics.cpp +++ b/src/quick/util/qquickfontmetrics.cpp @@ -346,3 +346,5 @@ QString QQuickFontMetrics::elidedText(const QString &text, Qt::TextElideMode mod } QT_END_NAMESPACE + +#include "moc_qquickfontmetrics_p.cpp" diff --git a/src/quick/util/qquickglobal.cpp b/src/quick/util/qquickglobal.cpp index 20bb23338d..2070fd7ff0 100644 --- a/src/quick/util/qquickglobal.cpp +++ b/src/quick/util/qquickglobal.cpp @@ -810,6 +810,7 @@ public: #ifndef QT_NO_DESKTOPSERVICES return QDesktopServices::openUrl(url); #else + Q_UNUSED(url); return false; #endif } diff --git a/src/quick/util/qquickimageprovider.cpp b/src/quick/util/qquickimageprovider.cpp index c4a98c69f9..b4a6b9e1f6 100644 --- a/src/quick/util/qquickimageprovider.cpp +++ b/src/quick/util/qquickimageprovider.cpp @@ -715,3 +715,4 @@ QQuickImageProviderWithOptions *QQuickImageProviderWithOptions::checkedCast(QQui QT_END_NAMESPACE +#include "moc_qquickimageprovider.cpp" diff --git a/src/quick/util/qquickpath.cpp b/src/quick/util/qquickpath.cpp index e31aed7b6d..8abb9377a6 100644 --- a/src/quick/util/qquickpath.cpp +++ b/src/quick/util/qquickpath.cpp @@ -1886,3 +1886,5 @@ void QQuickPathPercent::setValue(qreal value) } } QT_END_NAMESPACE + +#include "moc_qquickpath_p.cpp" diff --git a/src/quick/util/qquickpathinterpolator.cpp b/src/quick/util/qquickpathinterpolator.cpp index adc166dd8a..838213042e 100644 --- a/src/quick/util/qquickpathinterpolator.cpp +++ b/src/quick/util/qquickpathinterpolator.cpp @@ -169,3 +169,5 @@ void QQuickPathInterpolator::_q_pathUpdated() } QT_END_NAMESPACE + +#include "moc_qquickpathinterpolator_p.cpp" diff --git a/src/quick/util/qquickpixmapcache.cpp b/src/quick/util/qquickpixmapcache.cpp index 7d88935402..8df1a892e4 100644 --- a/src/quick/util/qquickpixmapcache.cpp +++ b/src/quick/util/qquickpixmapcache.cpp @@ -1573,3 +1573,5 @@ bool QQuickPixmap::connectDownloadProgress(QObject *object, int method) QT_END_NAMESPACE #include <qquickpixmapcache.moc> + +#include "moc_qquickpixmapcache_p.cpp" diff --git a/src/quick/util/qquickprofiler.cpp b/src/quick/util/qquickprofiler.cpp index 841a1c9bcf..402cd44ff0 100644 --- a/src/quick/util/qquickprofiler.cpp +++ b/src/quick/util/qquickprofiler.cpp @@ -79,6 +79,7 @@ public: }; #include "qquickprofiler.moc" +#include "moc_qquickprofiler_p.cpp" QQuickProfiler::QQuickProfiler(QObject *parent) : QObject(parent) { diff --git a/src/quick/util/qquickpropertychanges.cpp b/src/quick/util/qquickpropertychanges.cpp index 20aa52e472..8d76bd986f 100644 --- a/src/quick/util/qquickpropertychanges.cpp +++ b/src/quick/util/qquickpropertychanges.cpp @@ -785,3 +785,5 @@ void QQuickPropertyChanges::attachToState() } QT_END_NAMESPACE + +#include "moc_qquickpropertychanges_p.cpp" diff --git a/src/quick/util/qquickshortcut.cpp b/src/quick/util/qquickshortcut.cpp index 72d9c889e3..2fe4962b1a 100644 --- a/src/quick/util/qquickshortcut.cpp +++ b/src/quick/util/qquickshortcut.cpp @@ -416,3 +416,5 @@ void QQuickShortcut::ungrabShortcut(Shortcut &shortcut) } QT_END_NAMESPACE + +#include "moc_qquickshortcut_p.cpp" diff --git a/src/quick/util/qquickshortcut_p.h b/src/quick/util/qquickshortcut_p.h index 93430ad893..db918058b2 100644 --- a/src/quick/util/qquickshortcut_p.h +++ b/src/quick/util/qquickshortcut_p.h @@ -111,6 +111,7 @@ protected: bool event(QEvent *event) Q_DECL_OVERRIDE; struct Shortcut { + Shortcut() : id(0) { } bool matches(QShortcutEvent *event) const; int id; QVariant userValue; diff --git a/src/quick/util/qquicksmoothedanimation.cpp b/src/quick/util/qquicksmoothedanimation.cpp index e7beee8ed3..607f39768b 100644 --- a/src/quick/util/qquicksmoothedanimation.cpp +++ b/src/quick/util/qquicksmoothedanimation.cpp @@ -568,3 +568,5 @@ void QQuickSmoothedAnimation::setMaximumEasingTime(int v) } QT_END_NAMESPACE + +#include "moc_qquicksmoothedanimation_p.cpp" diff --git a/src/quick/util/qquickspringanimation.cpp b/src/quick/util/qquickspringanimation.cpp index a9940959a0..bf844589ba 100644 --- a/src/quick/util/qquickspringanimation.cpp +++ b/src/quick/util/qquickspringanimation.cpp @@ -597,3 +597,5 @@ QAbstractAnimationJob* QQuickSpringAnimation::transition(QQuickStateActions &act } QT_END_NAMESPACE + +#include "moc_qquickspringanimation_p.cpp" diff --git a/src/quick/util/qquickstate.cpp b/src/quick/util/qquickstate.cpp index 2d3934cce8..0a49d41491 100644 --- a/src/quick/util/qquickstate.cpp +++ b/src/quick/util/qquickstate.cpp @@ -708,3 +708,5 @@ void QQuickStateOperation::setState(QQuickState *state) } QT_END_NAMESPACE + +#include "moc_qquickstate_p.cpp" diff --git a/src/quick/util/qquickstategroup.cpp b/src/quick/util/qquickstategroup.cpp index f2cd4638fc..ebcbbf93ed 100644 --- a/src/quick/util/qquickstategroup.cpp +++ b/src/quick/util/qquickstategroup.cpp @@ -514,3 +514,4 @@ void QQuickStateGroup::stateAboutToComplete() QT_END_NAMESPACE +#include "moc_qquickstategroup_p.cpp" diff --git a/src/quick/util/qquicksystempalette.cpp b/src/quick/util/qquicksystempalette.cpp index 7443c3f577..c5768a5d9f 100644 --- a/src/quick/util/qquicksystempalette.cpp +++ b/src/quick/util/qquicksystempalette.cpp @@ -285,3 +285,5 @@ void QQuickSystemPalette::setColorGroup(QQuickSystemPalette::ColorGroup colorGro } QT_END_NAMESPACE + +#include "moc_qquicksystempalette_p.cpp" diff --git a/src/quick/util/qquicktextmetrics.cpp b/src/quick/util/qquicktextmetrics.cpp index f969a1da42..43945b0f5a 100644 --- a/src/quick/util/qquicktextmetrics.cpp +++ b/src/quick/util/qquicktextmetrics.cpp @@ -265,3 +265,5 @@ QString QQuickTextMetrics::elidedText() const } QT_END_NAMESPACE + +#include "moc_qquicktextmetrics_p.cpp" diff --git a/src/quick/util/qquicktransition.cpp b/src/quick/util/qquicktransition.cpp index 1d258d84bf..29690a4857 100644 --- a/src/quick/util/qquicktransition.cpp +++ b/src/quick/util/qquicktransition.cpp @@ -457,3 +457,5 @@ QQmlListProperty<QQuickAbstractAnimation> QQuickTransition::animations() QT_END_NAMESPACE //#include <qquicktransition.moc> + +#include "moc_qquicktransition_p.cpp" diff --git a/src/quick/util/qquickvalidator.cpp b/src/quick/util/qquickvalidator.cpp index 015a376603..a05117bd06 100644 --- a/src/quick/util/qquickvalidator.cpp +++ b/src/quick/util/qquickvalidator.cpp @@ -225,3 +225,4 @@ void QQuickDoubleValidator::resetLocaleName() QT_END_NAMESPACE +#include "moc_qquickvalidator_p.cpp" diff --git a/src/quick/util/qquickvaluetypes.cpp b/src/quick/util/qquickvaluetypes.cpp index 4afcb07a5c..4d34c6d661 100644 --- a/src/quick/util/qquickvaluetypes.cpp +++ b/src/quick/util/qquickvaluetypes.cpp @@ -758,3 +758,5 @@ void QQuickFontValueType::setHintingPreference(QQuickFontValueType::HintingPrefe } QT_END_NAMESPACE + +#include "moc_qquickvaluetypes_p.cpp" diff --git a/src/quickwidgets/qquickwidget.cpp b/src/quickwidgets/qquickwidget.cpp index a2ea0f7af2..4d021cb680 100644 --- a/src/quickwidgets/qquickwidget.cpp +++ b/src/quickwidgets/qquickwidget.cpp @@ -1616,3 +1616,5 @@ void QQuickWidget::paintEvent(QPaintEvent *event) } QT_END_NAMESPACE + +#include "moc_qquickwidget.cpp" |