diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2016-08-25 11:58:24 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2016-08-25 13:37:23 +0200 |
commit | 39169acf3bc2bc43cc32a6455d43e9588765c84a (patch) | |
tree | 3e0cbee0c68e15c87fe34746d1e9eb148ddd7bd1 /options/value.hpp | |
parent | c7532ed82f57e4281d3f5ecded59a95a4f756b04 (diff) |
options: use non-generic comparison for bundle modification check
The generic QVariant comparison works badly for QList<QPointF>.
Create a comparator between two QVariants for base_value in value<tp>
ctor, using QVariant::value<tp> which returns right results once it's
converted to tp.
If a value was registered for a name in a bundle, use that comparator as
the comparator for that name. In case conflicting value types were
registered always use generic comparison for that name.
std::type_index needs to be used here since value<t> can be instantiated
in different modules (libraries), resulting in different value for the
comparator function pointer.
Move group::operator== to bundle type to avoid circular include for
connector.h.
Also use element_type more consistently in value<tp>.
Diffstat (limited to 'options/value.hpp')
-rw-r--r-- | options/value.hpp | 32 |
1 files changed, 24 insertions, 8 deletions
diff --git a/options/value.hpp b/options/value.hpp index 4ed61f1c..6942ed88 100644 --- a/options/value.hpp +++ b/options/value.hpp @@ -5,6 +5,8 @@ #include "bundle.hpp" #include "slider.hpp" #include <type_traits> +#include <typeinfo> +#include <typeindex> #include <QString> #include <QPointF> #include <QList> @@ -28,9 +30,16 @@ class OPENTRACK_OPTIONS_EXPORT base_value : public QObject { Q_OBJECT friend class ::options::detail::connector; + + using comparator = bool(*)(const QVariant& val1, const QVariant& val2); + public: QString name() const { return self_name; } - base_value(bundle b, const QString& name) : b(b), self_name(name) + base_value(bundle b, const QString& name, comparator cmp, std::type_index type_idx) : + b(b), + self_name(name), + cmp(cmp), + type_index(type_idx) { b->on_value_created(name, this); } @@ -57,6 +66,8 @@ signals: protected: bundle b; QString self_name; + comparator cmp; + std::type_index type_index; template<typename t> void store(const t& datum) @@ -64,11 +75,6 @@ protected: b->store_kv(self_name, QVariant::fromValue(datum)); } - void store(float datum) - { - store(double(datum)); - } - public slots: OPENTRACK_DEFINE_SLOT(double) OPENTRACK_DEFINE_SLOT(int) @@ -122,6 +128,8 @@ struct value_element_type<t, typename std::enable_if<std::is_enum<t>::value>::ty using type = int; }; +template<> struct value_element_type<float, void> { using type = double; }; + template<typename t> using value_element_type_t = typename value_element_type<t>::type; } @@ -132,16 +140,24 @@ class value final : public base_value public: using element_type = detail::value_element_type_t<t>; + // XXX pointer comparison is wrong, need typeid since is_equal in one module doesn't equal in another! + static bool is_equal(const QVariant& val1, const QVariant& val2) + { + return val1.value<element_type>() == val2.value<element_type>(); + } + t operator=(const t& datum) { - store(static_cast<element_type>(datum)); + const element_type tmp = static_cast<element_type>(datum); + if (tmp != get()) + store(tmp); return datum; } static constexpr const Qt::ConnectionType DIRECT_CONNTYPE = Qt::AutoConnection; static constexpr const Qt::ConnectionType SAFE_CONNTYPE = Qt::QueuedConnection; - value(bundle b, const QString& name, t def) : base_value(b, name), def(def) + value(bundle b, const QString& name, t def) : base_value(b, name, &is_equal, std::type_index(typeid(element_type))), def(def) { QObject::connect(b.get(), SIGNAL(reloading()), this, SLOT(reload()), |