Skip to content

Commit

Permalink
QmlDebugging: Object Tree and States List
Browse files Browse the repository at this point in the history
All created instances are stored under the root context.
Check for the creation context of the object when building
up the tree. Do the same when building up the states list.

Change-Id: I8716d9966a61b8f7cb3ad4b7ab5acd4c94b4cd03
Reviewed-by: Kai Koehne <kai.koehne@nokia.com>
  • Loading branch information
Aurindam Jana authored and Qt by Nokia committed Mar 19, 2012
1 parent af3a870 commit cad5df2
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 43 deletions.
5 changes: 4 additions & 1 deletion src/qml/debugger/qqmldebugstatesdelegate_p.h
Expand Up @@ -54,6 +54,8 @@
//

#include <QtQml/qtqmlglobal.h>
#include <QtCore/QList>
#include <QtCore/QPointer>

QT_BEGIN_HEADER

Expand All @@ -74,7 +76,8 @@ class QQmlDebugStatesDelegate
public:
virtual ~QQmlDebugStatesDelegate() {}

virtual void buildStatesList(QQmlContext *ctxt, bool cleanList) = 0;
virtual void buildStatesList(bool cleanList,
const QList<QPointer<QObject> > &instances) = 0;
virtual void updateBinding(QQmlContext *context,
const QQmlProperty &property,
const QVariant &expression, bool isLiteralValue,
Expand Down
44 changes: 28 additions & 16 deletions src/qml/debugger/qqmlenginedebugservice.cpp
Expand Up @@ -297,7 +297,9 @@ void QQmlEngineDebugService::prepareDeferredObjects(QObject *obj)

}

void QQmlEngineDebugService::buildObjectList(QDataStream &message, QQmlContext *ctxt)
void QQmlEngineDebugService::buildObjectList(QDataStream &message,
QQmlContext *ctxt,
const QList<QPointer<QObject> > &instances)
{
QQmlContextData *p = QQmlContextData::get(ctxt);

Expand All @@ -318,29 +320,30 @@ void QQmlEngineDebugService::buildObjectList(QDataStream &message, QQmlContext *

child = p->childContexts;
while (child) {
buildObjectList(message, child->asQQmlContext());
buildObjectList(message, child->asQQmlContext(), instances);
child = child->nextChild;
}

// Clean deleted objects
QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(ctxt);
for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
if (!ctxtPriv->instances.at(ii)) {
ctxtPriv->instances.removeAt(ii);
--ii;
}
count = 0;
for (int ii = 0; ii < instances.count(); ++ii) {
QQmlData *data = QQmlData::get(instances.at(ii));
if (data->context == p)
count ++;
}
message << count;

message << ctxtPriv->instances.count();
for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
message << objectData(ctxtPriv->instances.at(ii));
for (int ii = 0; ii < instances.count(); ++ii) {
QQmlData *data = QQmlData::get(instances.at(ii));
if (data->context == p)
message << objectData(instances.at(ii));
}
}

void QQmlEngineDebugService::buildStatesList(QQmlContext *ctxt, bool cleanList)
void QQmlEngineDebugService::buildStatesList(bool cleanList,
const QList<QPointer<QObject> > &instances)
{
if (m_statesDelegate)
m_statesDelegate->buildStatesList(ctxt, cleanList);
m_statesDelegate->buildStatesList(cleanList, instances);
}

QQmlEngineDebugService::QQmlObjectData
Expand Down Expand Up @@ -427,8 +430,17 @@ void QQmlEngineDebugService::processMessage(const QByteArray &message)
rs << QByteArray("LIST_OBJECTS_R") << queryId;

if (engine) {
buildObjectList(rs, engine->rootContext());
buildStatesList(engine->rootContext(), true);
QQmlContext *rootContext = engine->rootContext();
// Clean deleted objects
QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(rootContext);
for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
if (!ctxtPriv->instances.at(ii)) {
ctxtPriv->instances.removeAt(ii);
--ii;
}
}
buildObjectList(rs, rootContext, ctxtPriv->instances);
buildStatesList(true, ctxtPriv->instances);
}

sendMessage(reply);
Expand Down
6 changes: 4 additions & 2 deletions src/qml/debugger/qqmlenginedebugservice_p.h
Expand Up @@ -57,6 +57,7 @@

#include <QtCore/qurl.h>
#include <QtCore/qvariant.h>
#include <QtCore/QPointer>

QT_BEGIN_NAMESPACE

Expand Down Expand Up @@ -111,9 +112,10 @@ private Q_SLOTS:

