1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3
4#include "qqmldebugservice_p.h"
5#include "qqmldebugconnector_p.h"
6#include <private/qqmldata_p.h>
7#include <private/qqmlcontext_p.h>
8
9#include <QtCore/QDebug>
10#include <QtCore/QStringList>
11#include <QtCore/QFileInfo>
12
13QT_BEGIN_NAMESPACE
14
15class QQmlDebugServer;
16
17class QQmlDebugServicePrivate : public QObjectPrivate
18{
19 Q_DECLARE_PUBLIC(QQmlDebugService)
20public:
21 QQmlDebugServicePrivate(const QString &name, float version);
22
23 const QString name;
24 const float version;
25 QQmlDebugService::State state;
26};
27
28QQmlDebugServicePrivate::QQmlDebugServicePrivate(const QString &name, float version) :
29 name(name), version(version), state(QQmlDebugService::NotConnected)
30{
31}
32
33QQmlDebugService::QQmlDebugService(const QString &name, float version, QObject *parent)
34 : QObject(*(new QQmlDebugServicePrivate(name, version)), parent)
35{
36 Q_D(QQmlDebugService);
37 QQmlDebugConnector *server = QQmlDebugConnector::instance();
38
39 if (!server)
40 return;
41
42 if (server->service(name: d->name)) {
43 qWarning() << "QQmlDebugService: Conflicting plugin name" << d->name;
44 } else {
45 server->addService(name: d->name, service: this);
46 }
47}
48
49QQmlDebugService::~QQmlDebugService()
50{
51 Q_D(QQmlDebugService);
52 QQmlDebugConnector *server = QQmlDebugConnector::instance();
53
54 if (!server)
55 return;
56
57 if (server->service(name: d->name) != this)
58 qWarning() << "QQmlDebugService: Plugin" << d->name << "is not registered.";
59 else
60 server->removeService(name: d->name);
61}
62
63const QString &QQmlDebugService::name() const
64{
65 Q_D(const QQmlDebugService);
66 return d->name;
67}
68
69float QQmlDebugService::version() const
70{
71 Q_D(const QQmlDebugService);
72 return d->version;
73}
74
75QQmlDebugService::State QQmlDebugService::state() const
76{
77 Q_D(const QQmlDebugService);
78 return d->state;
79}
80
81void QQmlDebugService::setState(QQmlDebugService::State newState)
82{
83 Q_D(QQmlDebugService);
84 d->state = newState;
85}
86
87namespace {
88class ObjectReferenceHash : public QObject
89{
90 Q_OBJECT
91public:
92 ObjectReferenceHash() : nextId(0) {}
93
94 QHash<QObject *, int> objects;
95 QHash<int, QObject *> ids;
96
97 int nextId;
98
99 void remove(QObject *obj);
100};
101}
102Q_GLOBAL_STATIC(ObjectReferenceHash, objectReferenceHash)
103
104void ObjectReferenceHash::remove(QObject *obj)
105{
106 QHash<QObject *, int>::Iterator iter = objects.find(key: obj);
107 if (iter != objects.end()) {
108 ids.remove(key: iter.value());
109 objects.erase(it: iter);
110 }
111}
112
113/*!
114 Returns a unique id for \a object. Calling this method multiple times
115 for the same object will return the same id.
116*/
117int QQmlDebugService::idForObject(QObject *object)
118{
119 if (!object)
120 return -1;
121
122 ObjectReferenceHash *hash = objectReferenceHash();
123 QHash<QObject *, int>::Iterator iter = hash->objects.find(key: object);
124
125 if (iter == hash->objects.end()) {
126 int id = hash->nextId++;
127 hash->ids.insert(key: id, value: object);
128 iter = hash->objects.insert(key: object, value: id);
129 connect(sender: object, signal: &QObject::destroyed, context: hash, slot: &ObjectReferenceHash::remove);
130 }
131 return iter.value();
132}
133
134/*!
135 Returns the mapping of objects to unique \a ids, created through calls to idForObject().
136*/
137const QHash<int, QObject *> &QQmlDebugService::objectsForIds()
138{
139 return objectReferenceHash()->ids;
140}
141
142QT_END_NAMESPACE
143
144#include "qqmldebugservice.moc"
145#include "moc_qqmldebugservice_p.cpp"
146

source code of qtdeclarative/src/qml/debugger/qqmldebugservice.cpp