Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
qobjectregistrysingleton.cpp
Go to the documentation of this file.
1// Copyright (C) 2026 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
5
6#include <private/qabstractobjectregistryref_p.h>
7#include <private/qqmldata_p.h>
8
9#include <QtQml/qqmlengine.h>
10
12
13QObjectRegistrySingleton::QObjectRegistrySingleton(QObject *parent)
14 : QObject(parent)
15{
16}
17
18QObjectRegistrySingleton::~QObjectRegistrySingleton()
19{
20 for (const auto &guards : std::as_const(m_objects))
21 qDeleteAll(guards);
22}
23
24void QObjectRegistrySingleton::add(const QString &key, QObject *obj)
25{
26 if (key.isEmpty() || !obj)
27 return;
28
29 if (QQmlData::wasDeleted(obj))
30 return;
31
32 auto &guards = m_objects[key];
33 if (guards.contains(obj))
34 return;
35
36 guards.insert(obj, new ObjectGuard(this, key, obj));
37
38 notifyRefs(key, obj, Notification::ObjectAdded);
39}
40
41void QObjectRegistrySingleton::remove(const QString &key, QObject *obj)
42{
43 if (key.isEmpty() || !obj)
44 return;
45
46 const auto keyIt = m_objects.find(key);
47 if (keyIt == m_objects.end())
48 return;
49
50 const std::unique_ptr<ObjectGuard> guard(keyIt->take(obj));
51 if (!guard)
52 return;
53
54 if (keyIt->isEmpty())
55 m_objects.erase(keyIt);
56
57 notifyRefs(key, obj, Notification::ObjectRemoved);
58}
59
60void QObjectRegistrySingleton::notifyRefs(const QString &key, QObject *obj,
61 Notification notification)
62{
63 // Guard against add/remove handlers changing/removing existing references by iterating over
64 // a copy of references and checking each reference is still registered before each notification
65 const auto refs = m_refs.value(key);
66 for (const auto &ref : refs) {
67 const auto keyIt = m_refs.constFind(key);
68 if (keyIt == m_refs.cend() || !keyIt->contains(ref))
69 continue;
70
71 if (notification == Notification::ObjectAdded)
72 ref->handleObjectAdded(obj);
73 else
74 ref->handleObjectRemoved(obj);
75 }
76}
77
78QSet<QObject*> QObjectRegistrySingleton::objects(const QString &key) const
79{
80 const auto keyIt = m_objects.constFind(key);
81 if (keyIt == m_objects.cend())
82 return {};
83
84 return QSet<QObject *>(keyIt->keyBegin(), keyIt->keyEnd());
85}
86
87void QObjectRegistrySingleton::registerRef(QAbstractObjectRegistryRefPrivate *ref)
88{
89 if (!ref)
90 return;
91
92 m_refs[ref->key()].insert(ref);
93}
94
95void QObjectRegistrySingleton::deregisterRef(QAbstractObjectRegistryRefPrivate *ref)
96{
97 if (!ref)
98 return;
99
100 if (m_refs.contains(ref->key())) {
101 m_refs[ref->key()].remove(ref);
102 if (m_refs[ref->key()].isEmpty())
103 m_refs.remove(ref->key());
104 }
105}
106
107QObjectRegistrySingleton *QObjectRegistrySingleton::registryForObject(QObject *obj)
108{
109 return registryForEngine(qmlEngine(obj));
110}
111
112QObjectRegistrySingleton *QObjectRegistrySingleton::registryForEngine(QQmlEngine *engine)
113{
114 if (engine) {
115 static int typeId = qmlTypeId("QtQml.DesignSupport",
116 QT_VERSION_MAJOR,
117 QT_VERSION_MINOR,
118 "InternalObjectRegistry");
119
120 return engine->singletonInstance<QObjectRegistrySingleton *>(typeId);
121 }
122 return nullptr;
123}
124
125QT_END_NAMESPACE
Combined button and popup list for selecting options.