Files
qbz/crates/qbz-qt/cxx/local_artists_model.h
T
vicrodh 6fd83c42df feat(library): page Artists from local catalog
Materialize source-scoped artist aggregates and FTS, then expose exact keyset pages and bounded A-Z metadata for the existing Artists rail.

Query the selected artist's albums through the indexed credit relationship with an independent bounded model, generation cancellation, artwork updates, and per-surface legacy fallback.

cx
2026-08-23 12:17:08 -06:00

80 lines
2.6 KiB
C++

#ifndef QBZ_LOCAL_ARTISTS_MODEL_H
#define QBZ_LOCAL_ARTISTS_MODEL_H
#include <QtCore/QAbstractListModel>
#include <QtCore/QHash>
#include <QtCore/QList>
#include <QtCore/QVariantMap>
class LocalArtistsModel final : public QAbstractListModel
{
Q_OBJECT
Q_PROPERTY(int generation READ generation NOTIFY generationChanged)
Q_PROPERTY(qint64 totalCount READ totalCount NOTIFY totalCountChanged)
Q_PROPERTY(qint64 artistTotal READ artistTotal NOTIFY artistTotalChanged)
Q_PROPERTY(int residentArtists READ residentArtists NOTIFY residentArtistsChanged)
Q_PROPERTY(qint64 evictions READ evictions NOTIFY evictionsChanged)
public:
enum Role { ModelDataRole = Qt::UserRole + 1 };
explicit LocalArtistsModel(QObject *parent = nullptr);
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QHash<int, QByteArray> roleNames() const override;
int generation() const { return m_generation; }
qint64 totalCount() const { return m_totalCount; }
qint64 artistTotal() const { return m_artistTotal; }
int residentArtists() const { return m_residentArtists; }
qint64 evictions() const { return m_evictions; }
Q_INVOKABLE QVariantMap rowAt(qint64 row) const;
Q_INVOKABLE void setArtwork(const QString &artKey, const QString &path);
void resetQuery(int generation, qint64 totalCount, qint64 artistTotal);
bool applyPage(int generation, int page, const QByteArray &json);
signals:
void generationChanged();
void totalCountChanged();
void artistTotalChanged();
void residentArtistsChanged();
void evictionsChanged();
void pageMiss(int page, int generation);
private:
struct Entry {
QVariantMap values;
QString artKey;
bool isArtist = false;
};
using Page = QList<Entry>;
static constexpr int PageEntries = 100;
static constexpr int MaxResidentArtists = 2000;
QVariantMap modelData(qint64 row) const;
void requestPage(int page, bool prefetch = false) const;
void touch(int page) const;
void evictIfNeeded();
int m_generation = 0;
qint64 m_totalCount = 0;
qint64 m_artistTotal = 0;
QHash<int, Page> m_pages;
mutable QList<int> m_lru;
mutable QHash<int, bool> m_pending;
int m_residentArtists = 0;
qint64 m_evictions = 0;
};
extern "C" {
void qbz_local_artists_register_qml_type();
void qbz_local_artists_reset(int generation, qint64 totalCount, qint64 artistTotal);
bool qbz_local_artists_apply_page(int generation, int page, const char *json);
}
#endif // QBZ_LOCAL_ARTISTS_MODEL_H