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/options.hpp | |
| 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/options.hpp')
| -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); -    } -} | 
