summaryrefslogtreecommitdiff
path: root/jsonobjectfilesingleton.h
diff options
context:
space:
mode:
Diffstat (limited to 'jsonobjectfilesingleton.h')
-rw-r--r--jsonobjectfilesingleton.h169
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;