summaryrefslogtreecommitdiffhomepage
path: root/options/value.hpp
diff options
context:
space:
mode:
authorStanislaw Halik <sthalik@misaki.pl>2016-08-25 11:58:24 +0200
committerStanislaw Halik <sthalik@misaki.pl>2016-08-25 13:37:23 +0200
commit39169acf3bc2bc43cc32a6455d43e9588765c84a (patch)
tree3e0cbee0c68e15c87fe34746d1e9eb148ddd7bd1 /options/value.hpp
parentc7532ed82f57e4281d3f5ecded59a95a4f756b04 (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.hpp32
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()),