QML tooling: Make sure we signal object creation also from QQmlIncubator

We have to call the QQmlEngineDebugService back from QQmlObjectCreator
rather than QQmlComponent, as there are more ways to create an object.

We also add the new instance to the global instance list if only the V4
debug service is active, as both QQmlEngineDebugService and
QV4DebugService use it.

Change-Id: I5dcc71b2e91049bc19ec70d7b87959a61c9b6b75
Reviewed-by: Simon Hausmann <simon.hausmann@qt.io>
This commit is contained in:
Ulf Hermann 2017-01-11 11:44:58 +01:00
parent 046d1a092b
commit 6746db54f2
5 changed files with 45 additions and 13 deletions

View File

@ -47,8 +47,6 @@
#include "qqml.h"
#include "qqmlengine.h"
#include "qqmlbinding_p.h"
#include <private/qqmldebugconnector_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
#include "qqmlincubator.h"
#include "qqmlincubator_p.h"
#include <private/qqmljavascriptexpression_p.h>
@ -876,15 +874,6 @@ QQmlComponentPrivate::beginCreate(QQmlContextData *context)
depthIncreased = false;
}
if (rv) {
if (QQmlEngineDebugService *service =
QQmlDebugConnector::service<QQmlEngineDebugService>()) {
if (!context->isInternal)
context->asQQmlContextPrivate()->instances.append(rv);
service->objectCreated(engine, rv);
}
}
return rv;
}

View File

@ -53,6 +53,8 @@
#include <private/qqmlscriptstring_p.h>
#include <private/qqmlpropertyvalueinterceptor_p.h>
#include <private/qqmlvaluetypeproxybinding_p.h>
#include <private/qqmldebugconnector_p.h>
#include <private/qqmldebugserviceinterfaces_p.h>
QT_USE_NAMESPACE
@ -216,6 +218,17 @@ QObject *QQmlObjectCreator::create(int subComponentIndex, QObject *parent, QQmlI
phase = ObjectsCreated;
if (instance) {
if (QQmlEngineDebugService *service
= QQmlDebugConnector::service<QQmlEngineDebugService>()) {
if (!parentContext->isInternal)
parentContext->asQQmlContextPrivate()->instances.append(instance);
service->objectCreated(engine, instance);
} else if (!parentContext->isInternal && QQmlDebugConnector::service<QV4DebugService>()) {
parentContext->asQQmlContextPrivate()->instances.append(instance);
}
}
return instance;
}

View File

@ -45,6 +45,7 @@
#include <QtQml/qqmlcomponent.h>
#include <QtQml/qqmlexpression.h>
#include <QtQml/qqmlproperty.h>
#include <QtQml/qqmlincubator.h>
#include <QtQuick/qquickitem.h>
#include <QtNetwork/qhostaddress.h>
@ -136,6 +137,7 @@ private slots:
void regression_QTCREATORBUG_7451();
void queryObjectWithNonStreamableTypes();
void asynchronousCreate();
};
QmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(
@ -1220,6 +1222,32 @@ void tst_QQmlEngineDebugService::queryObjectTree()
QCOMPARE(findProperty(animation.properties,"duration").value.toInt(), 100);
}
void tst_QQmlEngineDebugService::asynchronousCreate() {
QmlDebugObjectReference object;
auto connection = connect(m_dbg, &QQmlEngineDebugClient::newObject, this, [&](int objectId) {
object.debugId = objectId;
});
QByteArray asynchronousComponent = "import QtQuick 2.5\n"
"Rectangle { id: asyncRect }";
QQmlComponent component(m_engine);
component.setData(asynchronousComponent, QUrl::fromLocalFile(""));
QVERIFY(component.isReady()); // fails if bad syntax
QQmlIncubator incubator(QQmlIncubator::Asynchronous);
component.create(incubator);
QVERIFY(m_dbg->object().idString != QLatin1String("asyncRect"));
QTRY_VERIFY(object.debugId != -1);
disconnect(connection);
bool success = false;
m_dbg->queryObject(object, &success);
QVERIFY(success);
QTRY_COMPARE(m_dbg->object().idString, QLatin1String("asyncRect"));
}
int main(int argc, char *argv[])
{
int _argc = argc + 1;

View File

@ -489,7 +489,9 @@ void QQmlEngineDebugClient::messageReceived(const QByteArray &data)
return;
} else if (type == "OBJECT_CREATED") {
emit newObjects();
int engineId, objectId, parentId;
ds >> engineId >> objectId >> parentId;
emit newObject(objectId);
return;
} else if (type == "SET_BINDING_R") {
ds >> m_valid;

View File

@ -213,7 +213,7 @@ public:
bool valid() { return m_valid; }
signals:
void newObjects();
void newObject(int objectId);
void valueChanged(QByteArray,QVariant);
void result();