From 904add389667ff9d97cde3930a881fae89c3fb50 Mon Sep 17 00:00:00 2001 From: Stanislaw Halik Date: Tue, 31 Dec 2013 08:40:02 +0100 Subject: options: fix some bugs --- facetracknoir/options.hpp | 96 +++++++++++++++++++++++++++++++---------------- 1 file changed, 63 insertions(+), 33 deletions(-) diff --git a/facetracknoir/options.hpp b/facetracknoir/options.hpp index 900f06c0..1305bd0a 100644 --- a/facetracknoir/options.hpp +++ b/facetracknoir/options.hpp @@ -7,11 +7,13 @@ #pragma once -#include +#include #include #include #include #include +#include +#include #include #include #include @@ -21,6 +23,13 @@ #include #include #include +#include + +#ifdef __GNUC__ +# define ov override +#else +# define ov +#endif namespace options { template @@ -101,8 +110,10 @@ namespace options { } }; - class impl_bundle { + class impl_bundle : public QObject { + Q_OBJECT private: + QMutex mtx; const QString group_name; group saved; group transient; @@ -111,6 +122,7 @@ namespace options { bool modified; public: impl_bundle(const QString& group_name) : + mtx(QMutex::Recursive), group_name(group_name), saved(group_name), transient(saved), @@ -119,8 +131,10 @@ namespace options { } /* keep in mind doesn't fire signals */ void reload() { + QMutexLocker l(&mtx); saved = group(group_name); transient = saved; + emit reloaded(); } std::shared_ptr make(const QString& name) { @@ -128,33 +142,46 @@ namespace options { } void store(const QString& name, const QVariant& datum) { + QMutexLocker l(&mtx); if (!transient.contains(name) || datum != transient.get(name)) { modified = true; transient.put(name, datum); + emit bundleChanged(); } } bool contains(const QString& name) { + QMutexLocker l(&mtx); return transient.contains(name); } template - T get(QString& name) { + T get(const QString& name) { + QMutexLocker l(&mtx); return transient.get(name); } void save() { + QMutexLocker l(&mtx); modified = false; saved = transient; transient.save(); } void revert() { + QMutexLocker l(&mtx); modified = false; transient = saved; + emit bundleChanged(); } - bool modifiedp() const { return modified; } + bool modifiedp() { + QMutexLocker l(&mtx); + return modified; + } + signals: + void bundleChanged(); + void reloaded(); }; typedef std::shared_ptr pbundle; @@ -162,7 +189,18 @@ namespace options { class base_value : public QObject { Q_OBJECT public: + base_value(pbundle b, const QString& name) : b(b), self_name(name) { + connect(b.get(), SIGNAL(reloaded()), this, SLOT(reread_value())); + } virtual QVariant operator=(const QVariant& datum) = 0; + protected: + pbundle b; + QString self_name; + public slots: + void reread_value() + { + this->operator=(b->get(self_name)); + } public slots: #define DEFINE_SLOT(t) void setValue(t datum) { this->operator=(datum); } DEFINE_SLOT(double) @@ -179,13 +217,11 @@ namespace options { template class value : public base_value { - private: - QString self_name; - pbundle b; + private: T def; public: - value(pbundle& b, const QString& name, T def) : - self_name(name), - b(b) + static constexpr const Qt::ConnectionType CONNTYPE = Qt::QueuedConnection; + value(pbundle b, const QString& name, T def) : + base_value(b, name), def(def) { if (!b->contains(name)) { @@ -196,15 +232,9 @@ namespace options { operator T() { return b->get(self_name); } QVariant operator=(const QVariant& datum) { b->store(self_name, datum); - switch (datum.type()) - { -#define BRANCH_ON(e, m) case QVariant::e: return valueChanged(datum.m()), datum - BRANCH_ON(Int, toInt); - BRANCH_ON(Double, toDouble); - BRANCH_ON(String, toString); - BRANCH_ON(Bool, toBool); - default: abort(); - } + auto foo = qcruft_to_t(datum); + emit valueChanged(foo); + return datum; } }; @@ -214,56 +244,56 @@ namespace options { template<> inline void tie_setting(value& v, QComboBox* cb) { - base_value::connect(cb, SIGNAL(currentIndexChanged(int)), &v, SLOT(setValue(int))); - base_value::connect(&v, SIGNAL(valueChanged(int)), cb, SLOT(setCurrentIndex(int))); + base_value::connect(cb, SIGNAL(currentIndexChanged(int)), &v, SLOT(setValue(int)), v.CONNTYPE); + base_value::connect(&v, SIGNAL(valueChanged(int)), cb, SLOT(setCurrentIndex(int)), v.CONNTYPE); cb->setCurrentIndex(v); } template<> inline void tie_setting(value& v, QComboBox* cb) { - base_value::connect(cb, SIGNAL(currentTextChanged(QString)), &v, SLOT(setValue(int))); - base_value::connect(&v, SIGNAL(valueChanged(QString)), cb, SLOT(setCurrentText(QString))); + base_value::connect(cb, SIGNAL(currentTextChanged(QString)), &v, SLOT(setValue(QString)), v.CONNTYPE); + base_value::connect(&v, SIGNAL(valueChanged(QString)), cb, SLOT(setCurrentText(QString)), v.CONNTYPE); cb->setCurrentText(v); } template<> inline void tie_setting(value& v, QCheckBox* cb) { - base_value::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool))); - base_value::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool))); + base_value::connect(cb, SIGNAL(toggled(bool)), &v, SLOT(setValue(bool)), v.CONNTYPE); + base_value::connect(&v, SIGNAL(valueChanged(bool)), cb, SLOT(setChecked(bool)), v.CONNTYPE); cb->setChecked(v); } template<> inline void tie_setting(value& v, QDoubleSpinBox* dsb) { - base_value::connect(dsb, SIGNAL(valueChanged(double)), &v, SLOT(setValue(double))); - base_value::connect(&v, SIGNAL(valueChanged(double)), dsb, SLOT(setValue(double))); + base_value::connect(dsb, SIGNAL(valueChanged(double)), &v, SLOT(setValue(double)), v.CONNTYPE); + base_value::connect(&v, SIGNAL(valueChanged(double)), dsb, SLOT(setValue(double)), v.CONNTYPE); dsb->setValue(v); } template<> inline void tie_setting(value& v, QSpinBox* sb) { - base_value::connect(sb, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int))); - base_value::connect(&v, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int))); + base_value::connect(sb, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.CONNTYPE); + base_value::connect(&v, SIGNAL(valueChanged(int)), sb, SLOT(setValue(int)), v.CONNTYPE); sb->setValue(v); } template<> inline void tie_setting(value& v, QSlider* sl) { - base_value::connect(sl, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int))); - base_value::connect(&v, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int))); + base_value::connect(sl, SIGNAL(valueChanged(int)), &v, SLOT(setValue(int)), v.CONNTYPE); + base_value::connect(&v, SIGNAL(valueChanged(int)), sl, SLOT(setValue(int)), v.CONNTYPE); sl->setValue(v); } template<> inline void tie_setting(value& v, QLineEdit* le) { - base_value::connect(le, SIGNAL(textChanged(QString)), &v, SLOT(setValue(QString))); - base_value::connect(&v, SIGNAL(valueChanged(QString)),le, SLOT(setText(QString))); + base_value::connect(le, SIGNAL(textChanged(QString)), &v, SLOT(setValue(QString)), v.CONNTYPE); + base_value::connect(&v, SIGNAL(valueChanged(QString)),le, SLOT(setText(QString)), v.CONNTYPE); le->setText(v); } -- cgit v1.2.3