From 9abdb41764001804c5c960ec2762a323ed697659 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Mon, 2 Feb 2015 17:17:19 -0800 Subject: [PATCH] Rearrange settings classes in correct files --- .../src/{Settings.h => SettingHandle.h} | 24 +---- .../{Settings.cpp => SettingInterface.cpp} | 87 ++++++------------- libraries/shared/src/SettingInterface.h | 45 ++++++++++ libraries/shared/src/SettingManager.cpp | 81 +++++++++++++++++ libraries/shared/src/SettingManager.h | 48 ++++++++++ 5 files changed, 205 insertions(+), 80 deletions(-) rename libraries/shared/src/{Settings.h => SettingHandle.h} (77%) rename libraries/shared/src/{Settings.cpp => SettingInterface.cpp} (61%) create mode 100644 libraries/shared/src/SettingInterface.h create mode 100644 libraries/shared/src/SettingManager.cpp create mode 100644 libraries/shared/src/SettingManager.h diff --git a/libraries/shared/src/Settings.h b/libraries/shared/src/SettingHandle.h similarity index 77% rename from libraries/shared/src/Settings.h rename to libraries/shared/src/SettingHandle.h index 87fbc3d87b..3b01fa3e27 100644 --- a/libraries/shared/src/Settings.h +++ b/libraries/shared/src/SettingHandle.h @@ -16,32 +16,14 @@ #include #include +#include "SettingInterface.h" + // TODO: remove class Settings : public QSettings { }; namespace Setting { - class Interface { - protected: - Interface(const QString& key) : _key(key) {} - virtual ~Interface(); - void init(); - void maybeInit(); - - QString getKey() const { return _key; } - bool isSet() const { return _isSet; } - - virtual void setVariant(const QVariant& variant) = 0; - virtual QVariant getVariant() = 0; - - bool _isInitialized = false; - bool _isSet = false; - const QString _key; - - friend class Manager; - }; - template class Handle : public Interface { public: @@ -51,6 +33,8 @@ namespace Setting { Handle(const QString& key, const T& defaultValue) : Interface(key), _defaultValue(defaultValue) {} Handle(const QStringList& path, const T& defaultValue) : Handle(path.join("/"), defaultValue) {} + virtual ~Handle() { save(); } + // Returns setting value, returns its default value if not found T get() { return get(_defaultValue); } // Returns setting value, returns other if not found diff --git a/libraries/shared/src/Settings.cpp b/libraries/shared/src/SettingInterface.cpp similarity index 61% rename from libraries/shared/src/Settings.cpp rename to libraries/shared/src/SettingInterface.cpp index 309d5a1ae4..0ef22e3fcb 100644 --- a/libraries/shared/src/Settings.cpp +++ b/libraries/shared/src/SettingInterface.cpp @@ -1,39 +1,25 @@ // -// Settings.cpp +// SettingInterface.cpp // // -// Created by Clement on 1/18/15. +// Created by Clement on 2/2/15. // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // + #include #include -#include -#include #include -#include #include "PathUtils.h" -#include "Settings.h" +#include "SettingInterface.h" +#include "SettingManager.h" 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 _handles; - }; - Manager* privateInstance = nullptr; + static Manager* privateInstance = nullptr; // cleans up the settings private instance. Should only be run once at closing down. void cleanupPrivateInstance() { @@ -55,10 +41,13 @@ namespace Setting { // Let's set up the settings Private instance on it's own thread QThread* thread = new QThread(); Q_CHECK_PTR(thread); + thread->setObjectName("Settings Thread"); + privateInstance = new Manager(); Q_CHECK_PTR(privateInstance); - thread->setObjectName("Settings Thread"); + QObject::connect(privateInstance, SIGNAL(destroyed()), thread, SLOT(quit())); + QObject::connect(thread, SIGNAL(started()), privateInstance, SLOT(startTimer())); QObject::connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); privateInstance->moveToThread(thread); thread->start(); @@ -70,6 +59,7 @@ namespace Setting { // Register setupPrivateInstance to run after QCoreApplication's constructor. Q_COREAPP_STARTUP_FUNCTION(setupPrivateInstance) + Interface::~Interface() { if (privateInstance) { privateInstance->removeHandle(_key); @@ -77,16 +67,17 @@ namespace Setting { } 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"; + if (!privateInstance) { + qWarning() << "Setting::Interface::init(): Manager not yet created, bailing"; + return; } + + // Register Handle + privateInstance->registerHandle(this); + _isInitialized = true; + + // Load value from disk + load(); } void Interface::maybeInit() { @@ -95,39 +86,15 @@ namespace Setting { } } - 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 Interface::save() { + if (privateInstance) { + privateInstance->saveSetting(this); } } - void Manager::saveAll() { - for (auto handle : _handles) { - saveSetting(handle); + void Interface::load() { + if (privateInstance) { + privateInstance->loadSetting(this); } } - } \ No newline at end of file diff --git a/libraries/shared/src/SettingInterface.h b/libraries/shared/src/SettingInterface.h new file mode 100644 index 0000000000..5bb7da4507 --- /dev/null +++ b/libraries/shared/src/SettingInterface.h @@ -0,0 +1,45 @@ +// +// SettingInterface.h +// +// +// Created by Clement on 2/2/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_SettingInterface_h +#define hifi_SettingInterface_h + +#include +#include + +namespace Setting { + class Interface { + public: + QString getKey() const { return _key; } + bool isSet() const { return _isSet; } + + virtual void setVariant(const QVariant& variant) = 0; + virtual QVariant getVariant() = 0; + + protected: + Interface(const QString& key) : _key(key) {} + virtual ~Interface(); + + void init(); + void maybeInit(); + + void save(); + void load(); + + bool _isInitialized = false; + bool _isSet = false; + const QString _key; + + friend class Manager; + }; +} + +#endif // hifi_SettingInterface_h \ No newline at end of file diff --git a/libraries/shared/src/SettingManager.cpp b/libraries/shared/src/SettingManager.cpp new file mode 100644 index 0000000000..b9ee39022f --- /dev/null +++ b/libraries/shared/src/SettingManager.cpp @@ -0,0 +1,81 @@ +// +// SettingManager.cpp +// +// +// Created by Clement on 2/2/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include "SettingInterface.h" +#include "SettingManager.h" + +namespace Setting { + Manager::~Manager() { + // Cleanup timer + stopTimer(); + disconnect(_saveTimer, 0, 0, 0); + _saveTimer.clear(); + + // Save all settings before exit + 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()); + } + } + + static const int SAVE_INTERVAL_MSEC = 5 * 1000; // 5 sec + void Manager::startTimer() { + if (!_saveTimer) { + _saveTimer = new QTimer(this); + Q_CHECK_PTR(_saveTimer); + _saveTimer->setSingleShot(true); // We will restart it once settings are saved. + _saveTimer->setInterval(SAVE_INTERVAL_MSEC); + connect(_saveTimer, SIGNAL(timeout()), this, SLOT(saveAll())); + } + _saveTimer->start(); + } + + void Manager::stopTimer() { + if (_saveTimer) { + _saveTimer->stop(); + } + } + + void Manager::saveAll() { + for (auto handle : _handles) { + saveSetting(handle); + } + + // Restart timer + if (_saveTimer) { + _saveTimer->start(); + } + } +} diff --git a/libraries/shared/src/SettingManager.h b/libraries/shared/src/SettingManager.h new file mode 100644 index 0000000000..8199b29170 --- /dev/null +++ b/libraries/shared/src/SettingManager.h @@ -0,0 +1,48 @@ +// +// SettingManager.h +// +// +// Created by Clement on 2/2/15. +// Copyright 2015 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_SettingManager_h +#define hifi_SettingManager_h + +#include +#include +#include + +namespace Setting { + class Interface; + + class Manager : public QSettings { + Q_OBJECT + protected: + ~Manager(); + void registerHandle(Interface* handle); + void removeHandle(const QString& key); + + void loadSetting(Interface* handle); + void saveSetting(Interface* handle); + + private slots: + void startTimer(); + void stopTimer(); + + void saveAll(); + + private: + QHash _handles; + QPointer _saveTimer = nullptr; + + friend class Interface; + friend void cleanupPrivateInstance(); + friend void setupPrivateInstance(); + }; +} + +#endif // hifi_SettingManager_h \ No newline at end of file