WIP: feat: video wallpapers #163

Draft
zach wants to merge 10 commits from feat/video-wallpaper into main
Showing only changes of commit dc0f222ace - Show all commits
+44 -6
View File
@@ -17,6 +17,8 @@
#include <quuid.h> #include <quuid.h>
#include <algorithm> #include <algorithm>
#include <atomic>
#include <mutex>
Q_LOGGING_CATEGORY(dbLog, "ZShell.Internal.wallpaper.db", QtWarningMsg) Q_LOGGING_CATEGORY(dbLog, "ZShell.Internal.wallpaper.db", QtWarningMsg)
@@ -27,11 +29,21 @@ class WallpaperImageProvider : public QQuickImageProvider {
explicit WallpaperImageProvider(const QString& dbPath) explicit WallpaperImageProvider(const QString& dbPath)
: QQuickImageProvider(QQuickImageProvider::Image), m_dbPath(dbPath) {} : QQuickImageProvider(QQuickImageProvider::Image), m_dbPath(dbPath) {}
void setDbPath(const QString& dbPath) {
std::lock_guard<std::mutex> lock(m_mutex);
if (m_dbPath == dbPath) {
return;
}
m_dbPath = dbPath;
m_generation.fetch_add(1, std::memory_order_relaxed);
}
QImage requestImage( QImage requestImage(
const QString& id, QSize* size, const QSize& requestedSize) override { const QString& id, QSize* size, const QSize& requestedSize) override {
const QString path = const QString path =
QString::fromUtf8(QByteArray::fromHex(id.toUtf8())); QString::fromUtf8(QByteArray::fromHex(id.toUtf8()));
if (path.isEmpty() || !openThreadDb()) { if (path.isEmpty() || !openThreadDb(currentDbPath())) {
return {}; return {};
} }
@@ -68,12 +80,31 @@ class WallpaperImageProvider : public QQuickImageProvider {
} }
private: private:
bool openThreadDb() { QString currentDbPath() const {
if (!m_threadUuid.isEmpty()) { std::lock_guard<std::mutex> lock(m_mutex);
return m_dbPath;
}
bool openThreadDb(const QString& dbPath) {
const quint64 generation = m_generation.load(std::memory_order_relaxed);
if (!m_threadUuid.isEmpty() && m_threadGeneration == generation) {
return true; return true;
} }
if (m_dbPath.isEmpty()) { if (!m_threadUuid.isEmpty()) {
{
auto db = QSqlDatabase::database(m_threadUuid, false);
if (db.isValid()) {
db.close();
}
}
QSqlDatabase::removeDatabase(m_threadUuid);
m_threadUuid.clear();
}
if (dbPath.isEmpty()) {
return false; return false;
} }
@@ -81,7 +112,7 @@ class WallpaperImageProvider : public QQuickImageProvider {
auto db = QSqlDatabase::addDatabase("QSQLITE", uuid); auto db = QSqlDatabase::addDatabase("QSQLITE", uuid);
db.setConnectOptions("QSQLITE_OPEN_READONLY"); db.setConnectOptions("QSQLITE_OPEN_READONLY");
db.setDatabaseName(m_dbPath); db.setDatabaseName(dbPath);
if (!db.open()) { if (!db.open()) {
return false; return false;
@@ -91,14 +122,20 @@ class WallpaperImageProvider : public QQuickImageProvider {
query.exec("PRAGMA journal_mode=WAL"); query.exec("PRAGMA journal_mode=WAL");
m_threadUuid = uuid; m_threadUuid = uuid;
m_threadGeneration = generation;
return true; return true;
} }
const QString m_dbPath; mutable std::mutex m_mutex;
QString m_dbPath;
std::atomic<quint64> m_generation = 0;
thread_local static QString m_threadUuid; thread_local static QString m_threadUuid;
thread_local static quint64 m_threadGeneration;
}; };
thread_local QString WallpaperImageProvider::m_threadUuid; thread_local QString WallpaperImageProvider::m_threadUuid;
thread_local quint64 WallpaperImageProvider::m_threadGeneration;
WallpaperEntry::WallpaperEntry( WallpaperEntry::WallpaperEntry(
const QString& path, const QString& relativePath, QObject* parent) const QString& path, const QString& relativePath, QObject* parent)
@@ -326,6 +363,7 @@ void WallpaperDb::setCacheSize(const QSize& cacheSize) {
void WallpaperDb::registerProvider() { void WallpaperDb::registerProvider() {
if (m_provider != nullptr) { if (m_provider != nullptr) {
m_provider->setDbPath(m_dbPath);
return; return;
} }