1// Copyright (C) 2019 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#ifndef QQMLTYPEMODULE_P_H
5#define QQMLTYPEMODULE_P_H
6
7//
8// W A R N I N G
9// -------------
10//
11// This file is not part of the Qt API. It exists purely as an
12// implementation detail. This header file may change from version to
13// version without notice, or even be removed.
14//
15// We mean it.
16//
17
18#include <QtQml/qtqmlglobal.h>
19#include <QtQml/private/qstringhash_p.h>
20#include <QtQml/private/qqmltype_p.h>
21#include <QtCore/qmutex.h>
22#include <QtCore/qstring.h>
23#include <QtCore/qversionnumber.h>
24
25#include <functional>
26
27QT_BEGIN_NAMESPACE
28
29class QQmlType;
30class QQmlTypePrivate;
31struct QQmlMetaTypeData;
32
33namespace QV4 {
34struct String;
35}
36
37class QQmlTypeModule
38{
39public:
40 enum class LockLevel {
41 Open = 0,
42 Weak = 1,
43 Strong = 2
44 };
45
46 QQmlTypeModule() = default;
47 QQmlTypeModule(const QString &uri, quint8 majorVersion)
48 : m_module(uri), m_majorVersion(majorVersion)
49 {}
50
51 void add(QQmlTypePrivate *);
52 void remove(const QQmlTypePrivate *type);
53
54 LockLevel lockLevel() const { return LockLevel(m_lockLevel.loadRelaxed()); }
55 bool setLockLevel(LockLevel mode)
56 {
57 while (true) {
58 const int currentLock = m_lockLevel.loadAcquire();
59 if (currentLock > int(mode))
60 return false;
61 if (currentLock == int(mode) || m_lockLevel.testAndSetRelease(expectedValue: currentLock, newValue: int(mode)))
62 return true;
63 }
64 }
65
66 QString module() const
67 {
68 // No need to lock. m_module is const
69 return m_module;
70 }
71
72 quint8 majorVersion() const
73 {
74 // No need to lock. d->majorVersion is const
75 return m_majorVersion;
76 }
77
78 void addMinorVersion(quint8 minorVersion);
79 quint8 minimumMinorVersion() const { return m_minMinorVersion.loadRelaxed(); }
80 quint8 maximumMinorVersion() const { return m_maxMinorVersion.loadRelaxed(); }
81
82 QQmlType type(const QHashedStringRef &name, QTypeRevision version) const
83 {
84 QMutexLocker lock(&m_mutex);
85 return findType(types: m_typeHash.value(key: name), version);
86 }
87
88 QQmlType type(const QV4::String *name, QTypeRevision version) const
89 {
90 QMutexLocker lock(&m_mutex);
91 return findType(types: m_typeHash.value(string: name), version);
92 }
93
94 void walkCompositeSingletons(const std::function<void(const QQmlType &)> &callback) const;
95
96private:
97 static Q_QML_PRIVATE_EXPORT QQmlType findType(
98 const QList<QQmlTypePrivate *> *types, QTypeRevision version);
99
100 const QString m_module;
101 const quint8 m_majorVersion = 0;
102
103 // Can only ever decrease
104 QAtomicInt m_minMinorVersion = std::numeric_limits<quint8>::max();
105
106 // Can only ever increase
107 QAtomicInt m_maxMinorVersion = 0;
108
109 // LockLevel. Can only be increased.
110 QAtomicInt m_lockLevel = int(LockLevel::Open);
111
112 using TypeHash = QStringHash<QList<QQmlTypePrivate *>>;
113 TypeHash m_typeHash;
114
115 mutable QMutex m_mutex;
116};
117
118QT_END_NAMESPACE
119
120#endif // QQMLTYPEMODULE_P_H
121

source code of qtdeclarative/src/qml/qml/qqmltypemodule_p.h