diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2015-11-01 11:29:24 +0100 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2015-11-01 11:29:24 +0100 |
commit | be36337e46218c6f843a478036497a3f494502ed (patch) | |
tree | dbb9dcb91f8a0233d3facb91e7d860c23a97ca4c /opentrack | |
parent | 0424a2802aec3600774ba9347c49312bb09b8cfe (diff) |
options: don't define options singleton in every module
Instead, define in opentrack-api.so only.
Also, move to opentrack-compat to break a circular dependency
Diffstat (limited to 'opentrack')
-rw-r--r-- | opentrack/options.hpp | 481 |
1 files changed, 0 insertions, 481 deletions
diff --git a/opentrack/options.hpp b/opentrack/options.hpp deleted file mode 100644 index f8475877..00000000 --- a/opentrack/options.hpp +++ /dev/null @@ -1,481 +0,0 @@ -/* Copyright (c) 2013-2015 Stanislaw Halik - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - */ - -#pragma once - -#include <memory> -#include <tuple> -#include <map> -#include <string> - -#include <QObject> -#include <QSettings> -#include <QString> -#include <QVariant> -#include <QMutex> -#include <QMutexLocker> -#include <QWidget> -#include <QComboBox> -#include <QCheckBox> -#include <QDoubleSpinBox> -#include <QSpinBox> -#include <QSlider> -#include <QLineEdit> -#include <QLabel> -#include <QTabWidget> -#include <QCoreApplication> -#include <QFileInfo> -#include <QDir> -#include <QStandardPaths> - -#include <cinttypes> - -#include <QDebug> - -#include <memory> -template<typename t> using mem = std::shared_ptr<t>; - -#define OPENTRACK_CONFIG_FILENAME_KEY "settings-filename" -#define OPENTRACK_DEFAULT_CONFIG "default.ini" -#define OPENTRACK_ORG "opentrack-2.3" - -namespace options { - template<typename k, typename v> - using map = std::map<k, v>; - using std::string; - - template<typename t> - // don't elide usages of the function, qvariant default implicit - // conversion results in nonsensical runtime behavior -sh - inline t qcruft_to_t (const QVariant& datum); - - template<> - inline int qcruft_to_t<int>(const QVariant& t) - { - return t.toInt(); - } - - template<> - inline QString qcruft_to_t<QString>(const QVariant& t) - { - return t.toString(); - } - - template<> - inline bool qcruft_to_t<bool>(const QVariant& t) - { - return t.toBool(); - } - - template<> - inline double qcruft_to_t<double>(const QVariant& t) - { - return t.toDouble(); - } - - template<> - inline QVariant qcruft_to_t<QVariant>(const QVariant& t) - { - return t; - } - - // snapshot of qsettings group at given time - class group { - private: - map<string, QVariant> kvs; - string name; - public: - group(const string& name) : name(name) - { - auto conf = ini_file(); - auto q_name = QString::fromStdString(name); - conf->beginGroup(q_name); - for (auto& k_ : conf->childKeys()) - { - auto tmp = k_.toUtf8(); - string k(tmp); - kvs[k] = conf->value(k_); - } - conf->endGroup(); - } - - void save() - { - auto s = ini_file(); - auto q_name = QString::fromStdString(name); - s->beginGroup(q_name); - for (auto& i : kvs) - { - auto k = QString::fromStdString(i.first); - s->setValue(k, i.second); - } - s->endGroup(); - s->sync(); - } - - template<typename t> - t get(const string& k) - { - return qcruft_to_t<t>(kvs[k]); - } - - void put(const string& s, const QVariant& d) - { - kvs[s] = d; - } - - bool contains(const string& s) - { - return kvs.count(s) != 0; - } - - static QString ini_directory() - { - const auto dirs = QStandardPaths::standardLocations(QStandardPaths::DocumentsLocation); - if (dirs.size() == 0) - return ""; - if (QDir(dirs[0]).mkpath(OPENTRACK_ORG)) - return dirs[0] + "/" OPENTRACK_ORG; - return ""; - } - - static QString ini_filename() - { - QSettings settings(OPENTRACK_ORG); - return settings.value(OPENTRACK_CONFIG_FILENAME_KEY, OPENTRACK_DEFAULT_CONFIG).toString(); - } - - static QString ini_pathname() - { - const auto dir = ini_directory(); - if (dir == "") - return ""; - QSettings settings(OPENTRACK_ORG); - return dir + "/" + settings.value(OPENTRACK_CONFIG_FILENAME_KEY, OPENTRACK_DEFAULT_CONFIG).toString(); - } - - static const QStringList ini_list() - { - const auto dirname = ini_directory(); - if (dirname == "") - return QStringList(); - QDir settings_dir(dirname); - return settings_dir.entryList( QStringList { "*.ini" } , QDir::Files, QDir::Name ); - } - - static const mem<QSettings> ini_file() - { - const auto pathname = ini_pathname(); - if (pathname != "") - return std::make_shared<QSettings>(ini_pathname(), QSettings::IniFormat); - return std::make_shared<QSettings>(); - } - }; - - class impl_bundle : public QObject { - Q_OBJECT - protected: - QMutex mtx; - const string group_name; - group saved; - group transient; - bool modified; - impl_bundle(const impl_bundle&) = delete; - impl_bundle& operator=(const impl_bundle&) = delete; - signals: - void reloading(); - void saving(); - public: - impl_bundle(const string& group_name) : - mtx(QMutex::Recursive), - group_name(group_name), - saved(group_name), - transient(saved), - modified(false) - { - } - - string name() { return group_name; } - - void reload() { - { - QMutexLocker l(&mtx); - saved = group(group_name); - transient = saved; - modified = false; - } - emit reloading(); - } - - void store_kv(const string& name, const QVariant& datum) - { - QMutexLocker l(&mtx); - - auto old = transient.get<QVariant>(name); - if (!transient.contains(name) || datum != old) - { - modified = true; - transient.put(name, datum); - } - } - bool contains(const string& name) - { - QMutexLocker l(&mtx); - return transient.contains(name); - } - template<typename t> - t get(const string& name) - { - QMutexLocker l(&mtx); - return transient.get<t>(name); - } - void save() - { - { - QMutexLocker l(&mtx); - modified = false; - saved = transient; - transient.save(); - } - emit saving(); - } - - bool modifiedp() { - QMutexLocker l(&mtx); - return modified; - } - }; - - class opt_bundle; - - namespace - { - template<typename k, typename v, typename cnt = int> - struct opt_singleton - { - public: - using pbundle = std::shared_ptr<v>; - using tt = std::tuple<cnt, std::weak_ptr<v>>; - private: - QMutex implsgl_mtx; - map<k, tt> implsgl_data; - public: - opt_singleton() : implsgl_mtx(QMutex::Recursive) {} - - static opt_singleton<k, v>& datum() - { - static auto ret = std::make_shared<opt_singleton<k, v>>(); - return *ret; - } - - pbundle bundle(const k& key) - { - QMutexLocker l(&implsgl_mtx); - - if (implsgl_data.count(key) != 0) - { - auto shared = std::get<1>(implsgl_data[key]).lock(); - if (shared != nullptr) - return shared; - } - - qDebug() << "bundle +" << QString::fromStdString(key); - - auto shr = std::make_shared<v>(key); - implsgl_data[key] = tt(cnt(1), shr); - return shr; - } - - void bundle_decf(const k& key) - { - QMutexLocker l(&implsgl_mtx); - - if (--std::get<0>(implsgl_data[key]) == 0) - implsgl_data.erase(key); - } - }; - - using pbundle = std::shared_ptr<opt_bundle>; - using t_fact = opt_singleton<string, opt_bundle>; - } - - static inline t_fact::pbundle bundle(const string name) { return t_fact::datum().bundle(name); } - - class opt_bundle : public impl_bundle - { - public: - opt_bundle() : impl_bundle("i-have-no-name") {} - opt_bundle(const string& group_name) : impl_bundle(group_name) - { - } - - ~opt_bundle() - { - qDebug() << "bundle -" << QString::fromStdString(group_name); - t_fact::datum().bundle_decf(group_name); - } - }; - - class base_value : public QObject - { - Q_OBJECT -#define DEFINE_SLOT(t) void setValue(t datum) { store(datum); } -#define DEFINE_SIGNAL(t) void valueChanged(t) - public: - string name() { return self_name; } - base_value(pbundle b, const string& name) : b(b), self_name(name) {} - signals: - DEFINE_SIGNAL(double); - DEFINE_SIGNAL(int); - DEFINE_SIGNAL(bool); - DEFINE_SIGNAL(QString); - protected: - pbundle b; - string self_name; - - template<typename t> - void store(const t& datum) - { - b->store_kv(self_name, datum); - emit valueChanged(static_cast<t>(datum)); - } - public slots: - DEFINE_SLOT(double) - DEFINE_SLOT(int) - DEFINE_SLOT(QString) - DEFINE_SLOT(bool) - public slots: - virtual void reload() = 0; - }; - - static inline string string_from_qstring(const QString& datum) - { - auto tmp = datum.toUtf8(); - return string(tmp.constData()); - } - - template<typename t> - class value : public base_value { - public: - t operator=(const t datum) - { - store(datum); - return datum; - } - static constexpr const Qt::ConnectionType DIRECT_CONNTYPE = Qt::DirectConnection; - static constexpr const Qt::ConnectionType SAFE_CONNTYPE = Qt::UniqueConnection; - value(pbundle b, const string& name, t def) : base_value(b, name), def(def) - { - QObject::connect(b.get(), SIGNAL(reloading()), - this, SLOT(reload()), - DIRECT_CONNTYPE); - if (!b->contains(name) || b->get<QVariant>(name).type() == QVariant::Invalid) - *this = def; - } - value(pbundle b, const QString& name, t def) : value(b, string_from_qstring(name), def) {} - value(pbundle b, const char* name, t def) : value(b, string(name), def) {} - - operator t() - { - return b->contains(self_name) ? b->get<t>(self_name) : def; - } - void reload() override { - *this = static_cast<t>(*this); - } - private: - t def; - }; - - struct opts - { - pbundle b; - - opts(const std::string& name) : b(bundle(name)) {} - - ~opts() - { - b->reload(); - } - }; - - template<typename t, typename q> - inline void tie_setting(value<t>&, q*); - - template<> - inline void tie_setting(value<int>& v, QComboBox* cb) - { - cb->setCurrentIndex(v); - v = cb->currentIndex(); - base_value::connect(cb, SIGNAL(currentIndexChanged(int)), &v, SLOT(setValue(int)), v.DIRECT_CONNTYPE); - base_value::connect(&v, SIGNAL(valueChanged(int)), cb, SLOT(setCurrentIndex(int)), v.SAFE_CONNTYPE); - } - - template<> - inline void tie_setting(value<QString>& v, QComboBox* cb) - { - cb->setCurrentText(v); - v = cb->currentText(); - base_value::connect(cb, SIGNAL(currentTextChanged(QString)), &v, SLOT(setValue(QString)), v.DIRECT_CONNTYPE); - base_value::connect(&v, SIGNAL(valueChanged(QString)), cb, SLOT(setCurrentText(QString)), v.SAFE_CONNTYPE); - } - - template<> - inline void tie_setting(value<bool>& v, QCheckBox* cb) - { - cb->setChecked(v); - base_value::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool)), v.DIRECT_CONNTYPE); - base_value::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool)), v.SAFE_CONNTYPE); - } - - template<> - inline void tie_setting(value<double>& v, QDoubleSpinBox* dsb) - { - dsb->setValue(v); - base_value::connect(dsb, SIGNAL(valueChanged(double)), &v, SLOT(setValue(double)), v.DIRECT_CONNTYPE); - base_value::connect(&v, SIGNAL(valueChanged(double)), dsb, SLOT(setValue(double)), v.SAFE_CONNTYPE); - } - - template<> - inline void tie_setting(value<int>& v, QSpinBox* sb) - { - sb->setValue(v); - base_value::connect(sb, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.DIRECT_CONNTYPE); - base_value::connect(&v, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int)), v.SAFE_CONNTYPE); - } - - template<> - inline void tie_setting(value<int>& v, QSlider* sl) - { - sl->setValue(v); - v = sl->value(); - base_value::connect(sl, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.DIRECT_CONNTYPE); - base_value::connect(&v, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int)), v.SAFE_CONNTYPE); - } - - template<> - inline void tie_setting(value<QString>& v, QLineEdit* le) - { - le->setText(v); - base_value::connect(le, SIGNAL(textChanged(QString)), &v, SLOT(setValue(QString)), v.DIRECT_CONNTYPE); - base_value::connect(&v, SIGNAL(valueChanged(QString)),le, SLOT(setText(QString)), v.SAFE_CONNTYPE); - } - - template<> - inline void tie_setting(value<QString>& v, QLabel* lb) - { - lb->setText(v); - base_value::connect(&v, SIGNAL(valueChanged(QString)), lb, SLOT(setText(QString)), v.SAFE_CONNTYPE); - } - - template<> - inline void tie_setting(value<int>& v, QTabWidget* t) - { - t->setCurrentIndex(v); - base_value::connect(t, SIGNAL(currentChanged(int)), &v, SLOT(setValue(int)), v.DIRECT_CONNTYPE); - base_value::connect(&v, SIGNAL(valueChanged(int)), t, SLOT(setCurrentIndex(int)), v.SAFE_CONNTYPE); - } -} |