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
qrhivaluemapper_p.h
Go to the documentation of this file.
1// Copyright (C) 2024 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 QRHIVALUEMAPPER_P_H
5#define QRHIVALUEMAPPER_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 <QtMultimedia/qtmultimediaglobal.h>
19#include <QtMultimedia/private/qmultimedia_ranges_p.h>
20
21#include <qreadwritelock.h>
22
23#include <memory>
24#include <map>
25
26QT_BEGIN_NAMESPACE
27
28class QRhi;
29
30/**
31 * @brief The QRhiCallback class implements a thread-safe wrapper around QRhi
32 * cleanup callbacks. For adding a callback to QRhi, create a shared insance
33 * of the class and invoke addToRhi for the specific QRhi. To deactivate
34 * the callback delete the instance.
35 */
36class Q_MULTIMEDIA_EXPORT QRhiCallback : public std::enable_shared_from_this<QRhiCallback>
37{
38public:
39 class Manager;
40
41 QRhiCallback();
42 virtual ~QRhiCallback();
43
44 void registerCallback(QRhi &rhi);
45
46protected:
47 virtual void onRhiCleanup(QRhi &rhi) = 0;
48
49private:
50 std::shared_ptr<Manager> m_manager;
51};
52
53/**
54 * @brief The class associates values of the specified type with different QRhi.
55 * One instance of QRhiValueMapper associates one QRhi with one value.
56 * The mapped value is deleted when the matching QRhi is cleaned/deleted,
57 * when QRhiValueMapper::clear is invoked, or the QRhiValueMapper's
58 * instance is deleted.
59 *
60 * QRhiValueMapper's API is thread safe, whereas the objects, which pointers you
61 * obtain via QRhiValueMapper::get(), are not. Thus, their thread-safity
62 * has to be managed by the code using the mapper.
63
64 * Note, that QRhiValueMapper destructs the values under its mutex.
65 * Keep it in mind and aim to avoid callbacks and signals emissions fror
66 * the Value's destructor.
67 */
68template <typename Value>
70{
71 struct Data : QRhiCallback
72 {
73 QReadWriteLock lock;
74 // In most cases, one or 2 elements will be here, so let's use map
75 // instead of unordered_map for better efficiency with few elements.
76 std::map<QRhi *, Value> storage;
77
78 void onRhiCleanup(QRhi &rhi) override
79 {
80 QWriteLocker locker(&lock);
81 storage.erase(&rhi);
82 }
83 };
84
85public:
87 {
88 clear(); // it must be cleared when on the destruction to synchronize with rhi cleanup
89 }
90
92
93 QRhiValueMapper(QRhiValueMapper&& ) noexcept = default;
94 QRhiValueMapper& operator = (QRhiValueMapper&&) noexcept = default;
95
96 QRhiValueMapper() : m_data(std::make_shared<Data>()) { }
97
98 template <typename V>
99 std::pair<Value *, bool> tryMap(QRhi &rhi, V &&value)
100 {
101 QWriteLocker locker(&m_data->lock);
102
103 auto [rhiIt, rhiAdded] = m_data->storage.try_emplace(&rhi, std::forward<V>(value));
104
105 if (rhiAdded)
106 m_data->registerCallback(rhi);
107
108 return { &rhiIt->second, rhiAdded };
109 }
110
111 Value *get(QRhi *rhi) const
112 {
113 QReadLocker locker(&m_data->lock);
114 auto rhiIt = m_data->storage.find(rhi);
115 return rhiIt == m_data->storage.end() ? nullptr : &rhiIt->second;
116 }
117
118 // To be added for thread-safe value read:
119 //
120 // template <typename Reader>
121 // void read(QRhi &rhi, Reader&& reader) const {
122 // QReadLocker locker(&m_data->lock);
123 // auto rhiIt = m_data->storage.find(&rhi);
124 // if (rhiIt != m_data->storage.end())
125 // reader(const_cast<const Value&>(rhiIt->second));
126 // }
127
128 void clear()
129 {
130 if (!m_data)
131 return; // the object has been moved
132 QWriteLocker locker(&m_data->lock);
133 m_data->storage.clear();
134 }
135
136 template <typename Predicate>
137 QRhi *findRhi(Predicate &&p) const
138 {
139 QReadLocker locker(&m_data->lock);
140 auto &storage = m_data->storage;
141 namespace ranges = QtMultimediaPrivate::ranges;
142
143 auto it = ranges::find_if(storage, [&](auto &rhiItem) {
144 return p(*rhiItem.first);
145 });
146 return it == storage.end() ? nullptr : it->first;
147 }
148
149private:
150 std::shared_ptr<Data> m_data;
151};
152
153QT_END_NAMESPACE
154
155#endif // QRHIVALUEMAPPER_P_H
\inmodule QtCore
Definition qmutex.h:346
void registerCallback(QRhi &rhi, const std::weak_ptr< QRhiCallback > &cb)
The QRhiCallback class implements a thread-safe wrapper around QRhi cleanup callbacks....
The class associates values of the specified type with different QRhi. One instance of QRhiValueMappe...
QRhiValueMapper & operator=(QRhiValueMapper &&) noexcept=default
QRhiValueMapper(QRhiValueMapper &&) noexcept=default
QRhi * findRhi(Predicate &&p) const
std::pair< Value *, bool > tryMap(QRhi &rhi, V &&value)
Value * get(QRhi *rhi) const
Combined button and popup list for selecting options.
QMutex QBasicMutex
Definition qmutex.h:360
Q_GLOBAL_STATIC(const QTzTimeZoneHash, tzZones, loadTzTimeZones())