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 | |
13 | QT_BEGIN_NAMESPACE |
14 | |
15 | class QQmlDebugServer; |
16 | |
17 | class QQmlDebugServicePrivate : public QObjectPrivate |
18 | { |
19 | Q_DECLARE_PUBLIC(QQmlDebugService) |
20 | public: |
21 | QQmlDebugServicePrivate(const QString &name, float version); |
22 | |
23 | const QString name; |
24 | const float version; |
25 | QQmlDebugService::State state; |
26 | }; |
27 | |
28 | QQmlDebugServicePrivate::QQmlDebugServicePrivate(const QString &name, float version) : |
29 | name(name), version(version), state(QQmlDebugService::NotConnected) |
30 | { |
31 | } |
32 | |
33 | QQmlDebugService::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 | |
49 | QQmlDebugService::~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 | |
63 | const QString &QQmlDebugService::name() const |
64 | { |
65 | Q_D(const QQmlDebugService); |
66 | return d->name; |
67 | } |
68 | |
69 | float QQmlDebugService::version() const |
70 | { |
71 | Q_D(const QQmlDebugService); |
72 | return d->version; |
73 | } |
74 | |
75 | QQmlDebugService::State QQmlDebugService::state() const |
76 | { |
77 | Q_D(const QQmlDebugService); |
78 | return d->state; |
79 | } |
80 | |
81 | void QQmlDebugService::setState(QQmlDebugService::State newState) |
82 | { |
83 | Q_D(QQmlDebugService); |
84 | d->state = newState; |
85 | } |
86 | |
87 | namespace { |
88 | class ObjectReferenceHash : public QObject |
89 | { |
90 | Q_OBJECT |
91 | public: |
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 | } |
102 | Q_GLOBAL_STATIC(ObjectReferenceHash, objectReferenceHash) |
103 | |
104 | void 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 | */ |
117 | int 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 | */ |
137 | const QHash<int, QObject *> &QQmlDebugService::objectsForIds() |
138 | { |
139 | return objectReferenceHash()->ids; |
140 | } |
141 | |
142 | QT_END_NAMESPACE |
143 | |
144 | #include "qqmldebugservice.moc" |
145 | #include "moc_qqmldebugservice_p.cpp" |
146 | |