plugin/cim: better cache impl

This commit is contained in:
2 * r + 2 * t 2025-08-30 14:45:42 +10:00
parent 3596f2906e
commit d22576ee82
5 changed files with 42 additions and 19 deletions

View file

@ -16,11 +16,6 @@ Image {
sourceSize.width: sourceWidth sourceSize.width: sourceWidth
sourceSize.height: sourceHeight sourceSize.height: sourceHeight
onStatusChanged: {
if (!manager.usingCache && status === Image.Ready)
CUtils.saveItem(this, manager.cachePath);
}
Connections { Connections {
target: QsWindow.window target: QsWindow.window

View file

@ -1,4 +1,4 @@
find_package(Qt6 REQUIRED COMPONENTS Core Qml) find_package(Qt6 REQUIRED COMPONENTS Core Qml Gui)
if(QT_KNOWN_POLICY_QTP0001) if(QT_KNOWN_POLICY_QTP0001)
qt_policy(SET QTP0001 NEW) qt_policy(SET QTP0001 NEW)

View file

@ -23,4 +23,4 @@ install(TARGETS "${module_plugin_target}" LIBRARY DESTINATION "${module_dir}" RU
install(FILES "${module_qmldir}" DESTINATION "${module_dir}") install(FILES "${module_qmldir}" DESTINATION "${module_dir}")
install(FILES "${module_typeinfo}" DESTINATION "${module_dir}") install(FILES "${module_typeinfo}" DESTINATION "${module_dir}")
target_link_libraries(caelestia PRIVATE Qt::Core Qt::Qml) target_link_libraries(caelestia PRIVATE Qt::Core Qt::Qml Qt::Gui)

View file

@ -6,6 +6,8 @@
#include <QCryptographicHash> #include <QCryptographicHash>
#include <QThreadPool> #include <QThreadPool>
#include <QFile> #include <QFile>
#include <QDir>
#include <QImageReader>
qreal CachingImageManager::effectiveScale() const { qreal CachingImageManager::effectiveScale() const {
if (m_item->window()) { if (m_item->window()) {
@ -99,10 +101,9 @@ void CachingImageManager::updateSource(const QString& path) {
const QString sha = sha256sum(path); const QString sha = sha256sum(path);
QMetaObject::invokeMethod(this, [path, sha, this]() { QMetaObject::invokeMethod(this, [path, sha, this]() {
const QString filename = QString("%1@%2x%3.png") int width = effectiveWidth();
.arg(sha) int height = effectiveHeight();
.arg(effectiveWidth()) const QString filename = QString("%1@%2x%3.png").arg(sha).arg(width).arg(height);
.arg(effectiveHeight());
const QUrl cache = m_cacheDir.resolved(QUrl(filename)); const QUrl cache = m_cacheDir.resolved(QUrl(filename));
if (m_cachePath == cache) { if (m_cachePath == cache) {
@ -123,10 +124,8 @@ void CachingImageManager::updateSource(const QString& path) {
m_item->setProperty("source", cache); m_item->setProperty("source", cache);
} else { } else {
m_item->setProperty("source", QUrl::fromLocalFile(path)); m_item->setProperty("source", QUrl::fromLocalFile(path));
createCache(path, cache.toLocalFile(), QSize(width, height));
} }
m_usingCache = cacheExists;
emit usingCacheChanged();
}, Qt::QueuedConnection); }, Qt::QueuedConnection);
}); });
} }
@ -135,8 +134,39 @@ QUrl CachingImageManager::cachePath() const {
return m_cachePath; return m_cachePath;
} }
bool CachingImageManager::usingCache() const { void CachingImageManager::createCache(const QString& path, const QString& cache, const QSize& size) const {
return m_usingCache; QThreadPool::globalInstance()->start([path, cache, size] {
QImageReader reader(path);
QSize imgSize = reader.size();
if (!imgSize.isValid()) {
qWarning() << "CachingImageManager::createCache: unable to get size of" << path;
return;
}
qreal scale = std::max(
qreal(size.width()) / imgSize.width(),
qreal(size.height()) / imgSize.height()
);
QSizeF scaledSize(imgSize.width() * scale, imgSize.height() * scale);
qreal xOff = (scaledSize.width() - size.width()) / 2.0;
qreal yOff = (scaledSize.height() - size.height()) / 2.0;
reader.setScaledSize(scaledSize.toSize());
reader.setScaledClipRect(QRectF(xOff, yOff, size.width(), size.height()).toRect());
QImage image = reader.read();
if (image.isNull()) {
qWarning() << "CachingImageManager::createCache: failed to read" << path;
return;
}
const QString parent = QFileInfo(cache).absolutePath();
if (!QDir().mkpath(parent) || !image.save(cache)) {
qWarning() << "CachingImageManager::createCache: failed to save to" << cache;
}
});
} }
QString CachingImageManager::sha256sum(const QString& path) const { QString CachingImageManager::sha256sum(const QString& path) const {

View file

@ -13,7 +13,6 @@ class CachingImageManager : public QObject {
Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged); Q_PROPERTY(QString path READ path WRITE setPath NOTIFY pathChanged);
Q_PROPERTY(QUrl cachePath READ cachePath NOTIFY cachePathChanged); Q_PROPERTY(QUrl cachePath READ cachePath NOTIFY cachePathChanged);
Q_PROPERTY(bool usingCache READ usingCache NOTIFY usingCacheChanged);
public: public:
explicit CachingImageManager(QObject* parent = nullptr): QObject(parent) {}; explicit CachingImageManager(QObject* parent = nullptr): QObject(parent) {};
@ -28,7 +27,6 @@ public:
void setPath(const QString& path); void setPath(const QString& path);
[[nodiscard]] QUrl cachePath() const; [[nodiscard]] QUrl cachePath() const;
[[nodiscard]] bool usingCache() const;
Q_INVOKABLE void updateSource(); Q_INVOKABLE void updateSource();
Q_INVOKABLE void updateSource(const QString& path); Q_INVOKABLE void updateSource(const QString& path);
@ -47,7 +45,6 @@ private:
QString m_path; QString m_path;
QUrl m_cachePath; QUrl m_cachePath;
bool m_usingCache;
QMetaObject::Connection m_widthConn; QMetaObject::Connection m_widthConn;
QMetaObject::Connection m_heightConn; QMetaObject::Connection m_heightConn;
@ -56,5 +53,6 @@ private:
[[nodiscard]] int effectiveWidth() const; [[nodiscard]] int effectiveWidth() const;
[[nodiscard]] int effectiveHeight() const; [[nodiscard]] int effectiveHeight() const;
void createCache(const QString& path, const QString& cache, const QSize& size) const;
[[nodiscard]] QString sha256sum(const QString& path) const; [[nodiscard]] QString sha256sum(const QString& path) const;
}; };