diff options
Diffstat (limited to 'jsonobjectfilesingleton.h')
| -rw-r--r-- | jsonobjectfilesingleton.h | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/jsonobjectfilesingleton.h b/jsonobjectfilesingleton.h new file mode 100644 index 0000000..f11b30a --- /dev/null +++ b/jsonobjectfilesingleton.h @@ -0,0 +1,169 @@ +#pragma once + +// qt +#include <QDebug> +#include <QDir> +#include <QFile> +#include <QFileSystemWatcher> +#include <QJsonDocument> +#include <QJsonObject> +#include <QMutex> +#include <QSharedPointer> +#include <QStandardPaths> +#include <QVariant> + +#define JSON_OBJECT_FILE(classname) JsonObjectFile<classname>::get().data() + +template <class T> class JsonObjectFile +{ +public: + static QSharedPointer<T> get() + { + static QMutex mtx; + QMutexLocker l(&mtx); + + if (!m_instance) + { + m_instance = read(); + + qDebug() << "add filepath" << filepath(); + if (!m_watcher.addPath(filepath())) + { + qt_noop(); + } + qDebug() << m_watcher.directories() << m_watcher.files(); + + QObject::connect( + &m_watcher, + &QFileSystemWatcher::directoryChanged, + &m_watcher, + [&](const QString& path) { + qDebug() << filepath() << "changed"; + if (path == filename()) + { + qDebug() << "file changed:" << filename(); + *get() = *read(); + } + }, + Qt::DirectConnection + ); + } + + return m_instance; + } + + static QSharedPointer<T> read(const QString fileName = QString()) + { + static QMutex mtx; + QMutexLocker l(&mtx); + + if (!QDir(filepath()).exists()) + { + QDir().mkpath(filepath()); + } + + QFile f(!fileName.isEmpty() ? fileName : filename()); + + if (!f.open(QFile::ReadOnly)) + { + qDebug() << Q_FUNC_INFO << ":" + << "cannot open file" << f.fileName() << ":\n" + << f.errorString(); + + return QSharedPointer<T>(); + } + + auto data = f.readAll(); + QJsonValue json = QJsonDocument::fromJson(data).object(); + return QSharedPointer<T>( + new T(json[T::staticMetaObject.className()]), + &T::deleteLater + ); + } + + static bool write( + const QSharedPointer<T>& value, + const QString fileName = QString() + ) + { + static QMutex mtx; + QMutexLocker l(&mtx); + + QFile f(!fileName.isEmpty() ? fileName : filename()); + + if (!QDir(filepath()).exists()) + { + QDir().mkpath(filepath()); + } + + // bool fileExists = f.exists(); + + if (!f.open(QFile::WriteOnly)) + { + qDebug() << Q_FUNC_INFO << ":" + << "cannot open file" << f.fileName() << ":\n" + << f.errorString(); + + return false; + } + + const auto json = + QJsonObject{{T::staticMetaObject.className(), *value}}; + + f.write(QJsonDocument(json).toJson()); + f.flush(); + + m_instance = read(); + + return true; + } + + static bool remove(const QString fileName = QString()) + { + static QMutex mtx; + QMutexLocker l(&mtx); + + QFile f(!fileName.isEmpty() ? fileName : filename()); + + if (!f.remove()) + { + qDebug() << Q_FUNC_INFO << ":" + << "cannot delete file" << f.fileName() << ":\n" + << f.errorString(); + + return false; + } + + return true; + } + + static QString filepath() + { + return QStandardPaths::writableLocation( + QStandardPaths::AppConfigLocation + ); + } + + static QString filename() + { + return filepath() + QDir::separator() + + T::staticMetaObject.className() + "." + extension; + } + + typedef QSharedPointer<T> FactorySharedPointer; + +public: + static const QString extension; + +private: + static FactorySharedPointer m_instance; + static QFileSystemWatcher m_watcher; +}; + +template <typename T> +QString const JsonObjectFile<T>::extension = QStringLiteral("json"); + +template <class T> +typename JsonObjectFile<T>::FactorySharedPointer JsonObjectFile<T>::m_instance; + +template <class T> QFileSystemWatcher JsonObjectFile<T>::m_watcher; |
