Commit 95cfe23e authored by Aurindam Jana's avatar Aurindam Jana
Browse files

QmlJSInspector: Optimize server requests



Fetch objects on demand. Update objects that are
currently in the crumble path rather than query the
complete tree.

Change-Id: Id4e263fa7a35c90248444461210dbba32dd61b12
Reviewed-by: default avatarKai Koehne <kai.koehne@nokia.com>
parent 8a88e4fa
......@@ -185,27 +185,27 @@ void QmlEngineDebugClient::messageReceived(const QByteArray &data)
ds >> eng.m_debugId;
engines << eng;
}
emit result(queryId, QVariant::fromValue(engines));
emit result(queryId, QVariant::fromValue(engines), type);
} else if (type == "LIST_OBJECTS_R") {
QmlDebugContextReference rootContext;
if (!ds.atEnd())
decode(ds, rootContext);
emit result(queryId, QVariant::fromValue(rootContext));
emit result(queryId, QVariant::fromValue(rootContext), type);
} else if (type == "FETCH_OBJECT_R") {
QmlDebugObjectReference object;
if (!ds.atEnd())
decode(ds, object, false);
emit result(queryId, QVariant::fromValue(object));
emit result(queryId, QVariant::fromValue(object), type);
} else if (type == "EVAL_EXPRESSION_R") {;
QVariant exprResult;
ds >> exprResult;
emit result(queryId, exprResult);
emit result(queryId, exprResult, type);
} else if (type == "WATCH_PROPERTY_R" ||
type == "WATCH_OBJECT_R" ||
type == "WATCH_EXPR_OBJECT_R") {
bool valid;
ds >> valid;
emit result(queryId, valid);
emit result(queryId, valid, type);
} else if (type == "UPDATE_WATCH") {
int debugId;
QByteArray name;
......
......@@ -81,7 +81,7 @@ signals:
void newObjects();
void valueChanged(int debugId, const QByteArray &name,
const QVariant &value);
void result(quint32 queryId, const QVariant &result);
void result(quint32 queryId, const QVariant &result, const QByteArray &type);
protected:
virtual void statusChanged(Status status);
......
......@@ -284,6 +284,11 @@ QVariant CrumblePath::dataForLastIndex() const
return d->m_buttons.last()->data();
}
int CrumblePath::length() const
{
return d->m_buttons.length();
}
void CrumblePath::pushElement(const QString &title, const QVariant &data)
{
CrumblePathButton *newButton = new CrumblePathButton(title, this);
......
......@@ -53,6 +53,7 @@ public:
void selectIndex(int index);
QVariant dataForIndex(int index) const;
QVariant dataForLastIndex() const;
int length() const;
public slots:
void pushElement(const QString &title, const QVariant &data = QVariant());
......
......@@ -314,12 +314,12 @@ void QmlAdapter::setEngineDebugClient(QmlJsDebugClient::QmlEngineDebugClient *cl
Internal::QmlEngine *engine =
qobject_cast<Internal::QmlEngine *>(d->m_engine.data());
if (engine && d->m_engineDebugClient)
disconnect(d->m_engineDebugClient, SIGNAL(result(quint32,QVariant)),
disconnect(d->m_engineDebugClient, SIGNAL(result(quint32,QVariant,QByteArray)),
engine,
SLOT(expressionEvaluated(quint32,QVariant)));
d->m_engineDebugClient = client;
if (engine && d->m_engineDebugClient)
connect(d->m_engineDebugClient, SIGNAL(result(quint32,QVariant)),
connect(d->m_engineDebugClient, SIGNAL(result(quint32,QVariant,QByteArray)),
engine,
SLOT(expressionEvaluated(quint32,QVariant)));
}
......
......@@ -57,10 +57,6 @@ ClientProxy::ClientProxy(Debugger::QmlAdapter *adapter, QObject *parent)
, m_contextQueryId(0)
, m_isConnected(false)
{
m_requestObjectsTimer.setSingleShot(true);
m_requestObjectsTimer.setInterval(3000);
connect(&m_requestObjectsTimer, SIGNAL(timeout()),
this, SLOT(refreshObjectTree()));
connectToServer();
}
......@@ -135,8 +131,8 @@ void ClientProxy::engineClientStatusChanged(QDeclarativeDebugClient::Status stat
if (status == QDeclarativeDebugClient::Enabled) {
m_engineClient = qobject_cast<QmlEngineDebugClient *>(sender());
connect(m_engineClient, SIGNAL(newObjects()), this, SLOT(newObjects()));
connect(m_engineClient, SIGNAL(result(quint32,QVariant)),
SLOT(onResult(quint32,QVariant)));
connect(m_engineClient, SIGNAL(result(quint32,QVariant,QByteArray)),
SLOT(onResult(quint32,QVariant,QByteArray)));
connect(m_engineClient, SIGNAL(valueChanged(int,QByteArray,QVariant)),
SLOT(objectWatchTriggered(int,QByteArray,QVariant)));
m_adapter.data()->setEngineDebugClient(m_engineClient);
......@@ -147,7 +143,6 @@ void ClientProxy::engineClientStatusChanged(QDeclarativeDebugClient::Status stat
void ClientProxy::refreshObjectTree()
{
if (!m_contextQueryId) {
m_requestObjectsTimer.stop();
m_objectTreeQueryIds.clear();
queryEngineContext(m_engines.value(0).debugId());
}
......@@ -429,6 +424,12 @@ bool ClientProxy::addObjectWatch(int objectDebugId)
return false;
}
bool ClientProxy::isObjectBeingWatched(int objectDebugId)
{
return m_objectWatches.contains(objectDebugId);
}
void ClientProxy::objectWatchTriggered(int objectDebugId,
const QByteArray &propertyName,
const QVariant &propertyValue)
......@@ -476,17 +477,10 @@ void ClientProxy::queryEngineContext(int id)
void ClientProxy::contextChanged(const QVariant &value)
{
log(LogReceive, QString("LIST_OBJECTS_R"));
if (m_contextQueryId) {
m_rootObjects.clear();
QmlDebugContextReference rootContext =
qvariant_cast<QmlDebugContextReference>(value);
m_contextQueryId = 0;
m_objectTreeQueryIds.clear();
m_requestObjectsTimer.stop();
fetchContextObjectRecursive(rootContext);
emit rootContext(value);
}
}
......@@ -498,26 +492,33 @@ quint32 ClientProxy::fetchContextObject(const QmlDebugObjectReference& obj)
}
void ClientProxy::fetchContextObjectRecursive(
const QmlDebugContextReference& context)
const QmlDebugContextReference& context, bool clear)
{
if (!isConnected())
return;
if (clear) {
m_rootObjects.clear();
m_objectTreeQueryIds.clear();
}
foreach (const QmlDebugObjectReference & obj, context.objects()) {
log(LogSend, QString("FETCH_OBJECT %1").arg(obj.idString()));
quint32 queryId = fetchContextObject(obj);
if (queryId)
m_objectTreeQueryIds << queryId;
}
foreach (const QmlDebugContextReference& child, context.contexts()) {
fetchContextObjectRecursive(child);
fetchContextObjectRecursive(child, false);
}
}
void ClientProxy::onResult(quint32 queryId, const QVariant &value)
void ClientProxy::onResult(quint32 queryId, const QVariant &value, const QByteArray &type)
{
if (type == "FETCH_OBJECT_R") {
log(LogReceive, QString("FETCH_OBJECT_R %1").arg(
qvariant_cast<QmlDebugObjectReference>(value).idString()));
} else {
log(LogReceive, QLatin1String(type));
}
if (m_objectTreeQueryIds.contains(queryId))
objectTreeFetched(queryId, value);
else if (queryId == m_engineQueryId)
......@@ -531,9 +532,6 @@ void ClientProxy::onResult(quint32 queryId, const QVariant &value)
void ClientProxy::objectTreeFetched(quint32 queryId, const QVariant &result)
{
QmlDebugObjectReference obj = qvariant_cast<QmlDebugObjectReference>(result);
log(LogReceive, QString("FETCH_OBJECT_R %1").arg(obj.idString()));
m_rootObjects.append(obj);
m_objectTreeQueryIds.removeOne(queryId);
......@@ -686,8 +684,6 @@ QList<QmlDebugEngineReference> ClientProxy::engines() const
void ClientProxy::updateEngineList(const QVariant &value)
{
log(LogReceive, QString("LIST_ENGINES_R"));
m_engines = qvariant_cast<QmlDebugEngineReferenceList>(value);
m_engineQueryId = 0;
emit enginesChanged();
......@@ -706,6 +702,5 @@ bool ClientProxy::isConnected() const
void ClientProxy::newObjects()
{
log(LogReceive, QString("OBJECT_CREATED"));
if (!m_requestObjectsTimer.isActive())
m_requestObjectsTimer.start();
refreshObjectTree();
}
......@@ -73,6 +73,7 @@ public:
void clearComponentCache();
bool addObjectWatch(int objectDebugId);
bool isObjectBeingWatched(int objectDebugId);
bool removeObjectWatch(int objectDebugId);
void removeAllObjectWatches();
......@@ -95,6 +96,7 @@ public:
quint32 fetchContextObject(const QmlDebugObjectReference& obj);
void addObjectToTree(const QmlDebugObjectReference &obj);
void fetchContextObjectRecursive(const QmlDebugContextReference &context, bool clear);
signals:
void objectTreeUpdated();
......@@ -119,6 +121,7 @@ signals:
void propertyChanged(int debugId, const QByteArray &propertyName, const QVariant &propertyValue);
void result(quint32 queryId, const QVariant &result);
void rootContext(const QVariant &context);
public slots:
void refreshObjectTree();
......@@ -143,10 +146,9 @@ private slots:
void engineClientStatusChanged(QDeclarativeDebugClient::Status status);
void onCurrentObjectsChanged(const QList<int> &debugIds, bool requestIfNeeded = true);
void fetchContextObjectRecursive(const QmlDebugContextReference &context);
void newObjects();
void objectWatchTriggered(int debugId, const QByteArray &propertyName, const QVariant &propertyValue);
void onResult(quint32 queryId, const QVariant &result);
void onResult(quint32 queryId, const QVariant &value, const QByteArray &type);
private:
void contextChanged(const QVariant &value);
......@@ -178,7 +180,6 @@ private:
QList<QmlDebugObjectReference> m_rootObjects;
QmlDebugEngineReferenceList m_engines;
QTimer m_requestObjectsTimer;
DebugIdHash m_debugIdHash;
QList<int> m_objectWatches;
......
......@@ -277,6 +277,15 @@ void InspectorUi::onResult(quint32 queryId, const QVariant &result)
return;
}
if (m_updateObjectQueryIds.contains(queryId)) {
m_updateObjectQueryIds.removeOne(queryId);
QmlDebugObjectReference obj = qvariant_cast<QmlDebugObjectReference>(result);
m_clientProxy->addObjectToTree(obj);
if (m_updateObjectQueryIds.empty())
showObject(obj);
return;
}
if (m_debugQuery != queryId)
return;
......@@ -349,13 +358,28 @@ void InspectorUi::disconnected()
setDebuggerEngine(0);
}
void InspectorUi::onRootContext(const QVariant &value)
{
if (m_crumblePath->dataForLastIndex().toInt() < 0) {
m_clientProxy->fetchContextObjectRecursive(
qvariant_cast<QmlDebugContextReference>(
value), true);
} else {
for (int i = 1; i < m_crumblePath->length(); i++) {
m_updateObjectQueryIds << m_clientProxy->fetchContextObject(
m_crumblePath->dataForIndex(i).toInt());
}
}
}
void InspectorUi::objectTreeReady()
{
// Should only run once, after debugger startup
if (!m_clientProxy->rootObjectReference().isEmpty()) {
if (m_crumblePath->dataForLastIndex().toInt() >= 0) {
selectItems(QList<QmlDebugObjectReference>() <<
m_clientProxy->objectReferenceForId(
m_crumblePath->dataForLastIndex().toInt()));
} else if (!m_clientProxy->rootObjectReference().isEmpty()) {
selectItems(m_clientProxy->rootObjectReference());
disconnect(m_clientProxy, SIGNAL(objectTreeUpdated()),
this, SLOT(objectTreeReady()));
}
}
......@@ -553,8 +577,8 @@ void InspectorUi::selectItems(const QList<QmlDebugObjectReference> &objectRefere
int debugId = objref.debugId();
if (debugId != -1) {
// select only the first valid element of the list
m_clientProxy->removeAllObjectWatches();
if (!m_clientProxy->isObjectBeingWatched(debugId))
m_clientProxy->removeAllObjectWatches();
//Check if the object is complete
if (objref.needsMoreData())
m_showObjectQueryId = m_clientProxy->fetchContextObject(objref);
......@@ -842,6 +866,8 @@ void InspectorUi::connectSignals()
this, SLOT(serverReloaded()));
connect(m_clientProxy, SIGNAL(objectTreeUpdated()),
this, SLOT(objectTreeReady()));
connect(m_clientProxy, SIGNAL(rootContext(QVariant)),
this, SLOT(onRootContext(QVariant)));
connect(m_clientProxy, SIGNAL(connected()),
this, SLOT(enable()));
connect(m_clientProxy, SIGNAL(disconnected()),
......
......@@ -121,6 +121,7 @@ private slots:
void changeSelectedItems(const QList<QmlDebugObjectReference> &objects);
void changePropertyValue(int debugId,const QString &propertyName, const QString &valueExpression);
void objectTreeReady();
void onRootContext(const QVariant &value);
void updateEngineList();
......@@ -160,6 +161,7 @@ private:
QObject *m_qmlEngine;
quint32 m_debugQuery;
quint32 m_showObjectQueryId;
QList<quint32> m_updateObjectQueryIds;
// Qml/JS integration
QHash<QString, QmlJSLiveTextPreview *> m_textPreviews;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment