core/variants: expose instances list as a property

This commit is contained in:
outfoxxed 2024-03-21 05:32:55 -07:00
parent f09f591e6a
commit 4eb5dc5593
Signed by: outfoxxed
GPG key ID: 4C88A185FB89301E
2 changed files with 30 additions and 7 deletions

View file

@ -8,6 +8,7 @@
#include <qqmlengine.h> #include <qqmlengine.h>
#include <qqmllist.h> #include <qqmllist.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <qtypes.h>
#include <qvariant.h> #include <qvariant.h>
#include "reload.hpp" #include "reload.hpp"
@ -15,10 +16,10 @@
void Variants::onReload(QObject* oldInstance) { void Variants::onReload(QObject* oldInstance) {
auto* old = qobject_cast<Variants*>(oldInstance); auto* old = qobject_cast<Variants*>(oldInstance);
for (auto& [variant, instanceObj]: this->instances.values) { for (auto& [variant, instanceObj]: this->mInstances.values) {
QObject* oldInstance = nullptr; QObject* oldInstance = nullptr;
if (old != nullptr) { if (old != nullptr) {
auto& values = old->instances.values; auto& values = old->mInstances.values;
if (variant.canConvert<QVariantMap>()) { if (variant.canConvert<QVariantMap>()) {
auto variantMap = variant.value<QVariantMap>(); auto variantMap = variant.value<QVariantMap>();
@ -96,6 +97,19 @@ void Variants::setModel(const QVariant& model) {
this->updateVariants(); this->updateVariants();
emit this->modelChanged(); emit this->modelChanged();
emit this->instancesChanged();
}
QQmlListProperty<QObject> Variants::instances() {
return QQmlListProperty<QObject>(this, nullptr, &Variants::instanceCount, &Variants::instanceAt);
}
qsizetype Variants::instanceCount(QQmlListProperty<QObject>* prop) {
return static_cast<Variants*>(prop->object)->mInstances.values.length(); // NOLINT
}
QObject* Variants::instanceAt(QQmlListProperty<QObject>* prop, qsizetype i) {
return static_cast<Variants*>(prop->object)->mInstances.values.at(i).second; // NOLINT
} }
void Variants::componentComplete() { void Variants::componentComplete() {
@ -110,12 +124,12 @@ void Variants::updateVariants() {
} }
// clean up removed entries // clean up removed entries
for (auto iter = this->instances.values.begin(); iter < this->instances.values.end();) { for (auto iter = this->mInstances.values.begin(); iter < this->mInstances.values.end();) {
if (this->mModel.contains(iter->first)) { if (this->mModel.contains(iter->first)) {
iter++; iter++;
} else { } else {
iter->second->deleteLater(); iter->second->deleteLater();
iter = this->instances.values.erase(iter); iter = this->mInstances.values.erase(iter);
} }
} }
@ -130,7 +144,7 @@ void Variants::updateVariants() {
} }
{ {
if (this->instances.contains(variant)) { if (this->mInstances.contains(variant)) {
continue; // we dont need to recreate this one continue; // we dont need to recreate this one
} }
@ -151,7 +165,7 @@ void Variants::updateVariants() {
QQmlEngine::setObjectOwnership(instance, QQmlEngine::CppOwnership); QQmlEngine::setObjectOwnership(instance, QQmlEngine::CppOwnership);
instance->setParent(this); instance->setParent(this);
this->instances.insert(variant, instance); this->mInstances.insert(variant, instance);
if (this->loaded) { if (this->loaded) {
if (auto* reloadable = qobject_cast<Reloadable*>(instance)) reloadable->onReload(nullptr); if (auto* reloadable = qobject_cast<Reloadable*>(instance)) reloadable->onReload(nullptr);

View file

@ -6,6 +6,7 @@
#include <qmap.h> #include <qmap.h>
#include <qobject.h> #include <qobject.h>
#include <qqmlcomponent.h> #include <qqmlcomponent.h>
#include <qqmllist.h>
#include <qqmlparserstatus.h> #include <qqmlparserstatus.h>
#include <qtmetamacros.h> #include <qtmetamacros.h>
#include <qvariant.h> #include <qvariant.h>
@ -52,6 +53,8 @@ class Variants: public Reloadable {
/// Each set creates an instance of the component, which are updated when the input sets update. /// Each set creates an instance of the component, which are updated when the input sets update.
QSDOC_PROPERTY_OVERRIDE(QList<QVariant> model READ model WRITE setModel NOTIFY modelChanged); QSDOC_PROPERTY_OVERRIDE(QList<QVariant> model READ model WRITE setModel NOTIFY modelChanged);
QSDOC_HIDE Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged); QSDOC_HIDE Q_PROPERTY(QVariant model READ model WRITE setModel NOTIFY modelChanged);
/// Current instances of the delegate.
Q_PROPERTY(QQmlListProperty<QObject> instances READ instances NOTIFY instancesChanged);
Q_CLASSINFO("DefaultProperty", "delegate"); Q_CLASSINFO("DefaultProperty", "delegate");
QML_ELEMENT; QML_ELEMENT;
@ -64,14 +67,20 @@ public:
[[nodiscard]] QVariant model() const; [[nodiscard]] QVariant model() const;
void setModel(const QVariant& model); void setModel(const QVariant& model);
QQmlListProperty<QObject> instances();
signals: signals:
void modelChanged(); void modelChanged();
void instancesChanged();
private: private:
static qsizetype instanceCount(QQmlListProperty<QObject>* prop);
static QObject* instanceAt(QQmlListProperty<QObject>* prop, qsizetype i);
void updateVariants(); void updateVariants();
QQmlComponent* mDelegate = nullptr; QQmlComponent* mDelegate = nullptr;
QVariantList mModel; QVariantList mModel;
AwfulMap<QVariant, QObject*> instances; AwfulMap<QVariant, QObject*> mInstances;
bool loaded = false; bool loaded = false;
}; };