9#include <QtCore/QPointer>
10#include <QtCore/QVariant>
11#include <QtQml/QQmlComponent>
12#include <QtQml/QQmlEngine>
13#include <QtQml/QQmlIncubator>
15#include "qml_material/export.hpp"
20auto pool_object_count() -> std::size_t;
24class QML_MATERIAL_API PoolRequest :
public QObject {
26 QML_NAMED_ELEMENT(PoolRequest)
27 QML_UNCREATABLE(
"PoolRequest objects are returned by Pool.request()")
29 Q_PROPERTY(qint64
id READ
id CONSTANT FINAL)
30 Q_PROPERTY(QVariant key READ key CONSTANT FINAL)
31 Q_PROPERTY(Status status READ status NOTIFY statusChanged FINAL)
32 Q_PROPERTY(qreal progress READ progress NOTIFY progressChanged FINAL)
33 Q_PROPERTY(QObject*
object READ
object NOTIFY objectChanged FINAL)
34 Q_PROPERTY(
bool cached READ cached NOTIFY cachedChanged FINAL)
35 Q_PROPERTY(QString errorString READ errorString NOTIFY errorStringChanged FINAL)
49 auto id() const -> qint64;
50 auto key() const -> QVariant;
51 auto status() const -> Status;
52 auto progress() const -> qreal;
53 auto
object() const -> QObject*;
54 auto cached() const ->
bool;
55 auto errorString() const -> QString;
57 Q_INVOKABLE
void cancel();
58 Q_INVOKABLE
void forceCompletion();
59 Q_INVOKABLE
void release();
61 Q_SIGNAL
void statusChanged();
62 Q_SIGNAL
void progressChanged();
63 Q_SIGNAL
void objectChanged();
64 Q_SIGNAL
void cachedChanged();
65 Q_SIGNAL
void errorStringChanged();
70 PoolRequest(Pool* pool, qint64
id, QVariant key);
72 void setStatus(Status value);
73 void setProgress(qreal value);
74 void setObject(QObject* value);
75 void setCached(
bool value);
76 void setErrorString(QString value);
78 QPointer<Pool> m_pool;
81 Status m_status { Null };
82 qreal m_progress { 0 };
83 QPointer<QObject> m_object;
84 bool m_cached {
false };
85 QString m_errorString;
88class PoolIncubator :
public QQmlIncubator {
90 PoolIncubator(Pool* pool, qint64
id, IncubationMode mode);
93 void statusChanged(Status status)
override;
94 void setInitialState(QObject*
object)
override;
101class QML_MATERIAL_API Pool :
public QObject {
105 Q_PROPERTY(
bool async READ async WRITE setAsync NOTIFY asyncChanged FINAL)
107 friend class PoolIncubator;
108 friend class PoolRequest;
114 AsynchronousIfNested,
117 Q_ENUM(IncubationMode)
119 explicit Pool(QObject* parent =
nullptr);
122 Q_INVOKABLE PoolRequest* request(
const QVariant& source,
123 const QVariantMap& initialProperties = {},
124 const QVariant& key = {},
125 IncubationMode mode = AsynchronousIfNested);
127 Q_INVOKABLE
bool contains(
const QString& key)
const;
128 Q_INVOKABLE QObject* get(
const QString& key)
const;
129 Q_INVOKABLE
bool evict(
const QVariant& key);
130 Q_INVOKABLE
void clear();
132 Q_INVOKABLE
void add(
const QVariant& source,
const QVariantMap& initialProperties,
133 bool autoKey =
false);
134 Q_INVOKABLE
void addWithKey(
const QString& key,
const QVariant& source,
135 const QVariantMap& initialProperties);
136 Q_SIGNAL
void objectAdded(QObject*
object,
const QVariant& key);
138 auto async() const ->
bool;
139 void setAsync(
bool value);
140 Q_SIGNAL
void asyncChanged(
bool value);
142 Q_INVOKABLE
bool removeObject(QObject*
object);
144 void add(std::optional<QStringView> key, QQmlComponent* component,
145 const QVariantMap& initialProperties);
151 QVariantMap initialProperties;
153 bool hasKey {
false };
155 QPointer<PoolRequest> request;
156 QPointer<QQmlComponent> component;
157 std::unique_ptr<QQmlComponent> ownedComponent;
158 std::unique_ptr<PoolIncubator> incubator;
160 bool terminal {
false };
164 QPointer<QObject> object;
165 QPointer<PoolRequest> lease;
167 bool evictOnRelease {
false };
170 void incubatorStateChanged(qint64
id, QQmlIncubator::Status status);
171 void setInitialState(qint64
id, QObject*
object);
172 void onComponentStatusChanged(qint64
id);
173 void onComponentProgressChanged(qint64
id, qreal progress);
174 void startIncubation(qint64
id);
175 void forceRequest(PoolRequest* request);
176 void cancelRequest(PoolRequest* request);
177 void releaseRequest(PoolRequest* request);
179 auto createComponent(Task& task, QQmlComponent::CompilationMode mode) -> bool;
180 auto taskError(
const Task& task)
const -> QString;
181 auto genSerial() -> qint64;
182 auto toQtMode(IncubationMode mode)
const -> QQmlIncubator::IncubationMode;
184 void finishReady(qint64
id, QObject*
object);
185 void finishError(qint64
id, QString error);
186 void finishCancelled(qint64
id);
187 void scheduleTaskCleanup(qint64
id);
188 void removeInflightKey(
const Task& task);
190 void onCacheObjectDestroyed(
const QString& key, qint64 generation);
191 void onUncachedObjectDestroyed(QObject*
object);
192 void attachLegacy(PoolRequest* request);
193 void queueLegacyDrain();
196 std::map<qint64, std::unique_ptr<Task>> m_tasks;
197 std::map<QString, CacheEntry, std::less<>> m_cache;
198 std::map<QString, QPointer<PoolRequest>, std::less<>> m_inflightKeys;
199 std::map<QObject*, QPointer<PoolRequest>> m_uncached;
200 std::deque<QPointer<PoolRequest>> m_legacyQueue;
202 qint64 m_serial { 0 };
203 bool m_async {
true };
204 bool m_destroying {
false };
205 bool m_legacyDrainPending {
false };