mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
New settings api
This commit is contained in:
parent
1cfd98b2d7
commit
633ec9807d
2 changed files with 166 additions and 115 deletions
|
@ -9,35 +9,125 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include <QCoreApplication>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QHash>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QThread>
|
#include <QThread>
|
||||||
#include <QThreadStorage>
|
#include <QVector>
|
||||||
|
|
||||||
|
#include "PathUtils.h"
|
||||||
#include "Settings.h"
|
#include "Settings.h"
|
||||||
|
|
||||||
namespace SettingHandles {
|
namespace Setting {
|
||||||
|
class Manager : public QSettings {
|
||||||
|
public:
|
||||||
|
~Manager();
|
||||||
|
void registerHandle(Interface* handle);
|
||||||
|
void removeHandle(const QString& key);
|
||||||
|
|
||||||
|
void loadSetting(Interface* handle);
|
||||||
|
void saveSetting(Interface* handle);
|
||||||
|
void saveAll();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QHash<QString, Interface*> _handles;
|
||||||
|
};
|
||||||
|
Manager* privateInstance = nullptr;
|
||||||
|
|
||||||
static QThreadStorage<QSettings*> storage;
|
// cleans up the settings private instance. Should only be run once at closing down.
|
||||||
|
void cleanupPrivateInstance() {
|
||||||
QSettings* getSettings() {
|
delete privateInstance;
|
||||||
if (!storage.hasLocalData()) {
|
privateInstance = nullptr;
|
||||||
storage.setLocalData(new QSettings());
|
|
||||||
QObject::connect(QThread::currentThread(), &QThread::destroyed,
|
|
||||||
storage.localData(), &QSettings::deleteLater);
|
|
||||||
}
|
}
|
||||||
return storage.localData();
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariant SettingsBridge::getFromSettings(const QString& key, const QVariant& defaultValue) {
|
// Sets up the settings private instance. Should only be run once at startup
|
||||||
return getSettings()->value(key, defaultValue);
|
void setupPrivateInstance() {
|
||||||
}
|
// read the ApplicationInfo.ini file for Name/Version/Domain information
|
||||||
|
QSettings::setDefaultFormat(QSettings::IniFormat);
|
||||||
void SettingsBridge::setInSettings(const QString& key, const QVariant& value) {
|
QSettings applicationInfo(PathUtils::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat);
|
||||||
getSettings()->setValue(key, value);
|
// set the associated application properties
|
||||||
}
|
applicationInfo.beginGroup("INFO");
|
||||||
|
QCoreApplication::setApplicationName(applicationInfo.value("name").toString());
|
||||||
|
QCoreApplication::setOrganizationName(applicationInfo.value("organizationName").toString());
|
||||||
|
QCoreApplication::setOrganizationDomain(applicationInfo.value("organizationDomain").toString());
|
||||||
|
|
||||||
|
// Let's set up the settings Private instance on it's own thread
|
||||||
|
QThread* thread = new QThread();
|
||||||
|
Q_CHECK_PTR(thread);
|
||||||
|
privateInstance = new Manager();
|
||||||
|
Q_CHECK_PTR(privateInstance);
|
||||||
|
thread->setObjectName("Settings Thread");
|
||||||
|
QObject::connect(privateInstance, SIGNAL(destroyed()), thread, SLOT(quit()));
|
||||||
|
QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
|
||||||
|
privateInstance->moveToThread(thread);
|
||||||
|
thread->start();
|
||||||
|
qDebug() << "Settings thread started.";
|
||||||
|
|
||||||
|
// Register cleanupPrivateInstance to run inside QCoreApplication's destructor.
|
||||||
|
qAddPostRoutine(cleanupPrivateInstance);
|
||||||
|
}
|
||||||
|
// Register setupPrivateInstance to run after QCoreApplication's constructor.
|
||||||
|
Q_COREAPP_STARTUP_FUNCTION(setupPrivateInstance)
|
||||||
|
|
||||||
void SettingsBridge::removeFromSettings(const QString& key) {
|
Interface::~Interface() {
|
||||||
getSettings()->remove(key);
|
if (privateInstance) {
|
||||||
}
|
privateInstance->removeHandle(_key);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Interface::init() {
|
||||||
|
if (privateInstance) {
|
||||||
|
// Register Handle
|
||||||
|
privateInstance->registerHandle(this);
|
||||||
|
_isInitialized = true;
|
||||||
|
|
||||||
|
// Load value from disk
|
||||||
|
privateInstance->loadSetting(this);
|
||||||
|
} else {
|
||||||
|
qWarning() << "Setting::Interface::init(): Manager not yet created";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Interface::maybeInit() {
|
||||||
|
if (!_isInitialized) {
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::~Manager() {
|
||||||
|
saveAll();
|
||||||
|
sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::registerHandle(Setting::Interface* handle) {
|
||||||
|
QString key = handle->getKey();
|
||||||
|
if (_handles.contains(key)) {
|
||||||
|
qWarning() << "Setting::Manager::registerHandle(): Key registered more than once, overriding: " << key;
|
||||||
|
}
|
||||||
|
_handles.insert(key, handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::removeHandle(const QString& key) {
|
||||||
|
_handles.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::loadSetting(Interface* handle) {
|
||||||
|
handle->setVariant(value(handle->getKey()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::saveSetting(Interface* handle) {
|
||||||
|
if (handle->isSet()) {
|
||||||
|
setValue(handle->getKey(), handle->getVariant());
|
||||||
|
} else {
|
||||||
|
remove(handle->getKey());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::saveAll() {
|
||||||
|
for (auto handle : _handles) {
|
||||||
|
saveSetting(handle);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -21,101 +21,62 @@ class Settings : public QSettings {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace SettingHandles {
|
namespace Setting {
|
||||||
|
class Interface {
|
||||||
template <typename T>
|
protected:
|
||||||
class SettingHandle {
|
Interface(const QString& key) : _key(key) {}
|
||||||
public:
|
virtual ~Interface();
|
||||||
SettingHandle(const QString& key);
|
void init();
|
||||||
SettingHandle(const QStringList& path);
|
void maybeInit();
|
||||||
SettingHandle(const QString& key, const T& defaultValue);
|
|
||||||
SettingHandle(const QStringList& path, const T& defaultValue);
|
|
||||||
|
|
||||||
T get() const; // Returns setting value, returns its default value if not found
|
|
||||||
T get(const T& other) const; // Returns setting value, returns other if not found
|
|
||||||
T getDefault() const;
|
|
||||||
|
|
||||||
void set(const T& value) const;
|
|
||||||
void reset() const;
|
|
||||||
|
|
||||||
void remove() const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
const QString _key;
|
|
||||||
const QVariant _defaultValue;
|
|
||||||
};
|
|
||||||
|
|
||||||
class SettingsBridge {
|
|
||||||
private:
|
|
||||||
static QVariant getFromSettings(const QString& key, const QVariant& defaultValue);
|
|
||||||
static void setInSettings(const QString& key, const QVariant& value);
|
|
||||||
static void removeFromSettings(const QString& key);
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
friend class SettingHandle;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
SettingHandle<T>::SettingHandle(const QString& key) : _key(key) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
SettingHandle<T>::SettingHandle(const QStringList& path) : _key(path.join("/")) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
SettingHandle<T>::SettingHandle(const QString& key, const T& defaultValue) :
|
|
||||||
_key(key),
|
|
||||||
_defaultValue(defaultValue) {
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
SettingHandle<T>::SettingHandle(const QStringList& path, const T& defaultValue) :
|
|
||||||
_key(path.join("/")),
|
|
||||||
_defaultValue(defaultValue) {
|
|
||||||
|
|
||||||
}
|
QString getKey() const { return _key; }
|
||||||
|
bool isSet() const { return _isSet; }
|
||||||
template <typename T>
|
|
||||||
T SettingHandle<T>::get() const {
|
virtual void setVariant(const QVariant& variant) = 0;
|
||||||
QVariant variant = SettingsBridge::getFromSettings(_key, _defaultValue);
|
virtual QVariant getVariant() = 0;
|
||||||
if (variant.canConvert<T>()) {
|
|
||||||
return variant.value<T>();
|
bool _isInitialized = false;
|
||||||
}
|
bool _isSet = false;
|
||||||
return _defaultValue.value<T>();
|
const QString _key;
|
||||||
}
|
|
||||||
|
friend class Manager;
|
||||||
template <typename T>
|
};
|
||||||
T SettingHandle<T>::get(const T& other) const {
|
|
||||||
QVariant variant = SettingsBridge::getFromSettings(_key, QVariant(other));
|
|
||||||
if (variant.canConvert<T>()) {
|
|
||||||
return variant.value<T>();
|
|
||||||
}
|
|
||||||
return other;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline
|
|
||||||
T SettingHandle<T>::getDefault() const {
|
|
||||||
return _defaultValue.value<T>();
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline
|
|
||||||
void SettingHandle<T>::set(const T& value) const {
|
|
||||||
if (value != get()) {
|
|
||||||
SettingsBridge::setInSettings(_key, QVariant(value));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline
|
|
||||||
void SettingHandle<T>::reset() const {
|
|
||||||
SettingsBridge::setInSettings(_key, _defaultValue);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T> inline
|
template <typename T>
|
||||||
void SettingHandle<T>::remove() const {
|
class Handle : public Interface {
|
||||||
SettingsBridge::removeFromSettings(_key);
|
public:
|
||||||
}
|
Handle(const QString& key) : Interface(key) {}
|
||||||
|
Handle(const QStringList& path) : Interface(path.join("/")) {}
|
||||||
|
|
||||||
|
Handle(const QString& key, const T& defaultValue) : Interface(key), _defaultValue(defaultValue) {}
|
||||||
|
Handle(const QStringList& path, const T& defaultValue) : Handle(path.join("/"), defaultValue) {}
|
||||||
|
|
||||||
|
// Returns setting value, returns its default value if not found
|
||||||
|
T get() { return get(_defaultValue); }
|
||||||
|
// Returns setting value, returns other if not found
|
||||||
|
T get(const T& other) { maybeInit(); return (_isSet) ? _value : other; }
|
||||||
|
T getDefault() const { return _defaultValue; }
|
||||||
|
|
||||||
|
void set(const T& value) { maybeInit(); _value = value; _isSet = true; }
|
||||||
|
void reset() { set(_defaultValue); }
|
||||||
|
|
||||||
|
void remove() { maybeInit(); _isSet = false; }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void setVariant(const QVariant& variant);
|
||||||
|
virtual QVariant getVariant() { return QVariant::fromValue(get()); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T _value;
|
||||||
|
const T _defaultValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Handle<T>::setVariant(const QVariant& variant) {
|
||||||
|
if (variant.canConvert<T>()) {
|
||||||
|
set(variant.value<T>());
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // hifi_Settings_h
|
#endif // hifi_Settings_h
|
Loading…
Reference in a new issue