private:
void prepareDeferredObjects(QObject *);
void buildObjectList(QDataStream &, QQmlContext *);
void buildObjectList(QDataStream &, QQmlContext *,
const QList<QPointer<QObject> > &instances);
void buildObjectDump(QDataStream &, QObject *, bool, bool);
void buildStatesList(QQmlContext *, bool);
void buildStatesList(bool cleanList, const QList<QPointer<QObject> > &instances);
QQmlObjectData objectData(QObject *);
QQmlObjectProperty propertyData(QObject *, int);
QVariant valueContents(const QVariant &defaultValue) const;
Expand Down
17 changes: 6 additions & 11 deletions src/quick/qtquick2.cpp
Expand Up @@ -63,7 +63,7 @@ class QQmlQtQuick2DebugStatesDelegate : public QQmlDebugStatesDelegate
public:
QQmlQtQuick2DebugStatesDelegate();
virtual ~QQmlQtQuick2DebugStatesDelegate();
virtual void buildStatesList(QQmlContext *ctxt, bool cleanList);
virtual void buildStatesList(bool cleanList, const QList<QPointer<QObject> > &instances);
virtual void updateBinding(QQmlContext *context,
const QQmlProperty &property,
const QVariant &expression, bool isLiteralValue,
Expand All @@ -90,20 +90,15 @@ QQmlQtQuick2DebugStatesDelegate::~QQmlQtQuick2DebugStatesDelegate()
{
}

void QQmlQtQuick2DebugStatesDelegate::buildStatesList(QQmlContext *ctxt, bool cleanList)
void QQmlQtQuick2DebugStatesDelegate::buildStatesList(bool cleanList,
const QList<QPointer<QObject> > &instances)
{
if (cleanList)
m_allStates.clear();

QQmlContextPrivate *ctxtPriv = QQmlContextPrivate::get(ctxt);
for (int ii = 0; ii < ctxtPriv->instances.count(); ++ii) {
buildStatesList(ctxtPriv->instances.at(ii));
}

QQmlContextData *child = QQmlContextData::get(ctxt)->childContexts;
while (child) {
buildStatesList(child->asQQmlContext());
child = child->nextChild;
//only root context has all instances
for (int ii = 0; ii < instances.count(); ++ii) {
buildStatesList(instances.at(ii));
}
}

Expand Down
Expand Up @@ -137,11 +137,15 @@ QQmlDebugObjectReference tst_QQmlEngineDebugService::findRootObject(int context,
QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this);
waitForQuery(q_context);

if (q_context->rootContext().objects().count() == 0)
if (q_context->rootContext().contexts().count() == 0 ||
q_context->rootContext().contexts().last().objects().count() == 0)
return QQmlDebugObjectReference();

//Contexts are in a stack
int count = q_context->rootContext().contexts().count();
QQmlDebugObjectQuery *q_obj = recursive ?
m_dbg->queryObjectRecursive(q_context->rootContext().objects()[context], this) :
m_dbg->queryObject(q_context->rootContext().objects()[context], this);
m_dbg->queryObjectRecursive(q_context->rootContext().contexts()[count - context - 1].objects()[0], this) :
m_dbg->queryObject(q_context->rootContext().contexts()[count - context - 1].objects()[0], this);
waitForQuery(q_obj);

QQmlDebugObjectReference result = q_obj->object();
Expand Down Expand Up @@ -493,8 +497,9 @@ void tst_QQmlEngineDebugService::watch_object()
QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this);
waitForQuery(q_context);

QVERIFY(q_context->rootContext().objects().count() > 0);
QQmlDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().objects()[0], this);
QVERIFY(q_context->rootContext().contexts().count());
QVERIFY(q_context->rootContext().contexts().last().objects().count() > 0);
QQmlDebugObjectQuery *q_obj = m_dbg->queryObject(q_context->rootContext().contexts().last().objects()[0], this);
waitForQuery(q_obj);

QQmlDebugObjectReference obj = q_obj->object();
Expand Down Expand Up @@ -705,12 +710,9 @@ void tst_QQmlEngineDebugService::queryRootContexts()
QCOMPARE(context.debugId(), QQmlDebugService::idForObject(actualContext));
QCOMPARE(context.name(), actualContext->objectName());

QCOMPARE(context.objects().count(), 4); // 4 qml component objects created for context in main()

// root context query sends only root object data - it doesn't fill in
// the children or property info
QCOMPARE(context.objects()[0].properties().count(), 0);
QCOMPARE(context.objects()[0].children().count(), 0);
QCOMPARE(context.objects().count(), 0);

QCOMPARE(context.contexts().count(), 5);
QVERIFY(context.contexts()[0].debugId() >= 0);
Expand All @@ -734,7 +736,7 @@ void tst_QQmlEngineDebugService::queryObject()

QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this);
waitForQuery(q_context);
QQmlDebugObjectReference rootObject = q_context->rootContext().objects()[0];
QQmlDebugObjectReference rootObject = q_context->rootContext().contexts().last().objects()[0];

QQmlDebugObjectQuery *q_obj = 0;

Expand Down Expand Up @@ -815,7 +817,7 @@ void tst_QQmlEngineDebugService::queryExpressionResult()

QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this);
waitForQuery(q_context);
int objectId = q_context->rootContext().objects()[0].debugId();
int objectId = q_context->rootContext().contexts().last().objects()[0].debugId();

QQmlDebugExpressionQuery *q_expr;

Expand Down Expand Up @@ -1164,8 +1166,9 @@ void tst_QQmlEngineDebugService::queryObjectTree()
QQmlDebugRootContextQuery *q_context = m_dbg->queryRootContexts(q_engines->engines()[0].debugId(), this);
waitForQuery(q_context);

QVERIFY(q_context->rootContext().objects().count() > sourceIndex);
QQmlDebugObjectReference rootObject = q_context->rootContext().objects()[sourceIndex];
QVERIFY(q_context->rootContext().contexts().count() >= sourceIndex);
int count = q_context->rootContext().contexts().count();
QQmlDebugObjectReference rootObject = q_context->rootContext().contexts()[count - sourceIndex - 1].objects()[0];

QQmlDebugObjectQuery *q_obj = m_dbg->queryObjectRecursive(rootObject, this);
waitForQuery(q_obj);
Expand Down

0 comments on commit cad5df2

Please sign in to comment.